From b1e857cf1471d1871a9396696b22fa531da98249 Mon Sep 17 00:00:00 2001 From: Aldrik Ramaekers Date: Sat, 23 Nov 2024 22:33:43 +0100 Subject: add projbase to repo --- project-base/src/input.c | 339 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 339 insertions(+) create mode 100644 project-base/src/input.c (limited to 'project-base/src/input.c') diff --git a/project-base/src/input.c b/project-base/src/input.c new file mode 100644 index 0000000..7151c6a --- /dev/null +++ b/project-base/src/input.c @@ -0,0 +1,339 @@ +/* +* BSD 2-Clause “Simplified” License +* Copyright (c) 2019, Aldrik Ramaekers, aldrik.ramaekers@protonmail.com +* All rights reserved. +*/ + +inline bool mouse_interacts_peak(s32 x, s32 y, s32 w, s32 h) +{ + // Mouse is in rectangle and mouse has not been clicked yet. + vec4 area = renderer->render_get_scissor(); + bool result = (!_global_mouse.is_hovering_item) && + (_global_mouse.x >= x && _global_mouse.x <= x+w && _global_mouse.y >= y && _global_mouse.y <= y+h) && + (_global_mouse.x >= area.x && _global_mouse.x <= area.x+area.w && _global_mouse.y >= area.y && _global_mouse.y <= area.y+area.h); + return result; +} + +inline bool mouse_interacts(s32 x, s32 y, s32 w, s32 h) +{ + // Mouse is in rectangle and mouse has not been clicked yet. + vec4 area = renderer->render_get_scissor(); + bool result = (!_global_mouse.is_hovering_item) && + (_global_mouse.x >= x && _global_mouse.x <= x+w && _global_mouse.y >= y && _global_mouse.y <= y+h) && + (_global_mouse.x >= area.x && _global_mouse.x <= area.x+area.w && _global_mouse.y >= area.y && _global_mouse.y <= area.y+area.h); + if (result) _global_mouse.is_hovering_item = true; + return result; +} + +inline bool is_left_down() +{ + bool result = _global_mouse.left_state & MOUSE_DOWN; + if (result) reset_left_down(); + return result; +} + +inline bool is_left_released() +{ + return _global_mouse.left_state & MOUSE_RELEASE; +} + +inline bool is_left_clicked_peak() +{ + return _global_mouse.left_state & MOUSE_CLICK && _global_mouse.inside_of_window; +} + +inline bool is_left_clicked() +{ + bool result = _global_mouse.left_state & MOUSE_CLICK && _global_mouse.inside_of_window; + if (result) reset_left_click(); + return result; +} + +inline bool is_left_double_clicked() +{ + return _global_mouse.left_state & MOUSE_DOUBLE_CLICK; +} + +inline bool is_right_down() +{ + return _global_mouse.right_state & MOUSE_DOWN; +} + +inline bool is_right_released() +{ + return _global_mouse.right_state & MOUSE_RELEASE; +} + +inline bool is_right_clicked() +{ + return _global_mouse.right_state & MOUSE_CLICK; +} + +inline bool keyboard_is_key_down(s16 key) +{ + return _global_keyboard.keys[key]; +} + +inline bool keyboard_is_key_pressed(s16 key) +{ + return _global_keyboard.input_keys[key]; +} + +inline void keyboard_set_input_text(char *text) +{ + string_copyn(_global_keyboard.input_text, text, MAX_INPUT_LENGTH); + u32 len = utf8len(_global_keyboard.input_text); + _global_keyboard.cursor = len; + _global_keyboard.input_text_len = len; +} + +mouse_input mouse_input_create() +{ + mouse_input mouse; + mouse.x = -1; + mouse.y = -1; + mouse.move_x = 0; + mouse.move_y = 0; + mouse.left_state = 0; + mouse.right_state = 0; + mouse.is_hovering_item = false; + mouse.inside_of_window = false; + + return mouse; +} + +keyboard_input keyboard_input_create() +{ + keyboard_input keyboard; + keyboard.modifier_state = 0; + keyboard.input_text = mem_alloc(MAX_INPUT_LENGTH); + keyboard.input_text[0] = '\0'; + keyboard.take_input = false; + keyboard.cursor = 0; + keyboard.input_text_len = 0; + keyboard.input_mode = INPUT_FULL; + keyboard.has_selection = false; + keyboard.selection_begin_offset = 0; + keyboard.selection_length = 0; + memset(keyboard.keys, 0, MAX_KEYCODE); + + return keyboard; +} + +void keyboard_set_input_mode(keyboard_input_mode mode) +{ + _global_keyboard.input_mode = mode; +} + +inline void keyboard_input_destroy() +{ + mem_free(_global_keyboard.input_text); +} + +static void keyboard_handle_input_copy_and_paste(platform_window *window) +{ + bool is_lctrl_down = _global_keyboard.keys[KEY_LEFT_CONTROL]; + + if (is_lctrl_down && keyboard_is_key_pressed(KEY_V)) + { + char buf[MAX_INPUT_LENGTH]; + bool result = platform_get_clipboard(window, buf); + + if (_global_keyboard.input_mode == INPUT_NUMERIC && !string_is_numeric(buf)) + { + return; + } + + if (_global_keyboard.has_selection) + { + _global_keyboard.cursor = _global_keyboard.selection_begin_offset; + utf8_str_remove_range(_global_keyboard.input_text, _global_keyboard.selection_begin_offset, + _global_keyboard.selection_begin_offset + _global_keyboard.selection_length); + _global_keyboard.has_selection = false; + _global_keyboard.text_changed = true; + } + + if (result) + { + s32 len = utf8len(buf); + utf8_str_insert_utf8str(_global_keyboard.input_text, _global_keyboard.cursor, buf); + + _global_keyboard.cursor += len; + _global_keyboard.input_text_len += len; + _global_keyboard.text_changed = true; + } + } + else if (is_lctrl_down && keyboard_is_key_pressed(KEY_C)) + { + char buffer[MAX_INPUT_LENGTH]; + utf8_str_copy_range(_global_keyboard.input_text, + _global_keyboard.selection_begin_offset, + _global_keyboard.selection_begin_offset+_global_keyboard.selection_length, + buffer); + + if (!string_equals(buffer, "")) + platform_set_clipboard(window, buffer); + } +} + +void keyboard_handle_input_string(platform_window *window, char *ch) +{ + keyboard_handle_input_copy_and_paste(window); + + bool is_lctrl_down = _global_keyboard.keys[KEY_LEFT_CONTROL]; + + if (ch) + { + if (string_equals(ch, "\n")) is_lctrl_down = false; + + if (_global_keyboard.input_text_len < MAX_INPUT_LENGTH && !is_lctrl_down) + { + if (_global_keyboard.has_selection) + { + _global_keyboard.cursor = _global_keyboard.selection_begin_offset; + utf8_str_remove_range(_global_keyboard.input_text, _global_keyboard.selection_begin_offset, + _global_keyboard.selection_begin_offset + _global_keyboard.selection_length); + _global_keyboard.has_selection = false; + _global_keyboard.text_changed = true; + } + + if (_global_keyboard.input_text_len) + { + utf8_str_insert_at(_global_keyboard.input_text, _global_keyboard.cursor, *ch); + _global_keyboard.text_changed = true; + } + else + { + string_appendn(_global_keyboard.input_text, ch, MAX_INPUT_LENGTH); + _global_keyboard.text_changed = true; + } + + _global_keyboard.cursor++; + _global_keyboard.input_text_len = utf8len(_global_keyboard.input_text); + } + } + else + { + bool is_lctrl_down = _global_keyboard.keys[KEY_LEFT_CONTROL]; + + // cursor movement + if (keyboard_is_key_down(KEY_LEFT) && _global_keyboard.cursor > 0) + { + if (is_lctrl_down) + _global_keyboard.cursor = 0; + else + _global_keyboard.cursor--; + } + if (keyboard_is_key_down(KEY_RIGHT) && _global_keyboard.cursor < _global_keyboard.input_text_len) + { + if (is_lctrl_down) + _global_keyboard.cursor = utf8len(_global_keyboard.input_text); + else + _global_keyboard.cursor++; + } + } + + if (keyboard_is_key_pressed(KEY_X)) + { + bool is_lctrl_down = _global_keyboard.keys[KEY_LEFT_CONTROL]; + + if (is_lctrl_down) + { + // copy selection + if (_global_keyboard.has_selection) + { + char buffer[MAX_INPUT_LENGTH]; + utf8_str_copy_range(_global_keyboard.input_text, + _global_keyboard.selection_begin_offset, + _global_keyboard.selection_begin_offset+_global_keyboard.selection_length, + buffer); + + if (!string_equals(buffer, "")) + platform_set_clipboard(window, buffer); + } + + // delete selection + if (_global_keyboard.has_selection) + { + utf8_str_remove_range(_global_keyboard.input_text, _global_keyboard.selection_begin_offset, + _global_keyboard.selection_begin_offset + _global_keyboard.selection_length); + _global_keyboard.has_selection = false; + _global_keyboard.text_changed = true; + + if (_global_keyboard.selection_begin_offset < _global_keyboard.cursor) + { + _global_keyboard.cursor -= _global_keyboard.selection_length; + } + } + + _global_keyboard.input_text_len = utf8len(_global_keyboard.input_text); + } + } + + if (keyboard_is_key_down(KEY_BACKSPACE)) + { + _global_keyboard.keys[KEY_BACKSPACE] = false; + + bool is_lctrl_down = _global_keyboard.keys[KEY_LEFT_CONTROL]; + + if (_global_keyboard.has_selection) + { + utf8_str_remove_range(_global_keyboard.input_text, _global_keyboard.selection_begin_offset, + _global_keyboard.selection_begin_offset + _global_keyboard.selection_length); + _global_keyboard.has_selection = false; + _global_keyboard.text_changed = true; + + if (_global_keyboard.selection_begin_offset < _global_keyboard.cursor) + { + _global_keyboard.cursor -= _global_keyboard.selection_length; + } + } + else if (is_lctrl_down) + { + char *iter = _global_keyboard.input_text; + s32 index = 0; + s32 found_index = 0; + utf8_int32_t br; + while((iter = utf8codepoint(iter, &br)) && index < _global_keyboard.cursor && br) + { + index++; + if (br == ' ' && index+1 < _global_keyboard.cursor) + { + found_index = index; + } + } + + for (s32 i = found_index; i < _global_keyboard.cursor; i++) + { + utf8_str_remove_at(_global_keyboard.input_text, found_index); + } + _global_keyboard.cursor = found_index; + _global_keyboard.text_changed = true; + } + else if (_global_keyboard.cursor > 0) + { + utf8_str_remove_at(_global_keyboard.input_text, _global_keyboard.cursor-1); + + _global_keyboard.cursor--; + _global_keyboard.text_changed = true; + } + + _global_keyboard.input_text_len = utf8len(_global_keyboard.input_text); + } +} + +inline bool keyboard_is_shortcut_down(s32 shortcut_keys[2]) +{ + return keyboard_is_key_down(shortcut_keys[0]) && + keyboard_is_key_pressed(shortcut_keys[1]); +} + +inline void reset_left_click() { + _global_mouse.left_state &= ~MOUSE_CLICK; +} +inline void reset_left_down() { + _global_mouse.left_state &= ~MOUSE_DOWN; +} +inline void reset_right_click() { + _global_mouse.right_state &= ~MOUSE_CLICK; +} \ No newline at end of file -- cgit v1.2.3-70-g09d2