items) + 4; $this->redraw($left, $top, $width, $height); $showing = true; while ($showing) { while (null === ($ch = $this->terminal->readKey())) { usleep(10000); } if (mb_strlen($ch) == 1) { if ($ch == "\x03") { $showing = false; } if ($ch == "\r") { return array_keys($this->items)[$this->index]; } } else { if ($ch == "k{UP}") { $this->index--; if ($this->index < 0) $this->index = count($this->items) - 1; $this->redraw($left, $top, $width, $height); } elseif ($ch == "k{DOWN}") { $this->index++; if ($this->index >= count($this->items)) $this->index = 0; $this->redraw($left, $top, $width, $height); } } } return null; } private function redraw(int $left, int $top, int $width, int $height) { $visibleItems = $height - 4; // draw head echo "\e[40;37m"; $this->terminal ->writeAt($left, $top + 0, self::U_CORNER_ROUNDED_TOPLEFT.str_repeat(self::U_EDGE_HORIZONTAL,$width - 2).self::U_CORNER_ROUNDED_TOPRIGHT) ->writeAt($left, $top + 1, self::U_EDGE_VERTICAL.str_repeat(" ",$width - 2).self::U_EDGE_VERTICAL) ->writeAt($left + 2, $top + 1, "\e[1m" . $this->title . "\e[22m") ->writeAt($left, $top + 2, self::U_EDGE_VERTICAL_RIGHT.str_repeat(self::U_EDGE_HORIZONTAL,$width - 2).self::U_EDGE_VERTICAL_LEFT) ->writeAt($left, $top + $height - 1, self::U_CORNER_BOTTOMLEFT.str_repeat(self::U_EDGE_HORIZONTAL,$width - 2).self::U_CORNER_BOTTOMRIGHT) ; $keys = array_keys($this->items); 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 = (($n == $this->index)?"\e[37;44m":"\e[40;37m") . $item; $this->terminal ->writeAt($left, $top + 3 + $n, self::U_EDGE_VERTICAL.$item.self::U_EDGE_VERTICAL_THUMB); } echo "\e[0m"; } }