Theming improvements, theme save/load, cursor funcs

This commit is contained in:
2025-10-22 01:21:36 +02:00
parent 9360f4bf94
commit 9a96a7b09e
3 changed files with 103 additions and 11 deletions

View File

@@ -17,26 +17,84 @@ class Style
{ {
} }
public static function fromThemeString(string $style): Style
{
$defs = explode(",", $style);
$tri = function(string $t, string $f) use ($defs) {
if (in_array($t, $defs)) return true;
if (in_array($f, $defs)) return false;
return null;
};
$fg = null;
$bg = null;
foreach ($defs as $def) {
if ($def[0] === 'F') {
$fg = intval(substr($def, 1));
}
if ($def[0] === 'B') {
$bg = intval(substr($def, 1));
}
}
return new Style(
fg: $fg,
bg: $bg,
bold: $tri('b', '-b'),
dim: $tri('d', '-d'),
italic: $tri('i', '-i'),
underline: $tri('u', '-u'),
reverse: $tri('r', '-r'),
reset: in_array('R', $defs),
);
}
public function toThemeString(): string
{
$def = [];
if ($this->reset === true) $def[] = "R";
if ($this->bold === true) $def[] = "b";
if ($this->bold === false) $def[] = "-b";
if ($this->dim === true) $def[] = "d";
if ($this->dim === false) $def[] = "-d";
if ($this->italic === true) $def[] = "i";
if ($this->italic === false) $def[] = "-i";
if ($this->underline === true) $def[] = "u";
if ($this->underline === false) $def[] = "-u";
if ($this->reverse === true) $def[] = "r";
if ($this->reverse === false) $def[] = "-r";
if ($this->fg !== null) $def[] = "F{$this->fg}";
if ($this->bg !== null) $def[] = "B{$this->bg}";
return join(",", $def);
}
public function __invoke(string $content): string public function __invoke(string $content): string
{ {
return $this->toSgr() . $content; return $this->toSgr() . $content;
} }
public function __toString(): string
{
return $this->toSgr();
}
public function toSgr(): string public function toSgr(): string
{ {
$sgr = []; $sgr = [];
if ($this->reset == true) $sgr[] = "0"; if ($this->reset === true) $sgr[] = "0";
if ($this->bold == true) $sgr[] = "1"; if ($this->bold === true) $sgr[] = "1";
if ($this->bold == false) $sgr[] = "22"; if ($this->bold === false) $sgr[] = "22";
if ($this->dim == true) $sgr[] = "2"; if ($this->dim === true) $sgr[] = "2";
if ($this->dim == false) $sgr[] = "22"; if ($this->dim === false) $sgr[] = "22";
if ($this->italic == true) $sgr[] = "3"; if ($this->italic === true) $sgr[] = "3";
if ($this->italic == false) $sgr[] = "23"; if ($this->italic === false) $sgr[] = "23";
if ($this->underline == true) $sgr[] = "4"; if ($this->underline === true) $sgr[] = "4";
if ($this->underline == false) $sgr[] = "24"; if ($this->underline === false) $sgr[] = "24";
if ($this->reverse == true) $sgr[] = "7"; if ($this->reverse === true) $sgr[] = "7";
if ($this->reverse == false) $sgr[] = "27"; if ($this->reverse === false) $sgr[] = "27";
if ($this->fg !== null) { if ($this->fg !== null) {
if ($this->fg > 7) { if ($this->fg > 7) {

View File

@@ -177,6 +177,20 @@ class Terminal implements EventEmitterInterface
echo "\e[?25" . ($visible?"h":"l"); echo "\e[?25" . ($visible?"h":"l");
} }
public function showCursorAt(int $line, int $column): void
{
$this->setCursorPosition($line, $column);
$this->setCursorVisible(true);
}
public function setCursorPosition(int $line, int $column): void
{
$l = $line+1;
$c = $column+1;
$data = "\e[{$l};{$c}H";
$this->write($data);
}
public function writeAt(int $line, int $column, string $data, ?Style $style = null): void public function writeAt(int $line, int $column, string $data, ?Style $style = null): void
{ {
$l = $line+1; $l = $line+1;

View File

@@ -10,6 +10,26 @@ class Theme implements ArrayAccess
private array $styles = []; private array $styles = [];
public function saveFile(string $filename): void
{
$theme = [];
foreach ($this->defaults as $name => $style) {
if (isset($this->styles[$name]))
$style = $this->styles[$name];
$theme[] = sprintf("%s: %s", $name, $style->toThemeString());
}
file_put_contents($filename, join("\n", $theme));
}
public function loadFile(string $filename, bool $throw = true): void
{
$defs = file($filename, FILE_IGNORE_NEW_LINES);
foreach ($defs as $def) {
[$name,$style] = explode(": ", $def);
$this->set($name, Style::fromThemeString($style));
}
}
public function define(string $element, Style $defaultStyle): void public function define(string $element, Style $defaultStyle): void
{ {
$this->defaults[$element] = $defaultStyle; $this->defaults[$element] = $defaultStyle;