aboutsummaryrefslogtreecommitdiff
path: root/TUI/module.jai
diff options
context:
space:
mode:
Diffstat (limited to 'TUI/module.jai')
-rw-r--r--TUI/module.jai232
1 files changed, 97 insertions, 135 deletions
diff --git a/TUI/module.jai b/TUI/module.jai
index 0d0f468..78b7605 100644
--- a/TUI/module.jai
+++ b/TUI/module.jai
@@ -11,6 +11,14 @@
#import "Thread";
Drawings :: struct {
+ // TODO Maybe just use unicode instead of jumping back and forth between drawing mode?!
+ // test_drawing_without_mode :: () {
+ // top := "┌───┐";
+ // btm := "└───┘";
+ // print(">%<\n", top);
+ // print(">%<\n", btm);
+ // }
+ // #run test_drawing_without_mode();
CornerBR :: "\x6A";
CornerTR :: "\x6B";
CornerTL :: "\x6C";
@@ -96,111 +104,56 @@ Commands :: struct {
It kinda looks OK, but it may drive the users to extract info from the code while
it should be used only for comparison.
*/
-test_union :: ()
-{
-
- K :: union {
- // #as text: [8] u8;
- text: [8] u8;
- code: u64;
- }
-
- to_key :: inline (value: $T) -> K #modify { return T == u8 || T == ([]u8) || T == string; } {
- k: K;
- #if T == u8 {
- k.text[0] = value;
- }
- #if T == ([]u8) || T == string {
- size := ifx value.count > K.text.count then K.text.count else value.count;
- // assert(size <= K.text.count); This is now under the user responsability.
- memcpy(k.text.data, value.data, size);
- }
- return k;
- }
-
- operator == :: inline (a: K, b: K) -> bool {
- return a.code == b.code;
- }
-
- operator == :: inline (a: K, b: $T) -> bool {
- k := to_key(b);
- return a.code == k.code;
- }
-
-
- // ti := type_info(K);
- print("\n---\n%\n---\n", type_info(K).*);
- a: K;
- b: u8;
- print(">%\n", a == to_key(b));
- c: string = "";
- print(">%\n", a == to_key(c));
- d: []u8 = xx "";
- print(">%\n", a == to_key(d));
- print(">%\n", a == b);
- print(">%\n", a == c);
- print(">%\n", a == d);
-
- zed := K.{ xx "Bazinga!" };
- zed = to_key("abc");
-
- print("\n- - -\n%\n- - -\n", cast(string)zed.text);
+Key :: u64;
- print("$ $ $\n%\n$ $ $\n", zed == "abc");
-
+KEY_SIZE :: #run type_info(Key).runtime_size;
+
+Keys :: enum Key {
+ // Terminal key-codes have 1 to 6 bytes, so we can signal special cases setting the edge-bytes.
+ None :: 0xF0000000_0000000F;
+ Resize :: 0xF0000000_0000001F;
}
-#run test_union();
-/*
- In this block, we're testing having the Key as: [8] u8
- ...WIP...
+/* TODO
+ This has to be compatible with: (#char "a" == key) ... so "a" must be stored in the LSB of key
+ |-|-|-|-|-|
+ string |a|b|c|0|0|
+ key/u64 |0|0|c|b|a| -> that in memory lays as (BE:|0|0|c|b|a|) and (LE:|a|b|c|0|0|)
*/
-/*
-test_array :: ()
-{
- K :: #type,distinct [8] u8;
- K_count :: 8;// #run type_info(K).array_count;
- // #run print("###\n%\n###\n", type_info(K).*);
- // #run print("###\n%\n###\n", type_info(K).array_count);
- // #run print(":%", type_info(K).*);
- // #run print(":%", ;
- // #run print("\n###\n");
- // #run print("%", cast(*Type_Info_Array)type_info(K).array_count);
- // #run print("%", type_info(K).count);
- // #run print("\n###\n");
-
- to_key :: inline (value: $T) -> K #modify { return T == u8 || T == ([]u8) || T == string; } {
- k: K;
- #if T == u8 {
- k[0] = value;
- }
- #if T == ([]u8) || T == string {
- size := ifx value.count > K_count then K_count else value.count;
- // assert(size <= K.text.count); This is now under the user responsability.
- memcpy(k.data, value.data, size);
- }
- return k;
- }
- operator == :: inline (a: K, b: K) -> bool #dump {
- // return memcmp(a.data, b.data, 8) == 0;
- return (cast,force(*u64)*a).* == (cast,force(*u64)*b).*;
+to_key :: inline (str: $T) -> Key #modify { return T == ([]u8) || T == string; } {
+ k: Key;
+ // #if DEBUG {
+ // assert(str.count <= 8); // TODO Add DEBUG to module parameters.
+ // }
+ for 0..str.count-1 #no_abc {
+ k |= ((cast(u64)str[it]) << (it*8));
}
+ return k;
+}
- operator == :: inline (a: K, b: $T) -> bool {
- k := to_key(b);
- return a == k;
+to_string :: inline (key: Key) -> string #dump {
+ str := talloc_string(KEY_SIZE);
+ str.count = 0;
+ while key != 0 #no_abc {
+ str[str.count] = xx key & 0xFF;
+ key >>= 8;
+ str.count += 1;
}
+ return str;
+}
- print("\n:::%\n", K_count);
+test_union :: ()
+{
// ti := type_info(K);
- print("\n---\n%\n---\n", type_info(K).*);
- a: K;
+ print("\n---\n%\n---\n", type_info(Key).*);
+ print("\n---\n%\n---\n", type_info(Key).runtime_size);
+ a: Key;
b: u8;
- print(">%\n", a == to_key(b));
+ print(">%\n", a == b);
c: string = "";
print(">%\n", a == to_key(c));
@@ -208,26 +161,30 @@ test_array :: ()
d: []u8 = xx "";
print(">%\n", a == to_key(d));
- // print(">%\n", a == b);
- // print(">%\n", a == c);
- // print(">%\n", a == d);
-}
-#run test_array();
-*/
-
-// Rest of the module ---
+ top := "┌───┐";
+ btm := "└───┘";
+ print(">%<\n", top);
+ print(">%<\n", btm);
-Key :: u32;
+ str := "abcd";
+ tok := to_key(str);
+ tos := to_string(tok);
+
+ print("1:%:\n", str);
+ print("2:");
+ for 0..7 {
+ val := tok & 0xFF;
+ tok >>=8 ;
+ print("% ", FormatInt.{value=val, base=16, minimum_digits=2});
+ }
+ print(":\n");
+ print("3:%:\n", tos);
+
+}
+#run test_union();
// Terminal action codes are encoded with values incompatible with UTF-8 to avoid collisions.
-// Keys :: struct {
- // None :: #run to_key("\0");
- // Resize :: #run to_key(xx 1);
-// }
-Keys :: enum Key {
- None :: 0xFF000000;
- Resize :: 0xFF000001;
-}
+
initialized := false;
@@ -235,7 +192,10 @@ input_buffer : [64] u8;
input_string : string;
input_override : Key;
-row := 5;
+#run {
+ // Some tests.
+ assert(input_buffer.count >= 6, "The input buffer size must be capable to hold an entire terminal (6 bytes) or UTF8 (4 bytes) code.");
+}
assert_is_initialized :: inline () {
assert(initialized, "TUI is not ready.");
@@ -264,20 +224,6 @@ get_key :: (timeout_milliseconds: s32 = -1) -> Key {
return 1;
}
-
- /*
- TODO WIP Implement UTF-8 support, i.e., merge continuation bytes if needed:
-
- key = arg[0]
- while is_last_utf8_byte(buffer[0]) == false {
- key = key << 8
- advance(buffer)
- key |= buffer[0]
- TODO Sometimes we may not have all the necessary bytes in the buffer... and we may need to fetch some more into it. How to do it?
- }
- advance(arg)
- */
-
if input_override != xx Keys.None {
defer input_override = xx Keys.None;
return input_override;
@@ -293,11 +239,26 @@ get_key :: (timeout_milliseconds: s32 = -1) -> Key {
// FIXME New version...
if input_string.count > 0 {
utf8_bytes := count_utf8_bytes(input_string[0]);
- key: Key;
- for 1..utf8_bytes {
- key = key << 8;
- key |= input_string[utf8_bytes-it];
+
+ // TODO We're assuming the input_buffer contains the entirety of what we need to read for the UTF8 symbols...
+ if utf8_bytes > input_string.count {
+
+ // TODO Test this and make sure it's working...
+ print("<WOW>");
+
+ // Copy buffered bytes to the start, and read the remaining ones from input.
+ for 0..utf8_bytes-1 {
+ input_buffer[it] = input_string[it];
+ }
+ OS_read_input(input_buffer.data + utf8_bytes, utf8_bytes-input_string.count); // TODO Does not check for read errors.
+ input_string.data = input_buffer.data;
+ input_string.count = utf8_bytes;
}
+
+ to_parse := input_string;
+ to_parse.count = utf8_bytes;
+ key := to_key(to_parse);
+
advance(*input_string, utf8_bytes);
return key;
}
@@ -323,12 +284,15 @@ get_key :: (timeout_milliseconds: s32 = -1) -> Key {
input_string.data = input_buffer.data;
input_string.count = bytes_read;
utf8_bytes := count_utf8_bytes(input_string[0]);
+
+ assert(utf8_bytes <= input_string.count, "The input buffer is too small."); // TODO Improve error message.
- key: Key;
- for 1..utf8_bytes {
- key = key << 8;
- key |= input_string[utf8_bytes-it];
- }
+ to_parse := input_string;
+ to_parse.count = utf8_bytes;
+ key := to_key(to_parse);
+
+ advance(*input_string, utf8_bytes);
+ return key;
/// /// /// /// /// /// /// /// ///
// DEBUG
@@ -338,7 +302,7 @@ get_key :: (timeout_milliseconds: s32 = -1) -> Key {
// nr, rc := get_terminal_size();
//
// if row >= (rc - 5) then row = 5;
-//
+ //
// set_cursor_position(row, column);
// for 0..input_string.count-1 {
// print("%:% | ",
@@ -349,8 +313,6 @@ get_key :: (timeout_milliseconds: s32 = -1) -> Key {
// set_cursor_position(br, bc);
/// /// /// /// /// /// /// /// ///
- advance(*input_string, utf8_bytes);
- return key;
}
}
return xx Keys.None;