textbox bugfixes
authorBrendan Hansen <brendan.f.hansen@gmail.com>
Sat, 2 Apr 2022 20:43:44 +0000 (15:43 -0500)
committerBrendan Hansen <brendan.f.hansen@gmail.com>
Sat, 2 Apr 2022 20:43:44 +0000 (15:43 -0500)
src/gfx/ui.onyx
src/utils/input.onyx

index 6afc690e278831b349370f22a01fb9720f833ea1..82bc13fa3b3d2e048658cff2527ed82a0578af00 100644 (file)
@@ -285,33 +285,27 @@ draw_textbox :: (use r: Rect, text_buffer: ^[..] u8, placeholder := null_str, th
             textbox_editing_state.cursor_position = screen_to_cursor(^font, text_x, text_y, text, ~~mx, ~~my);
         }
 
-        move_towards(^textbox_editing_state.action_key_timeout, 0, 0.05f);
-        if textbox_editing_state.action_key_timeout == 0 {
-            keys := input_get_keys_this_frame();
-            for key: iter.as_iterator(^keys) {
-                textbox_editing_state.action_key_timeout = 0.17f;
-
-                switch key.key {
-                    case GLFW_KEY_ESCAPE {
-                        set_active_item(0);
-                        input_release_keys();
-                    }
+        for key: input_get_keys_this_frame() {
+            switch key.key {
+                case GLFW_KEY_ESCAPE {
+                    set_active_item(0);
+                    input_release_keys();
+                }
 
-                    case GLFW_KEY_LEFT  do textbox_editing_state.cursor_position -= 1;
-                    case GLFW_KEY_RIGHT do textbox_editing_state.cursor_position += 1;
-                    case GLFW_KEY_END   do textbox_editing_state.cursor_position = text_buffer.count;
-                    case GLFW_KEY_HOME  do textbox_editing_state.cursor_position = 0;
+                case GLFW_KEY_LEFT  do textbox_editing_state.cursor_position -= 1;
+                case GLFW_KEY_RIGHT do textbox_editing_state.cursor_position += 1;
+                case GLFW_KEY_END   do textbox_editing_state.cursor_position = text_buffer.count;
+                case GLFW_KEY_HOME  do textbox_editing_state.cursor_position = 0;
 
-                    case GLFW_KEY_BACKSPACE {
-                        if textbox_editing_state.cursor_position > 0 {
-                            array.delete(text_buffer, textbox_editing_state.cursor_position - 1);
-                        }
-                        textbox_editing_state.cursor_position = math.max(~~0, textbox_editing_state.cursor_position - 1);
+                case GLFW_KEY_BACKSPACE {
+                    if textbox_editing_state.cursor_position > 0 {
+                        array.delete(text_buffer, textbox_editing_state.cursor_position - 1);
                     }
+                    textbox_editing_state.cursor_position = math.max(~~0, textbox_editing_state.cursor_position - 1);
+                }
 
-                    case GLFW_KEY_DELETE {
-                        array.delete(text_buffer, textbox_editing_state.cursor_position);
-                    }
+                case GLFW_KEY_DELETE {
+                    array.delete(text_buffer, textbox_editing_state.cursor_position);
                 }
             }
         }
index 798eefefba76806526dbf2b1e576e167c3665040..31a9022a75913749d8c8e8524ccf89bb6ecf5654 100644 (file)
@@ -9,29 +9,29 @@ Mouse_Offset_Function :: immediate_get_scroll
 
 
 #local {
-       keys_this_frame  : Set(Key_Descriptor)   // Keys currently being pressed this frame
-       keys_last_frame  : Set(Key_Descriptor)   // Keys being pressed in the last frame
+    keys_this_frame  : Set(Key_Descriptor)   // Keys currently being pressed this frame
+    keys_last_frame  : Set(Key_Descriptor)   // Keys being pressed in the last frame
 
-       key_codepoints : [..] u32
+    key_codepoints : [..] u32
 
-       buttons_this_frame: [8] bool  // Mouse buttons being pressed this frame
-       buttons_last_frame: [8] bool  // Mouse buttons being pressed last frame
+    buttons_this_frame: [8] bool  // Mouse buttons being pressed this frame
+    buttons_last_frame: [8] bool  // Mouse buttons being pressed last frame
 
-       scroll_x: f64
-       scroll_y: f64
+    scroll_x: f64
+    scroll_y: f64
 
-       character_mode := false;
+    character_mode := false;
 }
 
 #init () {
-       set.init(^keys_this_frame);
-       set.init(^keys_last_frame);
+    set.init(^keys_this_frame);
+    set.init(^keys_last_frame);
 }
 
 Key_Descriptor :: struct {
-       key: u32;
-       scancode: u32 = 0;
-       mod: u32      = 0;
+    key: u32;
+    scancode: u32 = 0;
+    mod: u32      = 0;
 }
 #match hash.to_u32 (use x: Key_Descriptor) => hash.to_u32(key);
 #operator == (x, y: Key_Descriptor) => x.key == y.key;
@@ -41,33 +41,48 @@ input_update :: () {
 }
 
 input_post_update :: () {
-       set.clear(^keys_last_frame);
-       for keys_this_frame.entries do keys_last_frame << it.value;
+    set.clear(^keys_last_frame);
+    for keys_this_frame.entries do keys_last_frame << it.value;
 
-       for 8 do buttons_last_frame[it] = buttons_this_frame[it];
+    for 8 do buttons_last_frame[it] = buttons_this_frame[it];
 
-       last_mouse_x = mouse_x;
-       last_mouse_y = mouse_y;
-       scroll_x = 0;
-       scroll_y = 0;
+    last_mouse_x = mouse_x;
+    last_mouse_y = mouse_y;
+    scroll_x = 0;
+    scroll_y = 0;
 
-       array.clear(^key_codepoints);
+    array.clear(^key_codepoints);
 }
 
 input_get_chars_this_frame :: () -> [] u32 {
-       return key_codepoints;
+    return key_codepoints;
 }
 
-input_get_keys_this_frame :: () -> Set(Key_Descriptor) {
-       return keys_this_frame;
+input_get_keys_this_frame :: () -> Iterator(Key_Descriptor) {
+    #persist index := 0;
+
+    next :: (_: rawptr) -> (Key_Descriptor, bool) {
+        if index >= keys_this_frame.entries.count do return .{0}, false;
+
+        while keys_last_frame->has(keys_this_frame.entries[index].value) {
+            index += 1;
+            if index >= keys_this_frame.entries.count do return .{0}, false;
+        }
+
+        defer index += 1;
+        return keys_this_frame.entries[index].value, true;
+    }
+
+    index = 0;
+    return .{ null, next };
 }
 
 input_capture_keys :: () {
-       character_mode = true;
+    character_mode = true;
 }
 
 input_release_keys :: () {
-       character_mode = false;
+    character_mode = false;
 }
 
 is_key_down      :: (key) => !character_mode && set.has(^keys_this_frame, .{key});
@@ -79,94 +94,94 @@ is_button_just_down :: (button) => buttons_this_frame[button] && !buttons_last_f
 is_button_just_up   :: (button) => !buttons_this_frame[button] && buttons_last_frame[button];
 
 #local {
-       last_mouse_x: f64;
-       last_mouse_y: f64;
+    last_mouse_x: f64;
+    last_mouse_y: f64;
 
-       mouse_x: f64;
-       mouse_y: f64;
+    mouse_x: f64;
+    mouse_y: f64;
 }
 
 mouse_get_delta :: () -> (f64, f64) {
-       return mouse_x - last_mouse_x, mouse_y - last_mouse_y;
+    return mouse_x - last_mouse_x, mouse_y - last_mouse_y;
 }
 
 mouse_get_delta_vector :: () -> Vector2 {
-       dmx, dmy := mouse_get_delta();
-       return .{ ~~dmx, ~~dmy };
+    dmx, dmy := mouse_get_delta();
+    return .{ ~~dmx, ~~dmy };
 }
 
 mouse_get_position :: () -> (f64, f64) {
-       mx, my := mouse_x, mouse_y;     
-       #if #defined(Mouse_Offset_Function) {
-               scroll := Mouse_Offset_Function();
-               mx -= ~~ scroll.x;
-               my -= ~~ scroll.y;
-       }
-       return mx, my;
+    mx, my := mouse_x, mouse_y;        
+    #if #defined(Mouse_Offset_Function) {
+        scroll := Mouse_Offset_Function();
+        mx -= ~~ scroll.x;
+        my -= ~~ scroll.y;
+    }
+    return mx, my;
 }
 
 mouse_get_position_vector :: () -> Vector2 {
-       mx, my := mouse_x, mouse_y;     
-       #if #defined(Mouse_Offset_Function) {
-               scroll := Mouse_Offset_Function();
-               mx -= ~~ scroll.x;
-               my -= ~~ scroll.y;
-       }
-       return .{ ~~mx, ~~my };
+    mx, my := mouse_x, mouse_y;        
+    #if #defined(Mouse_Offset_Function) {
+        scroll := Mouse_Offset_Function();
+        mx -= ~~ scroll.x;
+        my -= ~~ scroll.y;
+    }
+    return .{ ~~mx, ~~my };
 }
 
 mouse_get_scroll :: () -> (f64, f64) {
-       return scroll_x, scroll_y;
+    return scroll_x, scroll_y;
 }
 
 mouse_get_scroll_vector :: () -> Vector2 {
-       return .{ ~~scroll_x, ~~scroll_y };
+    return .{ ~~scroll_x, ~~scroll_y };
 }
 
 input_bind_glfw_events :: (window: GLFWwindow_p) {
-       glfwSetKeyCallback(window, INPUT_KEY_EVENT);
-       glfwSetCharCallback(window, INPUT_CHAR_EVENT);
-       glfwSetMouseButtonCallback(window, INPUT_BUTTON_EVENT);
-       glfwSetScrollCallback(window, INPUT_SCROLL_EVENT);
+    glfwSetKeyCallback(window, INPUT_KEY_EVENT);
+    glfwSetCharCallback(window, INPUT_CHAR_EVENT);
+    glfwSetMouseButtonCallback(window, INPUT_BUTTON_EVENT);
+    glfwSetScrollCallback(window, INPUT_SCROLL_EVENT);
 }
 
 #local {
-       INPUT_BUTTON_EVENT :: "__input_button_event"
-       INPUT_KEY_EVENT    :: "__input_key_event"
-       INPUT_SCROLL_EVENT :: "__input_scroll_event"
-       INPUT_CHAR_EVENT   :: "__input_char_event"
+    INPUT_BUTTON_EVENT :: "__input_button_event"
+    INPUT_KEY_EVENT    :: "__input_key_event"
+    INPUT_SCROLL_EVENT :: "__input_scroll_event"
+    INPUT_CHAR_EVENT   :: "__input_char_event"
 }
 
 #export INPUT_BUTTON_EVENT (window: GLFWwindow_p, button, action, mod: u32) {
-       if action == GLFW_PRESS {
-               buttons_this_frame[button] = true;
-       }
+    if action == GLFW_PRESS {
+        buttons_this_frame[button] = true;
+    }
 
-       if action == GLFW_RELEASE {
-               buttons_this_frame[button] = false;
-       }
+    if action == GLFW_RELEASE {
+        buttons_this_frame[button] = false;
+    }
 }
 
 #export INPUT_KEY_EVENT (window: GLFWwindow_p, key, scancode, action, mod: u32) {
-       if action == GLFW_PRESS {
-               keys_this_frame << .{ key, scancode, mod };
-       }
+    if action == GLFW_PRESS {
+        keys_this_frame << .{ key, scancode, mod };
+    }
 
-       if action == GLFW_REPEAT {
-               set.remove(^keys_last_frame, .{key});
-       }
+    if action == GLFW_REPEAT {
+        set.remove(^keys_last_frame, .{key});
+    }
 
-       if action == GLFW_RELEASE {
-               set.remove(^keys_this_frame, .{ key });
-       }
+    if action == GLFW_RELEASE {
+        set.remove(^keys_this_frame, .{ key });
+    }
 }
 
 #export INPUT_CHAR_EVENT (window: GLFWwindow_p, codepoint: u32) {
-       if !character_mode do return;
-       key_codepoints << codepoint;    
+    if !character_mode do return;
+    key_codepoints << codepoint;       
 }
 
 #export INPUT_SCROLL_EVENT (window: GLFWwindow_p, xoff, yoff: f64) {
-       scroll_x = xoff;
-       scroll_y = yoff;
+    scroll_x = xoff;
+    scroll_y = yoff;
 }