From e5f550e362ca6d9233bede1bc2ece5a87eb5a940 Mon Sep 17 00:00:00 2001 From: Brendan Hansen Date: Tue, 8 Mar 2022 21:13:48 -0600 Subject: [PATCH] learned about glfwSetCharCallback... --- src/gfx/ui.onyx | 282 ++++--------------------------------------- src/utils/input.onyx | 39 +++--- 2 files changed, 43 insertions(+), 278 deletions(-) diff --git a/src/gfx/ui.onyx b/src/gfx/ui.onyx index d9e81b4..16baaca 100644 --- a/src/gfx/ui.onyx +++ b/src/gfx/ui.onyx @@ -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", - ]; } diff --git a/src/utils/input.onyx b/src/utils/input.onyx index da9a2c3..798eefe 100644 --- a/src/utils/input.onyx +++ b/src/utils/input.onyx @@ -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; -- 2.25.1