diff options
Diffstat (limited to 'modules/TUI/module.jai')
| -rw-r--r-- | modules/TUI/module.jai | 117 |
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(); |
