From 88b846ab6d05c3eaacc569cbbf27e5dce031ec08 Mon Sep 17 00:00:00 2001 From: Brendan Hansen Date: Sat, 2 Apr 2022 15:43:44 -0500 Subject: [PATCH] textbox bugfixes --- src/gfx/ui.onyx | 40 +++++------ src/utils/input.onyx | 167 +++++++++++++++++++++++-------------------- 2 files changed, 108 insertions(+), 99 deletions(-) diff --git a/src/gfx/ui.onyx b/src/gfx/ui.onyx index 6afc690..82bc13f 100644 --- a/src/gfx/ui.onyx +++ b/src/gfx/ui.onyx @@ -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); } } } diff --git a/src/utils/input.onyx b/src/utils/input.onyx index 798eefe..31a9022 100644 --- a/src/utils/input.onyx +++ b/src/utils/input.onyx @@ -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; } -- 2.25.1