diff --git a/src/Style.php b/src/Style.php index 16f8339..1761e5e 100644 --- a/src/Style.php +++ b/src/Style.php @@ -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 { return $this->toSgr() . $content; } + public function __toString(): string + { + return $this->toSgr(); + } + public function toSgr(): string { $sgr = []; - if ($this->reset == true) $sgr[] = "0"; - if ($this->bold == true) $sgr[] = "1"; - if ($this->bold == false) $sgr[] = "22"; - if ($this->dim == true) $sgr[] = "2"; - if ($this->dim == false) $sgr[] = "22"; - if ($this->italic == true) $sgr[] = "3"; - if ($this->italic == false) $sgr[] = "23"; - if ($this->underline == true) $sgr[] = "4"; - if ($this->underline == false) $sgr[] = "24"; - if ($this->reverse == true) $sgr[] = "7"; - if ($this->reverse == false) $sgr[] = "27"; + if ($this->reset === true) $sgr[] = "0"; + if ($this->bold === true) $sgr[] = "1"; + if ($this->bold === false) $sgr[] = "22"; + if ($this->dim === true) $sgr[] = "2"; + if ($this->dim === false) $sgr[] = "22"; + if ($this->italic === true) $sgr[] = "3"; + if ($this->italic === false) $sgr[] = "23"; + if ($this->underline === true) $sgr[] = "4"; + if ($this->underline === false) $sgr[] = "24"; + if ($this->reverse === true) $sgr[] = "7"; + if ($this->reverse === false) $sgr[] = "27"; if ($this->fg !== null) { if ($this->fg > 7) { diff --git a/src/Terminal.php b/src/Terminal.php index d01d44d..c7976cf 100644 --- a/src/Terminal.php +++ b/src/Terminal.php @@ -177,6 +177,20 @@ class Terminal implements EventEmitterInterface 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 { $l = $line+1; diff --git a/src/Theme.php b/src/Theme.php index 23c3e85..8ca2f81 100644 --- a/src/Theme.php +++ b/src/Theme.php @@ -10,6 +10,26 @@ class Theme implements ArrayAccess 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 { $this->defaults[$element] = $defaultStyle;