aboutsummaryrefslogtreecommitdiff
path: root/modules/TUI/module.jai
diff options
context:
space:
mode:
Diffstat (limited to 'modules/TUI/module.jai')
-rw-r--r--modules/TUI/module.jai117
1 files changed, 49 insertions, 68 deletions
diff --git a/modules/TUI/module.jai b/modules/TUI/module.jai
index e0bd9b4..2d23bff 100644
--- a/modules/TUI/module.jai
+++ b/modules/TUI/module.jai
@@ -1,4 +1,4 @@
-#module_parameters(COLOR_BIT_DEPTH := 24); // TODO - Do #assert module parameters to make sure they are valid.
+#module_parameters(COLOR_BIT_DEPTH := 24); // TODO - Do #assert module parameters to make sure they are valid... and maybe rename to: COLOR_MODE with a enum.
#if OS == {
case .LINUX;
@@ -111,7 +111,7 @@ Commands :: struct {
set_colors :: inline (foreground: Palette, background: Palette) {
print(
- #run sprint("% %", Commands.SetGraphicsRendition, Commands.SetGraphicsRendition),
+ #run sprint("%0%0", Commands.SetGraphicsRendition, Commands.SetGraphicsRendition),
cast(u8)foreground + 30, cast(u8)background + 40);
}
}
@@ -407,13 +407,13 @@ read_input :: (count_limit: int = -1, terminators: .. u8) -> string {
}
}
-read_input_line :: (count_limit: int, is_visible: bool = true, placeholder: string = "") -> string, Key {
+read_input_line :: (count_limit: int, is_visible: bool = true) -> string, Key {
/*
- Use the get_key to read user input and show it on screen.
- Should allow to move the cursor left and right and to delete/backspace.
- Enter should end the input, returning the input string and the Enter key.
- Escape should discard the input returning an empty string and a Escape key.
- Resize should discard the input returning an empty string and a Resize key.
+ Uses the get_key to read user input and show it on screen.
+ Allows to move the cursor left and right and to delete/backspace.
+ Enter ends the input, returning the input string and the Enter key.
+ Escape discards the input returning an empty string and a Escape key.
+ Resize discards the input returning an empty string and a Resize key.
*/
assert(count_limit >= 0, "Invalid value on count_limit parameter.");
@@ -421,32 +421,34 @@ read_input_line :: (count_limit: int, is_visible: bool = true, placeholder: stri
str := alloc_string(count_limit);
str.count = 0;
idx := 0;
-
- // placeholder: string = "",
- // {
- // copy_size := ifx placeholder.count > str.count then str.count else placeholder.count;
- // memcpy(str.data, placeholder.data, copy_size);
- // idx = copy_size;
- // }
-
+
// TODO Some of these may be nice to have:
// > https://unix.stackexchange.com/questions/255707/what-are-the-keyboard-shortcuts-for-the-command-line
x, y := get_cursor_position();
write_strings(Commands.StartBlinking, Commands.BlinkingBarShape);
- // Clear line for input.
- for 1..count_limit {
- print_character(#char " ");
- }
- set_cursor_position(x, y);
-
key := Keys.None;
while true {
auto_release_temp();
-
- key = get_key();
+ chars_count := count_characters(str);
+
+ // Preview input.
+ if is_visible {
+ set_cursor_position(x, y);
+ write_string(str);
+ for chars_count..count_limit-1 print_character(#char " ");
+ }
+ else {
+ set_cursor_position(x, y);
+ for 0..chars_count print_character(#char "*");
+ for chars_count..count_limit-1 print_character(#char " ");
+ }
+ set_cursor_position(x+idx, y);
+
+ // Process input key.
+ key = get_key();
if key == {
case Keys.Resize; #through;
case Keys.Escape; #through;
@@ -455,63 +457,47 @@ read_input_line :: (count_limit: int, is_visible: bool = true, placeholder: stri
case Keys.Left;
if idx > 0 then idx -= 1;
-
+
case Keys.Right;
- if idx < str.count then idx += 1;
-
+ if idx < chars_count then idx += 1;
+
case Keys.Home;
idx = 0;
case Keys.End;
- idx = str.count;
+ idx = chars_count;
case Keys.Delete;
- if idx == str.count continue;
- for idx..str.count-2 {
- str.data[it] = str.data[it+1];
- }
- str.data[str.count-1] = 0;
- str.count -= 1;
-
+ if idx == chars_count continue;
+ delete_character(*str, idx);
+
case Keys.Backspace;
if idx == 0 continue;
idx -= 1;
- for idx..str.count-2 {
- str.data[it] = str.data[it+1];
- }
- str.data[str.count-1] = 0;
- str.count -= 1;
-
+ delete_character(*str, idx);
+
case;
-
- // TODO FIXME Does not support UTF8 input...
-
- if idx >= count_limit continue;
if is_escape_code(key) continue;
+
+ buff_idx := map_character_to_buffer_idx(str, idx);
+ key_str := to_string(key);
- for < count_limit..idx+1 {
- str.data[it] = str.data[it-1];
+ // Make sure we have space to append the new character at the end (in case we're trying to do it).
+ if buff_idx > count_limit - key_str.count then continue;
+
+ // Move text to allow inserting new character.
+ for < count_limit..buff_idx+key_str.count {
+ str.data[it] = str.data[it-key_str.count];
}
- key_str := to_string(key);
- str.data[idx] = key_str.data[0];
+ memcpy(*str.data[buff_idx], key_str.data, key_str.count);
- if str.count < count_limit then str.count += 1;
+ if str.count < count_limit then str.count += key_str.count;
idx += 1;
+
+ // Truncate string to avoid incomplete utf8 codes on the string tail.
+ str.count = truncate_string(str, count_limit);
}
-
- if is_visible {
- set_cursor_position(x, y);
- write_string(str);
- for str.count..count_limit-1 print_character(#char " ");
- }
- else {
- set_cursor_position(x, y);
- for 0..str.count-1 print_character(#char "*");
- for str.count..count_limit-1 print_character(#char " ");
- }
-
- set_cursor_position(x+idx, y);
}
write_strings(Commands.StopBlinking, Commands.DefaultShape);
@@ -559,11 +545,6 @@ flush_input :: () {
input_string.count = 0;
}
-// TODO move style related procedures here!
-// set_style :: () {
- // print("", Commands.) --
-// }
-
draw_box :: (x: int, y: int, width: int, height: int) {
assert_is_active();