Fix scrollbars on Menu/MessageBox
This commit is contained in:
		@@ -490,6 +490,7 @@ class Editor
 | 
			
		||||
    private function doOpenFile()
 | 
			
		||||
    {
 | 
			
		||||
        $wd = getcwd();
 | 
			
		||||
        $menu = new Menu($this->term, []);
 | 
			
		||||
        while (true) {
 | 
			
		||||
            $items = [
 | 
			
		||||
                dirname($wd) => sprintf(
 | 
			
		||||
@@ -508,9 +509,11 @@ class Editor
 | 
			
		||||
                    date("Y-m-d H:i:s", filemtime($file))
 | 
			
		||||
                );
 | 
			
		||||
            }
 | 
			
		||||
            $menu = new Menu($this->term, $items, $wd);
 | 
			
		||||
            $this->redrawInfoBar([ '^C' => "Cancel", '↑↓' => "Navigate", 'Enter' => "Select/Open" ]);
 | 
			
		||||
            $sel = $menu->display(0, 0, 70, 20, null);
 | 
			
		||||
            $sel = $menu
 | 
			
		||||
                ->setItems($items)
 | 
			
		||||
                ->setTitle($wd)
 | 
			
		||||
                ->display(0, 0, 70, 20, null);
 | 
			
		||||
            if ($sel === null) {
 | 
			
		||||
                $this->redrawEditor();
 | 
			
		||||
                return;
 | 
			
		||||
 
 | 
			
		||||
@@ -20,8 +20,8 @@ class Menu
 | 
			
		||||
    const U_EDGE_HORIZONTAL = "\u{2500}";
 | 
			
		||||
 | 
			
		||||
    const U_EDGE_VERTICAL = "\u{2502}";
 | 
			
		||||
    const U_EDGE_VERTICAL_SCROLL = "\u{250a}";
 | 
			
		||||
    const U_EDGE_VERTICAL_THUMB = "\u{2503}";
 | 
			
		||||
    const U_EDGE_VERTICAL_SCROLL = "\u{2591}";
 | 
			
		||||
    const U_EDGE_VERTICAL_THUMB = "\u{2593}";
 | 
			
		||||
    const U_EDGE_VERTICAL_LEFT = "\u{2524}";
 | 
			
		||||
    const U_EDGE_VERTICAL_RIGHT = "\u{251c}";
 | 
			
		||||
 | 
			
		||||
@@ -29,13 +29,55 @@ class Menu
 | 
			
		||||
 | 
			
		||||
    private int $scroll = 0;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * constructor
 | 
			
		||||
     *
 | 
			
		||||
     * @param Terminal $terminal
 | 
			
		||||
     * @param array $items
 | 
			
		||||
     * @param string $title
 | 
			
		||||
     */
 | 
			
		||||
    public function __construct(private Terminal $terminal, private array $items, private string $title = 'Menu')
 | 
			
		||||
    {
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Update the menu items
 | 
			
		||||
     *
 | 
			
		||||
     * @param array $items
 | 
			
		||||
     * @return self
 | 
			
		||||
     */
 | 
			
		||||
    public function setItems(array $items): self
 | 
			
		||||
    {
 | 
			
		||||
        $this->items = $items;
 | 
			
		||||
        return $this;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Set the menu title
 | 
			
		||||
     *
 | 
			
		||||
     * @param string $title
 | 
			
		||||
     * @return self
 | 
			
		||||
     */
 | 
			
		||||
    public function setTitle(string $title): self
 | 
			
		||||
    {
 | 
			
		||||
        $this->title = $title;
 | 
			
		||||
        return $this;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Display the menu
 | 
			
		||||
     *
 | 
			
		||||
     * @param int $left
 | 
			
		||||
     * @param int $top
 | 
			
		||||
     * @param int $width
 | 
			
		||||
     * @param int $height
 | 
			
		||||
     * @param string|int|null $value
 | 
			
		||||
     * @return mixed
 | 
			
		||||
     */
 | 
			
		||||
    public function display(int $left, int $top, int $width, int $height = 0, string|int|null $value): mixed
 | 
			
		||||
    {
 | 
			
		||||
        $this->index = 0;
 | 
			
		||||
 | 
			
		||||
        [$w,$h] = $this->terminal->getSize();
 | 
			
		||||
        if ($height == 0) {
 | 
			
		||||
@@ -80,6 +122,15 @@ class Menu
 | 
			
		||||
        return null;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Redraw menu
 | 
			
		||||
     *
 | 
			
		||||
     * @param int $left
 | 
			
		||||
     * @param int $top
 | 
			
		||||
     * @param int $width
 | 
			
		||||
     * @param int $height
 | 
			
		||||
     * @return void
 | 
			
		||||
     */
 | 
			
		||||
    private function redraw(int $left, int $top, int $width, int $height) {
 | 
			
		||||
 | 
			
		||||
        $visibleItems = $height - 2;
 | 
			
		||||
@@ -93,10 +144,9 @@ class Menu
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        $scrollTop = $this->scroll;
 | 
			
		||||
        $scrollVisible = $visibleItems / count($this->items); // / $visibleItems;
 | 
			
		||||
        $scrollBottom = $scrollTop + $scrollVisible;
 | 
			
		||||
        $thumbTop = round($scrollTop * $visibleItems);
 | 
			
		||||
        $thumbBottom = round($visibleItems * $scrollBottom);
 | 
			
		||||
        $scrollBottom = $scrollTop + $visibleItems - 1;
 | 
			
		||||
        $thumbTop = round(($visibleItems - 1) / count($this->items) * $scrollTop);
 | 
			
		||||
        $thumbBottom = round(($visibleItems - 1) / count($this->items) * $scrollBottom);
 | 
			
		||||
 | 
			
		||||
        $tleft = round(($width / 2) - ((mb_strlen($this->title) + 2) / 2));
 | 
			
		||||
 | 
			
		||||
@@ -135,6 +185,12 @@ class Menu
 | 
			
		||||
        echo "\e[0m";
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Calculate item length without markup
 | 
			
		||||
     *
 | 
			
		||||
     * @param string $item
 | 
			
		||||
     * @return int
 | 
			
		||||
     */
 | 
			
		||||
    private function itemlen(string $item): int
 | 
			
		||||
    {
 | 
			
		||||
        $item = preg_replace('<\e\[.+?m>', '', $item);
 | 
			
		||||
 
 | 
			
		||||
@@ -80,11 +80,16 @@ class MessageBox
 | 
			
		||||
        $visibleItems = $height - 4;
 | 
			
		||||
 | 
			
		||||
        // calculate scrollbar thumb positions
 | 
			
		||||
        $scrollTop = ($this->scroll / ($maxScroll + $visibleItems));
 | 
			
		||||
        $scrollVisible = $visibleItems / count($wrapped); // / $visibleItems;
 | 
			
		||||
        $scrollBottom = $scrollTop + $scrollVisible;
 | 
			
		||||
        $thumbTop = round($scrollTop * $visibleItems);
 | 
			
		||||
        $thumbBottom = round($visibleItems * $scrollBottom);
 | 
			
		||||
        // $scrollTop = ($this->scroll / ($maxScroll + $visibleItems));
 | 
			
		||||
        // $scrollVisible = $visibleItems / count($wrapped); // / $visibleItems;
 | 
			
		||||
        // $scrollBottom = $scrollTop + $scrollVisible;
 | 
			
		||||
        // $thumbTop = round($scrollTop * $visibleItems);
 | 
			
		||||
        // $thumbBottom = round($visibleItems * $scrollBottom);
 | 
			
		||||
 | 
			
		||||
        $scrollTop = $this->scroll;
 | 
			
		||||
        $scrollBottom = $scrollTop + $visibleItems - 1;
 | 
			
		||||
        $thumbTop = round(($visibleItems - 1) / count($wrapped) * $scrollTop);
 | 
			
		||||
        $thumbBottom = round(($visibleItems - 1) / count($wrapped) * $scrollBottom);
 | 
			
		||||
 | 
			
		||||
        echo "\e[40;37m";
 | 
			
		||||
        $this->terminal
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user