Implement folding (use '+' key), clean up code
This commit is contained in:
+33
-3
@@ -27,6 +27,8 @@ class Menu
|
||||
|
||||
private int $index = 0;
|
||||
|
||||
private int $scroll = 0;
|
||||
|
||||
public function __construct(private Terminal $terminal, private array $items, private string $title = 'Menu')
|
||||
{
|
||||
|
||||
@@ -35,7 +37,16 @@ class Menu
|
||||
public function display(int $left, int $top, int $width, int $height = 0, string|int|null $value): mixed
|
||||
{
|
||||
|
||||
if ($height == 0) $height = count($this->items) + 4;
|
||||
[$w,$h] = $this->terminal->getSize();
|
||||
if ($height == 0) {
|
||||
$height = min($h - 5, count($this->items) + 4);
|
||||
}
|
||||
if ($left == 0) {
|
||||
$left = round(($w - $width) / 2);
|
||||
}
|
||||
if ($top == 0) {
|
||||
$top = round(($h - $height) / 2);
|
||||
}
|
||||
|
||||
$this->redraw($left, $top, $width, $height);
|
||||
|
||||
@@ -69,7 +80,15 @@ class Menu
|
||||
}
|
||||
|
||||
private function redraw(int $left, int $top, int $width, int $height) {
|
||||
|
||||
$visibleItems = $height - 4;
|
||||
|
||||
$scrollTop = $this->scroll;
|
||||
$scrollVisible = $visibleItems / count($this->items); // / $visibleItems;
|
||||
$scrollBottom = $scrollTop + $scrollVisible;
|
||||
$thumbTop = round($scrollTop * $visibleItems);
|
||||
$thumbBottom = round($visibleItems * $scrollBottom);
|
||||
|
||||
// draw head
|
||||
echo "\e[40;37m";
|
||||
$this->terminal
|
||||
@@ -83,12 +102,23 @@ class Menu
|
||||
for ($n = 0; $n < $visibleItems; $n++) {
|
||||
$key = $keys[$n]??null;
|
||||
$item = " " . ($key ? ($this->items[$key]) : null);
|
||||
$item = $item . str_repeat(" ", $width - 2 - mb_strlen($item)) . "\e[40;37m";
|
||||
$item = $item . str_repeat(" ", $width - 2 - $this->itemlen($item)) . "\e[40;37m";
|
||||
$item = (($n == $this->index)?"\e[37;44m":"\e[40;37m") . $item;
|
||||
if ($n >= $thumbTop && $n <= $thumbBottom) {
|
||||
$scrollbar = "\e[97;1m".self::U_EDGE_VERTICAL_THUMB."\e[40;37;22m";
|
||||
} else {
|
||||
$scrollbar = "\e[37;2m".self::U_EDGE_VERTICAL_SCROLL."\e[40;37;22m";
|
||||
}
|
||||
$this->terminal
|
||||
->writeAt($left, $top + 3 + $n, self::U_EDGE_VERTICAL.$item.self::U_EDGE_VERTICAL_THUMB);
|
||||
->writeAt($left, $top + 3 + $n, self::U_EDGE_VERTICAL.$item.$scrollbar);
|
||||
}
|
||||
echo "\e[0m";
|
||||
}
|
||||
|
||||
private function itemlen(string $item): int
|
||||
{
|
||||
$item = preg_replace('<\e\[.+?m>', '', $item);
|
||||
return mb_strlen($item);
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user