From 7469ce1ab6c761e81334b918a34972fedba0923e Mon Sep 17 00:00:00 2001 From: dam Date: Tue, 12 Sep 2023 01:04:16 +0100 Subject: Adding a terminal user interface module (like ncurses but way simpler). --- tui.jai | 106 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 106 insertions(+) create mode 100644 tui.jai (limited to 'tui.jai') diff --git a/tui.jai b/tui.jai new file mode 100644 index 0000000..a0eb025 --- /dev/null +++ b/tui.jai @@ -0,0 +1,106 @@ +#import "Basic"; + +Drawings :: struct { + CornerBR :: "\x6A"; + CornerTR :: "\x6B"; + CornerTL :: "\x6C"; + CornerBL :: "\x6D"; + Cross :: "\x6E"; + LineH :: "\x71"; + TeeL :: "\x74"; + TeeR :: "\x75"; + TeeB :: "\x76"; + TeeT :: "\x77"; + LineV :: "\x78"; +} + +Commands :: struct { + EnterAlternateBuffer :: "\e[?1049h"; + EnterMainBuffer :: "\e[?1049l"; + + EnterDrawingMode :: "\e(0"; + EnterNormalMode :: "\e(B"; + ClearScreen :: "\e[2J"; + + // Cursor Visibility + ShowCursor :: "\e[?25h"; + HideCursor :: "\e[?25l"; + StartBlinking :: "\e[?25h]"; + StopBlinking :: "\e[?25l]"; + + // Cursor Shape + DefaultShape :: "\e[0 q"; + BlinkingBlockShape :: "\e[1 q"; + SteadyBlockShape :: "\e[2 q"; + BlinkingUnderlineShape :: "\e[3 q"; + SteadyUnderlineShape :: "\e[4 q"; + BlinkingBarShape :: "\e[5 q"; + SteadyBarShape :: "\e[6 q"; + + // Input Mode + KeypadAppMode :: "\e="; + KeypadNumMode :: "\e>"; + CursorAppMode :: "\e[?1h"; + CursorNormalMode :: "\e[?1l"; + + // Query State + QueryCursorPos :: "\e[6n"; // Emits the cursor position as: ESC [ ; R Where = row and = column. + QueryDeviceAttributes :: "\e[0c"; +} + +start :: () { + write_string(Commands.EnterAlternateBuffer); +} + +stop :: () { + write_string(Commands.EnterMainBuffer); +} + +draw_box :: (x: int, y: int, width: int, height: int, to_standard_error := false) { + + write_string(Commands.HideCursor); + write_strings( + // Commands.EnterNormalMode, + Commands.EnterDrawingMode, + "\e[1;1H", // Move to position 1,1 + // TODO // Move pointer to top-left corner. + Drawings.CornerTL, + to_standard_error = to_standard_error); + + for 1..width-2 { + write_string(Drawings.LineH, to_standard_error = to_standard_error); + } + write_string(Drawings.CornerTR, to_standard_error = to_standard_error); + + + // TODO Take care of the temporary allocations. + for idx: 2..height-1 { + tmpL := tprint("\e[%;%H", idx, 1); + tmpR := tprint("\e[%;%H", idx, width); + write_strings( + tmpL, + Drawings.LineV, + tmpR, + Drawings.LineV, + to_standard_error = to_standard_error); + } + + tmpBL := tprint("\e[%;%H", height, 1); + write_strings( + tmpBL, + Drawings.CornerBL, + to_standard_error = to_standard_error); + for 1..width-2 { + write_string(Drawings.LineH, to_standard_error = to_standard_error); + } + write_string(Drawings.CornerBR, to_standard_error = to_standard_error); + + write_strings( + // TODO // print + Commands.EnterNormalMode, + to_standard_error = to_standard_error); +} + +clear_screen :: inline () { + write_string(Commands.ClearScreen); +} -- cgit v1.2.3