learned about glfwSetCharCallback...
authorBrendan Hansen <brendan.f.hansen@gmail.com>
Wed, 9 Mar 2022 03:13:48 +0000 (21:13 -0600)
committerBrendan Hansen <brendan.f.hansen@gmail.com>
Wed, 9 Mar 2022 03:13:48 +0000 (21:13 -0600)
src/gfx/ui.onyx
src/utils/input.onyx

index d9e81b46404f97b390d4be809b563396b80792e2..16baaca418ce1ec5c0c3122f060b6307da3e4a82 100644 (file)
@@ -221,6 +221,10 @@ Textbox_Theme :: struct {
         cursor_position: i32 = 0;
         cursor_animation := 0.0f;
         cursor_animation_speed := 0.02f;
+
+        @HACK // Otherwise the backspace button deletes a character
+        // every frame, which obviously is way too fast.
+        backspace_timeout := 0.0f;
     }
 
     textbox_editing_state := Textbox_Editing_State.{};
@@ -282,6 +286,8 @@ 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.backspace_timeout, 0, 0.05f);
+
         keys := input_get_keys_this_frame();
         for key: iter.as_iterator(^keys) {
             switch key.key {
@@ -296,36 +302,28 @@ draw_textbox :: (use r: Rect, text_buffer: ^[..] u8, placeholder := null_str, th
                 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);
+                    if textbox_editing_state.backspace_timeout == 0 {
+                        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);
+
+                        textbox_editing_state.backspace_timeout = 0.20f;
                     }
-                    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 #default {
-                    if key.key >= 256 {
-                        // This is probably a modifier key.
-                        continue;
-                    }
-
-                    shift_is_pressed := (key.mod & 1) != 0;
-                    index := key.key * 2;
-                    if shift_is_pressed do index += 1;
-
-                    char := key_map[index];
-                    if char != #char "\0" {
-                        // array.push(text_buffer, char);
-                        array.insert(text_buffer, textbox_editing_state.cursor_position, char);
-                        textbox_editing_state.cursor_position += 1;
-                    } else {
-                        println(key.key);
+                    if textbox_editing_state.backspace_timeout == 0 {
+                        array.delete(text_buffer, textbox_editing_state.cursor_position);
+                        textbox_editing_state.backspace_timeout = 0.20f;
                     }
                 }
             }
+        }
+
+        for ch: input_get_chars_this_frame() {
+            array.insert(text_buffer, textbox_editing_state.cursor_position, ~~ch);
+            textbox_editing_state.cursor_position += 1;
             result = true;
         }
 
@@ -739,242 +737,4 @@ scrolling_region_stop :: () {
         b = c1.b * (1 - t) + c2.b * t,
         a = c1.a * (1 - t) + c2.a * t,
     };
-
-    @Relocate @Cleanup
-    // This keymap is very wrong in a lot of ways. It works for my standard US keyboard, but will break horribly
-    // for any other keyboard layout. I would like to use something else from the browser, but unsurprisingly the
-    // browser does not make this easy. Gotta love web "standards"....
-    key_map := u8.[
-        // Keycode     Normal        Shift
-        /* 00  */    #char "\0",   #char "\0",
-        /* 01  */    #char "\0",   #char "\0",
-        /* 02  */    #char "\0",   #char "\0",
-        /* 03  */    #char "\0",   #char "\0",
-        /* 04  */    #char "\0",   #char "\0",
-        /* 05  */    #char "\0",   #char "\0",
-        /* 06  */    #char "\0",   #char "\0",
-        /* 07  */    #char "\0",   #char "\0",
-        /* 08  */    #char "\0",   #char "\0",
-        /* 09  */    #char "\0",   #char "\0",
-        /* 10  */    #char "\0",   #char "\0",
-        /* 11  */    #char "\0",   #char "\0",
-        /* 12  */    #char "\0",   #char "\0",
-        /* 13  */    #char "\0",   #char "\0",
-        /* 14  */    #char "\0",   #char "\0",
-        /* 15  */    #char "\0",   #char "\0",
-        /* 16  */    #char "\0",   #char "\0",
-        /* 17  */    #char "\0",   #char "\0",
-        /* 18  */    #char "\0",   #char "\0",
-        /* 19  */    #char "\0",   #char "\0",
-        /* 20  */    #char "\0",   #char "\0",
-        /* 21  */    #char "\0",   #char "\0",
-        /* 22  */    #char "\0",   #char "\0",
-        /* 23  */    #char "\0",   #char "\0",
-        /* 24  */    #char "\0",   #char "\0",
-        /* 25  */    #char "\0",   #char "\0",
-        /* 26  */    #char "\0",   #char "\0",
-        /* 27  */    #char "\0",   #char "\0",
-        /* 28  */    #char "\0",   #char "\0",
-        /* 29  */    #char "\0",   #char "\0",
-        /* 30  */    #char "\0",   #char "\0",
-        /* 31  */    #char "\0",   #char "\0",
-        /* 32  */    #char " ",    #char " ",
-        /* 33  */    #char "\0",   #char "\0",
-        /* 34  */    #char "\0",   #char "\0",
-        /* 35  */    #char "\0",   #char "\0",
-        /* 36  */    #char "\0",   #char "\0",
-        /* 37  */    #char "\0",   #char "\0",
-        /* 38  */    #char "\0",   #char "\0",
-        /* 39  */    #char "'",    #char "\"",
-        /* 40  */    #char "\0",   #char "\0",
-        /* 41  */    #char "\0",   #char "\0",
-        /* 42  */    #char "\0",   #char "\0",
-        /* 43  */    #char "\0",   #char "\0",
-        /* 44  */    #char ",",    #char "<",
-        /* 45  */    #char "-",    #char "_",
-        /* 46  */    #char ".",    #char ">",
-        /* 47  */    #char "/",    #char "?",
-        /* 48  */    #char "0",    #char ")",
-        /* 49  */    #char "1",    #char "!",
-        /* 50  */    #char "2",    #char "@",
-        /* 51  */    #char "3",    #char "#",
-        /* 52  */    #char "4",    #char "$",
-        /* 53  */    #char "5",    #char "%",
-        /* 54  */    #char "6",    #char "^",
-        /* 55  */    #char "7",    #char "&",
-        /* 56  */    #char "8",    #char "*",
-        /* 57  */    #char "9",    #char "(",
-        /* 58  */    #char "\0",   #char "\0",
-        /* 59  */    #char ";",    #char ":",
-        /* 60  */    #char "\0",   #char "\0",
-        /* 61  */    #char "=",    #char "+",
-        /* 62  */    #char "\0",   #char "\0",
-        /* 63  */    #char "\0",   #char "\0",
-        /* 64  */    #char "\0",   #char "\0",
-        /* 65  */    #char "a",    #char "A",
-        /* 66  */    #char "b",    #char "B",
-        /* 67  */    #char "c",    #char "C",
-        /* 68  */    #char "d",    #char "D",
-        /* 69  */    #char "e",    #char "E",
-        /* 70  */    #char "f",    #char "F",
-        /* 71  */    #char "g",    #char "G",
-        /* 72  */    #char "h",    #char "H",
-        /* 73  */    #char "i",    #char "I",
-        /* 74  */    #char "j",    #char "J",
-        /* 75  */    #char "k",    #char "K",
-        /* 76  */    #char "l",    #char "L",
-        /* 77  */    #char "m",    #char "M",
-        /* 78  */    #char "n",    #char "N",
-        /* 79  */    #char "o",    #char "O",
-        /* 80  */    #char "p",    #char "P",
-        /* 81  */    #char "q",    #char "Q",
-        /* 82  */    #char "r",    #char "R",
-        /* 83  */    #char "s",    #char "S",
-        /* 84  */    #char "t",    #char "T",
-        /* 85  */    #char "u",    #char "U",
-        /* 86  */    #char "v",    #char "V",
-        /* 87  */    #char "w",    #char "W",
-        /* 88  */    #char "x",    #char "X",
-        /* 89  */    #char "y",    #char "Y",
-        /* 90  */    #char "z",    #char "Z",
-        /* 91  */    #char "[",    #char "{",
-        /* 92  */    #char "\\",   #char "|",
-        /* 93  */    #char "]",    #char "}",
-        /* 94  */    #char "\0",   #char "\0",
-        /* 95  */    #char "\0",   #char "\0",
-        /* 96  */    #char "`",    #char "~",
-        /* 97  */    #char "\0",   #char "\0",
-        /* 98  */    #char "\0",   #char "\0",
-        /* 99  */    #char "\0",   #char "\0",
-        /* 100 */    #char "\0",   #char "\0",
-        /* 101 */    #char "\0",   #char "\0",
-        /* 102 */    #char "\0",   #char "\0",
-        /* 103 */    #char "\0",   #char "\0",
-        /* 104 */    #char "\0",   #char "\0",
-        /* 105 */    #char "\0",   #char "\0",
-        /* 106 */    #char "\0",   #char "\0",
-        /* 107 */    #char "\0",   #char "\0",
-        /* 108 */    #char "\0",   #char "\0",
-        /* 109 */    #char "\0",   #char "\0",
-        /* 110 */    #char "\0",   #char "\0",
-        /* 111 */    #char "\0",   #char "\0",
-        /* 112 */    #char "\0",   #char "\0",
-        /* 113 */    #char "\0",   #char "\0",
-        /* 114 */    #char "\0",   #char "\0",
-        /* 115 */    #char "\0",   #char "\0",
-        /* 116 */    #char "\0",   #char "\0",
-        /* 117 */    #char "\0",   #char "\0",
-        /* 118 */    #char "\0",   #char "\0",
-        /* 119 */    #char "\0",   #char "\0",
-        /* 120 */    #char "\0",   #char "\0",
-        /* 121 */    #char "\0",   #char "\0",
-        /* 122 */    #char "\0",   #char "\0",
-        /* 123 */    #char "\0",   #char "\0",
-        /* 124 */    #char "\0",   #char "\0",
-        /* 125 */    #char "\0",   #char "\0",
-        /* 126 */    #char "\0",   #char "\0",
-        /* 127 */    #char "\0",   #char "\0",
-        /* 128 */    #char "\0",   #char "\0",
-        /* 129 */    #char "\0",   #char "\0",
-        /* 130 */    #char "\0",   #char "\0",
-        /* 131 */    #char "\0",   #char "\0",
-        /* 132 */    #char "\0",   #char "\0",
-        /* 133 */    #char "\0",   #char "\0",
-        /* 134 */    #char "\0",   #char "\0",
-        /* 135 */    #char "\0",   #char "\0",
-        /* 136 */    #char "\0",   #char "\0",
-        /* 137 */    #char "\0",   #char "\0",
-        /* 138 */    #char "\0",   #char "\0",
-        /* 139 */    #char "\0",   #char "\0",
-        /* 140 */    #char "\0",   #char "\0",
-        /* 141 */    #char "\0",   #char "\0",
-        /* 142 */    #char "\0",   #char "\0",
-        /* 143 */    #char "\0",   #char "\0",
-        /* 144 */    #char "\0",   #char "\0",
-        /* 145 */    #char "\0",   #char "\0",
-        /* 146 */    #char "\0",   #char "\0",
-        /* 147 */    #char "\0",   #char "\0",
-        /* 148 */    #char "\0",   #char "\0",
-        /* 149 */    #char "\0",   #char "\0",
-        /* 150 */    #char "\0",   #char "\0",
-        /* 151 */    #char "\0",   #char "\0",
-        /* 152 */    #char "\0",   #char "\0",
-        /* 153 */    #char "\0",   #char "\0",
-        /* 154 */    #char "\0",   #char "\0",
-        /* 155 */    #char "\0",   #char "\0",
-        /* 156 */    #char "\0",   #char "\0",
-        /* 157 */    #char "\0",   #char "\0",
-        /* 158 */    #char "\0",   #char "\0",
-        /* 159 */    #char "\0",   #char "\0",
-        /* 160 */    #char "\0",   #char "\0",
-        /* 161 */    #char "\0",   #char "\0",
-        /* 162 */    #char "\0",   #char "\0",
-        /* 163 */    #char "\0",   #char "\0",
-        /* 164 */    #char "\0",   #char "\0",
-        /* 165 */    #char "\0",   #char "\0",
-        /* 166 */    #char "\0",   #char "\0",
-        /* 167 */    #char "\0",   #char "\0",
-        /* 168 */    #char "\0",   #char "\0",
-        /* 169 */    #char "\0",   #char "\0",
-        /* 170 */    #char "\0",   #char "\0",
-        /* 171 */    #char "\0",   #char "\0",
-        /* 172 */    #char "\0",   #char "\0",
-        /* 173 */    #char "\0",   #char "\0",
-        /* 174 */    #char "\0",   #char "\0",
-        /* 175 */    #char "\0",   #char "\0",
-        /* 176 */    #char "\0",   #char "\0",
-        /* 177 */    #char "\0",   #char "\0",
-        /* 178 */    #char "\0",   #char "\0",
-        /* 179 */    #char "\0",   #char "\0",
-        /* 180 */    #char "\0",   #char "\0",
-        /* 181 */    #char "\0",   #char "\0",
-        /* 182 */    #char "\0",   #char "\0",
-        /* 183 */    #char "\0",   #char "\0",
-        /* 184 */    #char "\0",   #char "\0",
-        /* 185 */    #char "\0",   #char "\0",
-        /* 186 */    #char ";",    #char ":",
-        /* 187 */    #char "=",    #char "+",
-        /* 188 */    #char ",",    #char "<",
-        /* 189 */    #char "-",    #char "_",
-        /* 190 */    #char ".",    #char ">",
-        /* 191 */    #char "/",    #char "?",
-        /* 192 */    #char "`",    #char "~",
-        /* 193 */    #char "\0",   #char "\0",
-        /* 194 */    #char "\0",   #char "\0",
-        /* 195 */    #char "\0",   #char "\0",
-        /* 196 */    #char "\0",   #char "\0",
-        /* 197 */    #char "\0",   #char "\0",
-        /* 198 */    #char "\0",   #char "\0",
-        /* 199 */    #char "\0",   #char "\0",
-        /* 200 */    #char "\0",   #char "\0",
-        /* 201 */    #char "\0",   #char "\0",
-        /* 202 */    #char "\0",   #char "\0",
-        /* 203 */    #char "\0",   #char "\0",
-        /* 204 */    #char "\0",   #char "\0",
-        /* 205 */    #char "\0",   #char "\0",
-        /* 206 */    #char "\0",   #char "\0",
-        /* 207 */    #char "\0",   #char "\0",
-        /* 208 */    #char "\0",   #char "\0",
-        /* 209 */    #char "\0",   #char "\0",
-        /* 210 */    #char "\0",   #char "\0",
-        /* 211 */    #char "\0",   #char "\0",
-        /* 212 */    #char "\0",   #char "\0",
-        /* 213 */    #char "\0",   #char "\0",
-        /* 214 */    #char "\0",   #char "\0",
-        /* 215 */    #char "\0",   #char "\0",
-        /* 216 */    #char "\0",   #char "\0",
-        /* 217 */    #char "\0",   #char "\0",
-        /* 218 */    #char "\0",   #char "\0",
-        /* 219 */    #char "[",    #char "{",
-        /* 220 */    #char "\\",   #char "|",
-        /* 221 */    #char "]",    #char "}",
-        /* 222 */    #char "'",    #char "\"",
-        /* 223 */    #char "\0",   #char "\0",
-        /* 224 */    #char "\0",   #char "\0",
-        /* 225 */    #char "\0",   #char "\0",
-        /* 226 */    #char "\0",   #char "\0",
-        /* 227 */    #char "\0",   #char "\0",
-        /* 228 */    #char "\0",   #char "\0",
-        /* 229 */    #char "\0",   #char "\0",
-    ];
 }
index da9a2c33dacf6d4506ef1356555b42535f9e6810..798eefefba76806526dbf2b1e576e167c3665040 100644 (file)
@@ -10,21 +10,21 @@ Mouse_Offset_Function :: immediate_get_scroll
 
 #local {
        keys_this_frame  : Set(Key_Descriptor)   // Keys currently being pressed this frame
-       keys_pulse_frame : Set(Key_Descriptor)   // Keys pressed during this frame, only set once per keypress
        keys_last_frame  : Set(Key_Descriptor)   // Keys being pressed in the last frame
 
+       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
 
        scroll_x: f64
        scroll_y: f64
 
-       keys_captured := false;
+       character_mode := false;
 }
 
 #init () {
        set.init(^keys_this_frame);
-       set.init(^keys_pulse_frame);
        set.init(^keys_last_frame);
 }
 
@@ -38,17 +38,9 @@ Key_Descriptor :: struct {
 
 input_update :: () {
     glfwGetCursorPos(window, ^mouse_x, ^mouse_y);
-
-       set.clear(^keys_pulse_frame);
-       for iter.as_iterator(^keys_this_frame) {
-               if !set.has(^keys_last_frame, it) {
-                       keys_pulse_frame << it;
-               }
-       }
 }
 
 input_post_update :: () {
-       set.clear(^keys_pulse_frame);
        set.clear(^keys_last_frame);
        for keys_this_frame.entries do keys_last_frame << it.value;
 
@@ -58,23 +50,29 @@ input_post_update :: () {
        last_mouse_y = mouse_y;
        scroll_x = 0;
        scroll_y = 0;
+
+       array.clear(^key_codepoints);
+}
+
+input_get_chars_this_frame :: () -> [] u32 {
+       return key_codepoints;
 }
 
 input_get_keys_this_frame :: () -> Set(Key_Descriptor) {
-       return keys_pulse_frame;
+       return keys_this_frame;
 }
 
 input_capture_keys :: () {
-       keys_captured = true;
+       character_mode = true;
 }
 
 input_release_keys :: () {
-       keys_captured = false;
+       character_mode = false;
 }
 
-is_key_down      :: (key) => !keys_captured && set.has(^keys_this_frame, .{key});
-is_key_just_down :: (key) => !keys_captured && set.has(^keys_this_frame, .{key}) && !set.has(^keys_last_frame, .{key});
-is_key_just_up   :: (key) => !keys_captured && !set.has(^keys_this_frame, .{key}) && set.has(^keys_last_frame, .{key});
+is_key_down      :: (key) => !character_mode && set.has(^keys_this_frame, .{key});
+is_key_just_down :: (key) => !character_mode && set.has(^keys_this_frame, .{key}) && !set.has(^keys_last_frame, .{key});
+is_key_just_up   :: (key) => !character_mode && !set.has(^keys_this_frame, .{key}) && set.has(^keys_last_frame, .{key});
 
 is_button_down      :: (button) => buttons_this_frame[button];
 is_button_just_down :: (button) => buttons_this_frame[button] && !buttons_last_frame[button];
@@ -127,6 +125,7 @@ mouse_get_scroll_vector :: () -> Vector2 {
 
 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);
 }
@@ -135,6 +134,7 @@ input_bind_glfw_events :: (window: GLFWwindow_p) {
        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) {
@@ -161,6 +161,11 @@ input_bind_glfw_events :: (window: GLFWwindow_p) {
        }
 }
 
+#export INPUT_CHAR_EVENT (window: GLFWwindow_p, codepoint: u32) {
+       if !character_mode do return;
+       key_codepoints << codepoint;    
+}
+
 #export INPUT_SCROLL_EVENT (window: GLFWwindow_p, xoff, yoff: f64) {
        scroll_x = xoff;
        scroll_y = yoff;