Add messagebox, bugfixes
This commit is contained in:
110
src/Editor/MessageBox.php
Normal file
110
src/Editor/MessageBox.php
Normal file
@ -0,0 +1,110 @@
|
||||
<?php
|
||||
|
||||
namespace NoccyLabs\JEdit\Editor;
|
||||
|
||||
use NoccyLabs\JEdit\Terminal\Terminal;
|
||||
|
||||
class MessageBox
|
||||
{
|
||||
|
||||
const U_CORNER_TOPLEFT = "\u{250c}";
|
||||
const U_CORNER_TOPRIGHT = "\u{2510}";
|
||||
const U_CORNER_BOTTOMLEFT = "\u{2514}";
|
||||
const U_CORNER_BOTTOMRIGHT = "\u{2518}";
|
||||
|
||||
const U_CORNER_ROUNDED_TOPLEFT = "\u{256d}";
|
||||
const U_CORNER_ROUNDED_TOPRIGHT = "\u{256e}";
|
||||
const U_CORNER_ROUNDED_BOTTOMLEFT = "\u{2570}";
|
||||
const U_CORNER_ROUNDED_BOTTOMRIGHT = "\u{256f}";
|
||||
|
||||
const U_EDGE_HORIZONTAL = "\u{2500}";
|
||||
|
||||
const U_EDGE_VERTICAL = "\u{2502}";
|
||||
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}";
|
||||
|
||||
private int $scroll = 0;
|
||||
|
||||
public function __construct(private Terminal $terminal, private string $text, private string $title = 'Message')
|
||||
{
|
||||
}
|
||||
|
||||
public function display(int $left, int $top, int $width, int $height = 0): void
|
||||
{
|
||||
$wrapped = explode("\n", wordwrap($this->text, $width - 4, cut_long_words:true));
|
||||
|
||||
if ($height == 0) $height = count($wrapped) + 4;
|
||||
|
||||
$maxScroll = (count($wrapped) > $height) ? count($wrapped) - $height + 4 : 0;
|
||||
|
||||
$this->redraw($left, $top, $width, $height, $wrapped, $this->title, $maxScroll);
|
||||
|
||||
$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") {
|
||||
$showing = false;
|
||||
}
|
||||
} else {
|
||||
if ($ch == "k{UP}") {
|
||||
$this->scroll--;
|
||||
if ($this->scroll < 0) $this->scroll = 0;
|
||||
$this->redraw($left, $top, $width, $height, $wrapped, $this->title, $maxScroll);
|
||||
} elseif ($ch == "k{DOWN}") {
|
||||
$this->scroll++;
|
||||
if ($this->scroll > $maxScroll) $this->scroll = $maxScroll;
|
||||
$this->redraw($left, $top, $width, $height, $wrapped, $this->title, $maxScroll);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
private function redraw(int $left, int $top, int $width, int $height, array $wrapped, string $title, int $maxScroll) {
|
||||
$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);
|
||||
|
||||
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)
|
||||
;
|
||||
for ($n = 0; $n < $visibleItems; $n++) {
|
||||
if (isset($wrapped[$n+$this->scroll])) {
|
||||
$item = " " . $wrapped[$n+$this->scroll]??null;
|
||||
$item = $item . str_repeat(" ", $width - 2 - mb_strlen($item)) . "\e[40;37m";
|
||||
} else {
|
||||
$item = str_repeat(" ", $width - 2)."\e[40;37m";
|
||||
}
|
||||
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.$scrollbar);
|
||||
}
|
||||
|
||||
echo "\e[0m";
|
||||
}
|
||||
|
||||
}
|
Reference in New Issue
Block a user