From 38e38eaf3ba7d7df1404f8ab8a25c592cabd5f5a Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Mon, 13 May 2024 07:48:48 -0700 Subject: [PATCH] sketch out ui event type, to unify type & stream for text ops, nav actions, and all other user inputs --- src/df/gfx/df_gfx.c | 2 +- src/ui/ui_core.c | 72 +++++++++++++++++++++++++++++++++ src/ui/ui_core.h | 97 +++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 170 insertions(+), 1 deletion(-) diff --git a/src/df/gfx/df_gfx.c b/src/df/gfx/df_gfx.c index 184190e1..ec40244c 100644 --- a/src/df/gfx/df_gfx.c +++ b/src/df/gfx/df_gfx.c @@ -4183,7 +4183,7 @@ df_window_update_and_render(Arena *arena, OS_EventList *events, DF_Window *ws, D UI_Squish(0.25f-0.25f*ws->autocomp_open_t) UI_Transparency(1.f-ws->autocomp_open_t) { - autocomp_box = ui_build_box_from_stringf(UI_BoxFlag_DefaultFocusNavY|UI_BoxFlag_Clip|UI_BoxFlag_RoundChildrenByParent|UI_BoxFlag_DrawBorder|UI_BoxFlag_DrawBackgroundBlur|UI_BoxFlag_DrawDropShadow|UI_BoxFlag_DrawBackground, "autocomp_box"); + autocomp_box = ui_build_box_from_stringf(UI_BoxFlag_DefaultFocusNavY|UI_BoxFlag_Clickable|UI_BoxFlag_Clip|UI_BoxFlag_RoundChildrenByParent|UI_BoxFlag_DrawBorder|UI_BoxFlag_DrawBackgroundBlur|UI_BoxFlag_DrawDropShadow|UI_BoxFlag_DrawBackground, "autocomp_box"); } UI_Parent(autocomp_box) UI_WidthFill UI_PrefHeight(ui_px(row_height_px, 1.f)) UI_Font(df_font_from_slot(DF_FontSlot_Code)) UI_HoverCursor(OS_Cursor_HandPoint) UI_Focus(UI_FocusKind_Null) diff --git a/src/ui/ui_core.c b/src/ui/ui_core.c index 51f45dc2..86526102 100644 --- a/src/ui/ui_core.c +++ b/src/ui/ui_core.c @@ -94,6 +94,78 @@ ui_key_match(UI_Key a, UI_Key b) return a.u64[0] == b.u64[0]; } +//////////////////////////////// +//~ rjf: Event Functions + +internal UI_EventNode * +ui_event_list_push(Arena *arena, UI_EventList *list, UI_Event *v) +{ + UI_EventNode *n = push_array(arena, UI_EventNode, 1); + MemoryCopyStruct(&n->v, v); + n->v.string = push_str8_copy(arena, n->v.string); + DLLPushBack(list->first, list->last, n); + list->count += 1; + return n; +} + +internal void +ui_eat_event(UI_EventList *list, UI_EventNode *node) +{ + DLLRemove(list->first, list->last, node); + list->count -= 1; +} + +internal B32 +ui_key_press(UI_EventList *list, OS_EventFlags mods, OS_Key key) +{ + B32 result = 0; + for(UI_EventNode *n = list->first; n != 0; n = n->next) + { + if(n->v.kind == UI_EventKind_Press && n->v.key == key && n->v.modifiers == mods) + { + result = 1; + ui_eat_event(list, n); + break; + } + } + return result; +} + +internal B32 +ui_key_release(UI_EventList *list, OS_EventFlags mods, OS_Key key) +{ + B32 result = 0; + for(UI_EventNode *n = list->first; n != 0; n = n->next) + { + if(n->v.kind == UI_EventKind_Release && n->v.key == key && n->v.modifiers == mods) + { + result = 1; + ui_eat_event(list, n); + break; + } + } + return result; +} + +internal B32 +ui_text(UI_EventList *list, U32 character) +{ + B32 result = 0; + Temp scratch = scratch_begin(0, 0); + String8 character_text = str8_from_32(scratch.arena, str32(&character, 1)); + for(UI_EventNode *n = list->first; n != 0; n = n->next) + { + if(n->v.kind == UI_EventKind_Text && str8_match(character_text, n->v.string, 0)) + { + result = 1; + ui_eat_event(list, n); + break; + } + } + scratch_end(scratch); + return result; +} + //////////////////////////////// //~ rjf: Navigation Action List Building & Consumption Functions diff --git a/src/ui/ui_core.h b/src/ui/ui_core.h index d0f48eb6..cd03f31a 100644 --- a/src/ui/ui_core.h +++ b/src/ui/ui_core.h @@ -56,6 +56,94 @@ typedef enum UI_FocusKind } UI_FocusKind; +//////////////////////////////// +//~ rjf: Events + +typedef enum UI_EventKind +{ + UI_EventKind_Null, + UI_EventKind_Press, + UI_EventKind_Release, + UI_EventKind_Text, + UI_EventKind_Scroll, + UI_EventKind_COUNT +} +UI_EventKind; + +typedef U32 UI_EventFlags; +enum +{ + UI_EventFlag_KeepMark = (1<<0), + UI_EventFlag_Delete = (1<<1), + UI_EventFlag_Copy = (1<<2), + UI_EventFlag_Paste = (1<<3), + UI_EventFlag_ZeroDeltaOnSelect = (1<<4), + UI_EventFlag_PickSelectSide = (1<<5), + UI_EventFlag_CapAtLine = (1<<6), + UI_EventFlag_ExplicitDirectional = (1<<7), +}; + +typedef enum UI_EventDeltaUnit +{ + UI_EventDeltaUnit_Char, + UI_EventDeltaUnit_Word, + UI_EventDeltaUnit_Line, + UI_EventDeltaUnit_Whole, + UI_EventDeltaUnit_COUNT +} +UI_EventDeltaUnit; + +typedef struct UI_Event UI_Event; +struct UI_Event +{ + UI_EventKind kind; + UI_EventFlags flags; + UI_EventDeltaUnit delta_unit; + OS_Key key; + OS_EventFlags modifiers; + String8 string; + Vec2F32 pos; + Vec2F32 delta_2f32; + Vec2S32 delta_2s32; +}; + +typedef struct UI_EventNode UI_EventNode; +struct UI_EventNode +{ + UI_EventNode *next; + UI_EventNode *prev; + UI_Event v; +}; + +typedef struct UI_EventList UI_EventList; +struct UI_EventList +{ + UI_EventNode *first; + UI_EventNode *last; + U64 count; +}; + +//////////////////////////////// +//~ rjf: Textual Operations + +typedef U32 UI_TxtOpFlags; +enum +{ + UI_TxtOpFlag_Invalid = (1<<0), + UI_TxtOpFlag_Copy = (1<<1), +}; + +typedef struct UI_TxtOp UI_TxtOp; +struct UI_TxtOp +{ + UI_TxtOpFlags flags; + String8 replace; + String8 copy; + TxtRng range; + TxtPt cursor; + TxtPt mark; +}; + //////////////////////////////// //~ rjf: Navigation Types @@ -541,6 +629,15 @@ internal UI_Key ui_key_from_string(UI_Key seed_key, String8 string); internal UI_Key ui_key_from_stringf(UI_Key seed_key, char *fmt, ...); internal B32 ui_key_match(UI_Key a, UI_Key b); +//////////////////////////////// +//~ rjf: Event Functions + +internal UI_EventNode *ui_event_list_push(Arena *arena, UI_EventList *list, UI_Event *v); +internal void ui_eat_event(UI_EventList *list, UI_EventNode *node); +internal B32 ui_key_press(UI_EventList *list, OS_EventFlags mods, OS_Key key); +internal B32 ui_key_release(UI_EventList *list, OS_EventFlags mods, OS_Key key); +internal B32 ui_text(UI_EventList *list, U32 character); + //////////////////////////////// //~ rjf: Navigation Action List Building & Consumption Functions