aboutsummaryrefslogtreecommitdiff
path: root/modules/TUI/module.jai
diff options
context:
space:
mode:
authordam <dam@gudinoff>2024-05-05 02:34:33 +0100
committerdam <dam@gudinoff>2024-05-05 02:34:33 +0100
commit36af624cdd9cb54454587bfae21b30096986d22e (patch)
tree89fb9d3eb79ff68f047bd30dbcb680e6dce8abc3 /modules/TUI/module.jai
parentcb6c3caaa285bc8bd12c356d57bbfad86d70c0eb (diff)
downloadtask-time-tracker-36af624cdd9cb54454587bfae21b30096986d22e.tar.zst
task-time-tracker-36af624cdd9cb54454587bfae21b30096986d22e.zip
WIP : Cleanup TUI module and improved assert/error messages.
Diffstat (limited to 'modules/TUI/module.jai')
-rw-r--r--modules/TUI/module.jai137
1 files changed, 57 insertions, 80 deletions
diff --git a/modules/TUI/module.jai b/modules/TUI/module.jai
index ab2567d..07d121f 100644
--- a/modules/TUI/module.jai
+++ b/modules/TUI/module.jai
@@ -15,36 +15,46 @@
#assert(false, "Unsupported OS.");
}
+#if COLOR_MODE_BITS == {
+ case 4;
+ #load "palette_4b.jai";
+ case 8;
+ #load "palette_8b.jai";
+ case 24;
+ #load "palette_24b.jai";
+ _;
+ assert(false, "Invalid COLOR_MODE_BITS. Valid values are 4, 8, or 24 (default).");
+}
+
#import "Basic";
#import "String";
#import "Thread";
#import "UTF8";
#load "key_map.jai";
+active := false;
+input_override : Key;
+input_string : string;
+input_buffer : [1024] u8;
+
KEY_SIZE :: #run type_info(Key).runtime_size;
-#run {
- assert(COLOR_MODE_BITS == 4 || COLOR_MODE_BITS == 8 || COLOR_MODE_BITS == 24, "Invalid COLOR_MODE_BITS. Valid values are 4, 8, or 24 (default).");
- assert(input_buffer.count >= KEY_SIZE, "The input buffer size must be capable to hold an entire Key, which should be able to hold an UTF8 code (4 bytes) or a terminal escape code (6 bytes).");
-}
+#assert(input_buffer.count >= KEY_SIZE); // The input buffer size must be capable to hold an entire Key.
-active := false;
-input_buffer : [1024] u8;
-input_string : string;
-input_override : Key;
-previous_logger : (message: string, data: *void, info: Log_Info);
+#scope_module
-module_logger :: (message: string, data: *void, info: Log_Info) {
- write_strings(Commands.SaveCursorPosition, Commands.MainScreenBuffer);
- previous_logger(message, data, info);
- write_strings(Commands.AlternateScreenBuffer, Commands.RestoreCursorPosition);
-}
assert_is_active :: inline () {
assert(active, "Please call setup_terminal() to start using this module.");
}
+log_tui_error :: (format_string: string, args: .. Any) {
+ write_strings(Commands.SaveCursorPosition, Commands.MainScreenBuffer);
+ log_error(format_string, args);
+ write_strings(Commands.AlternateScreenBuffer, Commands.RestoreCursorPosition);
+}
+
#scope_export;
@@ -141,56 +151,7 @@ Commands :: struct #type_info_none {
CursorNormalMode :: "\e[?1l";
}
-// TODO Check which procedures need the assert_is_active call.
-// TODO Review the error messages on the asserts.
-
-////////////////////////////////////////////////////////////////////////////////
-
-
-#scope_file
-
-
-#if COLOR_MODE_BITS == 4 {
- #load "palette_4b.jai";
-
- set_colors :: inline (foreground: Palette, background: Palette) {
- print(
- #run sprint("%0%0", Commands.SetGraphicsRendition, Commands.SetGraphicsRendition),
- cast(u8)foreground + 30, cast(u8)background + 40);
- }
-}
-else #if COLOR_MODE_BITS == 8 {
- #load "palette_8b.jai";
-
- set_colors :: inline (foreground: Palette, background: Palette) {
- print(
- #run sprint(Commands.SetGraphicsRendition, "38;5;%;48;5;%"),
- cast(u8)foreground, cast(u8)background);
- }
-}
-else {
- #load "palette_24b.jai";
-
- set_colors :: inline (foreground: Color_24b, background: Color_24b) {
- print(
- #run sprint(Commands.SetGraphicsRendition, "38;2;%;%;%;48;2;%;%;%"),
- foreground.r, foreground.g, foreground.b,
- background.r, background.g, background.b);
- }
-}
-
-set_font_style :: inline (bold: bool, underline: bool = false, strike_through: bool = false, negative: bool = false) {
- print(
- #run sprint(Commands.SetGraphicsRendition, "%;%;%;%"),
- ifx bold then 1 else 22,
- ifx underline then 4 else 24,
- ifx strike_through then 9 else 29,
- ifx negative then 7 else 27);
-}
-
-
-#scope_export
-
+#add_context terminal_style: Style;
Style :: struct {
#if COLOR_MODE_BITS == 4 || COLOR_MODE_BITS == 8 {
@@ -214,11 +175,32 @@ Style :: struct {
negative: bool;
}
-#add_context terminal_style: Style;
-
set_style :: inline (style: Style) {
- set_font_style(style.bold, style.underline, style.strike_through, style.negative);
- set_colors(style.foreground, style.background);
+ print(
+ #run sprint(Commands.SetGraphicsRendition, "%;%;%;%"),
+ ifx style.bold then 1 else 22,
+ ifx style.underline then 4 else 24,
+ ifx style.strike_through then 9 else 29,
+ ifx style.negative then 7 else 27);
+
+ #if COLOR_MODE_BITS == {
+ case 4;
+ print(
+ #run sprint("%0%0", Commands.SetGraphicsRendition, Commands.SetGraphicsRendition),
+ cast(u8)style.foreground + 30, cast(u8)style.background + 40);
+
+ case 8;
+ print(
+ #run sprint(Commands.SetGraphicsRendition, "38;5;%;48;5;%"),
+ cast(u8)style.foreground, cast(u8)style.background);
+
+ case 24;
+ print(
+ #run sprint(Commands.SetGraphicsRendition, "38;2;%;%;%;48;2;%;%;%"),
+ style.foreground.r, style.foreground.g, style.foreground.b,
+ style.background.r, style.background.g, style.background.b);
+ }
+
context.terminal_style = style;
}
@@ -286,7 +268,7 @@ Keys :: struct #type_info_none {
}
to_key :: (str: $T) -> Key #modify { return T == ([]u8) || T == string; } {
- assert(str.count <= KEY_SIZE, "Invalid argument passed to to_key(): 'str.count' must be less-than or equal to %, but it was %.", KEY_SIZE, str.count);
+ assert(str.count <= KEY_SIZE, "Invalid arguments passed to to_key(): 'str' has more than % bytes and cannot be stored as a Key.", KEY_SIZE);
k: Key;
for 0..str.count-1 {
@@ -325,9 +307,6 @@ setup_terminal :: () -> success := true #must {
input_string.count = 0;
input_override = xx Keys.None;
- previous_logger = context.logger;
- context.logger = module_logger;
-
setup_key_map();
write_strings(
@@ -355,8 +334,6 @@ reset_terminal :: () -> success := true #must {
if !OS_reset_terminal() then return false;
- context.logger = previous_logger;
-
write_strings(
Commands.MainScreenBuffer,
Commands.RestoreCursorPosition,
@@ -446,8 +423,8 @@ get_key :: (timeout_milliseconds: s32 = -1) -> Key {
// At least one of the arguments must be properly setup to avoid an infinite-loop reading the input.
read_input :: (count_limit: int = -1, terminators: .. u8) -> string {
assert_is_active();
- assert(count_limit >= 0 || terminators.count > 0, "Invalid arguments passed to read_input() will result in infinite-loop.");
-
+ assert(count_limit >= 0 || terminators.count > 0, "Invalid arguments passed to read_input(): when 'count_limit' is less-than 0 (ignored), you need to provide 'terminators' to avoid an infinite-loop.");
+
// Read until one of the terminator characters is found.
// Since we don't know the resulting size of the returned string, we must keep the string builder growing.
if count_limit < 0 {
@@ -504,7 +481,7 @@ read_input :: (count_limit: int = -1, terminators: .. u8) -> string {
// Resize discards the input returning an empty string and a Resize key.
read_input_line :: (count_limit: int, is_visible: bool = true) -> string, Key {
assert_is_active();
- assert(count_limit >= 0, "Invalid value passed to count_limit(): %.", count_limit);
+ assert(count_limit >= 0, "Invalid arguments passed to read_input_line(): 'count_limit' must be greater-than or equal to 0.");
builder := String_Builder.{ allocator = temporary_allocator };
@@ -604,7 +581,7 @@ flush_input :: () {
draw_box :: (x: int, y: int, width: int, height: int) {
assert_is_active();
- assert(x > 0 && y > 0 && width > 1 && height > 1, "Invalid arguments passed to draw_box(): (%, %, %, %).\n", x, y, width, height);
+ assert(x > 0 && y > 0 && width > 1 && height > 1, "Invalid arguments passed to draw_box(): 'x' and 'y' must be greater-than 0; 'width' and 'height' must be greater-than 1.");
auto_release_temp();
@@ -674,7 +651,7 @@ get_terminal_size :: () -> width: int, height: int {
assert(input.count >= 3 &&
input[0] == FORMAT[0] && input[1] == FORMAT[1] && input[2] == FORMAT[2] && input[input.count-1] == FORMAT[FORMAT.count-1],
- "Query window size in chars returned invalid response.");
+ "Failed to query window size: invalid response.");
parts := split(input, ";",, temporary_allocator);
rows = parse_int(*parts[1]);
@@ -723,7 +700,7 @@ get_cursor_position :: () -> x: int, y: int {
assert(input.count >= 2 &&
input[0] == FORMAT[0] && input[1] == FORMAT[1] && input[input.count-1] == FORMAT[FORMAT.count-1],
- "Query cursor position returned invalid response.");
+ "Failed to query cursor position: invalid response.");
advance(*input, 2);
parts := split(input, ";",, temporary_allocator);