diff --git a/src/Editor/Editor.php b/src/Editor/Editor.php index 1ff301e..79f09ed 100644 --- a/src/Editor/Editor.php +++ b/src/Editor/Editor.php @@ -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; diff --git a/src/Editor/Menu.php b/src/Editor/Menu.php index 204f112..3d26154 100644 --- a/src/Editor/Menu.php +++ b/src/Editor/Menu.php @@ -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); diff --git a/src/Editor/MessageBox.php b/src/Editor/MessageBox.php index c0c2e76..2e5888d 100644 --- a/src/Editor/MessageBox.php +++ b/src/Editor/MessageBox.php @@ -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