From 9808d435d5cb08135749cf081a38312808b5c84c Mon Sep 17 00:00:00 2001 From: Krzosa Karol Date: Thu, 30 Jan 2025 13:51:46 +0100 Subject: [PATCH] text input, everything lister --- src/ui/ui.c | 114 +++++++++++++++++++++++++++++++++++++++++++++------- src/ui/ui.h | 11 +++-- 2 files changed, 107 insertions(+), 18 deletions(-) diff --git a/src/ui/ui.c b/src/ui/ui.c index af4aa8e..ce15051 100644 --- a/src/ui/ui.c +++ b/src/ui/ui.c @@ -459,7 +459,6 @@ fn void ui_text_input_draw(ui_box_t *box) { r2f32_t selection_rect = r2f32(co.rect.min.x + size_min.x, co.rect.min.y, co.rect.min.x + size_max.x, co.rect.min.y + ui_em(1)); rn_draw_rect(selection_rect, v4f32(1,1,1,0.5f)); - v2f32_t size_front = ti->caret.ifront == 0 ? size_min : size_max; r2f32_t caret_rect = r2f32(co.rect.min.x + size_front.x, co.rect.min.y, co.rect.min.x + size_front.x + 1, co.rect.min.y + ui_em(1)); rn_draw_rect(caret_rect, co.text_color); @@ -508,6 +507,11 @@ fn i32 ui_text_replace(ui_text_input_t *ti, r1i32_t range, s8_t string) { return change_size; } +fn void ui_text_clear(ui_text_input_t *ti) { + ti->len = 0; + ti->caret = ui_carets(0); +} + fn_test void ui_test_text_replace(void) { ui_text_input_t ti = {0}; char buff[4] = {0}; @@ -535,6 +539,7 @@ fn ui_signal_t ui__text_input(ui_code_loc_t loc, ui_text_input_t *ti) { app_event_t *ev = ui->event; i32 sel_size = r1i32_size(ti->caret.range); if (ev->kind == app_event_kind_text) { + signal.text_changed = true; ui_text_replace(ti, ti->caret.range, ev->text); if (sel_size) { ti->caret = ui_carets(ti->caret.range.min); @@ -543,30 +548,44 @@ fn ui_signal_t ui__text_input(ui_code_loc_t loc, ui_text_input_t *ti) { } } else if (ev->kind == app_event_kind_key_down) { if (ev->key == app_key_backspace) { - if (sel_size) { - ui_text_replace(ti, ti->caret.range, s8_lit("")); + signal.text_changed = true; + if (ev->ctrl) { + if (sel_size) { + ui_text_replace(ti, ti->caret.range, s8_lit("")); + } else { + ui_text_replace(ti, r1i32(0, ti->caret.range.max), s8_lit("")); + } } else { - ui_text_replace(ti, r1i32(ti->caret.e[0] - 1, ti->caret.e[0]), s8_null); - ti->caret = ui_carets(ti->caret.range.min - 1); + if (sel_size) { + ui_text_replace(ti, ti->caret.range, s8_lit("")); + } else { + ui_text_replace(ti, r1i32(ti->caret.e[0] - 1, ti->caret.e[0]), s8_null); + ti->caret = ui_carets(ti->caret.range.min - 1); + } } } else if (ev->key == app_key_delete) { + signal.text_changed = true; if (sel_size) { ui_text_replace(ti, ti->caret.range, s8_lit("")); } else { ui_text_replace(ti, r1i32(ti->caret.e[0], ti->caret.e[0] + 1), s8_null); } } else if (ev->key == app_key_left) { + signal.text_changed = true; if (ev->shift) { ti->caret = ui_caret_set_front(ti->caret, ui_caret_front(ti->caret) - 1); } else { ti->caret = ui_carets(ui_caret_front(ti->caret) - 1); } } else if (ev->key == app_key_right) { + signal.text_changed = true; if (ev->shift) { ti->caret = ui_caret_set_front(ti->caret, ui_caret_front(ti->caret) + 1); } else { ti->caret = ui_carets(ui_caret_front(ti->caret) + 1); } + } else if (ev->key == app_key_enter) { + signal.text_commit = true; } } v2f32_t size = rn_measure_string(rn->main_font, s8_lit("_")); @@ -639,6 +658,7 @@ fn ui_signal_t ui_tree_table_push_expandable(ui_code_loc_t loc, char *str, ...) ui_push_id(id); ui_tree_table_begin(loc); ui_box_t *box = ui_box(.loc = loc, .string = string, .flags = { .draw_rect = true, .draw_text = true, .keyboard_nav = true}); + ui_signal_t button = ui_signal_from_box(box); if (button.box->created_new) button.box->expanded = true; if (button.clicked) button.box->expanded = !button.box->expanded; @@ -1064,6 +1084,56 @@ fn void ui_end_reversal(void) { } } +gb_read_only i64 fuzzy_closer_word_begin = 5; +gb_read_only i64 fuzzy_consecutive_multiplier = 3; +fn i64 fuzzy_rate_string(s8_t string, s8_t with) { + if (with.len == 0) return 0; + + i64 points = 0; + i64 consecutive = 0; + i64 with_i = 0; + for (i64 i = 0; i < string.len; i++) { + if (string.str[i] == with.str[with_i]) { + i64 closer_begin = CLAMP_BOT((i64)0, fuzzy_closer_word_begin - i); + points += closer_begin; + consecutive++; + with_i += 1; + } else { + points += consecutive * fuzzy_consecutive_multiplier; + consecutive = 0; + with_i = 0; + } + + if (with_i >= with.len) with_i = 0; + } + points += consecutive * fuzzy_consecutive_multiplier; + return points; +} + +typedef struct fuzzy_pair_t fuzzy_pair_t; +struct fuzzy_pair_t { + i64 index; + i64 rating; +}; + +fn fuzzy_pair_t *fuzzy_rate_array(ma_arena_t *arena, s8_t needle, s8_t *array, i32 len) { + fuzzy_pair_t *pairs = ma_push_array(arena, fuzzy_pair_t, len); + for (i32 i = 0; i < len; i += 1) { + pairs[i].rating = fuzzy_rate_string(array[i], needle); + pairs[i].index = i; + } + + for (i32 i = 0; i < len - 1; i++) { + for (i32 j = 0; j < len - 1; j++) { + if (pairs[j].rating < pairs[j + 1].rating) { + SWAP(fuzzy_pair_t, pairs[j], pairs[j + 1]); + } + } + } + + return pairs; +} + gb app_event_t ui_test_event; gb i32 ui_g_panel = 2; fn void ui_demo_update(app_frame_t *frame, mt_tweak_t *tweak_table, i32 tweak_count) { @@ -1526,17 +1596,31 @@ fn void ui_demo_update(app_frame_t *frame, mt_tweak_t *tweak_table, i32 tweak_co text_input.cap = lengthof(buff); } ui_signal_t ti_sig = ui_text_input(&text_input); - if (lister_just_opened) ui->focus = ti_sig.box->id; + ui->focus = ti_sig.box->id; - ui_button("[27.01.2025 08:55:20] Module loaded: 00007ff9`26860000 00007ff9`26908000 C:/Windows/System32/clbcatq.dll "); - ui_button("[27.01.2025 08:55:20] Module loaded: 00007ff9`06a80000 00007ff9`06add000 C:/Windows/System32/ApplicationTargetedFeatureDatabase.dll "); - ui_button("[27.01.2025 08:55:20] Module loaded: 00007ff9`16a50000 00007ff9`16c87000 C:/Windows/System32/twinapi.appcore.dll "); - ui_button("[27.01.2025 08:55:20] Thread exited: handle 0x854 with exit code 0 (0x0)"); - ui_button("[27.01.2025 08:55:20] Module loaded: 00007ff9`1c410000 00007ff9`1c51f000 C:/dev/wasm/build/app_temp_2106011489.dll (symbols loaded)"); - ui_button("opengl message: Buffer detailed info: Buffer object 1 (bound to NONE, usage hint is GL_DYNAMIC_DRAW) will use VIDEO memory as the source for buffer object operations."); - ui_button("failed to load library: app_temp_1403378047.dll"); - ui_button("failed to load library: app_temp_1765879053.dll"); - ui_button("failed to load library: app_temp_1515670551.dll"); + s8_t cmds[] = { + s8_lit("show data tab"), + s8_lit("show log tab"), + s8_lit("show menus tab"), + }; + + ma_temp_t scratch = ma_begin_scratch(); + s8_t needle = s8(text_input.str, text_input.len); + fuzzy_pair_t *pairs = fuzzy_rate_array(scratch.arena, needle, cmds, lengthof(cmds)); + + ui_set_string_pos_offset(ui_dm(1)) + for (i32 i = 0; i < lengthof(cmds); i += 1) { + ui_button(cmds[pairs[i].index].str); + } + + if (ti_sig.text_commit) { + fuzzy_pair_t *pair = &pairs[0]; + ui_g_panel = (i32)pair->index + 1; + ui_text_clear(&text_input); + lister_open = false; + } + + ma_end_scratch(scratch); } } diff --git a/src/ui/ui.h b/src/ui/ui.h index 92206bc..cd72aa7 100644 --- a/src/ui/ui.h +++ b/src/ui/ui.h @@ -104,10 +104,15 @@ struct ui_box_t { typedef struct ui_signal_t ui_signal_t; struct ui_signal_t { ui_box_t *box; - b8 clicked; - b8 press; - b8 dragging; v2f32_t drag; + struct { + b8 clicked: 1; + b8 press: 1; + b8 dragging: 1; + + b8 text_changed: 1; + b8 text_commit: 1; + }; }; typedef struct ui_t ui_t;