From 4cb0073909b4741debf39ba6b04db4197479e2f7 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Fri, 10 May 2024 16:32:01 -0700 Subject: [PATCH 01/30] stop non-x64 builds with less cryptic errors --- src/base/base_context_cracking.h | 10 ++++++++++ .../metagen_base/metagen_base_context_cracking.h | 10 ++++++++++ 2 files changed, 20 insertions(+) diff --git a/src/base/base_context_cracking.h b/src/base/base_context_cracking.h index f9f1a782..9df1dc5e 100644 --- a/src/base/base_context_cracking.h +++ b/src/base/base_context_cracking.h @@ -234,4 +234,14 @@ # define LANG_C 0 #endif +//////////////////////////////// +//~ rjf: Unsupported Errors + +#if ARCH_X86 +# error You tried to build in x86 (32 bit) mode, but currently, only building in x64 (64 bit) mode is supported. +#endif +#if !ARCH_X64 +# error You tried to build with an unsupported architecture. Currently, only building in x64 mode is supported. +#endif + #endif // BASE_CONTEXT_CRACKING_H diff --git a/src/metagen/metagen_base/metagen_base_context_cracking.h b/src/metagen/metagen_base/metagen_base_context_cracking.h index 65f49e7b..e35b10f4 100644 --- a/src/metagen/metagen_base/metagen_base_context_cracking.h +++ b/src/metagen/metagen_base/metagen_base_context_cracking.h @@ -141,4 +141,14 @@ # error Endianness of this architecture not understood by context cracker #endif +//////////////////////////////// +//~ rjf: Unsupported Errors + +#if ARCH_X86 +# error You tried to build in x86 (32 bit) mode, but currently, only building in x64 (64 bit) mode is supported. +#endif +#if !ARCH_X64 +# error You tried to build with an unsupported architecture. Currently, only building in x64 mode is supported. +#endif + #endif // BASE_CONTEXT_CRACKING_H From 9f89735b01bc0cc006aa58237bb81c0a38f43074 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Sun, 12 May 2024 14:11:08 -0700 Subject: [PATCH 02/30] preserve jeff notes from emails - put into todo list --- src/lib_raddbg_markup/raddbg_markup.h | 6 +++--- src/raddbg/raddbg.h | 12 ++++++++++++ 2 files changed, 15 insertions(+), 3 deletions(-) diff --git a/src/lib_raddbg_markup/raddbg_markup.h b/src/lib_raddbg_markup/raddbg_markup.h index bd0b0cc4..66b0fa31 100644 --- a/src/lib_raddbg_markup/raddbg_markup.h +++ b/src/lib_raddbg_markup/raddbg_markup.h @@ -1,8 +1,8 @@ // Copyright (c) 2024 Epic Games Tools // Licensed under the MIT license (https://opensource.org/license/mit/) -#ifndef RDI_MARKUP_H -#define RDI_MARKUP_H +#ifndef RADDBG_MARKUP_H +#define RADDBG_MARKUP_H //////////////////////////////// //~ Usage Macros @@ -75,4 +75,4 @@ raddbg_log__impl(char *fmt, ...) #endif // defined(_WIN32) -#endif // RDI_MARKUP_H +#endif // RADDBG_MARKUP_H diff --git a/src/raddbg/raddbg.h b/src/raddbg/raddbg.h index bb0f5087..e9c83a4a 100644 --- a/src/raddbg/raddbg.h +++ b/src/raddbg/raddbg.h @@ -73,6 +73,18 @@ //////////////////////////////// //~ rjf: Hot, Medium Priority Tasks (Low-Hanging-Fruit Features, UI Jank, Cleanup) // +// [ ] Jeff Notes +// [ ] highlighted text & ctrl+f -> auto-fill search query +// [ ] double-click any part of frame in callstack view -> snap to function +// [ ] sort locals by appearance in source code (or maybe just debug info) +// [ ] bit more padding on the tabs +// [ ] sum view rule +// [ ] plot view rule +// [ ] histogram view rule +// [ ] max view rule +// [ ] min view rule +// [ ] double click on procedure in procedures tab to jump to source +// // [ ] investigate /DEBUG:FASTLINK - can we somehow alert that we do not // support it? // From 38e38eaf3ba7d7df1404f8ab8a25c592cabd5f5a Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Mon, 13 May 2024 07:48:48 -0700 Subject: [PATCH 03/30] 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 From 58192b83560cd224770a92707eac1b3f7b5eb69a Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Mon, 13 May 2024 10:33:30 -0700 Subject: [PATCH 04/30] move all ui/df codepaths onto new ui event consumption, rather than os/nav events in parallel --- src/df/gfx/df_gfx.c | 454 ++++++++++++++++++++++++-------------- src/df/gfx/df_views.c | 136 ++++++------ src/ui/ui_basic_widgets.c | 45 ++-- src/ui/ui_core.c | 447 ++++++++++++++++++++++++++----------- src/ui/ui_core.h | 25 ++- 5 files changed, 728 insertions(+), 379 deletions(-) diff --git a/src/df/gfx/df_gfx.c b/src/df/gfx/df_gfx.c index ec40244c..9333073b 100644 --- a/src/df/gfx/df_gfx.c +++ b/src/df/gfx/df_gfx.c @@ -1074,7 +1074,7 @@ df_window_update_and_render(Arena *arena, OS_EventList *events, DF_Window *ws, D //- rjf: do core-layer commands & batch up commands to be dispatched to views // B32 panel_reset_done = 0; - UI_NavActionList nav_actions = {0}; + UI_EventList events_ui = {0}; ProfScope("do commands") { Temp scratch = scratch_begin(&arena, 1); @@ -2084,191 +2084,317 @@ df_window_update_and_render(Arena *arena, OS_EventList *events, DF_Window *ws, D // case DF_CoreCmdKind_MoveLeft: { - UI_NavAction action = {UI_NavActionFlag_PickSelectSide|UI_NavActionFlag_ZeroDeltaOnSelect|UI_NavActionFlag_ExplicitDirectional, {-1, +0}}; - ui_nav_action_list_push(ui_build_arena(), &nav_actions, action); + UI_Event evt = {0}; + evt.kind = UI_EventKind_Navigate; + evt.flags = UI_EventFlag_PickSelectSide|UI_EventFlag_ZeroDeltaOnSelect|UI_EventFlag_ExplicitDirectional; + evt.delta_2s32 = v2s32(-1, +0); + ui_event_list_push(ui_build_arena(), &events_ui, &evt); }break; case DF_CoreCmdKind_MoveRight: { - UI_NavAction action = {UI_NavActionFlag_PickSelectSide|UI_NavActionFlag_ZeroDeltaOnSelect|UI_NavActionFlag_ExplicitDirectional, {+1, +0}}; - ui_nav_action_list_push(ui_build_arena(), &nav_actions, action); + UI_Event evt = {0}; + evt.kind = UI_EventKind_Navigate; + evt.flags = UI_EventFlag_PickSelectSide|UI_EventFlag_ZeroDeltaOnSelect|UI_EventFlag_ExplicitDirectional; + evt.delta_2s32 = v2s32(+1, +0); + ui_event_list_push(ui_build_arena(), &events_ui, &evt); }break; case DF_CoreCmdKind_MoveUp: { - UI_NavAction action = {UI_NavActionFlag_ExplicitDirectional, {+0, -1}}; - ui_nav_action_list_push(ui_build_arena(), &nav_actions, action); + UI_Event evt = {0}; + evt.kind = UI_EventKind_Navigate; + evt.flags = UI_EventFlag_ExplicitDirectional; + evt.delta_2s32 = v2s32(+0, -1); + ui_event_list_push(ui_build_arena(), &events_ui, &evt); }break; case DF_CoreCmdKind_MoveDown: { - UI_NavAction action = {UI_NavActionFlag_ExplicitDirectional, {+0, +1}}; - ui_nav_action_list_push(ui_build_arena(), &nav_actions, action); + UI_Event evt = {0}; + evt.kind = UI_EventKind_Navigate; + evt.flags = UI_EventFlag_ExplicitDirectional; + evt.delta_2s32 = v2s32(+0, +1); + ui_event_list_push(ui_build_arena(), &events_ui, &evt); }break; case DF_CoreCmdKind_MoveLeftSelect: { - UI_NavAction action = {UI_NavActionFlag_KeepMark|UI_NavActionFlag_ExplicitDirectional, {-1, +0}}; - ui_nav_action_list_push(ui_build_arena(), &nav_actions, action); + UI_Event evt = {0}; + evt.kind = UI_EventKind_Navigate; + evt.flags = UI_EventFlag_KeepMark|UI_EventFlag_ExplicitDirectional; + evt.delta_2s32 = v2s32(-1, +0); + ui_event_list_push(ui_build_arena(), &events_ui, &evt); }break; case DF_CoreCmdKind_MoveRightSelect: { - UI_NavAction action = {UI_NavActionFlag_KeepMark|UI_NavActionFlag_ExplicitDirectional, {+1, +0}}; - ui_nav_action_list_push(ui_build_arena(), &nav_actions, action); + UI_Event evt = {0}; + evt.kind = UI_EventKind_Navigate; + evt.flags = UI_EventFlag_KeepMark|UI_EventFlag_ExplicitDirectional; + evt.delta_2s32 = v2s32(+1, +0); + ui_event_list_push(ui_build_arena(), &events_ui, &evt); }break; case DF_CoreCmdKind_MoveUpSelect: { - UI_NavAction action = {UI_NavActionFlag_KeepMark|UI_NavActionFlag_ExplicitDirectional, {+0, -1}}; - ui_nav_action_list_push(ui_build_arena(), &nav_actions, action); + UI_Event evt = {0}; + evt.kind = UI_EventKind_Navigate; + evt.flags = UI_EventFlag_KeepMark|UI_EventFlag_ExplicitDirectional; + evt.delta_2s32 = v2s32(+0, -1); + ui_event_list_push(ui_build_arena(), &events_ui, &evt); }break; case DF_CoreCmdKind_MoveDownSelect: { - UI_NavAction action = {UI_NavActionFlag_KeepMark|UI_NavActionFlag_ExplicitDirectional, {+0, +1}}; - ui_nav_action_list_push(ui_build_arena(), &nav_actions, action); + UI_Event evt = {0}; + evt.kind = UI_EventKind_Navigate; + evt.flags = UI_EventFlag_KeepMark|UI_EventFlag_ExplicitDirectional; + evt.delta_2s32 = v2s32(+0, +1); + ui_event_list_push(ui_build_arena(), &events_ui, &evt); }break; case DF_CoreCmdKind_MoveLeftChunk: { - UI_NavAction action = {UI_NavActionFlag_ExplicitDirectional, {-1, +0}, UI_NavDeltaUnit_Chunk}; - ui_nav_action_list_push(ui_build_arena(), &nav_actions, action); + UI_Event evt = {0}; + evt.kind = UI_EventKind_Navigate; + evt.flags = UI_EventFlag_ExplicitDirectional; + evt.delta_unit = UI_EventDeltaUnit_Word; + evt.delta_2s32 = v2s32(-1, +0); + ui_event_list_push(ui_build_arena(), &events_ui, &evt); }break; case DF_CoreCmdKind_MoveRightChunk: { - UI_NavAction action = {UI_NavActionFlag_ExplicitDirectional, {+1, +0}, UI_NavDeltaUnit_Chunk}; - ui_nav_action_list_push(ui_build_arena(), &nav_actions, action); + UI_Event evt = {0}; + evt.kind = UI_EventKind_Navigate; + evt.flags = UI_EventFlag_ExplicitDirectional; + evt.delta_unit = UI_EventDeltaUnit_Word; + evt.delta_2s32 = v2s32(+1, +0); + ui_event_list_push(ui_build_arena(), &events_ui, &evt); }break; case DF_CoreCmdKind_MoveUpChunk: { - UI_NavAction action = {UI_NavActionFlag_ExplicitDirectional, {+0, -1}, UI_NavDeltaUnit_Chunk}; - ui_nav_action_list_push(ui_build_arena(), &nav_actions, action); + UI_Event evt = {0}; + evt.kind = UI_EventKind_Navigate; + evt.flags = UI_EventFlag_ExplicitDirectional; + evt.delta_unit = UI_EventDeltaUnit_Word; + evt.delta_2s32 = v2s32(+0, -1); + ui_event_list_push(ui_build_arena(), &events_ui, &evt); }break; case DF_CoreCmdKind_MoveDownChunk: { - UI_NavAction action = {UI_NavActionFlag_ExplicitDirectional, {+0, +1}, UI_NavDeltaUnit_Chunk}; - ui_nav_action_list_push(ui_build_arena(), &nav_actions, action); + UI_Event evt = {0}; + evt.kind = UI_EventKind_Navigate; + evt.flags = UI_EventFlag_ExplicitDirectional; + evt.delta_unit = UI_EventDeltaUnit_Word; + evt.delta_2s32 = v2s32(+0, +1); + ui_event_list_push(ui_build_arena(), &events_ui, &evt); }break; case DF_CoreCmdKind_MoveUpPage: { - UI_NavAction action = {0, {+0, -1}, UI_NavDeltaUnit_Whole}; - ui_nav_action_list_push(ui_build_arena(), &nav_actions, action); + UI_Event evt = {0}; + evt.kind = UI_EventKind_Navigate; + evt.delta_unit = UI_EventDeltaUnit_Page; + evt.delta_2s32 = v2s32(+0, -1); + ui_event_list_push(ui_build_arena(), &events_ui, &evt); }break; case DF_CoreCmdKind_MoveDownPage: { - UI_NavAction action = {0, {+0, +1}, UI_NavDeltaUnit_Whole}; - ui_nav_action_list_push(ui_build_arena(), &nav_actions, action); + UI_Event evt = {0}; + evt.kind = UI_EventKind_Navigate; + evt.delta_unit = UI_EventDeltaUnit_Page; + evt.delta_2s32 = v2s32(+0, +1); + ui_event_list_push(ui_build_arena(), &events_ui, &evt); }break; case DF_CoreCmdKind_MoveUpWhole: { - UI_NavAction action = {0, {+0, -1}, UI_NavDeltaUnit_EndPoint}; - ui_nav_action_list_push(ui_build_arena(), &nav_actions, action); + UI_Event evt = {0}; + evt.kind = UI_EventKind_Navigate; + evt.delta_unit = UI_EventDeltaUnit_Whole; + evt.delta_2s32 = v2s32(+0, -1); + ui_event_list_push(ui_build_arena(), &events_ui, &evt); }break; case DF_CoreCmdKind_MoveDownWhole: { - UI_NavAction action = {0, {+0, +1}, UI_NavDeltaUnit_EndPoint}; - ui_nav_action_list_push(ui_build_arena(), &nav_actions, action); + UI_Event evt = {0}; + evt.kind = UI_EventKind_Navigate; + evt.delta_unit = UI_EventDeltaUnit_Whole; + evt.delta_2s32 = v2s32(+0, +1); + ui_event_list_push(ui_build_arena(), &events_ui, &evt); }break; case DF_CoreCmdKind_MoveLeftChunkSelect: { - UI_NavAction action = {UI_NavActionFlag_KeepMark|UI_NavActionFlag_ExplicitDirectional, {-1, +0}, UI_NavDeltaUnit_Chunk}; - ui_nav_action_list_push(ui_build_arena(), &nav_actions, action); + UI_Event evt = {0}; + evt.kind = UI_EventKind_Navigate; + evt.flags = UI_EventFlag_KeepMark|UI_EventFlag_ExplicitDirectional; + evt.delta_unit = UI_EventDeltaUnit_Word; + evt.delta_2s32 = v2s32(-1, +0); + ui_event_list_push(ui_build_arena(), &events_ui, &evt); }break; case DF_CoreCmdKind_MoveRightChunkSelect: { - UI_NavAction action = {UI_NavActionFlag_KeepMark|UI_NavActionFlag_ExplicitDirectional, {+1, +0}, UI_NavDeltaUnit_Chunk}; - ui_nav_action_list_push(ui_build_arena(), &nav_actions, action); + UI_Event evt = {0}; + evt.kind = UI_EventKind_Navigate; + evt.flags = UI_EventFlag_KeepMark|UI_EventFlag_ExplicitDirectional; + evt.delta_unit = UI_EventDeltaUnit_Word; + evt.delta_2s32 = v2s32(+1, +0); + ui_event_list_push(ui_build_arena(), &events_ui, &evt); }break; case DF_CoreCmdKind_MoveUpChunkSelect: { - UI_NavAction action = {UI_NavActionFlag_KeepMark|UI_NavActionFlag_ExplicitDirectional, {+0, -1}, UI_NavDeltaUnit_Chunk}; - ui_nav_action_list_push(ui_build_arena(), &nav_actions, action); + UI_Event evt = {0}; + evt.kind = UI_EventKind_Navigate; + evt.flags = UI_EventFlag_KeepMark|UI_EventFlag_ExplicitDirectional; + evt.delta_unit = UI_EventDeltaUnit_Word; + evt.delta_2s32 = v2s32(+0, -1); + ui_event_list_push(ui_build_arena(), &events_ui, &evt); }break; case DF_CoreCmdKind_MoveDownChunkSelect: { - UI_NavAction action = {UI_NavActionFlag_KeepMark|UI_NavActionFlag_ExplicitDirectional, {+0, +1}, UI_NavDeltaUnit_Chunk}; - ui_nav_action_list_push(ui_build_arena(), &nav_actions, action); + UI_Event evt = {0}; + evt.kind = UI_EventKind_Navigate; + evt.flags = UI_EventFlag_KeepMark|UI_EventFlag_ExplicitDirectional; + evt.delta_unit = UI_EventDeltaUnit_Word; + evt.delta_2s32 = v2s32(+0, +1); + ui_event_list_push(ui_build_arena(), &events_ui, &evt); }break; case DF_CoreCmdKind_MoveUpPageSelect: { - UI_NavAction action = {UI_NavActionFlag_KeepMark|UI_NavActionFlag_ExplicitDirectional, {+0, -1}, UI_NavDeltaUnit_Whole}; - ui_nav_action_list_push(ui_build_arena(), &nav_actions, action); + UI_Event evt = {0}; + evt.kind = UI_EventKind_Navigate; + evt.flags = UI_EventFlag_KeepMark; + evt.delta_unit = UI_EventDeltaUnit_Page; + evt.delta_2s32 = v2s32(+0, -1); + ui_event_list_push(ui_build_arena(), &events_ui, &evt); }break; case DF_CoreCmdKind_MoveDownPageSelect: { - UI_NavAction action = {UI_NavActionFlag_KeepMark|UI_NavActionFlag_ExplicitDirectional, {+0, +1}, UI_NavDeltaUnit_Whole}; - ui_nav_action_list_push(ui_build_arena(), &nav_actions, action); + UI_Event evt = {0}; + evt.kind = UI_EventKind_Navigate; + evt.flags = UI_EventFlag_KeepMark; + evt.delta_unit = UI_EventDeltaUnit_Page; + evt.delta_2s32 = v2s32(+0, +1); + ui_event_list_push(ui_build_arena(), &events_ui, &evt); }break; case DF_CoreCmdKind_MoveUpWholeSelect: { - UI_NavAction action = {UI_NavActionFlag_KeepMark, {+0, -1}, UI_NavDeltaUnit_EndPoint}; - ui_nav_action_list_push(ui_build_arena(), &nav_actions, action); + UI_Event evt = {0}; + evt.kind = UI_EventKind_Navigate; + evt.flags = UI_EventFlag_KeepMark; + evt.delta_unit = UI_EventDeltaUnit_Whole; + evt.delta_2s32 = v2s32(+0, -1); + ui_event_list_push(ui_build_arena(), &events_ui, &evt); }break; case DF_CoreCmdKind_MoveDownWholeSelect: { - UI_NavAction action = {UI_NavActionFlag_KeepMark, {+0, +1}, UI_NavDeltaUnit_EndPoint}; - ui_nav_action_list_push(ui_build_arena(), &nav_actions, action); + UI_Event evt = {0}; + evt.kind = UI_EventKind_Navigate; + evt.flags = UI_EventFlag_KeepMark; + evt.delta_unit = UI_EventDeltaUnit_Whole; + evt.delta_2s32 = v2s32(+0, +1); + ui_event_list_push(ui_build_arena(), &events_ui, &evt); }break; case DF_CoreCmdKind_MoveHome: { - UI_NavAction action = {0, {-1, +0}, UI_NavDeltaUnit_Whole}; - ui_nav_action_list_push(ui_build_arena(), &nav_actions, action); + UI_Event evt = {0}; + evt.kind = UI_EventKind_Navigate; + evt.delta_unit = UI_EventDeltaUnit_Line; + evt.delta_2s32 = v2s32(-1, +0); + ui_event_list_push(ui_build_arena(), &events_ui, &evt); }break; case DF_CoreCmdKind_MoveEnd: { - UI_NavAction action = {0, {+1, +0}, UI_NavDeltaUnit_Whole}; - ui_nav_action_list_push(ui_build_arena(), &nav_actions, action); + UI_Event evt = {0}; + evt.kind = UI_EventKind_Navigate; + evt.delta_unit = UI_EventDeltaUnit_Line; + evt.delta_2s32 = v2s32(+1, +0); + ui_event_list_push(ui_build_arena(), &events_ui, &evt); }break; case DF_CoreCmdKind_MoveHomeSelect: { - UI_NavAction action = {UI_NavActionFlag_KeepMark, {-1, +0}, UI_NavDeltaUnit_Whole}; - ui_nav_action_list_push(ui_build_arena(), &nav_actions, action); + UI_Event evt = {0}; + evt.kind = UI_EventKind_Navigate; + evt.flags = UI_EventFlag_KeepMark; + evt.delta_unit = UI_EventDeltaUnit_Line; + evt.delta_2s32 = v2s32(-1, +0); + ui_event_list_push(ui_build_arena(), &events_ui, &evt); }break; case DF_CoreCmdKind_MoveEndSelect: { - UI_NavAction action = {UI_NavActionFlag_KeepMark, {+1, +0}, UI_NavDeltaUnit_Whole}; - ui_nav_action_list_push(ui_build_arena(), &nav_actions, action); + UI_Event evt = {0}; + evt.kind = UI_EventKind_Navigate; + evt.flags = UI_EventFlag_KeepMark; + evt.delta_unit = UI_EventDeltaUnit_Line; + evt.delta_2s32 = v2s32(+1, +0); + ui_event_list_push(ui_build_arena(), &events_ui, &evt); }break; case DF_CoreCmdKind_SelectAll: { - UI_NavAction action1 = {0, {-1, +0}, UI_NavDeltaUnit_EndPoint}; - ui_nav_action_list_push(ui_build_arena(), &nav_actions, action1); - UI_NavAction action2 = {UI_NavActionFlag_KeepMark, {+1, +0}, UI_NavDeltaUnit_EndPoint}; - ui_nav_action_list_push(ui_build_arena(), &nav_actions, action2); + UI_Event evt1 = {0}; + evt1.kind = UI_EventKind_Navigate; + evt1.delta_unit = UI_EventDeltaUnit_Whole; + evt1.delta_2s32 = v2s32(-1, +0); + ui_event_list_push(ui_build_arena(), &events_ui, &evt1); + UI_Event evt2 = {0}; + evt2.kind = UI_EventKind_Navigate; + evt2.flags = UI_EventFlag_KeepMark; + evt2.delta_unit = UI_EventDeltaUnit_Whole; + evt2.delta_2s32 = v2s32(+1, +0); + ui_event_list_push(ui_build_arena(), &events_ui, &evt2); }break; case DF_CoreCmdKind_DeleteSingle: { - UI_NavAction action = {UI_NavActionFlag_Delete, {+1, +0}, UI_NavDeltaUnit_Element}; - ui_nav_action_list_push(ui_build_arena(), &nav_actions, action); + UI_Event evt = {0}; + evt.kind = UI_EventKind_Edit; + evt.flags = UI_EventFlag_Delete; + evt.delta_2s32 = v2s32(+1, +0); + ui_event_list_push(ui_build_arena(), &events_ui, &evt); }break; case DF_CoreCmdKind_DeleteChunk: { - UI_NavAction action = {UI_NavActionFlag_Delete, {+1, +0}, UI_NavDeltaUnit_Chunk}; - ui_nav_action_list_push(ui_build_arena(), &nav_actions, action); + UI_Event evt = {0}; + evt.kind = UI_EventKind_Edit; + evt.flags = UI_EventFlag_Delete; + evt.delta_2s32 = v2s32(+1, +0); + evt.delta_unit = UI_EventDeltaUnit_Word; + ui_event_list_push(ui_build_arena(), &events_ui, &evt); }break; case DF_CoreCmdKind_BackspaceSingle: { - UI_NavAction action = {UI_NavActionFlag_Delete|UI_NavActionFlag_ZeroDeltaOnSelect, {-1, +0}, UI_NavDeltaUnit_Element}; - ui_nav_action_list_push(ui_build_arena(), &nav_actions, action); + UI_Event evt = {0}; + evt.kind = UI_EventKind_Edit; + evt.flags = UI_EventFlag_Delete|UI_EventFlag_ZeroDeltaOnSelect; + evt.delta_2s32 = v2s32(-1, +0); + ui_event_list_push(ui_build_arena(), &events_ui, &evt); }break; case DF_CoreCmdKind_BackspaceChunk: { - UI_NavAction action = {UI_NavActionFlag_Delete|UI_NavActionFlag_ZeroDeltaOnSelect, {-1, +0}, UI_NavDeltaUnit_Chunk}; - ui_nav_action_list_push(ui_build_arena(), &nav_actions, action); + UI_Event evt = {0}; + evt.kind = UI_EventKind_Edit; + evt.flags = UI_EventFlag_Delete; + evt.delta_2s32 = v2s32(-1, +0); + evt.delta_unit = UI_EventDeltaUnit_Word; + ui_event_list_push(ui_build_arena(), &events_ui, &evt); }break; case DF_CoreCmdKind_Copy: { - UI_NavAction action = {UI_NavActionFlag_Copy|UI_NavActionFlag_KeepMark}; - ui_nav_action_list_push(ui_build_arena(), &nav_actions, action); + UI_Event evt = {0}; + evt.kind = UI_EventKind_Edit; + evt.flags = UI_EventFlag_Copy|UI_EventFlag_KeepMark; + ui_event_list_push(ui_build_arena(), &events_ui, &evt); }break; case DF_CoreCmdKind_Cut: { - UI_NavAction action = {UI_NavActionFlag_Copy|UI_NavActionFlag_Delete}; - ui_nav_action_list_push(ui_build_arena(), &nav_actions, action); + UI_Event evt = {0}; + evt.kind = UI_EventKind_Edit; + evt.flags = UI_EventFlag_Copy|UI_EventFlag_Delete; + ui_event_list_push(ui_build_arena(), &events_ui, &evt); }break; case DF_CoreCmdKind_Paste: { - UI_NavAction action = {UI_NavActionFlag_Paste}; - ui_nav_action_list_push(ui_build_arena(), &nav_actions, action); + UI_Event evt = {0}; + evt.kind = UI_EventKind_Text; + evt.string = os_get_clipboard_text(ui_build_arena()); + ui_event_list_push(ui_build_arena(), &events_ui, &evt); }break; case DF_CoreCmdKind_InsertText: { - String8 insertion = params.string; - UI_NavAction action = {0, {0}, (UI_NavDeltaUnit)0, push_str8_copy(ui_build_arena(), insertion)}; - ui_nav_action_list_push(ui_build_arena(), &nav_actions, action); + UI_Event evt = {0}; + evt.kind = UI_EventKind_Text; + evt.string = params.string; + ui_event_list_push(ui_build_arena(), &events_ui, &evt); }break; //- rjf: address finding @@ -3073,7 +3199,7 @@ df_window_update_and_render(Arena *arena, OS_EventList *events, DF_Window *ws, D } // rjf: begin & push initial stack values - ui_begin_build(events, ws->os, &nav_actions, &icon_info, df_dt(), df_dt()); + ui_begin_build(ws->os, &events_ui, &icon_info, df_dt(), df_dt()); ui_push_font(main_font); ui_push_font_size(main_font_size); ui_push_pref_width(ui_em(20.f, 1)); @@ -4008,14 +4134,14 @@ df_window_update_and_render(Arena *arena, OS_EventList *events, DF_Window *ws, D UI_BackgroundColor(df_rgba_from_theme_color(DF_ThemeColor_ActionBackground)) UI_TextColor(df_rgba_from_theme_color(DF_ThemeColor_ActionText)) UI_BorderColor(df_rgba_from_theme_color(DF_ThemeColor_ActionBorder)) - if(ui_clicked(ui_buttonf("OK")) || (ui_key_match(bg_box->default_nav_focus_hot_key, ui_key_zero()) && os_key_press(ui_events(), ui_window(), 0, OS_Key_Return))) + if(ui_clicked(ui_buttonf("OK")) || (ui_key_match(bg_box->default_nav_focus_hot_key, ui_key_zero()) && ui_key_press(ui_events(), 0, OS_Key_Return))) { DF_CmdParams p = df_cmd_params_zero(); df_push_cmd__root(&p, df_cmd_spec_from_core_cmd_kind(DF_CoreCmdKind_ConfirmAccept)); } UI_CornerRadius10(ui_top_font_size()*0.25f) UI_CornerRadius11(ui_top_font_size()*0.25f) - if(ui_clicked(ui_buttonf("Cancel")) || os_key_press(ui_events(), ui_window(), 0, OS_Key_Esc)) + if(ui_clicked(ui_buttonf("Cancel")) || ui_key_press(ui_events(), 0, OS_Key_Esc)) { DF_CmdParams p = df_cmd_params_zero(); df_push_cmd__root(&p, df_cmd_spec_from_core_cmd_kind(DF_CoreCmdKind_ConfirmCancel)); @@ -4203,8 +4329,8 @@ df_window_update_and_render(Arena *arena, OS_EventList *events, DF_Window *ws, D UI_Signal item_sig = ui_signal_from_box(item_box); if(ui_clicked(item_sig)) { - UI_NavAction autocomp_action = {UI_NavActionFlag_ReplaceAndCommit, {0}, (UI_NavDeltaUnit)0, push_str8_copy(ui_build_arena(), item->string)}; - ui_nav_action_list_push(ui_build_arena(), ui_nav_actions(), autocomp_action); + // UI_NavAction autocomp_action = {UI_NavActionFlag_ReplaceAndCommit, {0}, (UI_NavDeltaUnit)0, push_str8_copy(ui_build_arena(), item->string)}; + // ui_nav_action_list_push(ui_build_arena(), ui_nav_actions(), autocomp_action); } } } @@ -4544,28 +4670,28 @@ df_window_update_and_render(Arena *arena, OS_EventList *events, DF_Window *ws, D U64 open_menu_idx_prime = open_menu_idx; if(menu_open && ws->menu_bar_focused && window_is_focused) { - UI_NavActionList *nav_actions = ui_nav_actions(); - for(UI_NavActionNode *n = nav_actions->first, *next = 0; + UI_EventList *events = ui_events(); + for(UI_EventNode *n = events->first, *next = 0; n != 0; n = next) { next = n->next; - UI_NavAction *action = &n->v; + UI_Event *evt = &n->v; B32 taken = 0; - if(action->delta.x > 0) + if(evt->delta_2s32.x > 0) { taken = 1; open_menu_idx_prime += 1; open_menu_idx_prime = open_menu_idx_prime%ArrayCount(items); } - if(action->delta.x < 0) + if(evt->delta_2s32.x < 0) { taken = 1; open_menu_idx_prime = open_menu_idx_prime > 0 ? open_menu_idx_prime-1 : (ArrayCount(items)-1); } if(taken) { - ui_nav_eat_action_node(nav_actions, n); + ui_eat_event(events, n); } } } @@ -4575,7 +4701,7 @@ df_window_update_and_render(Arena *arena, OS_EventList *events, DF_Window *ws, D { ui_set_next_fastpath_codepoint(items[idx].codepoint); B32 alt_fastpath_key = 0; - if(os_key_press(ui_events(), ui_window(), OS_EventFlag_Alt, items[idx].key)) + if(ui_key_press(ui_events(), OS_EventFlag_Alt, items[idx].key)) { alt_fastpath_key = 1; } @@ -6238,7 +6364,7 @@ df_window_update_and_render(Arena *arena, OS_EventList *events, DF_Window *ws, D DF_View *view = df_view_from_handle(panel->selected_tab_view); UI_Focus(UI_FocusKind_On) { - if(view->is_filtering && ui_is_focus_active() && os_key_press(ui_events(), ui_window(), 0, OS_Key_Return)) + if(view->is_filtering && ui_is_focus_active() && ui_key_press(ui_events(), 0, OS_Key_Return)) { DF_CmdParams p = df_cmd_params_from_view(ws, panel, view); df_push_cmd__root(&p, df_cmd_spec_from_core_cmd_kind(DF_CoreCmdKind_ApplyFilter)); @@ -6457,25 +6583,26 @@ df_window_update_and_render(Arena *arena, OS_EventList *events, DF_Window *ws, D if(ui_is_focus_active() && view->spec->info.flags & DF_ViewSpecFlag_TypingAutomaticallyFilters && !view->is_filtering) { DF_CmdParams p = df_cmd_params_from_view(ws, panel, view); - for(UI_NavActionNode *n = ui_nav_actions()->first, *next = 0; n != 0; n = next) + UI_EventList *events = ui_events(); + for(UI_EventNode *n = events->first, *next = 0; n != 0; n = next) { next = n->next; - if(n->v.flags & UI_NavActionFlag_Paste) + if(n->v.flags & UI_EventFlag_Paste) { - ui_nav_eat_action_node(ui_nav_actions(), n); + ui_eat_event(events, n); df_push_cmd__root(&p, df_cmd_spec_from_core_cmd_kind(DF_CoreCmdKind_Filter)); df_push_cmd__root(&p, df_cmd_spec_from_core_cmd_kind(DF_CoreCmdKind_Paste)); } - else if(n->v.insertion.size != 0) + else if(n->v.string.size != 0) { - ui_nav_eat_action_node(ui_nav_actions(), n); + ui_eat_event(events, n); df_push_cmd__root(&p, df_cmd_spec_from_core_cmd_kind(DF_CoreCmdKind_Filter)); - p.string = n->v.insertion; + p.string = n->v.string; df_push_cmd__root(&p, df_cmd_spec_from_core_cmd_kind(DF_CoreCmdKind_InsertText)); } } } - if((view->query_string_size != 0 || view->is_filtering) && ui_is_focus_active() && os_key_press(ui_events(), ui_window(), 0, OS_Key_Esc)) + if((view->query_string_size != 0 || view->is_filtering) && ui_is_focus_active() && ui_key_press(ui_events(), 0, OS_Key_Esc)) { DF_CmdParams p = df_cmd_params_from_view(ws, panel, view); df_push_cmd__root(&p, df_cmd_spec_from_core_cmd_kind(DF_CoreCmdKind_ClearFilter)); @@ -7046,7 +7173,7 @@ df_window_update_and_render(Arena *arena, OS_EventList *events, DF_Window *ws, D //////////////////////////// //- rjf: drag/drop cancelling // - if(df_drag_is_active() && os_key_press(events, ws->os, 0, OS_Key_Esc)) + if(df_drag_is_active() && ui_key_press(&events_ui, 0, OS_Key_Esc)) { df_drag_kill(); ui_kill_action(); @@ -7055,17 +7182,19 @@ df_window_update_and_render(Arena *arena, OS_EventList *events, DF_Window *ws, D //////////////////////////// //- rjf: font size changing // - for(OS_Event *event = events->first; event != 0; event = event->next) + for(UI_EventNode *n = events_ui.first, *next = 0; n != 0; n = next) { - if(os_handle_match(event->window, ws->os) && event->kind == OS_EventKind_Scroll && event->flags & OS_EventFlag_Ctrl) + next = n->next; + UI_Event *event = &n->v; + if(event->kind == OS_EventKind_Scroll && event->flags & OS_EventFlag_Ctrl) { - os_eat_event(ui_events(), event); - if(event->delta.y < 0) + ui_eat_event(&events_ui, n); + if(event->delta_2f32.y < 0) { DF_CmdParams params = df_cmd_params_from_window(ws); df_push_cmd__root(¶ms, df_cmd_spec_from_core_cmd_kind(DF_CoreCmdKind_IncUIFontScale)); } - else if(event->delta.y > 0) + else if(event->delta_2f32.y > 0) { DF_CmdParams params = df_cmd_params_from_window(ws); df_push_cmd__root(¶ms, df_cmd_spec_from_core_cmd_kind(DF_CoreCmdKind_DecUIFontScale)); @@ -10673,17 +10802,20 @@ df_code_slice(DF_Window *ws, DF_CtrlCtx *ctrl_ctx, EVAL_ParseCtx *parse_ctx, DF_ //- rjf: hovering text container & ctrl+scroll -> change font size if(ui_hovering(text_container_sig)) { - for(OS_Event *event = ui_events()->first; event != 0; event = event->next) + UI_EventList *events = ui_events(); + for(UI_EventNode *n = events->first, *next = 0; n != 0; n = next) { - if(os_handle_match(event->window, ui_window()) && event->kind == OS_EventKind_Scroll && event->flags & OS_EventFlag_Ctrl) + next = n->next; + UI_Event *event = &n->v; + if(event->kind == OS_EventKind_Scroll && event->flags & OS_EventFlag_Ctrl) { - os_eat_event(ui_events(), event); - if(event->delta.y < 0) + ui_eat_event(events, n); + if(event->delta_2f32.y < 0) { DF_CmdParams params = df_cmd_params_from_window(ws); df_push_cmd__root(¶ms, df_cmd_spec_from_core_cmd_kind(DF_CoreCmdKind_IncCodeFontScale)); } - else if(event->delta.y > 0) + else if(event->delta_2f32.y > 0) { DF_CmdParams params = df_cmd_params_from_window(ws); df_push_cmd__root(¶ms, df_cmd_spec_from_core_cmd_kind(DF_CoreCmdKind_DecCodeFontScale)); @@ -11275,25 +11407,25 @@ df_do_txt_controls(TXT_TextInfo *info, String8 data, U64 line_count_per_page, Tx { Temp scratch = scratch_begin(0, 0); B32 change = 0; - UI_NavActionList *nav_actions = ui_nav_actions(); - for(UI_NavActionNode *n = nav_actions->first, *next = 0; n != 0; n = next) + UI_EventList *events = ui_events(); + for(UI_EventNode *n = events->first, *next = 0; n != 0; n = next) { next = n->next; B32 taken = 0; String8 line = txt_string_from_info_data_line_num(info, data, cursor->line); - UI_NavTxtOp single_line_op = ui_nav_single_line_txt_op_from_action(scratch.arena, n->v, line, *cursor, *mark); + UI_TxtOp single_line_op = ui_single_line_txt_op_from_event(scratch.arena, &n->v, line, *cursor, *mark); //- rjf: invalid single-line op or endpoint units => try multiline - if(n->v.delta_unit == UI_NavDeltaUnit_EndPoint || single_line_op.flags & UI_NavTxtOpFlag_Invalid) + if(n->v.delta_unit == UI_EventDeltaUnit_Whole || single_line_op.flags & UI_TxtOpFlag_Invalid) { U64 line_count = info->lines_count; String8 prev_line = txt_string_from_info_data_line_num(info, data, cursor->line-1); String8 next_line = txt_string_from_info_data_line_num(info, data, cursor->line+1); - Vec2S32 delta = n->v.delta; + Vec2S32 delta = n->v.delta_2s32; //- rjf: wrap lines right - if(n->v.delta_unit != UI_NavDeltaUnit_EndPoint && delta.x > 0 && cursor->column == line.size+1 && cursor->line+1 <= line_count) + if(n->v.delta_unit != UI_EventDeltaUnit_Whole && delta.x > 0 && cursor->column == line.size+1 && cursor->line+1 <= line_count) { cursor->line += 1; cursor->column = 1; @@ -11303,7 +11435,7 @@ df_do_txt_controls(TXT_TextInfo *info, String8 data, U64 line_count_per_page, Tx } //- rjf: wrap lines left - if(n->v.delta_unit != UI_NavDeltaUnit_EndPoint && delta.x < 0 && cursor->column == 1 && cursor->line-1 >= 1) + if(n->v.delta_unit != UI_EventDeltaUnit_Whole && delta.x < 0 && cursor->column == 1 && cursor->line-1 >= 1) { cursor->line -= 1; cursor->column = prev_line.size+1; @@ -11313,7 +11445,7 @@ df_do_txt_controls(TXT_TextInfo *info, String8 data, U64 line_count_per_page, Tx } //- rjf: movement down (plain) - if(n->v.delta_unit == UI_NavDeltaUnit_Element && delta.y > 0 && cursor->line+1 <= line_count) + if(n->v.delta_unit == UI_EventDeltaUnit_Whole && delta.y > 0 && cursor->line+1 <= line_count) { cursor->line += 1; cursor->column = Min(*preferred_column, next_line.size+1); @@ -11322,7 +11454,7 @@ df_do_txt_controls(TXT_TextInfo *info, String8 data, U64 line_count_per_page, Tx } //- rjf: movement up (plain) - if(n->v.delta_unit == UI_NavDeltaUnit_Element && delta.y < 0 && cursor->line-1 >= 1) + if(n->v.delta_unit == UI_EventDeltaUnit_Char && delta.y < 0 && cursor->line-1 >= 1) { cursor->line -= 1; cursor->column = Min(*preferred_column, prev_line.size+1); @@ -11331,7 +11463,7 @@ df_do_txt_controls(TXT_TextInfo *info, String8 data, U64 line_count_per_page, Tx } //- rjf: movement down (chunk) - if(n->v.delta_unit == UI_NavDeltaUnit_Chunk && delta.y > 0 && cursor->line+1 <= line_count) + if(n->v.delta_unit == UI_EventDeltaUnit_Word && delta.y > 0 && cursor->line+1 <= line_count) { for(S64 line_num = cursor->line+1; line_num <= line_count; line_num += 1) { @@ -11354,7 +11486,7 @@ df_do_txt_controls(TXT_TextInfo *info, String8 data, U64 line_count_per_page, Tx } //- rjf: movement up (chunk) - if(n->v.delta_unit == UI_NavDeltaUnit_Chunk && delta.y < 0 && cursor->line-1 >= 1) + if(n->v.delta_unit == UI_EventDeltaUnit_Word && delta.y < 0 && cursor->line-1 >= 1) { for(S64 line_num = cursor->line-1; line_num > 0; line_num -= 1) { @@ -11377,7 +11509,7 @@ df_do_txt_controls(TXT_TextInfo *info, String8 data, U64 line_count_per_page, Tx } //- rjf: movement down (page) - if(n->v.delta_unit == UI_NavDeltaUnit_Whole && delta.y > 0) + if(n->v.delta_unit == UI_EventDeltaUnit_Page && delta.y > 0) { cursor->line += line_count_per_page; cursor->column = 1; @@ -11387,7 +11519,7 @@ df_do_txt_controls(TXT_TextInfo *info, String8 data, U64 line_count_per_page, Tx } //- rjf: movement up (page) - if(n->v.delta_unit == UI_NavDeltaUnit_Whole && delta.y < 0) + if(n->v.delta_unit == UI_EventDeltaUnit_Page && delta.y < 0) { cursor->line -= line_count_per_page; cursor->column = 1; @@ -11397,7 +11529,7 @@ df_do_txt_controls(TXT_TextInfo *info, String8 data, U64 line_count_per_page, Tx } //- rjf: movement to endpoint (+) - if(n->v.delta_unit == UI_NavDeltaUnit_EndPoint && (delta.y > 0 || delta.x > 0)) + if(n->v.delta_unit == UI_EventDeltaUnit_Whole && (delta.y > 0 || delta.x > 0)) { *cursor = txt_pt(line_count, info->lines_count ? dim_1u64(info->lines_ranges[info->lines_count-1])+1 : 1); change = 1; @@ -11405,7 +11537,7 @@ df_do_txt_controls(TXT_TextInfo *info, String8 data, U64 line_count_per_page, Tx } //- rjf: movement to endpoint (-) - if(n->v.delta_unit == UI_NavDeltaUnit_EndPoint && (delta.y < 0 || delta.x < 0)) + if(n->v.delta_unit == UI_EventDeltaUnit_Whole && (delta.y < 0 || delta.x < 0)) { *cursor = txt_pt(1, 1); change = 1; @@ -11413,7 +11545,7 @@ df_do_txt_controls(TXT_TextInfo *info, String8 data, U64 line_count_per_page, Tx } //- rjf: stick mark to cursor, when we don't want to keep it in the same spot - if(!(n->v.flags & UI_NavActionFlag_KeepMark)) + if(!(n->v.flags & UI_EventFlag_KeepMark)) { *mark = *cursor; } @@ -11430,7 +11562,7 @@ df_do_txt_controls(TXT_TextInfo *info, String8 data, U64 line_count_per_page, Tx } //- rjf: copy - if(n->v.flags & UI_NavActionFlag_Copy) + if(n->v.flags & UI_EventFlag_Copy) { String8 text = txt_string_from_info_data_txt_rng(info, data, txt_rng(*cursor, *mark)); os_set_clipboard_text(text); @@ -11439,7 +11571,7 @@ df_do_txt_controls(TXT_TextInfo *info, String8 data, U64 line_count_per_page, Tx //- rjf: consume if(taken) { - ui_nav_eat_action_node(nav_actions, n); + ui_eat_event(events, n); } } @@ -11452,26 +11584,26 @@ df_do_txti_controls(TXTI_Handle handle, U64 line_count_per_page, TxtPt *cursor, { Temp scratch = scratch_begin(0, 0); B32 change = 0; - UI_NavActionList *nav_actions = ui_nav_actions(); + UI_EventList *events = ui_events(); TXTI_BufferInfo buffer_info = txti_buffer_info_from_handle(scratch.arena, handle); - for(UI_NavActionNode *n = nav_actions->first, *next = 0; n != 0; n = next) + for(UI_EventNode *n = events->first, *next = 0; n != 0; n = next) { next = n->next; B32 taken = 0; String8 line = txti_string_from_handle_line_num(scratch.arena, handle, cursor->line); - UI_NavTxtOp single_line_op = ui_nav_single_line_txt_op_from_action(scratch.arena, n->v, line, *cursor, *mark); + UI_TxtOp single_line_op = ui_single_line_txt_op_from_event(scratch.arena, &n->v, line, *cursor, *mark); //- rjf: invalid single-line op or endpoint units => try multiline - if(n->v.delta_unit == UI_NavDeltaUnit_EndPoint || single_line_op.flags & UI_NavTxtOpFlag_Invalid) + if(n->v.delta_unit == UI_EventDeltaUnit_Whole || single_line_op.flags & UI_TxtOpFlag_Invalid) { U64 line_count = buffer_info.total_line_count; String8 prev_line = txti_string_from_handle_line_num(scratch.arena, handle, cursor->line-1); String8 next_line = txti_string_from_handle_line_num(scratch.arena, handle, cursor->line+1); - Vec2S32 delta = n->v.delta; + Vec2S32 delta = n->v.delta_2s32; //- rjf: wrap lines right - if(n->v.delta_unit != UI_NavDeltaUnit_EndPoint && delta.x > 0 && cursor->column == line.size+1 && cursor->line+1 <= line_count) + if(n->v.delta_unit != UI_EventDeltaUnit_Whole && delta.x > 0 && cursor->column == line.size+1 && cursor->line+1 <= line_count) { cursor->line += 1; cursor->column = 1; @@ -11481,7 +11613,7 @@ df_do_txti_controls(TXTI_Handle handle, U64 line_count_per_page, TxtPt *cursor, } //- rjf: wrap lines left - if(n->v.delta_unit != UI_NavDeltaUnit_EndPoint && delta.x < 0 && cursor->column == 1 && cursor->line-1 >= 1) + if(n->v.delta_unit != UI_EventDeltaUnit_Whole && delta.x < 0 && cursor->column == 1 && cursor->line-1 >= 1) { cursor->line -= 1; cursor->column = prev_line.size+1; @@ -11491,7 +11623,7 @@ df_do_txti_controls(TXTI_Handle handle, U64 line_count_per_page, TxtPt *cursor, } //- rjf: movement down (plain) - if(n->v.delta_unit == UI_NavDeltaUnit_Element && delta.y > 0 && cursor->line+1 <= line_count) + if(n->v.delta_unit == UI_EventDeltaUnit_Char && delta.y > 0 && cursor->line+1 <= line_count) { cursor->line += 1; cursor->column = Min(*preferred_column, next_line.size+1); @@ -11500,7 +11632,7 @@ df_do_txti_controls(TXTI_Handle handle, U64 line_count_per_page, TxtPt *cursor, } //- rjf: movement up (plain) - if(n->v.delta_unit == UI_NavDeltaUnit_Element && delta.y < 0 && cursor->line-1 >= 1) + if(n->v.delta_unit == UI_EventDeltaUnit_Char && delta.y < 0 && cursor->line-1 >= 1) { cursor->line -= 1; cursor->column = Min(*preferred_column, prev_line.size+1); @@ -11509,7 +11641,7 @@ df_do_txti_controls(TXTI_Handle handle, U64 line_count_per_page, TxtPt *cursor, } //- rjf: movement down (chunk) - if(n->v.delta_unit == UI_NavDeltaUnit_Chunk && delta.y > 0 && cursor->line+1 <= line_count) + if(n->v.delta_unit == UI_EventDeltaUnit_Word && delta.y > 0 && cursor->line+1 <= line_count) { for(S64 line_num = cursor->line+1; line_num <= line_count; line_num += 1) { @@ -11532,7 +11664,7 @@ df_do_txti_controls(TXTI_Handle handle, U64 line_count_per_page, TxtPt *cursor, } //- rjf: movement up (chunk) - if(n->v.delta_unit == UI_NavDeltaUnit_Chunk && delta.y < 0 && cursor->line-1 >= 1) + if(n->v.delta_unit == UI_EventDeltaUnit_Word && delta.y < 0 && cursor->line-1 >= 1) { for(S64 line_num = cursor->line-1; line_num > 0; line_num -= 1) { @@ -11555,7 +11687,7 @@ df_do_txti_controls(TXTI_Handle handle, U64 line_count_per_page, TxtPt *cursor, } //- rjf: movement down (page) - if(n->v.delta_unit == UI_NavDeltaUnit_Whole && delta.y > 0) + if(n->v.delta_unit == UI_EventDeltaUnit_Page && delta.y > 0) { cursor->line += line_count_per_page; cursor->column = 1; @@ -11565,7 +11697,7 @@ df_do_txti_controls(TXTI_Handle handle, U64 line_count_per_page, TxtPt *cursor, } //- rjf: movement up (page) - if(n->v.delta_unit == UI_NavDeltaUnit_Whole && delta.y < 0) + if(n->v.delta_unit == UI_EventDeltaUnit_Page && delta.y < 0) { cursor->line -= line_count_per_page; cursor->column = 1; @@ -11575,7 +11707,7 @@ df_do_txti_controls(TXTI_Handle handle, U64 line_count_per_page, TxtPt *cursor, } //- rjf: movement to endpoint (+) - if(n->v.delta_unit == UI_NavDeltaUnit_EndPoint && (delta.y > 0 || delta.x > 0)) + if(n->v.delta_unit == UI_EventDeltaUnit_Whole && (delta.y > 0 || delta.x > 0)) { *cursor = txt_pt(line_count, buffer_info.last_line_size); change = 1; @@ -11583,7 +11715,7 @@ df_do_txti_controls(TXTI_Handle handle, U64 line_count_per_page, TxtPt *cursor, } //- rjf: movement to endpoint (-) - if(n->v.delta_unit == UI_NavDeltaUnit_EndPoint && (delta.y < 0 || delta.x < 0)) + if(n->v.delta_unit == UI_EventDeltaUnit_Whole && (delta.y < 0 || delta.x < 0)) { *cursor = txt_pt(1, 1); change = 1; @@ -11591,7 +11723,7 @@ df_do_txti_controls(TXTI_Handle handle, U64 line_count_per_page, TxtPt *cursor, } //- rjf: stick mark to cursor, when we don't want to keep it in the same spot - if(!(n->v.flags & UI_NavActionFlag_KeepMark)) + if(!(n->v.flags & UI_EventFlag_KeepMark)) { *mark = *cursor; } @@ -11608,7 +11740,7 @@ df_do_txti_controls(TXTI_Handle handle, U64 line_count_per_page, TxtPt *cursor, } //- rjf: copy - if(n->v.flags & UI_NavActionFlag_Copy) + if(n->v.flags & UI_EventFlag_Copy) { String8 text = txti_string_from_handle_txt_rng(scratch.arena, handle, txt_rng(*cursor, *mark)); os_set_clipboard_text(text); @@ -11617,7 +11749,7 @@ df_do_txti_controls(TXTI_Handle handle, U64 line_count_per_page, TxtPt *cursor, //- rjf: consume if(taken) { - ui_nav_eat_action_node(nav_actions, n); + ui_eat_event(events, n); } } @@ -11914,16 +12046,16 @@ df_line_edit(DF_LineEditFlags flags, S32 depth, FuzzyMatchRangeList *matches, Tx B32 commit = 0; if(!is_focus_active && is_focus_hot) { - UI_NavActionList *nav_actions = ui_nav_actions(); - for(UI_NavActionNode *n = nav_actions->first, *next = 0; n != 0; n = next) + UI_EventList *events = ui_events(); + for(UI_EventNode *n = events->first, *next = 0; n != 0; n = next) { next = n->next; - UI_NavAction *action = &n->v; - if(action->flags & UI_NavActionFlag_Copy) + UI_Event *evt = &n->v; + if(evt->flags & UI_EventFlag_Copy) { os_set_clipboard_text(pre_edit_value); } - if(action->flags & UI_NavActionFlag_Delete) + if(evt->flags & UI_EventFlag_Delete) { commit = 1; edit_string_size_out[0] = 0; @@ -11946,17 +12078,17 @@ df_line_edit(DF_LineEditFlags flags, S32 depth, FuzzyMatchRangeList *matches, Tx B32 start_editing_via_typing = 0; if(is_focus_hot) { - UI_NavActionList *nav_actions = ui_nav_actions(); - for(UI_NavActionNode *n = nav_actions->first; n != 0; n = n->next) + UI_EventList *events = ui_events(); + for(UI_EventNode *n = events->first; n != 0; n = n->next) { - if(n->v.insertion.size != 0 || n->v.flags & UI_NavActionFlag_Paste) + if(n->v.string.size != 0 || n->v.flags & UI_EventFlag_Paste) { start_editing_via_typing = 1; break; } } } - if(is_focus_hot && os_key_press(ui_events(), ui_window(), 0, OS_Key_F2)) + if(is_focus_hot && ui_key_press(ui_events(), 0, OS_Key_F2)) { start_editing_via_typing = 1; } @@ -11984,32 +12116,32 @@ df_line_edit(DF_LineEditFlags flags, S32 depth, FuzzyMatchRangeList *matches, Tx if(!(flags & DF_LineEditFlag_DisableEdit) && (is_focus_active || focus_started)) { Temp scratch = scratch_begin(0, 0); - UI_NavActionList *nav_actions = ui_nav_actions(); - for(UI_NavActionNode *n = nav_actions->first, *next = 0; n != 0; n = next) + UI_EventList *events = ui_events(); + for(UI_EventNode *n = events->first, *next = 0; n != 0; n = next) { String8 edit_string = str8(edit_buffer, edit_string_size_out[0]); next = n->next; // rjf: do not consume anything that doesn't fit a single-line's operations - if(n->v.delta.y != 0) + if(n->v.delta_2s32.y != 0) { continue; } // rjf: map this action to an op - UI_NavTxtOp op = ui_nav_single_line_txt_op_from_action(scratch.arena, n->v, edit_string, *cursor, *mark); + UI_TxtOp op = ui_single_line_txt_op_from_event(scratch.arena, &n->v, edit_string, *cursor, *mark); // rjf: perform replace range if(!txt_pt_match(op.range.min, op.range.max) || op.replace.size != 0) { - String8 new_string = ui_nav_push_string_replace_range(scratch.arena, edit_string, r1s64(op.range.min.column, op.range.max.column), op.replace); + String8 new_string = ui_push_string_replace_range(scratch.arena, edit_string, r1s64(op.range.min.column, op.range.max.column), op.replace); new_string.size = Min(edit_buffer_size, new_string.size); MemoryCopy(edit_buffer, new_string.str, new_string.size); edit_string_size_out[0] = new_string.size; } // rjf: perform copy - if(op.flags & UI_NavTxtOpFlag_Copy) + if(op.flags & UI_TxtOpFlag_Copy) { os_set_clipboard_text(op.copy); } @@ -12020,7 +12152,7 @@ df_line_edit(DF_LineEditFlags flags, S32 depth, FuzzyMatchRangeList *matches, Tx // rjf: consume event { - ui_nav_eat_action_node(nav_actions, n); + ui_eat_event(events, n); changes_made = 1; } } diff --git a/src/df/gfx/df_views.c b/src/df/gfx/df_views.c index 2c438b71..611c1f2f 100644 --- a/src/df/gfx/df_views.c +++ b/src/df/gfx/df_views.c @@ -850,41 +850,42 @@ df_eval_watch_view_build(DF_Window *ws, DF_Panel *panel, DF_View *view, DF_EvalW { if(!ewv->input_editing && ui_is_focus_active()) { - UI_NavActionList *nav_actions = ui_nav_actions(); - for(UI_NavActionNode *n = nav_actions->first; n != 0; n = n->next) + UI_EventList *events = ui_events(); + for(UI_EventNode *n = events->first; n != 0; n = n->next) { - if(!str8_match(n->v.insertion, str8_lit(" "), 0) && (n->v.insertion.size != 0 || n->v.flags & UI_NavActionFlag_Paste)) + if(!str8_match(n->v.string, str8_lit(" "), 0) && (n->v.string.size != 0 || n->v.flags & UI_EventFlag_Paste)) { edit_begin = 1; break; } } - if(os_key_press(ui_events(), ui_window(), 0, OS_Key_F2)) + if(ui_key_press(ui_events(), 0, OS_Key_F2)) { edit_begin = 1; } - if(os_key_press(ui_events(), ui_window(), 0, OS_Key_Return)) + if(ui_key_press(ui_events(), 0, OS_Key_Return)) { edit_begin_or_expand = 1; } } if(ewv->input_editing && ui_is_focus_active()) { - if(os_key_press(ui_events(), ui_window(), 0, OS_Key_Esc)) + if(ui_key_press(ui_events(), 0, OS_Key_Esc)) { edit_end = 1; edit_commit = 0; } - if(os_key_press(ui_events(), ui_window(), 0, OS_Key_Return)) + if(ui_key_press(ui_events(), 0, OS_Key_Return)) { edit_end = 1; edit_commit = 1; edit_submit = 1; } - UI_NavActionList *nav_actions = ui_nav_actions(); - for(UI_NavActionNode *n = nav_actions->first; n != 0; n = n->next) +#if 0 + UI_EventList *events = ui_events(); + for(UI_EventNode *n = events->first; n != 0; n = n->next) { - if(n->v.flags & UI_NavActionFlag_ReplaceAndCommit) + if(n->v.flags & UI_EventFlag_ReplaceAndCommit) { edit_commit = 1; edit_end = 1; @@ -893,6 +894,7 @@ df_eval_watch_view_build(DF_Window *ws, DF_Panel *panel, DF_View *view, DF_EvalW break; } } +#endif } } @@ -1855,7 +1857,7 @@ DF_VIEW_UI_FUNCTION_DEF(Commands) df_cmd_lister_item_array_sort_by_strength__in_place(cmd_array); //- rjf: submit best match when hitting enter w/ no selection - if(cv->selected_cmd_spec == &df_g_nil_cmd_spec && os_key_press(ui_events(), ui_window(), 0, OS_Key_Return)) + if(cv->selected_cmd_spec == &df_g_nil_cmd_spec && ui_key_press(ui_events(), 0, OS_Key_Return)) { DF_CmdParams params = df_cmd_params_from_view(ws, panel, view); if(cmd_array.count > 0) @@ -2194,7 +2196,7 @@ DF_VIEW_UI_FUNCTION_DEF(FileSystem) } //- rjf: submit best match when hitting enter w/ no selection - if(ps->cursor.y == 0 && os_key_press(ui_events(), ui_window(), 0, OS_Key_Return)) + if(ps->cursor.y == 0 && ui_key_press(ui_events(), 0, OS_Key_Return)) { FileProperties query_normalized_with_opt_slash_props = os_properties_from_file_path(query_normalized_with_opt_slash); FileProperties path_query_path_props = os_properties_from_file_path(path_query.path); @@ -2533,7 +2535,7 @@ DF_VIEW_UI_FUNCTION_DEF(SystemProcesses) } //- rjf: submit best match when hitting enter w/ no selection - if(sp->selected_pid == 0 && process_info_array.count > 0 && os_key_press(ui_events(), ui_window(), 0, OS_Key_Return)) + if(sp->selected_pid == 0 && process_info_array.count > 0 && ui_key_press(ui_events(), 0, OS_Key_Return)) { DF_ProcessInfo *info = &process_info_array.v[0]; DF_CmdParams params = df_cmd_params_from_view(ws, panel, view); @@ -2690,7 +2692,7 @@ DF_VIEW_UI_FUNCTION_DEF(EntityLister) df_entity_lister_item_array_sort_by_strength__in_place(ent_arr); //- rjf: submit best match when hitting enter w/ no selection - if(df_entity_is_nil(df_entity_from_handle(fev->selected_entity_handle)) && ent_arr.count != 0 && os_key_press(ui_events(), ui_window(), 0, OS_Key_Return)) + if(df_entity_is_nil(df_entity_from_handle(fev->selected_entity_handle)) && ent_arr.count != 0 && ui_key_press(ui_events(), 0, OS_Key_Return)) { DF_Entity *ent = ent_arr.v[0].entity; DF_CmdParams params = df_cmd_params_from_view(ws, panel, view); @@ -2843,7 +2845,7 @@ DF_VIEW_UI_FUNCTION_DEF(SymbolLister) } //- rjf: submit best match when hitting enter w/ no selection - if(slv->cursor.y == 0 && items.count != 0 && os_key_press(ui_events(), ui_window(), 0, OS_Key_Return)) + if(slv->cursor.y == 0 && items.count != 0 && ui_key_press(ui_events(), 0, OS_Key_Return)) { RDI_Procedure *procedure = rdi_element_from_idx(rdi, procedures, items.v[0].idx); U64 name_size = 0; @@ -3043,32 +3045,32 @@ DF_VIEW_UI_FUNCTION_DEF(Target) { if(!tv->input_editing) { - UI_NavActionList *nav_actions = ui_nav_actions(); - for(UI_NavActionNode *n = nav_actions->first; n != 0; n = n->next) + UI_EventList *events = ui_events(); + for(UI_EventNode *n = events->first; n != 0; n = n->next) { - if(n->v.insertion.size != 0 || n->v.flags & UI_NavActionFlag_Paste) + if(n->v.string.size != 0 || n->v.flags & UI_EventFlag_Paste) { edit_begin = 1; break; } } - if(os_key_press(ui_events(), ui_window(), 0, OS_Key_F2)) + if(ui_key_press(ui_events(), 0, OS_Key_F2)) { edit_begin = 1; } - if(os_key_press(ui_events(), ui_window(), 0, OS_Key_Return)) + if(ui_key_press(ui_events(), 0, OS_Key_Return)) { edit_begin = 1; } } if(tv->input_editing) { - if(os_key_press(ui_events(), ui_window(), 0, OS_Key_Esc)) + if(ui_key_press(ui_events(), 0, OS_Key_Esc)) { edit_end = 1; edit_commit = 0; } - if(os_key_press(ui_events(), ui_window(), 0, OS_Key_Return)) + if(ui_key_press(ui_events(), 0, OS_Key_Return)) { edit_end = 1; edit_commit = 1; @@ -3518,28 +3520,28 @@ DF_VIEW_UI_FUNCTION_DEF(FilePathMap) { if(!fpms->input_editing) { - UI_NavActionList *nav_actions = ui_nav_actions(); - for(UI_NavActionNode *n = nav_actions->first; n != 0; n = n->next) + UI_EventList *events = ui_events(); + for(UI_EventNode *n = events->first; n != 0; n = n->next) { - if(n->v.insertion.size != 0 || n->v.flags & UI_NavActionFlag_Paste) + if(n->v.string.size != 0 || n->v.flags & UI_EventFlag_Paste) { edit_begin = 1; break; } } - if(os_key_press(ui_events(), ui_window(), 0, OS_Key_F2)) + if(ui_key_press(ui_events(), 0, OS_Key_F2)) { edit_begin = 1; } } if(fpms->input_editing) { - if(os_key_press(ui_events(), ui_window(), 0, OS_Key_Esc)) + if(ui_key_press(ui_events(), 0, OS_Key_Esc)) { edit_end = 1; edit_commit = 0; } - if(os_key_press(ui_events(), ui_window(), 0, OS_Key_Return)) + if(ui_key_press(ui_events(), 0, OS_Key_Return)) { edit_end = 1; edit_commit = 1; @@ -3836,28 +3838,28 @@ DF_VIEW_UI_FUNCTION_DEF(AutoViewRules) { if(!avrs->input_editing) { - UI_NavActionList *nav_actions = ui_nav_actions(); - for(UI_NavActionNode *n = nav_actions->first; n != 0; n = n->next) + UI_EventList *events = ui_events(); + for(UI_EventNode *n = events->first; n != 0; n = n->next) { - if(n->v.insertion.size != 0 || n->v.flags & UI_NavActionFlag_Paste) + if(n->v.string.size != 0 || n->v.flags & UI_EventFlag_Paste) { edit_begin = 1; break; } } - if(os_key_press(ui_events(), ui_window(), 0, OS_Key_F2)) + if(ui_key_press(ui_events(), 0, OS_Key_F2)) { edit_begin = 1; } } if(avrs->input_editing) { - if(os_key_press(ui_events(), ui_window(), 0, OS_Key_Esc)) + if(ui_key_press(ui_events(), 0, OS_Key_Esc)) { edit_end = 1; edit_commit = 0; } - if(os_key_press(ui_events(), ui_window(), 0, OS_Key_Return)) + if(ui_key_press(ui_events(), 0, OS_Key_Return)) { edit_end = 1; edit_commit = 1; @@ -4652,29 +4654,29 @@ DF_VIEW_UI_FUNCTION_DEF(Modules) B32 edit_submit = 0; if(!mv->txt_editing && ui_is_focus_active()) { - UI_NavActionList *nav_actions = ui_nav_actions(); - for(UI_NavActionNode *n = nav_actions->first; n != 0; n = n->next) + UI_EventList *events = ui_events(); + for(UI_EventNode *n = events->first; n != 0; n = n->next) { - if(n->v.insertion.size != 0 || n->v.flags & UI_NavActionFlag_Paste) + if(n->v.string.size != 0 || n->v.flags & UI_EventFlag_Paste) { edit_begin = 1; break; } } - if(os_key_press(ui_events(), ui_window(), 0, OS_Key_F2) || - os_key_press(ui_events(), ui_window(), 0, OS_Key_Return)) + if(ui_key_press(ui_events(), 0, OS_Key_F2) || + ui_key_press(ui_events(), 0, OS_Key_Return)) { edit_begin = 1; } } if(mv->txt_editing && ui_is_focus_active()) { - if(os_key_press(ui_events(), ui_window(), 0, OS_Key_Esc)) + if(ui_key_press(ui_events(), 0, OS_Key_Esc)) { edit_end = 1; edit_commit = 0; } - if(os_key_press(ui_events(), ui_window(), 0, OS_Key_Return)) + if(ui_key_press(ui_events(), 0, OS_Key_Return)) { edit_end = 1; edit_commit = 1; @@ -7847,47 +7849,47 @@ DF_VIEW_UI_FUNCTION_DEF(Memory) { U64 next_cursor = mv->cursor; U64 next_mark = mv->mark; - UI_NavActionList *nav_actions = ui_nav_actions(); - for(UI_NavActionNode *n = nav_actions->first, *next = 0; n != 0; n = next) + UI_EventList *events = ui_events(); + for(UI_EventNode *n = events->first, *next = 0; n != 0; n = next) { next = n->next; - UI_NavAction *action = &n->v; + UI_Event *evt = &n->v; Vec2S64 cell_delta = {0}; - switch(action->delta_unit) + switch(evt->delta_unit) { default:{}break; - case UI_NavDeltaUnit_Element: + case UI_EventDeltaUnit_Char: { - cell_delta.x = (S64)action->delta.x; - cell_delta.y = (S64)action->delta.y; + cell_delta.x = (S64)evt->delta_2s32.x; + cell_delta.y = (S64)evt->delta_2s32.y; }break; - case UI_NavDeltaUnit_Chunk: - case UI_NavDeltaUnit_Whole: + case UI_EventDeltaUnit_Word: + case UI_EventDeltaUnit_Page: { - if(action->delta.x < 0) + if(evt->delta_2s32.x < 0) { cell_delta.x = -(S64)(mv->cursor%mv->num_columns); } - else if(action->delta.x > 0) + else if(evt->delta_2s32.x > 0) { cell_delta.x = (mv->num_columns-1) - (S64)(mv->cursor%mv->num_columns); } - if(action->delta.y < 0) + if(evt->delta_2s32.y < 0) { cell_delta.y = -4; } - else if(action->delta.y > 0) + else if(evt->delta_2s32.y > 0) { cell_delta.y = +4; } }break; } B32 good_action = 0; - if(action->delta.x != 0 || action->delta.y != 0) + if(evt->delta_2s32.x != 0 || evt->delta_2s32.y != 0) { good_action = 1; } - if(good_action && action->flags & UI_NavActionFlag_ZeroDeltaOnSelect && mv->cursor != mv->mark) + if(good_action && evt->flags & UI_EventFlag_ZeroDeltaOnSelect && mv->cursor != mv->mark) { MemoryZeroStruct(&cell_delta); } @@ -7899,9 +7901,9 @@ DF_VIEW_UI_FUNCTION_DEF(Memory) next_cursor += cell_delta.y*mv->num_columns; next_cursor = ClampTop(0x7FFFFFFFFFFFull, next_cursor); } - if(good_action && action->flags & UI_NavActionFlag_PickSelectSide && mv->cursor != mv->mark) + if(good_action && evt->flags & UI_EventFlag_PickSelectSide && mv->cursor != mv->mark) { - if(action->delta.x < 0 || action->delta.y < 0) + if(evt->delta_2s32.x < 0 || evt->delta_2s32.y < 0) { next_cursor = Min(mv->cursor, mv->mark); } @@ -7910,14 +7912,14 @@ DF_VIEW_UI_FUNCTION_DEF(Memory) next_cursor = Max(mv->cursor, mv->mark); } } - if(good_action && !(action->flags & UI_NavActionFlag_KeepMark)) + if(good_action && !(evt->flags & UI_EventFlag_KeepMark)) { next_mark = next_cursor; } if(good_action) { mv->contain_cursor = 1; - ui_nav_eat_action_node(nav_actions, n); + ui_eat_event(events, n); } } mv->cursor = next_cursor; @@ -8320,18 +8322,20 @@ DF_VIEW_UI_FUNCTION_DEF(Memory) // rjf: ctrl+scroll -> change font size if(ui_hovering(sig)) { - for(OS_Event *event = ui_events()->first, *next = 0; event != 0; event = next) + UI_EventList *events = ui_events(); + for(UI_EventNode *n = events->first, *next = 0; n != 0; n = next) { - next = event->next; - if(os_handle_match(event->window, ui_window()) && event->kind == OS_EventKind_Scroll && event->flags & OS_EventFlag_Ctrl) + next = n->next; + UI_Event *event = &n->v; + if(event->kind == UI_EventKind_Scroll && event->modifiers & OS_EventFlag_Ctrl) { - os_eat_event(ui_events(), event); - if(event->delta.y < 0) + ui_eat_event(events, n); + if(event->delta_2f32.y < 0) { DF_CmdParams params = df_cmd_params_from_window(ws); df_push_cmd__root(¶ms, df_cmd_spec_from_core_cmd_kind(DF_CoreCmdKind_IncCodeFontScale)); } - else if(event->delta.y > 0) + else if(event->delta_2f32.y > 0) { DF_CmdParams params = df_cmd_params_from_window(ws); df_push_cmd__root(¶ms, df_cmd_spec_from_core_cmd_kind(DF_CoreCmdKind_DecCodeFontScale)); diff --git a/src/ui/ui_basic_widgets.c b/src/ui/ui_basic_widgets.c index 9cad0cf7..3aced18d 100644 --- a/src/ui/ui_basic_widgets.c +++ b/src/ui/ui_basic_widgets.c @@ -193,32 +193,32 @@ ui_line_edit(TxtPt *cursor, TxtPt *mark, U8 *edit_buffer, U64 edit_buffer_size, if(is_focus_active) { Temp scratch = scratch_begin(0, 0); - UI_NavActionList *nav_actions = ui_nav_actions(); - for(UI_NavActionNode *n = nav_actions->first, *next = 0; n != 0; n = next) + UI_EventList *events = ui_events(); + for(UI_EventNode *n = events->first, *next = 0; n != 0; n = next) { String8 edit_string = str8(edit_buffer, edit_string_size_out[0]); next = n->next; // rjf: do not consume anything that doesn't fit a single-line's operations - if(n->v.delta.y != 0) + if(n->v.delta_2s32.y != 0) { continue; } // rjf: map this action to an op - UI_NavTxtOp op = ui_nav_single_line_txt_op_from_action(scratch.arena, n->v, edit_string, *cursor, *mark); + UI_TxtOp op = ui_single_line_txt_op_from_event(scratch.arena, &n->v, edit_string, *cursor, *mark); // rjf: perform replace range if(!txt_pt_match(op.range.min, op.range.max) || op.replace.size != 0) { - String8 new_string = ui_nav_push_string_replace_range(scratch.arena, edit_string, r1s64(op.range.min.column, op.range.max.column), op.replace); + String8 new_string = ui_push_string_replace_range(scratch.arena, edit_string, r1s64(op.range.min.column, op.range.max.column), op.replace); new_string.size = Min(edit_buffer_size, new_string.size); MemoryCopy(edit_buffer, new_string.str, new_string.size); edit_string_size_out[0] = new_string.size; } // rjf: perform copy - if(op.flags & UI_NavTxtOpFlag_Copy) + if(op.flags & UI_TxtOpFlag_Copy) { os_set_clipboard_text(op.copy); } @@ -229,7 +229,7 @@ ui_line_edit(TxtPt *cursor, TxtPt *mark, U8 *edit_buffer, U64 edit_buffer_size, // rjf: consume event { - ui_nav_eat_action_node(nav_actions, n); + ui_eat_event(events, n); changes_made = 1; } } @@ -1345,27 +1345,27 @@ ui_scroll_list_begin(UI_ScrollListParams *params, UI_ScrollPt *scroll_pt, Vec2S6 B32 moved = 0; if(params->flags & UI_ScrollListFlag_Nav && cursor_out != 0 && ui_is_focus_active()) { - UI_NavActionList *nav_actions = ui_nav_actions(); + UI_EventList *events = ui_events(); Vec2S64 cursor = *cursor_out; - for(UI_NavActionNode *n = nav_actions->first, *next = 0; n != 0; n = next) + for(UI_EventNode *n = events->first, *next = 0; n != 0; n = next) { next = n->next; - UI_NavAction *action = &n->v; - if((action->delta.x == 0 && action->delta.y == 0) || - action->flags & (UI_NavActionFlag_KeepMark|UI_NavActionFlag_Delete)) + UI_Event *evt = &n->v; + if((evt->delta_2s32.x == 0 && evt->delta_2s32.y == 0) || + evt->flags & (UI_EventFlag_KeepMark|UI_EventFlag_Delete)) { continue; } - ui_nav_eat_action_node(nav_actions, n); + ui_eat_event(events, n); moved = 1; - switch(action->delta_unit) + switch(evt->delta_unit) { default:{moved = 0;}break; - case UI_NavDeltaUnit_Element: + case UI_EventDeltaUnit_Char: { for(Axis2 axis = (Axis2)0; axis < Axis2_COUNT; axis = (Axis2)(axis+1)) { - cursor.v[axis] += action->delta.v[axis]; + cursor.v[axis] += evt->delta_2s32.v[axis]; if(cursor.v[axis] < params->cursor_range.min.v[axis]) { cursor.v[axis] = params->cursor_range.max.v[axis]; @@ -1377,18 +1377,19 @@ ui_scroll_list_begin(UI_ScrollListParams *params, UI_ScrollPt *scroll_pt, Vec2S6 cursor.v[axis] = clamp_1s64(r1s64(params->cursor_range.min.v[axis], params->cursor_range.max.v[axis]), cursor.v[axis]); } }break; - case UI_NavDeltaUnit_Chunk: - case UI_NavDeltaUnit_Whole: + case UI_EventDeltaUnit_Word: + case UI_EventDeltaUnit_Line: + case UI_EventDeltaUnit_Page: { - cursor.x = (action->delta.x>0 ? params->cursor_range.max.x : action->delta.x<0 ? params->cursor_range.min.x + !!params->cursor_min_is_empty_selection[Axis2_X] : cursor.x); - cursor.y += ((action->delta.y>0 ? +(num_possible_visible_rows-3) : action->delta.y<0 ? -(num_possible_visible_rows-3) : 0)); + cursor.x = (evt->delta_2s32.x>0 ? params->cursor_range.max.x : evt->delta_2s32.x<0 ? params->cursor_range.min.x + !!params->cursor_min_is_empty_selection[Axis2_X] : cursor.x); + cursor.y += ((evt->delta_2s32.y>0 ? +(num_possible_visible_rows-3) : evt->delta_2s32.y<0 ? -(num_possible_visible_rows-3) : 0)); cursor.y = clamp_1s64(r1s64(params->cursor_range.min.y + !!params->cursor_min_is_empty_selection[Axis2_Y], params->cursor_range.max.y), cursor.y); }break; - case UI_NavDeltaUnit_EndPoint: + case UI_EventDeltaUnit_Whole: { for(Axis2 axis = (Axis2)0; axis < Axis2_COUNT; axis = (Axis2)(axis+1)) { - cursor.v[axis] = (action->delta.v[axis]>0 ? params->cursor_range.max.v[axis] : action->delta.v[axis]<0 ? params->cursor_range.min.v[axis] + !!params->cursor_min_is_empty_selection[axis] : cursor.v[axis]); + cursor.v[axis] = (evt->delta_2s32.v[axis]>0 ? params->cursor_range.max.v[axis] : evt->delta_2s32.v[axis]<0 ? params->cursor_range.min.v[axis] + !!params->cursor_min_is_empty_selection[axis] : cursor.v[axis]); } }break; } diff --git a/src/ui/ui_core.c b/src/ui/ui_core.c index 86526102..14b4c54f 100644 --- a/src/ui/ui_core.c +++ b/src/ui/ui_core.c @@ -166,9 +166,241 @@ ui_text(UI_EventList *list, U32 character) return result; } +//////////////////////////////// +//~ rjf: Text Operation Functions + +internal B32 +ui_char_is_scan_boundary(U8 c) +{ + return (char_is_alpha(c) || char_is_digit(c, 10) || c == '_'); +} + +internal S64 +ui_scanned_column_from_column(String8 string, S64 start_column, Side side) +{ + S64 new_column = start_column; + S64 delta = (!!side)*2 - 1; + B32 found_text = 0; + B32 found_non_space = 0; + S64 start_off = delta < 0 ? delta : 0; + for(S64 col = start_column+start_off; 1 <= col && col <= string.size+1; col += delta) + { + U8 byte = (col <= string.size) ? string.str[col-1] : 0; + B32 is_non_space = !char_is_space(byte); + B32 is_name = ui_char_is_scan_boundary(byte); + if(((side == Side_Min) && (col == 1)) || + ((side == Side_Max) && (col == string.size+1)) || + (found_non_space && !is_non_space) || + (found_text && !is_name)) + { + new_column = col + (!side && col != 1); + break; + } + else if (!found_text && is_name) + { + found_text = 1; + } + else if (!found_non_space && is_non_space) + { + found_non_space = 1; + } + } + return new_column; +} + +internal UI_TxtOp +ui_single_line_txt_op_from_event(Arena *arena, UI_Event *event, String8 string, TxtPt cursor, TxtPt mark) +{ + TxtPt next_cursor = cursor; + TxtPt next_mark = mark; + TxtRng range = {0}; + String8 replace = {0}; + String8 copy = {0}; + UI_TxtOpFlags flags = 0; + Vec2S32 delta = event->delta_2s32; + Vec2S32 original_delta = delta; + + //- rjf: resolve high-level delta into byte delta, based on unit + switch(event->delta_unit) + { + default:{}break; + case UI_EventDeltaUnit_Char: + { + // TODO(rjf): this should account for multi-byte characters in UTF-8... for now, just assume ASCII and + // no-op + }break; + case UI_EventDeltaUnit_Word: + { + delta.x = (S32)ui_scanned_column_from_column(string, cursor.column, delta.x > 0 ? Side_Max : Side_Min) - cursor.column; + }break; + case UI_EventDeltaUnit_Line: + case UI_EventDeltaUnit_Whole: + case UI_EventDeltaUnit_Page: + { + S64 first_nonwhitespace_column = 1; + for(U64 idx = 0; idx < string.size; idx += 1) + { + if(!char_is_space(string.str[idx])) + { + first_nonwhitespace_column = (S64)idx + 1; + break; + } + } + S64 home_dest_column = (cursor.column == first_nonwhitespace_column) ? 1 : first_nonwhitespace_column; + delta.x = (delta.x > 0) ? ((S64)string.size+1 - cursor.column) : (home_dest_column - cursor.column); + }break; + } + + //- rjf: zero delta + if(!txt_pt_match(cursor, mark) && event->flags & UI_EventFlag_ZeroDeltaOnSelect) + { + delta = v2s32(0, 0); + } + + //- rjf: form next cursor + if(txt_pt_match(cursor, mark) || !(event->flags & UI_EventFlag_ZeroDeltaOnSelect)) + { + next_cursor.column += delta.x; + } + + //- rjf: cap at line + if(event->flags & UI_EventFlag_CapAtLine) + { + next_cursor.column = Clamp(1, next_cursor.column, (S64)(string.size+1)); + } + + //- rjf: in some cases, we want to pick a selection side based on the delta + if(!txt_pt_match(cursor, mark) && event->flags & UI_EventFlag_PickSelectSide) + { + if(original_delta.x < 0 || original_delta.y < 0) + { + next_cursor = next_mark = txt_pt_min(cursor, mark); + } + else if(original_delta.x > 0 || original_delta.y > 0) + { + next_cursor = next_mark = txt_pt_max(cursor, mark); + } + } + + //- rjf: copying + if(event->flags & UI_EventFlag_Copy) + { + if(cursor.line == mark.line) + { + copy = str8_substr(string, r1u64(cursor.column-1, mark.column-1)); + flags |= UI_TxtOpFlag_Copy; + } + else + { + flags |= UI_TxtOpFlag_Invalid; + } + } + + //- rjf: pasting + if(event->flags & UI_EventFlag_Paste) + { + range = txt_rng(cursor, mark); + replace = os_get_clipboard_text(arena); + next_cursor = next_mark = txt_pt(cursor.line, cursor.column+replace.size); + } + + //- rjf: deletion + if(event->flags & UI_EventFlag_Delete) + { + TxtPt new_pos = txt_pt_min(next_cursor, next_mark); + range = txt_rng(next_cursor, next_mark); + replace = str8_lit(""); + next_cursor = next_mark = new_pos; + } + + //- rjf: stick mark to cursor, when we don't want to keep it in the same spot + if(!(event->flags & UI_EventFlag_KeepMark)) + { + next_mark = next_cursor; + } + + //- rjf: insertion + if(event->string.size != 0) + { + range = txt_rng(cursor, mark); + replace = push_str8_copy(arena, event->string); + next_cursor = next_mark = txt_pt(range.min.line, range.min.column + event->string.size); + } + + //- rjf: replace & commit -> replace entire range +#if 0 + if(event->flags & UI_EventFlag_ReplaceAndCommit) + { + range = txt_rng(txt_pt(cursor.line, 1), txt_pt(cursor.line, line.size+1)); + } +#endif + + //- rjf: determine if this event should be taken, based on bounds of cursor + { + if(next_cursor.column > string.size+1 || 1 > next_cursor.column || event->delta_2s32.y != 0) + { + flags |= UI_TxtOpFlag_Invalid; + } + next_cursor.column = Clamp(1, next_cursor.column, string.size+replace.size+1); + next_mark.column = Clamp(1, next_mark.column, string.size+replace.size+1); + } + + //- rjf: build+fill + UI_TxtOp op = {0}; + { + op.flags = flags; + op.replace = replace; + op.copy = copy; + op.range = range; + op.cursor = next_cursor; + op.mark = next_mark; + } + return op; +} + +internal String8 +ui_push_string_replace_range(Arena *arena, String8 string, Rng1S64 col_range, String8 replace) +{ + //- rjf: convert to offset range + Rng1U64 range = + { + (U64)(col_range.min-1), + (U64)(col_range.max-1), + }; + + //- rjf: clamp range + if(range.min > string.size) + { + range.min = 0; + } + if(range.max > string.size) + { + range.max = string.size; + } + + //- rjf: calculate new size + U64 old_size = string.size; + U64 new_size = old_size - (range.max - range.min) + replace.size; + + //- rjf: push+fill new string storage + U8 *push_base = push_array(arena, U8, new_size); + { + MemoryCopy(push_base+0, string.str, range.min); + MemoryCopy(push_base+range.min+replace.size, string.str+range.max, string.size-range.max); + if(replace.str != 0) + { + MemoryCopy(push_base+range.min, replace.str, replace.size); + } + } + + String8 result = str8(push_base, new_size); + return result; +} + //////////////////////////////// //~ rjf: Navigation Action List Building & Consumption Functions +#if 0 internal void ui_nav_action_list_push(Arena *arena, UI_NavActionList *list, UI_NavAction action) { @@ -187,8 +419,9 @@ ui_nav_eat_action_node(UI_NavActionList *list, UI_NavActionNode *node) //////////////////////////////// //~ rjf: High Level Navigation Action => Text Operations + internal B32 -ui_nav_char_is_code_symbol(U8 c) +ui_nav_char_is_scan_boundary(U8 c) { return (char_is_alpha(c) || char_is_digit(c, 10) || c == '_'); } @@ -205,7 +438,7 @@ ui_nav_scanned_column_from_column(String8 string, S64 start_column, Side side) { U8 byte = (col <= string.size) ? string.str[col-1] : 0; B32 is_non_space = !char_is_space(byte); - B32 is_name = ui_nav_char_is_code_symbol(byte); + B32 is_name = ui_nav_char_is_scan_boundary(byte); if (((side == Side_Min) && (col == 1)) || ((side == Side_Max) && (col == string.size+1)) || @@ -411,6 +644,8 @@ ui_nav_push_string_replace_range(Arena *arena, String8 string, Rng1S64 col_range return str8(push_base, new_size); } +#endif + //////////////////////////////// //~ rjf: Sizes @@ -561,18 +796,12 @@ ui_window(void) return ui_state->window; } -internal OS_EventList * +internal UI_EventList * ui_events(void) { return ui_state->events; } -internal UI_NavActionList * -ui_nav_actions(void) -{ - return ui_state->nav_actions; -} - internal Vec2F32 ui_mouse(void) { @@ -718,7 +947,7 @@ ui_box_from_key(UI_Key key) //~ rjf: Top-Level Building API internal void -ui_begin_build(OS_EventList *events, OS_Handle window, UI_NavActionList *nav_actions, UI_IconInfo *icon_info, F32 real_dt, F32 animation_dt) +ui_begin_build(OS_Handle window, UI_EventList *events, UI_IconInfo *icon_info, F32 real_dt, F32 animation_dt) { //- rjf: reset per-build ui state { @@ -734,9 +963,9 @@ ui_begin_build(OS_EventList *events, OS_Handle window, UI_NavActionList *nav_act } //- rjf: detect mouse-moves - for(OS_Event *e = events->first; e != 0; e = e->next) + for(UI_EventNode *n = events->first; n != 0; n = n->next) { - if(e->kind == OS_EventKind_MouseMove && os_handle_match(e->window, window)) + if(n->v.kind == UI_EventKind_MouseMove) { ui_state->last_time_mousemoved_us = os_now_microseconds(); } @@ -746,7 +975,6 @@ ui_begin_build(OS_EventList *events, OS_Handle window, UI_NavActionList *nav_act { ui_state->events = events; ui_state->window = window; - ui_state->nav_actions = nav_actions; ui_state->mouse = (os_window_is_focused(window) || ui_state->last_time_mousemoved_us+500000 >= os_now_microseconds()) ? os_mouse_from_window(window) : v2f32(-100, -100); ui_state->animation_dt = animation_dt; MemoryZeroStruct(&ui_state->icon_info); @@ -780,43 +1008,41 @@ ui_begin_build(OS_EventList *events, OS_Handle window, UI_NavActionList *nav_act B32 nav_next = 0; B32 nav_prev = 0; Axis2 axis_lock = Axis2_Invalid; - if(os_key_press(events, window, 0, OS_Key_Tab)) + if(ui_key_press(events, 0, OS_Key_Tab)) { nav_next = 1; } - if(os_key_press(events, window, OS_EventFlag_Shift, OS_Key_Tab)) + if(ui_key_press(events, OS_EventFlag_Shift, OS_Key_Tab)) { nav_prev = 1; } - for(UI_NavActionNode *node = nav_actions->first, *next = 0; - node != 0; - node = next) + for(UI_EventNode *node = events->first, *next = 0; node != 0; node = next) { next = node->next; B32 taken = 0; - if(node->v.delta.x == 0 && node->v.delta.y == 0) + if(node->v.delta_2s32.x == 0 && node->v.delta_2s32.y == 0) { continue; } - if(((node->v.delta.x > 0 && nav_root->flags & UI_BoxFlag_DefaultFocusNavX) || node->v.delta.x == 0) && - ((node->v.delta.y > 0 && nav_root->flags & UI_BoxFlag_DefaultFocusNavY) || node->v.delta.y == 0)) + if(((node->v.delta_2s32.x > 0 && nav_root->flags & UI_BoxFlag_DefaultFocusNavX) || node->v.delta_2s32.x == 0) && + ((node->v.delta_2s32.y > 0 && nav_root->flags & UI_BoxFlag_DefaultFocusNavY) || node->v.delta_2s32.y == 0)) { taken = 1; nav_next = 1; } - if(((node->v.delta.x < 0 && nav_root->flags & UI_BoxFlag_DefaultFocusNavX) || node->v.delta.x == 0) && - ((node->v.delta.y < 0 && nav_root->flags & UI_BoxFlag_DefaultFocusNavY) || node->v.delta.y == 0)) + if(((node->v.delta_2s32.x < 0 && nav_root->flags & UI_BoxFlag_DefaultFocusNavX) || node->v.delta_2s32.x == 0) && + ((node->v.delta_2s32.y < 0 && nav_root->flags & UI_BoxFlag_DefaultFocusNavY) || node->v.delta_2s32.y == 0)) { taken = 1; nav_prev = 1; } - if(node->v.flags & UI_NavActionFlag_ExplicitDirectional) + if(node->v.flags & UI_EventFlag_ExplicitDirectional) { - axis_lock = node->v.delta.x != 0 ? Axis2_X : Axis2_Y; + axis_lock = node->v.delta_2s32.x != 0 ? Axis2_X : Axis2_Y; } if(taken) { - ui_nav_eat_action_node(nav_actions, node); + ui_eat_event(events, node); } } @@ -944,7 +1170,7 @@ ui_begin_build(OS_EventList *events, OS_Handle window, UI_NavActionList *nav_act //- rjf: some child has the active focus -> accept escape keys to pop from the active key stack if(!ui_key_match(ui_key_zero(), nav_root->default_nav_focus_active_key)) { - for(;os_key_press(events, window, 0, OS_Key_Esc);) + for(;ui_key_press(events, 0, OS_Key_Esc);) { UI_Box *prev_focus_root = nav_root; for(UI_Box *focus_root = ui_box_from_key(nav_root->default_nav_focus_active_key); @@ -972,12 +1198,9 @@ ui_begin_build(OS_EventList *events, OS_Handle window, UI_NavActionList *nav_act UI_Box *active_box = ui_box_from_key(nav_root->default_nav_focus_active_key); if(!ui_box_is_nil(active_box)) { - for(OS_Event *event = events->first; event != 0; event = event->next) + for(UI_EventNode *n = events->first; n != 0; n = n->next) { - if(!os_handle_match(event->window, window)) - { - continue; - } + UI_Event *event = &n->v; if(event->kind == OS_EventKind_Press && event->key == OS_Key_LeftMouseButton && !contains_2f32(active_box->rect, ui_mouse())) @@ -1087,20 +1310,6 @@ ui_begin_build(OS_EventList *events, OS_Handle window, UI_NavActionList *nav_act ui_state->active_box_key[k] = ui_key_zero(); } } - - //- rjf: reset active keys if there is clicking activity on other windows - for(OS_Event *event = events->first; event != 0; event = event->next) - { - if((event->kind == OS_EventKind_Press || event->kind == OS_EventKind_Release) && - !os_handle_match(event->window, window)) - { - for(EachEnumVal(UI_MouseButtonKind, k)) - { - ui_state->active_box_key[k] = ui_key_zero(); - } - break; - } - } } internal void @@ -1109,7 +1318,7 @@ ui_end_build(void) ProfBeginFunction(); //- rjf: escape -> close context menu - if(ui_state->ctx_menu_open != 0 && os_key_press(ui_events(), ui_window(), 0, OS_Key_Esc)) + if(ui_state->ctx_menu_open != 0 && ui_key_press(ui_events(), 0, OS_Key_Esc)) { ui_ctx_menu_close(); } @@ -1359,12 +1568,16 @@ ui_end_build(void) } //- rjf: close ctx menu if unconsumed clicks - for(OS_Event *event = ui_events()->first; event != 0; event = event->next) { - if(event->kind == OS_EventKind_Press && os_handle_match(event->window, ui_window()) && - (event->key == OS_Key_LeftMouseButton || event->key == OS_Key_RightMouseButton)) + UI_EventList *events = ui_events(); + for(UI_EventNode *n = events->first; n != 0; n = n->next) { - ui_ctx_menu_close(); + UI_Event *event = &n->v; + if(event->kind == UI_EventKind_Press && + (event->key == OS_Key_LeftMouseButton || event->key == OS_Key_RightMouseButton)) + { + ui_ctx_menu_close(); + } } } @@ -2408,33 +2621,33 @@ ui_do_single_line_string_edits(TxtPt *cursor, TxtPt *mark, U64 string_max, Strin { B32 change = 0; Temp scratch = scratch_begin(0, 0); - UI_NavActionList *nav_actions = ui_nav_actions(); - for(UI_NavActionNode *n = nav_actions->first, *next = 0; n != 0; n = next) + UI_EventList *events = ui_events(); + for(UI_EventNode *n = events->first, *next = 0; n != 0; n = next) { next = n->next; // rjf: do not consume anything that doesn't fit a single-line's operations - if(n->v.delta.y != 0) + if(n->v.delta_2s32.y != 0) { continue; } // rjf: map this action to an op B32 taken = 0; - UI_NavTxtOp op = ui_nav_single_line_txt_op_from_action(scratch.arena, n->v, *out_string, *cursor, *mark); + UI_TxtOp op = ui_single_line_txt_op_from_event(scratch.arena, &n->v, *out_string, *cursor, *mark); // rjf: perform replace range if(!txt_pt_match(op.range.min, op.range.max) || op.replace.size != 0) { taken = 1; - String8 new_string = ui_nav_push_string_replace_range(scratch.arena, *out_string, r1s64(op.range.min.column, op.range.max.column), op.replace); + String8 new_string = ui_push_string_replace_range(scratch.arena, *out_string, r1s64(op.range.min.column, op.range.max.column), op.replace); new_string.size = Min(string_max, new_string.size); MemoryCopy(out_string->str, new_string.str, new_string.size); out_string->size = new_string.size; } // rjf: perform copy - if(op.flags & UI_NavTxtOpFlag_Copy) + if(op.flags & UI_TxtOpFlag_Copy) { taken = 1; os_set_clipboard_text(op.copy); @@ -2448,7 +2661,7 @@ ui_do_single_line_string_edits(TxtPt *cursor, TxtPt *mark, U64 string_max, Strin // rjf: consume event if(taken) { - ui_nav_eat_action_node(nav_actions, n); + ui_eat_event(events, n); change = 1; } } @@ -2507,15 +2720,13 @@ ui_signal_from_box(UI_Box *box) //- rjf: process events related to this box // B32 view_scrolled = 0; - for(OS_Event *evt = ui_state->events->first, *next = 0; - evt != 0; - evt = next) + for(UI_EventNode *n = ui_state->events->first, *next = 0; + n != 0; + n = next) { B32 taken = 0; - next = evt->next; - - //- rjf: skip disqualified events - if(!os_handle_match(evt->window, ui_state->window)) {continue;} + next = n->next; + UI_Event *evt = &n->v; //- rjf: unpack event Vec2F32 evt_mouse = evt->pos; @@ -2527,7 +2738,7 @@ ui_signal_from_box(UI_Box *box) B32 evt_key_is_mouse = (evt->key == OS_Key_LeftMouseButton || evt->key == OS_Key_MiddleMouseButton || evt->key == OS_Key_RightMouseButton); - sig.event_flags |= evt->flags; + sig.event_flags |= evt->modifiers; //- rjf: mouse presses in box -> set hot/active; mark signal accordingly if(box->flags & UI_BoxFlag_MouseClickable && @@ -2599,14 +2810,52 @@ ui_signal_from_box(UI_Box *box) taken = 1; } + //- rjf: focus is hot & copy event -> remember to copy this box tree's text content + if(is_focus_hot && + evt->flags & UI_EventFlag_Copy) + { + ui_state->clipboard_copy_key = box->key; + taken = 1; + } + + //- rjf: ancestor is focused & fastpath codepoint pressed -> press + if(box->flags & UI_BoxFlag_Clickable && box->fastpath_codepoint != 0 && evt->string.size != 0) + { + B32 ancestor_is_focused = 0; + for(UI_Box *parent = box->parent; !ui_box_is_nil(parent); parent = parent->parent) + { + if(parent->flags & UI_BoxFlag_FocusActive) + { + ancestor_is_focused = 1; + if(parent->flags & UI_BoxFlag_FocusActiveDisabled || + !ui_key_match(parent->default_nav_focus_active_key, ui_key_zero())) + { + ancestor_is_focused = 0; + break; + } + } + } + if(ancestor_is_focused) + { + Temp scratch = scratch_begin(0, 0); + String32 insertion32 = str32_from_8(scratch.arena, evt->string); + if(insertion32.size == 1 && insertion32.str[0] == box->fastpath_codepoint) + { + taken = 1; + sig.f |= UI_SignalFlag_Clicked|UI_SignalFlag_Pressed; + } + scratch_end(scratch); + } + } + //- rjf: scrolling if(box->flags & UI_BoxFlag_Scroll && evt->kind == OS_EventKind_Scroll && - evt->flags != OS_EventFlag_Ctrl && + evt->modifiers != OS_EventFlag_Ctrl && evt_mouse_in_bounds) { - Vec2F32 delta = evt->delta; - if(evt->flags & OS_EventFlag_Shift) + Vec2F32 delta = evt->delta_2f32; + if(evt->modifiers & OS_EventFlag_Shift) { Swap(F32, delta.x, delta.y); } @@ -2623,11 +2872,11 @@ ui_signal_from_box(UI_Box *box) //- rjf: view scrolling if(box->flags & UI_BoxFlag_ViewScroll && box->first_touched_build_index != box->last_touched_build_index && evt->kind == OS_EventKind_Scroll && - evt->flags != OS_EventFlag_Ctrl && + evt->modifiers != OS_EventFlag_Ctrl && evt_mouse_in_bounds) { - Vec2F32 delta = evt->delta; - if(evt->flags & OS_EventFlag_Shift) + Vec2F32 delta = evt->delta_2f32; + if(evt->modifiers & OS_EventFlag_Shift) { Swap(F32, delta.x, delta.y); } @@ -2647,7 +2896,6 @@ ui_signal_from_box(UI_Box *box) } delta.y = 0; } - os_eat_event(ui_state->events, evt); box->view_off_target.x += delta.x; box->view_off_target.y += delta.y; view_scrolled = 1; @@ -2657,58 +2905,7 @@ ui_signal_from_box(UI_Box *box) //- rjf: taken -> eat event if(taken) { - os_eat_event(ui_state->events, evt); - } - } - - ////////////////////////////// - //- rjf: process nav actions related to this box - // - { - for(UI_NavActionNode *n = ui_state->nav_actions->first, *next = 0; - n != 0; - n = next) - { - next = n->next; - UI_NavAction *action = &n->v; - B32 taken = 0; - if(is_focus_hot && box->flags & UI_BoxFlag_KeyboardClickable && action->flags & UI_NavActionFlag_Copy) - { - ui_state->clipboard_copy_key = box->key; - taken = 1; - } - if(box->flags & UI_BoxFlag_Clickable && box->fastpath_codepoint != 0) - { - B32 ancestor_is_focused = 0; - for(UI_Box *parent = box->parent; !ui_box_is_nil(parent); parent = parent->parent) - { - if(parent->flags & UI_BoxFlag_FocusActive) - { - ancestor_is_focused = 1; - if(parent->flags & UI_BoxFlag_FocusActiveDisabled || - !ui_key_match(parent->default_nav_focus_active_key, ui_key_zero())) - { - ancestor_is_focused = 0; - break; - } - } - } - if(ancestor_is_focused && action->insertion.size != 0) - { - Temp scratch = scratch_begin(0, 0); - String32 insertion32 = str32_from_8(scratch.arena, action->insertion); - if(insertion32.size == 1 && insertion32.str[0] == box->fastpath_codepoint) - { - taken = 1; - sig.f |= UI_SignalFlag_Clicked|UI_SignalFlag_Pressed; - } - scratch_end(scratch); - } - } - if(taken) - { - ui_nav_eat_action_node(ui_nav_actions(), n); - } + ui_eat_event(ui_state->events, n); } } diff --git a/src/ui/ui_core.h b/src/ui/ui_core.h index cd03f31a..57106585 100644 --- a/src/ui/ui_core.h +++ b/src/ui/ui_core.h @@ -65,6 +65,9 @@ typedef enum UI_EventKind UI_EventKind_Press, UI_EventKind_Release, UI_EventKind_Text, + UI_EventKind_Navigate, + UI_EventKind_Edit, + UI_EventKind_MouseMove, UI_EventKind_Scroll, UI_EventKind_COUNT } @@ -88,6 +91,7 @@ typedef enum UI_EventDeltaUnit UI_EventDeltaUnit_Char, UI_EventDeltaUnit_Word, UI_EventDeltaUnit_Line, + UI_EventDeltaUnit_Page, UI_EventDeltaUnit_Whole, UI_EventDeltaUnit_COUNT } @@ -105,6 +109,7 @@ struct UI_Event Vec2F32 pos; Vec2F32 delta_2f32; Vec2S32 delta_2s32; + U64 timestamp_us; }; typedef struct UI_EventNode UI_EventNode; @@ -144,6 +149,7 @@ struct UI_TxtOp TxtPt mark; }; +#if 0 //////////////////////////////// //~ rjf: Navigation Types @@ -213,6 +219,7 @@ struct UI_NavTxtOp TxtPt cursor; TxtPt mark; }; +#endif //////////////////////////////// //~ rjf: Keys @@ -573,8 +580,7 @@ struct UI_State //- rjf: build parameters UI_IconInfo icon_info; OS_Handle window; - OS_EventList *events; - UI_NavActionList *nav_actions; + UI_EventList *events; Vec2F32 mouse; F32 animation_dt; B32 external_focus_commit; @@ -638,6 +644,15 @@ 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: Text Operation Functions + +internal B32 ui_char_is_scan_boundary(U8 c); +internal S64 ui_scanned_column_from_column(String8 string, S64 start_column, Side side); +internal UI_TxtOp ui_single_line_txt_op_from_event(Arena *arena, UI_Event *event, String8 string, TxtPt cursor, TxtPt mark); +internal String8 ui_push_string_replace_range(Arena *arena, String8 string, Rng1S64 range, String8 replace); + +#if 0 //////////////////////////////// //~ rjf: Navigation Action List Building & Consumption Functions @@ -655,6 +670,7 @@ internal UI_NavTxtOp ui_nav_single_line_txt_op_from_action(Arena *arena, UI_NavA //~ rjf: Single-Line String Modification internal String8 ui_nav_push_string_replace_range(Arena *arena, String8 string, Rng1S64 col_range, String8 replace); +#endif //////////////////////////////// //~ rjf: Size Type Functions @@ -708,8 +724,7 @@ internal UI_State *ui_get_selected_state(void); //- rjf: per-frame info internal Arena * ui_build_arena(void); internal OS_Handle ui_window(void); -internal OS_EventList * ui_events(void); -internal UI_NavActionList *ui_nav_actions(void); +internal UI_EventList * ui_events(void); internal Vec2F32 ui_mouse(void); internal F_Tag ui_icon_font(void); internal String8 ui_icon_string_from_kind(UI_IconKind icon_kind); @@ -741,7 +756,7 @@ internal UI_Box * ui_box_from_key(UI_Key key); //////////////////////////////// //~ rjf: Top-Level Building API -internal void ui_begin_build(OS_EventList *events, OS_Handle window, UI_NavActionList *nav_actions, UI_IconInfo *icon_info, F32 real_dt, F32 animation_dt); +internal void ui_begin_build(OS_Handle window, UI_EventList *events, UI_IconInfo *icon_info, F32 real_dt, F32 animation_dt); internal void ui_end_build(void); internal void ui_calc_sizes_standalone__in_place_rec(UI_Box *root, Axis2 axis); internal void ui_calc_sizes_upwards_dependent__in_place_rec(UI_Box *root, Axis2 axis); From e41eb9430f54b419ae419aee8487ecaa400731d5 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Mon, 13 May 2024 11:48:42 -0700 Subject: [PATCH 05/30] finish pass to convert everything over to ui events, eliminate nav actions; intermix os events & ui event production with commands --- src/df/core/df_core.c | 18 ++ src/df/core/df_core.mdesk | 4 + src/df/core/generated/df_core.meta.c | 6 +- src/df/core/generated/df_core.meta.h | 5 +- src/df/gfx/df_gfx.c | 163 +++++++----- src/df/gfx/df_gfx.h | 2 +- src/df/gfx/df_views.c | 46 ++-- src/raddbg/raddbg.c | 192 ++++++++------ src/ui/ui_basic_widgets.c | 2 +- src/ui/ui_core.c | 382 +++++---------------------- src/ui/ui_core.h | 103 +------- 11 files changed, 347 insertions(+), 576 deletions(-) diff --git a/src/df/core/df_core.c b/src/df/core/df_core.c index 908b4991..29055c8d 100644 --- a/src/df/core/df_core.c +++ b/src/df/core/df_core.c @@ -6490,6 +6490,24 @@ df_push_cmd__root(DF_CmdParams *params, DF_CmdSpec *spec) if(params->voff != 0) { log_msgf("| voff: 0x%I64x\n", params->voff); } if(params->index != 0) { log_msgf("| index: 0x%I64x\n", params->index); } if(params->id != 0) { log_msgf("| id: 0x%I64x\n", params->id); } + if(params->os_event != 0) + { + String8 kind_string = str8_lit(""); + switch(params->os_event->kind) + { + default:{}break; + case OS_EventKind_Press: {kind_string = str8_lit("press");}break; + case OS_EventKind_Release: {kind_string = str8_lit("release");}break; + case OS_EventKind_MouseMove: {kind_string = str8_lit("mousemove");}break; + case OS_EventKind_Text: {kind_string = str8_lit("text");}break; + case OS_EventKind_Scroll: {kind_string = str8_lit("scroll");}break; + case OS_EventKind_WindowLoseFocus:{kind_string = str8_lit("losefocus");}break; + case OS_EventKind_WindowClose: {kind_string = str8_lit("closewindow");}break; + case OS_EventKind_FileDrop: {kind_string = str8_lit("filedrop");}break; + case OS_EventKind_Wakeup: {kind_string = str8_lit("wakeup");}break; + } + log_msgf("| os_event->kind: %S\n", kind_string); + } #undef HandleParamPrint log_msgf("--------------------------------\n"); scratch_end(scratch); diff --git a/src/df/core/df_core.mdesk b/src/df/core/df_core.mdesk index 08c95276..c37e1d23 100644 --- a/src/df/core/df_core.mdesk +++ b/src/df/core/df_core.mdesk @@ -89,6 +89,7 @@ DF_CmdParamSlotTable: {CmdSpec cmd_spec `struct DF_CmdSpec *`} {ViewSpec view_spec `struct DF_ViewSpec *`} {CfgNode cfg_node `struct DF_CfgNode *`} + {OSEvent os_event `struct OS_Event *`} {VirtualAddr vaddr `U64`} {VirtualOff voff `U64`} {Index index `U64`} @@ -114,6 +115,9 @@ DF_CoreCmdTable:// | | | //- rjf: notifications {Error 1 Null Nil 0 0 0 0 0 0 Null "error" "Error" "Notifies of an error." "" } + //- rjf: os event passthrough + {OSEvent 1 Null Nil 0 0 0 0 0 0 Null "os_event" "OS Event" "" "" } + //- rjf: low-level target control operations {LaunchAndRun 0 EntityList Target 0 0 0 0 0 1 Play "launch_and_run" "Launch and Run" "Starts debugging a new instance of a target, then runs." "launch,start,run,target" } {LaunchAndInit 0 EntityList Target 0 0 0 0 0 1 PlayStepForward "launch_and_init" "Launch and Initialize" "Starts debugging a new instance of a target, then stops at the program's entry point." "launch,start,entry,point" } diff --git a/src/df/core/generated/df_core.meta.c b/src/df/core/generated/df_core.meta.c index 3177beb5..4057bad1 100644 --- a/src/df/core/generated/df_core.meta.c +++ b/src/df/core/generated/df_core.meta.c @@ -4,7 +4,7 @@ //- GENERATED CODE C_LINKAGE_BEGIN -Rng1U64 df_g_cmd_param_slot_range_table[21] = +Rng1U64 df_g_cmd_param_slot_range_table[22] = { {0}, {OffsetOf(DF_CmdParams, window), OffsetOf(DF_CmdParams, window) + sizeof(DF_Handle)}, @@ -20,6 +20,7 @@ Rng1U64 df_g_cmd_param_slot_range_table[21] = {OffsetOf(DF_CmdParams, cmd_spec), OffsetOf(DF_CmdParams, cmd_spec) + sizeof(struct DF_CmdSpec *)}, {OffsetOf(DF_CmdParams, view_spec), OffsetOf(DF_CmdParams, view_spec) + sizeof(struct DF_ViewSpec *)}, {OffsetOf(DF_CmdParams, cfg_node), OffsetOf(DF_CmdParams, cfg_node) + sizeof(struct DF_CfgNode *)}, +{OffsetOf(DF_CmdParams, os_event), OffsetOf(DF_CmdParams, os_event) + sizeof(struct OS_Event *)}, {OffsetOf(DF_CmdParams, vaddr), OffsetOf(DF_CmdParams, vaddr) + sizeof(U64)}, {OffsetOf(DF_CmdParams, voff), OffsetOf(DF_CmdParams, voff) + sizeof(U64)}, {OffsetOf(DF_CmdParams, index), OffsetOf(DF_CmdParams, index) + sizeof(U64)}, @@ -216,12 +217,13 @@ DF_CoreCmdKind_Null, DF_CoreCmdKind_Null, }; -DF_CmdSpecInfo df_g_core_cmd_kind_spec_info_table[214] = +DF_CmdSpecInfo df_g_core_cmd_kind_spec_info_table[215] = { { str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp(""), (DF_CmdSpecFlag_OmitFromLists*1), {DF_CmdParamSlot_Null, DF_EntityKind_Nil, (DF_CmdQueryFlag_AllowFiles*0)|(DF_CmdQueryFlag_AllowFolders*0)|(DF_CmdQueryFlag_CodeInput*0)|(DF_CmdQueryFlag_KeepOldInput*0)|(DF_CmdQueryFlag_SelectOldInput*0)|(DF_CmdQueryFlag_Required*0)}, DF_IconKind_Null}, { str8_lit_comp("exit"), str8_lit_comp("Exits the debugger."), str8_lit_comp("quit,close,abort"), str8_lit_comp("Exit"), (DF_CmdSpecFlag_OmitFromLists*0), {DF_CmdParamSlot_Null, DF_EntityKind_Nil, (DF_CmdQueryFlag_AllowFiles*0)|(DF_CmdQueryFlag_AllowFolders*0)|(DF_CmdQueryFlag_CodeInput*0)|(DF_CmdQueryFlag_KeepOldInput*0)|(DF_CmdQueryFlag_SelectOldInput*0)|(DF_CmdQueryFlag_Required*0)}, DF_IconKind_X}, { str8_lit_comp("run_command"), str8_lit_comp("Runs a command from the command palette."), str8_lit_comp("help,cmd"), str8_lit_comp("Run Command"), (DF_CmdSpecFlag_OmitFromLists*0), {DF_CmdParamSlot_CmdSpec, DF_EntityKind_Nil, (DF_CmdQueryFlag_AllowFiles*0)|(DF_CmdQueryFlag_AllowFolders*0)|(DF_CmdQueryFlag_CodeInput*0)|(DF_CmdQueryFlag_KeepOldInput*0)|(DF_CmdQueryFlag_SelectOldInput*0)|(DF_CmdQueryFlag_Required*0)}, DF_IconKind_Null}, { str8_lit_comp("error"), str8_lit_comp("Notifies of an error."), str8_lit_comp(""), str8_lit_comp("Error"), (DF_CmdSpecFlag_OmitFromLists*1), {DF_CmdParamSlot_Null, DF_EntityKind_Nil, (DF_CmdQueryFlag_AllowFiles*0)|(DF_CmdQueryFlag_AllowFolders*0)|(DF_CmdQueryFlag_CodeInput*0)|(DF_CmdQueryFlag_KeepOldInput*0)|(DF_CmdQueryFlag_SelectOldInput*0)|(DF_CmdQueryFlag_Required*0)}, DF_IconKind_Null}, +{ str8_lit_comp("os_event"), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("OS Event"), (DF_CmdSpecFlag_OmitFromLists*1), {DF_CmdParamSlot_Null, DF_EntityKind_Nil, (DF_CmdQueryFlag_AllowFiles*0)|(DF_CmdQueryFlag_AllowFolders*0)|(DF_CmdQueryFlag_CodeInput*0)|(DF_CmdQueryFlag_KeepOldInput*0)|(DF_CmdQueryFlag_SelectOldInput*0)|(DF_CmdQueryFlag_Required*0)}, DF_IconKind_Null}, { str8_lit_comp("launch_and_run"), str8_lit_comp("Starts debugging a new instance of a target, then runs."), str8_lit_comp("launch,start,run,target"), str8_lit_comp("Launch and Run"), (DF_CmdSpecFlag_OmitFromLists*0), {DF_CmdParamSlot_EntityList, DF_EntityKind_Target, (DF_CmdQueryFlag_AllowFiles*0)|(DF_CmdQueryFlag_AllowFolders*0)|(DF_CmdQueryFlag_CodeInput*0)|(DF_CmdQueryFlag_KeepOldInput*0)|(DF_CmdQueryFlag_SelectOldInput*0)|(DF_CmdQueryFlag_Required*1)}, DF_IconKind_Play}, { str8_lit_comp("launch_and_init"), str8_lit_comp("Starts debugging a new instance of a target, then stops at the program's entry point."), str8_lit_comp("launch,start,entry,point"), str8_lit_comp("Launch and Initialize"), (DF_CmdSpecFlag_OmitFromLists*0), {DF_CmdParamSlot_EntityList, DF_EntityKind_Target, (DF_CmdQueryFlag_AllowFiles*0)|(DF_CmdQueryFlag_AllowFolders*0)|(DF_CmdQueryFlag_CodeInput*0)|(DF_CmdQueryFlag_KeepOldInput*0)|(DF_CmdQueryFlag_SelectOldInput*0)|(DF_CmdQueryFlag_Required*1)}, DF_IconKind_PlayStepForward}, { str8_lit_comp("kill"), str8_lit_comp("Kills the specified existing debugged process(es)."), str8_lit_comp("stop,kill"), str8_lit_comp("Kill"), (DF_CmdSpecFlag_OmitFromLists*0), {DF_CmdParamSlot_EntityList, DF_EntityKind_Process, (DF_CmdQueryFlag_AllowFiles*0)|(DF_CmdQueryFlag_AllowFolders*0)|(DF_CmdQueryFlag_CodeInput*0)|(DF_CmdQueryFlag_KeepOldInput*0)|(DF_CmdQueryFlag_SelectOldInput*0)|(DF_CmdQueryFlag_Required*1)}, DF_IconKind_Stop}, diff --git a/src/df/core/generated/df_core.meta.h b/src/df/core/generated/df_core.meta.h index c6c96bf5..d8ea126f 100644 --- a/src/df/core/generated/df_core.meta.h +++ b/src/df/core/generated/df_core.meta.h @@ -53,6 +53,7 @@ DF_CoreCmdKind_Null, DF_CoreCmdKind_Exit, DF_CoreCmdKind_RunCommand, DF_CoreCmdKind_Error, +DF_CoreCmdKind_OSEvent, DF_CoreCmdKind_LaunchAndRun, DF_CoreCmdKind_LaunchAndInit, DF_CoreCmdKind_Kill, @@ -378,6 +379,7 @@ DF_CmdParamSlot_TextPoint, DF_CmdParamSlot_CmdSpec, DF_CmdParamSlot_ViewSpec, DF_CmdParamSlot_CfgNode, +DF_CmdParamSlot_OSEvent, DF_CmdParamSlot_VirtualAddr, DF_CmdParamSlot_VirtualOff, DF_CmdParamSlot_Index, @@ -405,6 +407,7 @@ TxtPt text_point; struct DF_CmdSpec * cmd_spec; struct DF_ViewSpec * view_spec; struct DF_CfgNode * cfg_node; +struct OS_Event * os_event; U64 vaddr; U64 voff; U64 index; @@ -1522,7 +1525,7 @@ struct {B32 *value_ptr; String8 name;} DEV_toggle_table[] = {&DEV_updating_indicator, str8_lit_comp("updating_indicator")}, }; C_LINKAGE_BEGIN -extern Rng1U64 df_g_cmd_param_slot_range_table[21]; +extern Rng1U64 df_g_cmd_param_slot_range_table[22]; extern DF_IconKind df_g_entity_kind_icon_kind_table[27]; extern String8 df_g_entity_kind_display_string_table[27]; extern String8 df_g_entity_kind_name_label_table[27]; diff --git a/src/df/gfx/df_gfx.c b/src/df/gfx/df_gfx.c index 9333073b..ee7acbba 100644 --- a/src/df/gfx/df_gfx.c +++ b/src/df/gfx/df_gfx.c @@ -1030,7 +1030,7 @@ df_window_from_os_handle(OS_Handle os) #endif internal void -df_window_update_and_render(Arena *arena, OS_EventList *events, DF_Window *ws, DF_CmdList *cmds) +df_window_update_and_render(Arena *arena, DF_Window *ws, DF_CmdList *cmds) { ProfBeginFunction(); @@ -1073,8 +1073,8 @@ df_window_update_and_render(Arena *arena, OS_EventList *events, DF_Window *ws, D ////////////////////////////// //- rjf: do core-layer commands & batch up commands to be dispatched to views // + UI_EventList events = {0}; B32 panel_reset_done = 0; - UI_EventList events_ui = {0}; ProfScope("do commands") { Temp scratch = scratch_begin(&arena, 1); @@ -1119,6 +1119,36 @@ df_window_update_and_render(Arena *arena, OS_EventList *events, DF_Window *ws, D } }break; + //- rjf: OS events + case DF_CoreCmdKind_OSEvent: + { + OS_Event *os_event = params.os_event; + if(os_event != 0 && os_handle_match(os_event->window, ws->os)) + { + UI_Event ui_event = {0}; + UI_EventKind kind = UI_EventKind_Null; + { + switch(os_event->kind) + { + default:{}break; + case OS_EventKind_Press: {kind = UI_EventKind_Press;}break; + case OS_EventKind_Release: {kind = UI_EventKind_Release;}break; + case OS_EventKind_MouseMove: {kind = UI_EventKind_MouseMove;}break; + case OS_EventKind_Text: {kind = UI_EventKind_Text;}break; + case OS_EventKind_Scroll: {kind = UI_EventKind_Scroll;}break; + } + } + ui_event.kind = kind; + ui_event.key = os_event->key; + ui_event.modifiers = os_event->flags; + ui_event.string = os_event->character ? str8_from_32(ui_build_arena(), str32(&os_event->character, 1)) : str8_zero(); + ui_event.pos = os_event->pos; + ui_event.delta_2f32 = os_event->delta; + ui_event.timestamp_us = os_event->timestamp_us; + ui_event_list_push(ui_build_arena(), &events, &ui_event); + } + }break; + //- rjf: command fast path case DF_CoreCmdKind_RunCommand: { @@ -2087,64 +2117,72 @@ df_window_update_and_render(Arena *arena, OS_EventList *events, DF_Window *ws, D UI_Event evt = {0}; evt.kind = UI_EventKind_Navigate; evt.flags = UI_EventFlag_PickSelectSide|UI_EventFlag_ZeroDeltaOnSelect|UI_EventFlag_ExplicitDirectional; + evt.delta_unit = UI_EventDeltaUnit_Char; evt.delta_2s32 = v2s32(-1, +0); - ui_event_list_push(ui_build_arena(), &events_ui, &evt); + ui_event_list_push(ui_build_arena(), &events, &evt); }break; case DF_CoreCmdKind_MoveRight: { UI_Event evt = {0}; evt.kind = UI_EventKind_Navigate; evt.flags = UI_EventFlag_PickSelectSide|UI_EventFlag_ZeroDeltaOnSelect|UI_EventFlag_ExplicitDirectional; + evt.delta_unit = UI_EventDeltaUnit_Char; evt.delta_2s32 = v2s32(+1, +0); - ui_event_list_push(ui_build_arena(), &events_ui, &evt); + ui_event_list_push(ui_build_arena(), &events, &evt); }break; case DF_CoreCmdKind_MoveUp: { UI_Event evt = {0}; evt.kind = UI_EventKind_Navigate; evt.flags = UI_EventFlag_ExplicitDirectional; + evt.delta_unit = UI_EventDeltaUnit_Char; evt.delta_2s32 = v2s32(+0, -1); - ui_event_list_push(ui_build_arena(), &events_ui, &evt); + ui_event_list_push(ui_build_arena(), &events, &evt); }break; case DF_CoreCmdKind_MoveDown: { UI_Event evt = {0}; evt.kind = UI_EventKind_Navigate; evt.flags = UI_EventFlag_ExplicitDirectional; + evt.delta_unit = UI_EventDeltaUnit_Char; evt.delta_2s32 = v2s32(+0, +1); - ui_event_list_push(ui_build_arena(), &events_ui, &evt); + ui_event_list_push(ui_build_arena(), &events, &evt); }break; case DF_CoreCmdKind_MoveLeftSelect: { UI_Event evt = {0}; evt.kind = UI_EventKind_Navigate; evt.flags = UI_EventFlag_KeepMark|UI_EventFlag_ExplicitDirectional; + evt.delta_unit = UI_EventDeltaUnit_Char; evt.delta_2s32 = v2s32(-1, +0); - ui_event_list_push(ui_build_arena(), &events_ui, &evt); + ui_event_list_push(ui_build_arena(), &events, &evt); }break; case DF_CoreCmdKind_MoveRightSelect: { UI_Event evt = {0}; evt.kind = UI_EventKind_Navigate; evt.flags = UI_EventFlag_KeepMark|UI_EventFlag_ExplicitDirectional; + evt.delta_unit = UI_EventDeltaUnit_Char; evt.delta_2s32 = v2s32(+1, +0); - ui_event_list_push(ui_build_arena(), &events_ui, &evt); + ui_event_list_push(ui_build_arena(), &events, &evt); }break; case DF_CoreCmdKind_MoveUpSelect: { UI_Event evt = {0}; evt.kind = UI_EventKind_Navigate; evt.flags = UI_EventFlag_KeepMark|UI_EventFlag_ExplicitDirectional; + evt.delta_unit = UI_EventDeltaUnit_Char; evt.delta_2s32 = v2s32(+0, -1); - ui_event_list_push(ui_build_arena(), &events_ui, &evt); + ui_event_list_push(ui_build_arena(), &events, &evt); }break; case DF_CoreCmdKind_MoveDownSelect: { UI_Event evt = {0}; evt.kind = UI_EventKind_Navigate; evt.flags = UI_EventFlag_KeepMark|UI_EventFlag_ExplicitDirectional; + evt.delta_unit = UI_EventDeltaUnit_Char; evt.delta_2s32 = v2s32(+0, +1); - ui_event_list_push(ui_build_arena(), &events_ui, &evt); + ui_event_list_push(ui_build_arena(), &events, &evt); }break; case DF_CoreCmdKind_MoveLeftChunk: { @@ -2153,7 +2191,7 @@ df_window_update_and_render(Arena *arena, OS_EventList *events, DF_Window *ws, D evt.flags = UI_EventFlag_ExplicitDirectional; evt.delta_unit = UI_EventDeltaUnit_Word; evt.delta_2s32 = v2s32(-1, +0); - ui_event_list_push(ui_build_arena(), &events_ui, &evt); + ui_event_list_push(ui_build_arena(), &events, &evt); }break; case DF_CoreCmdKind_MoveRightChunk: { @@ -2162,7 +2200,7 @@ df_window_update_and_render(Arena *arena, OS_EventList *events, DF_Window *ws, D evt.flags = UI_EventFlag_ExplicitDirectional; evt.delta_unit = UI_EventDeltaUnit_Word; evt.delta_2s32 = v2s32(+1, +0); - ui_event_list_push(ui_build_arena(), &events_ui, &evt); + ui_event_list_push(ui_build_arena(), &events, &evt); }break; case DF_CoreCmdKind_MoveUpChunk: { @@ -2171,7 +2209,7 @@ df_window_update_and_render(Arena *arena, OS_EventList *events, DF_Window *ws, D evt.flags = UI_EventFlag_ExplicitDirectional; evt.delta_unit = UI_EventDeltaUnit_Word; evt.delta_2s32 = v2s32(+0, -1); - ui_event_list_push(ui_build_arena(), &events_ui, &evt); + ui_event_list_push(ui_build_arena(), &events, &evt); }break; case DF_CoreCmdKind_MoveDownChunk: { @@ -2180,7 +2218,7 @@ df_window_update_and_render(Arena *arena, OS_EventList *events, DF_Window *ws, D evt.flags = UI_EventFlag_ExplicitDirectional; evt.delta_unit = UI_EventDeltaUnit_Word; evt.delta_2s32 = v2s32(+0, +1); - ui_event_list_push(ui_build_arena(), &events_ui, &evt); + ui_event_list_push(ui_build_arena(), &events, &evt); }break; case DF_CoreCmdKind_MoveUpPage: { @@ -2188,7 +2226,7 @@ df_window_update_and_render(Arena *arena, OS_EventList *events, DF_Window *ws, D evt.kind = UI_EventKind_Navigate; evt.delta_unit = UI_EventDeltaUnit_Page; evt.delta_2s32 = v2s32(+0, -1); - ui_event_list_push(ui_build_arena(), &events_ui, &evt); + ui_event_list_push(ui_build_arena(), &events, &evt); }break; case DF_CoreCmdKind_MoveDownPage: { @@ -2196,7 +2234,7 @@ df_window_update_and_render(Arena *arena, OS_EventList *events, DF_Window *ws, D evt.kind = UI_EventKind_Navigate; evt.delta_unit = UI_EventDeltaUnit_Page; evt.delta_2s32 = v2s32(+0, +1); - ui_event_list_push(ui_build_arena(), &events_ui, &evt); + ui_event_list_push(ui_build_arena(), &events, &evt); }break; case DF_CoreCmdKind_MoveUpWhole: { @@ -2204,7 +2242,7 @@ df_window_update_and_render(Arena *arena, OS_EventList *events, DF_Window *ws, D evt.kind = UI_EventKind_Navigate; evt.delta_unit = UI_EventDeltaUnit_Whole; evt.delta_2s32 = v2s32(+0, -1); - ui_event_list_push(ui_build_arena(), &events_ui, &evt); + ui_event_list_push(ui_build_arena(), &events, &evt); }break; case DF_CoreCmdKind_MoveDownWhole: { @@ -2212,7 +2250,7 @@ df_window_update_and_render(Arena *arena, OS_EventList *events, DF_Window *ws, D evt.kind = UI_EventKind_Navigate; evt.delta_unit = UI_EventDeltaUnit_Whole; evt.delta_2s32 = v2s32(+0, +1); - ui_event_list_push(ui_build_arena(), &events_ui, &evt); + ui_event_list_push(ui_build_arena(), &events, &evt); }break; case DF_CoreCmdKind_MoveLeftChunkSelect: { @@ -2221,7 +2259,7 @@ df_window_update_and_render(Arena *arena, OS_EventList *events, DF_Window *ws, D evt.flags = UI_EventFlag_KeepMark|UI_EventFlag_ExplicitDirectional; evt.delta_unit = UI_EventDeltaUnit_Word; evt.delta_2s32 = v2s32(-1, +0); - ui_event_list_push(ui_build_arena(), &events_ui, &evt); + ui_event_list_push(ui_build_arena(), &events, &evt); }break; case DF_CoreCmdKind_MoveRightChunkSelect: { @@ -2230,7 +2268,7 @@ df_window_update_and_render(Arena *arena, OS_EventList *events, DF_Window *ws, D evt.flags = UI_EventFlag_KeepMark|UI_EventFlag_ExplicitDirectional; evt.delta_unit = UI_EventDeltaUnit_Word; evt.delta_2s32 = v2s32(+1, +0); - ui_event_list_push(ui_build_arena(), &events_ui, &evt); + ui_event_list_push(ui_build_arena(), &events, &evt); }break; case DF_CoreCmdKind_MoveUpChunkSelect: { @@ -2239,7 +2277,7 @@ df_window_update_and_render(Arena *arena, OS_EventList *events, DF_Window *ws, D evt.flags = UI_EventFlag_KeepMark|UI_EventFlag_ExplicitDirectional; evt.delta_unit = UI_EventDeltaUnit_Word; evt.delta_2s32 = v2s32(+0, -1); - ui_event_list_push(ui_build_arena(), &events_ui, &evt); + ui_event_list_push(ui_build_arena(), &events, &evt); }break; case DF_CoreCmdKind_MoveDownChunkSelect: { @@ -2248,7 +2286,7 @@ df_window_update_and_render(Arena *arena, OS_EventList *events, DF_Window *ws, D evt.flags = UI_EventFlag_KeepMark|UI_EventFlag_ExplicitDirectional; evt.delta_unit = UI_EventDeltaUnit_Word; evt.delta_2s32 = v2s32(+0, +1); - ui_event_list_push(ui_build_arena(), &events_ui, &evt); + ui_event_list_push(ui_build_arena(), &events, &evt); }break; case DF_CoreCmdKind_MoveUpPageSelect: { @@ -2257,7 +2295,7 @@ df_window_update_and_render(Arena *arena, OS_EventList *events, DF_Window *ws, D evt.flags = UI_EventFlag_KeepMark; evt.delta_unit = UI_EventDeltaUnit_Page; evt.delta_2s32 = v2s32(+0, -1); - ui_event_list_push(ui_build_arena(), &events_ui, &evt); + ui_event_list_push(ui_build_arena(), &events, &evt); }break; case DF_CoreCmdKind_MoveDownPageSelect: { @@ -2266,7 +2304,7 @@ df_window_update_and_render(Arena *arena, OS_EventList *events, DF_Window *ws, D evt.flags = UI_EventFlag_KeepMark; evt.delta_unit = UI_EventDeltaUnit_Page; evt.delta_2s32 = v2s32(+0, +1); - ui_event_list_push(ui_build_arena(), &events_ui, &evt); + ui_event_list_push(ui_build_arena(), &events, &evt); }break; case DF_CoreCmdKind_MoveUpWholeSelect: { @@ -2275,7 +2313,7 @@ df_window_update_and_render(Arena *arena, OS_EventList *events, DF_Window *ws, D evt.flags = UI_EventFlag_KeepMark; evt.delta_unit = UI_EventDeltaUnit_Whole; evt.delta_2s32 = v2s32(+0, -1); - ui_event_list_push(ui_build_arena(), &events_ui, &evt); + ui_event_list_push(ui_build_arena(), &events, &evt); }break; case DF_CoreCmdKind_MoveDownWholeSelect: { @@ -2284,7 +2322,7 @@ df_window_update_and_render(Arena *arena, OS_EventList *events, DF_Window *ws, D evt.flags = UI_EventFlag_KeepMark; evt.delta_unit = UI_EventDeltaUnit_Whole; evt.delta_2s32 = v2s32(+0, +1); - ui_event_list_push(ui_build_arena(), &events_ui, &evt); + ui_event_list_push(ui_build_arena(), &events, &evt); }break; case DF_CoreCmdKind_MoveHome: { @@ -2292,7 +2330,7 @@ df_window_update_and_render(Arena *arena, OS_EventList *events, DF_Window *ws, D evt.kind = UI_EventKind_Navigate; evt.delta_unit = UI_EventDeltaUnit_Line; evt.delta_2s32 = v2s32(-1, +0); - ui_event_list_push(ui_build_arena(), &events_ui, &evt); + ui_event_list_push(ui_build_arena(), &events, &evt); }break; case DF_CoreCmdKind_MoveEnd: { @@ -2300,7 +2338,7 @@ df_window_update_and_render(Arena *arena, OS_EventList *events, DF_Window *ws, D evt.kind = UI_EventKind_Navigate; evt.delta_unit = UI_EventDeltaUnit_Line; evt.delta_2s32 = v2s32(+1, +0); - ui_event_list_push(ui_build_arena(), &events_ui, &evt); + ui_event_list_push(ui_build_arena(), &events, &evt); }break; case DF_CoreCmdKind_MoveHomeSelect: { @@ -2309,7 +2347,7 @@ df_window_update_and_render(Arena *arena, OS_EventList *events, DF_Window *ws, D evt.flags = UI_EventFlag_KeepMark; evt.delta_unit = UI_EventDeltaUnit_Line; evt.delta_2s32 = v2s32(-1, +0); - ui_event_list_push(ui_build_arena(), &events_ui, &evt); + ui_event_list_push(ui_build_arena(), &events, &evt); }break; case DF_CoreCmdKind_MoveEndSelect: { @@ -2318,7 +2356,7 @@ df_window_update_and_render(Arena *arena, OS_EventList *events, DF_Window *ws, D evt.flags = UI_EventFlag_KeepMark; evt.delta_unit = UI_EventDeltaUnit_Line; evt.delta_2s32 = v2s32(+1, +0); - ui_event_list_push(ui_build_arena(), &events_ui, &evt); + ui_event_list_push(ui_build_arena(), &events, &evt); }break; case DF_CoreCmdKind_SelectAll: { @@ -2326,75 +2364,77 @@ df_window_update_and_render(Arena *arena, OS_EventList *events, DF_Window *ws, D evt1.kind = UI_EventKind_Navigate; evt1.delta_unit = UI_EventDeltaUnit_Whole; evt1.delta_2s32 = v2s32(-1, +0); - ui_event_list_push(ui_build_arena(), &events_ui, &evt1); + ui_event_list_push(ui_build_arena(), &events, &evt1); UI_Event evt2 = {0}; evt2.kind = UI_EventKind_Navigate; evt2.flags = UI_EventFlag_KeepMark; evt2.delta_unit = UI_EventDeltaUnit_Whole; evt2.delta_2s32 = v2s32(+1, +0); - ui_event_list_push(ui_build_arena(), &events_ui, &evt2); + ui_event_list_push(ui_build_arena(), &events, &evt2); }break; case DF_CoreCmdKind_DeleteSingle: { UI_Event evt = {0}; evt.kind = UI_EventKind_Edit; evt.flags = UI_EventFlag_Delete; + evt.delta_unit = UI_EventDeltaUnit_Char; evt.delta_2s32 = v2s32(+1, +0); - ui_event_list_push(ui_build_arena(), &events_ui, &evt); + ui_event_list_push(ui_build_arena(), &events, &evt); }break; case DF_CoreCmdKind_DeleteChunk: { UI_Event evt = {0}; evt.kind = UI_EventKind_Edit; evt.flags = UI_EventFlag_Delete; - evt.delta_2s32 = v2s32(+1, +0); evt.delta_unit = UI_EventDeltaUnit_Word; - ui_event_list_push(ui_build_arena(), &events_ui, &evt); + evt.delta_2s32 = v2s32(+1, +0); + ui_event_list_push(ui_build_arena(), &events, &evt); }break; case DF_CoreCmdKind_BackspaceSingle: { UI_Event evt = {0}; evt.kind = UI_EventKind_Edit; evt.flags = UI_EventFlag_Delete|UI_EventFlag_ZeroDeltaOnSelect; + evt.delta_unit = UI_EventDeltaUnit_Char; evt.delta_2s32 = v2s32(-1, +0); - ui_event_list_push(ui_build_arena(), &events_ui, &evt); + ui_event_list_push(ui_build_arena(), &events, &evt); }break; case DF_CoreCmdKind_BackspaceChunk: { UI_Event evt = {0}; evt.kind = UI_EventKind_Edit; evt.flags = UI_EventFlag_Delete; - evt.delta_2s32 = v2s32(-1, +0); evt.delta_unit = UI_EventDeltaUnit_Word; - ui_event_list_push(ui_build_arena(), &events_ui, &evt); + evt.delta_2s32 = v2s32(-1, +0); + ui_event_list_push(ui_build_arena(), &events, &evt); }break; case DF_CoreCmdKind_Copy: { UI_Event evt = {0}; evt.kind = UI_EventKind_Edit; evt.flags = UI_EventFlag_Copy|UI_EventFlag_KeepMark; - ui_event_list_push(ui_build_arena(), &events_ui, &evt); + ui_event_list_push(ui_build_arena(), &events, &evt); }break; case DF_CoreCmdKind_Cut: { UI_Event evt = {0}; evt.kind = UI_EventKind_Edit; evt.flags = UI_EventFlag_Copy|UI_EventFlag_Delete; - ui_event_list_push(ui_build_arena(), &events_ui, &evt); + ui_event_list_push(ui_build_arena(), &events, &evt); }break; case DF_CoreCmdKind_Paste: { UI_Event evt = {0}; evt.kind = UI_EventKind_Text; evt.string = os_get_clipboard_text(ui_build_arena()); - ui_event_list_push(ui_build_arena(), &events_ui, &evt); + ui_event_list_push(ui_build_arena(), &events, &evt); }break; case DF_CoreCmdKind_InsertText: { UI_Event evt = {0}; evt.kind = UI_EventKind_Text; evt.string = params.string; - ui_event_list_push(ui_build_arena(), &events_ui, &evt); + ui_event_list_push(ui_build_arena(), &events, &evt); }break; //- rjf: address finding @@ -3199,7 +3239,7 @@ df_window_update_and_render(Arena *arena, OS_EventList *events, DF_Window *ws, D } // rjf: begin & push initial stack values - ui_begin_build(ws->os, &events_ui, &icon_info, df_dt(), df_dt()); + ui_begin_build(ws->os, &events, &icon_info, df_dt(), df_dt()); ui_push_font(main_font); ui_push_font_size(main_font_size); ui_push_pref_width(ui_em(20.f, 1)); @@ -4134,14 +4174,14 @@ df_window_update_and_render(Arena *arena, OS_EventList *events, DF_Window *ws, D UI_BackgroundColor(df_rgba_from_theme_color(DF_ThemeColor_ActionBackground)) UI_TextColor(df_rgba_from_theme_color(DF_ThemeColor_ActionText)) UI_BorderColor(df_rgba_from_theme_color(DF_ThemeColor_ActionBorder)) - if(ui_clicked(ui_buttonf("OK")) || (ui_key_match(bg_box->default_nav_focus_hot_key, ui_key_zero()) && ui_key_press(ui_events(), 0, OS_Key_Return))) + if(ui_clicked(ui_buttonf("OK")) || (ui_key_match(bg_box->default_nav_focus_hot_key, ui_key_zero()) && ui_key_press(0, OS_Key_Return))) { DF_CmdParams p = df_cmd_params_zero(); df_push_cmd__root(&p, df_cmd_spec_from_core_cmd_kind(DF_CoreCmdKind_ConfirmAccept)); } UI_CornerRadius10(ui_top_font_size()*0.25f) UI_CornerRadius11(ui_top_font_size()*0.25f) - if(ui_clicked(ui_buttonf("Cancel")) || ui_key_press(ui_events(), 0, OS_Key_Esc)) + if(ui_clicked(ui_buttonf("Cancel")) || ui_key_press(0, OS_Key_Esc)) { DF_CmdParams p = df_cmd_params_zero(); df_push_cmd__root(&p, df_cmd_spec_from_core_cmd_kind(DF_CoreCmdKind_ConfirmCancel)); @@ -4701,7 +4741,7 @@ df_window_update_and_render(Arena *arena, OS_EventList *events, DF_Window *ws, D { ui_set_next_fastpath_codepoint(items[idx].codepoint); B32 alt_fastpath_key = 0; - if(ui_key_press(ui_events(), OS_EventFlag_Alt, items[idx].key)) + if(ui_key_press(OS_EventFlag_Alt, items[idx].key)) { alt_fastpath_key = 1; } @@ -5436,14 +5476,14 @@ df_window_update_and_render(Arena *arena, OS_EventList *events, DF_Window *ws, D //- rjf: query submission if((ui_is_focus_active() || (window_is_focused && !ui_any_ctx_menu_is_open() && !ws->menu_bar_focused && !ws->query_view_selected)) && - os_key_press(events, ws->os, 0, OS_Key_Esc)) + ui_key_press(0, OS_Key_Esc)) { DF_CmdParams params = df_cmd_params_from_window(ws); df_push_cmd__root(¶ms, df_cmd_spec_from_core_cmd_kind(DF_CoreCmdKind_CancelQuery)); } if(ui_is_focus_active()) { - if(os_key_press(events, ws->os, 0, OS_Key_Return)) + if(ui_key_press(0, OS_Key_Return)) { Temp scratch = scratch_begin(&arena, 1); DF_View *view = ws->query_view_stack_top; @@ -6364,7 +6404,7 @@ df_window_update_and_render(Arena *arena, OS_EventList *events, DF_Window *ws, D DF_View *view = df_view_from_handle(panel->selected_tab_view); UI_Focus(UI_FocusKind_On) { - if(view->is_filtering && ui_is_focus_active() && ui_key_press(ui_events(), 0, OS_Key_Return)) + if(view->is_filtering && ui_is_focus_active() && ui_key_press(0, OS_Key_Return)) { DF_CmdParams p = df_cmd_params_from_view(ws, panel, view); df_push_cmd__root(&p, df_cmd_spec_from_core_cmd_kind(DF_CoreCmdKind_ApplyFilter)); @@ -6602,7 +6642,7 @@ df_window_update_and_render(Arena *arena, OS_EventList *events, DF_Window *ws, D } } } - if((view->query_string_size != 0 || view->is_filtering) && ui_is_focus_active() && ui_key_press(ui_events(), 0, OS_Key_Esc)) + if((view->query_string_size != 0 || view->is_filtering) && ui_is_focus_active() && ui_key_press(0, OS_Key_Esc)) { DF_CmdParams p = df_cmd_params_from_view(ws, panel, view); df_push_cmd__root(&p, df_cmd_spec_from_core_cmd_kind(DF_CoreCmdKind_ClearFilter)); @@ -7173,7 +7213,7 @@ df_window_update_and_render(Arena *arena, OS_EventList *events, DF_Window *ws, D //////////////////////////// //- rjf: drag/drop cancelling // - if(df_drag_is_active() && ui_key_press(&events_ui, 0, OS_Key_Esc)) + if(df_drag_is_active() && ui_key_press(0, OS_Key_Esc)) { df_drag_kill(); ui_kill_action(); @@ -7182,13 +7222,13 @@ df_window_update_and_render(Arena *arena, OS_EventList *events, DF_Window *ws, D //////////////////////////// //- rjf: font size changing // - for(UI_EventNode *n = events_ui.first, *next = 0; n != 0; n = next) + for(UI_EventNode *n = events.first, *next = 0; n != 0; n = next) { next = n->next; UI_Event *event = &n->v; - if(event->kind == OS_EventKind_Scroll && event->flags & OS_EventFlag_Ctrl) + if(event->kind == UI_EventKind_Scroll && event->modifiers & OS_EventFlag_Ctrl) { - ui_eat_event(&events_ui, n); + ui_eat_event(&events, n); if(event->delta_2f32.y < 0) { DF_CmdParams params = df_cmd_params_from_window(ws); @@ -7256,7 +7296,7 @@ df_window_update_and_render(Arena *arena, OS_EventList *events, DF_Window *ws, D ////////////////////////////// //- rjf: hover eval cancelling // - if(ws->hover_eval_string.size != 0 && os_key_press(events, ws->os, 0, OS_Key_Esc)) + if(ws->hover_eval_string.size != 0 && ui_key_press(0, OS_Key_Esc)) { MemoryZeroStruct(&ws->hover_eval_string); arena_clear(ws->hover_eval_arena); @@ -10807,7 +10847,7 @@ df_code_slice(DF_Window *ws, DF_CtrlCtx *ctrl_ctx, EVAL_ParseCtx *parse_ctx, DF_ { next = n->next; UI_Event *event = &n->v; - if(event->kind == OS_EventKind_Scroll && event->flags & OS_EventFlag_Ctrl) + if(event->kind == UI_EventKind_Scroll && event->modifiers & OS_EventFlag_Ctrl) { ui_eat_event(events, n); if(event->delta_2f32.y < 0) @@ -11411,8 +11451,11 @@ df_do_txt_controls(TXT_TextInfo *info, String8 data, U64 line_count_per_page, Tx for(UI_EventNode *n = events->first, *next = 0; n != 0; n = next) { next = n->next; + if(n->v.kind != UI_EventKind_Navigate && n->v.kind != UI_EventKind_Edit) + { + continue; + } B32 taken = 0; - String8 line = txt_string_from_info_data_line_num(info, data, cursor->line); UI_TxtOp single_line_op = ui_single_line_txt_op_from_event(scratch.arena, &n->v, line, *cursor, *mark); @@ -11445,7 +11488,7 @@ df_do_txt_controls(TXT_TextInfo *info, String8 data, U64 line_count_per_page, Tx } //- rjf: movement down (plain) - if(n->v.delta_unit == UI_EventDeltaUnit_Whole && delta.y > 0 && cursor->line+1 <= line_count) + if(n->v.delta_unit == UI_EventDeltaUnit_Char && delta.y > 0 && cursor->line+1 <= line_count) { cursor->line += 1; cursor->column = Min(*preferred_column, next_line.size+1); @@ -12088,7 +12131,7 @@ df_line_edit(DF_LineEditFlags flags, S32 depth, FuzzyMatchRangeList *matches, Tx } } } - if(is_focus_hot && ui_key_press(ui_events(), 0, OS_Key_F2)) + if(is_focus_hot && ui_key_press(0, OS_Key_F2)) { start_editing_via_typing = 1; } @@ -12123,7 +12166,7 @@ df_line_edit(DF_LineEditFlags flags, S32 depth, FuzzyMatchRangeList *matches, Tx next = n->next; // rjf: do not consume anything that doesn't fit a single-line's operations - if(n->v.delta_2s32.y != 0) + if((n->v.kind != UI_EventKind_Edit && n->v.kind != UI_EventKind_Navigate && n->v.kind != UI_EventKind_Text) || n->v.delta_2s32.y != 0) { continue; } diff --git a/src/df/gfx/df_gfx.h b/src/df/gfx/df_gfx.h index 425ea56b..2859b9ac 100644 --- a/src/df/gfx/df_gfx.h +++ b/src/df/gfx/df_gfx.h @@ -899,7 +899,7 @@ internal DF_Window *df_window_open(Vec2F32 size, OS_Handle preferred_monitor, DF internal DF_Window *df_window_from_os_handle(OS_Handle os); -internal void df_window_update_and_render(Arena *arena, OS_EventList *events, DF_Window *ws, DF_CmdList *cmds); +internal void df_window_update_and_render(Arena *arena, DF_Window *ws, DF_CmdList *cmds); //////////////////////////////// //~ rjf: Eval Viz diff --git a/src/df/gfx/df_views.c b/src/df/gfx/df_views.c index 611c1f2f..9c10ba6f 100644 --- a/src/df/gfx/df_views.c +++ b/src/df/gfx/df_views.c @@ -859,23 +859,23 @@ df_eval_watch_view_build(DF_Window *ws, DF_Panel *panel, DF_View *view, DF_EvalW break; } } - if(ui_key_press(ui_events(), 0, OS_Key_F2)) + if(ui_key_press(0, OS_Key_F2)) { edit_begin = 1; } - if(ui_key_press(ui_events(), 0, OS_Key_Return)) + if(ui_key_press(0, OS_Key_Return)) { edit_begin_or_expand = 1; } } if(ewv->input_editing && ui_is_focus_active()) { - if(ui_key_press(ui_events(), 0, OS_Key_Esc)) + if(ui_key_press(0, OS_Key_Esc)) { edit_end = 1; edit_commit = 0; } - if(ui_key_press(ui_events(), 0, OS_Key_Return)) + if(ui_key_press(0, OS_Key_Return)) { edit_end = 1; edit_commit = 1; @@ -1857,7 +1857,7 @@ DF_VIEW_UI_FUNCTION_DEF(Commands) df_cmd_lister_item_array_sort_by_strength__in_place(cmd_array); //- rjf: submit best match when hitting enter w/ no selection - if(cv->selected_cmd_spec == &df_g_nil_cmd_spec && ui_key_press(ui_events(), 0, OS_Key_Return)) + if(cv->selected_cmd_spec == &df_g_nil_cmd_spec && ui_key_press(0, OS_Key_Return)) { DF_CmdParams params = df_cmd_params_from_view(ws, panel, view); if(cmd_array.count > 0) @@ -2196,7 +2196,7 @@ DF_VIEW_UI_FUNCTION_DEF(FileSystem) } //- rjf: submit best match when hitting enter w/ no selection - if(ps->cursor.y == 0 && ui_key_press(ui_events(), 0, OS_Key_Return)) + if(ps->cursor.y == 0 && ui_key_press(0, OS_Key_Return)) { FileProperties query_normalized_with_opt_slash_props = os_properties_from_file_path(query_normalized_with_opt_slash); FileProperties path_query_path_props = os_properties_from_file_path(path_query.path); @@ -2535,7 +2535,7 @@ DF_VIEW_UI_FUNCTION_DEF(SystemProcesses) } //- rjf: submit best match when hitting enter w/ no selection - if(sp->selected_pid == 0 && process_info_array.count > 0 && ui_key_press(ui_events(), 0, OS_Key_Return)) + if(sp->selected_pid == 0 && process_info_array.count > 0 && ui_key_press(0, OS_Key_Return)) { DF_ProcessInfo *info = &process_info_array.v[0]; DF_CmdParams params = df_cmd_params_from_view(ws, panel, view); @@ -2692,7 +2692,7 @@ DF_VIEW_UI_FUNCTION_DEF(EntityLister) df_entity_lister_item_array_sort_by_strength__in_place(ent_arr); //- rjf: submit best match when hitting enter w/ no selection - if(df_entity_is_nil(df_entity_from_handle(fev->selected_entity_handle)) && ent_arr.count != 0 && ui_key_press(ui_events(), 0, OS_Key_Return)) + if(df_entity_is_nil(df_entity_from_handle(fev->selected_entity_handle)) && ent_arr.count != 0 && ui_key_press(0, OS_Key_Return)) { DF_Entity *ent = ent_arr.v[0].entity; DF_CmdParams params = df_cmd_params_from_view(ws, panel, view); @@ -2845,7 +2845,7 @@ DF_VIEW_UI_FUNCTION_DEF(SymbolLister) } //- rjf: submit best match when hitting enter w/ no selection - if(slv->cursor.y == 0 && items.count != 0 && ui_key_press(ui_events(), 0, OS_Key_Return)) + if(slv->cursor.y == 0 && items.count != 0 && ui_key_press(0, OS_Key_Return)) { RDI_Procedure *procedure = rdi_element_from_idx(rdi, procedures, items.v[0].idx); U64 name_size = 0; @@ -3054,23 +3054,23 @@ DF_VIEW_UI_FUNCTION_DEF(Target) break; } } - if(ui_key_press(ui_events(), 0, OS_Key_F2)) + if(ui_key_press(0, OS_Key_F2)) { edit_begin = 1; } - if(ui_key_press(ui_events(), 0, OS_Key_Return)) + if(ui_key_press(0, OS_Key_Return)) { edit_begin = 1; } } if(tv->input_editing) { - if(ui_key_press(ui_events(), 0, OS_Key_Esc)) + if(ui_key_press(0, OS_Key_Esc)) { edit_end = 1; edit_commit = 0; } - if(ui_key_press(ui_events(), 0, OS_Key_Return)) + if(ui_key_press(0, OS_Key_Return)) { edit_end = 1; edit_commit = 1; @@ -3529,19 +3529,19 @@ DF_VIEW_UI_FUNCTION_DEF(FilePathMap) break; } } - if(ui_key_press(ui_events(), 0, OS_Key_F2)) + if(ui_key_press(0, OS_Key_F2)) { edit_begin = 1; } } if(fpms->input_editing) { - if(ui_key_press(ui_events(), 0, OS_Key_Esc)) + if(ui_key_press(0, OS_Key_Esc)) { edit_end = 1; edit_commit = 0; } - if(ui_key_press(ui_events(), 0, OS_Key_Return)) + if(ui_key_press(0, OS_Key_Return)) { edit_end = 1; edit_commit = 1; @@ -3847,19 +3847,19 @@ DF_VIEW_UI_FUNCTION_DEF(AutoViewRules) break; } } - if(ui_key_press(ui_events(), 0, OS_Key_F2)) + if(ui_key_press(0, OS_Key_F2)) { edit_begin = 1; } } if(avrs->input_editing) { - if(ui_key_press(ui_events(), 0, OS_Key_Esc)) + if(ui_key_press(0, OS_Key_Esc)) { edit_end = 1; edit_commit = 0; } - if(ui_key_press(ui_events(), 0, OS_Key_Return)) + if(ui_key_press(0, OS_Key_Return)) { edit_end = 1; edit_commit = 1; @@ -4663,20 +4663,20 @@ DF_VIEW_UI_FUNCTION_DEF(Modules) break; } } - if(ui_key_press(ui_events(), 0, OS_Key_F2) || - ui_key_press(ui_events(), 0, OS_Key_Return)) + if(ui_key_press(0, OS_Key_F2) || + ui_key_press(0, OS_Key_Return)) { edit_begin = 1; } } if(mv->txt_editing && ui_is_focus_active()) { - if(ui_key_press(ui_events(), 0, OS_Key_Esc)) + if(ui_key_press(0, OS_Key_Esc)) { edit_end = 1; edit_commit = 0; } - if(ui_key_press(ui_events(), 0, OS_Key_Return)) + if(ui_key_press(0, OS_Key_Return)) { edit_end = 1; edit_commit = 1; diff --git a/src/raddbg/raddbg.c b/src/raddbg/raddbg.c index 218b7fa8..465fa1b0 100644 --- a/src/raddbg/raddbg.c +++ b/src/raddbg/raddbg.c @@ -11,7 +11,9 @@ update_and_render(OS_Handle repaint_window_handle, void *user_data) ProfBeginFunction(); Temp scratch = scratch_begin(0, 0); + ////////////////////////////// //- rjf: begin logging + // if(main_thread_log == 0) { main_thread_log = log_alloc(); @@ -24,13 +26,17 @@ update_and_render(OS_Handle repaint_window_handle, void *user_data) log_select(main_thread_log); log_scope_begin(); + ////////////////////////////// //- rjf: tick cache layers + // txt_user_clock_tick(); dasm_user_clock_tick(); geo_user_clock_tick(); tex_user_clock_tick(); + ////////////////////////////// //- rjf: pick target hz + // // TODO(rjf): maximize target, given all windows and their monitors F32 target_hz = os_default_refresh_rate(); if(frame_time_us_history_idx > 32) @@ -66,29 +72,41 @@ update_and_render(OS_Handle repaint_window_handle, void *user_data) target_hz = best_target_hz; } + ////////////////////////////// //- rjf: target Hz -> delta time + // F32 dt = 1.f/target_hz; + ////////////////////////////// //- rjf: last frame before sleep -> disable txti change detection + // if(df_gfx_state->num_frames_requested == 0) { txti_set_external_change_detection_enabled(0); } + ////////////////////////////// //- rjf: get events from the OS + // OS_EventList events = {0}; if(os_handle_match(repaint_window_handle, os_handle_zero())) { events = os_get_events(scratch.arena, df_gfx_state->num_frames_requested == 0); } + ////////////////////////////// //- rjf: enable txti change detection + // txti_set_external_change_detection_enabled(1); + ////////////////////////////// //- rjf: begin measuring actual per-frame work + // U64 begin_time_us = os_now_microseconds(); + ////////////////////////////// //- rjf: bind change + // if(!df_gfx_state->confirm_active && df_gfx_state->bind_change_active) { if(os_key_press(&events, os_handle_zero(), 0, OS_Key_Esc)) @@ -136,7 +154,10 @@ update_and_render(OS_Handle repaint_window_handle, void *user_data) } } - //- rjf: take hotkeys + ////////////////////////////// + //- rjf: consume events + // + B32 queue_drag_drop = 0; { for(OS_Event *event = events.first, *next = 0; event != 0; @@ -145,7 +166,63 @@ update_and_render(OS_Handle repaint_window_handle, void *user_data) next = event->next; DF_Window *window = df_window_from_os_handle(event->window); DF_CmdParams params = window ? df_cmd_params_from_window(window) : df_cmd_params_from_gfx(); - if(event->kind == OS_EventKind_Press) + B32 take = 0; + B32 skip = 0; + + //- rjf: try drag-drop + if(df_drag_is_active() && event->kind == OS_EventKind_Release && event->key == OS_Key_LeftMouseButton) + { + skip = 1; + queue_drag_drop = 1; + } + + //- rjf: try window close + if(!take && event->kind == OS_EventKind_WindowClose && window != 0) + { + take = 1; + DF_CmdParams params = df_cmd_params_from_window(window); + df_push_cmd__root(¶ms, df_cmd_spec_from_core_cmd_kind(DF_CoreCmdKind_CloseWindow)); + } + + //- rjf: try menu bar operations + { + if(!take && event->kind == OS_EventKind_Press && event->key == OS_Key_Alt && event->flags == 0 && event->is_repeat == 0) + { + take = 1; + df_gfx_request_frame(); + window->menu_bar_focused_on_press = window->menu_bar_focused; + window->menu_bar_key_held = 1; + window->menu_bar_focus_press_started = 1; + } + if(!take && event->kind == OS_EventKind_Release && event->key == OS_Key_Alt && event->flags == 0 && event->is_repeat == 0) + { + take = 1; + df_gfx_request_frame(); + window->menu_bar_key_held = 0; + } + if(window->menu_bar_focused && event->kind == OS_EventKind_Press && event->key == OS_Key_Alt && event->flags == 0 && event->is_repeat == 0) + { + take = 1; + df_gfx_request_frame(); + window->menu_bar_focused = 0; + } + else if(window->menu_bar_focus_press_started && !window->menu_bar_focused && event->kind == OS_EventKind_Release && event->flags == 0 && event->key == OS_Key_Alt && event->is_repeat == 0) + { + take = 1; + df_gfx_request_frame(); + window->menu_bar_focused = !window->menu_bar_focused_on_press; + window->menu_bar_focus_press_started = 0; + } + else if(event->kind == OS_EventKind_Press && event->key == OS_Key_Esc && window->menu_bar_focused && !ui_any_ctx_menu_is_open()) + { + take = 1; + df_gfx_request_frame(); + window->menu_bar_focused = 0; + } + } + + //- rjf: try hotkey presses + if(!take && event->kind == OS_EventKind_Press) { DF_Binding binding = {event->key, event->flags}; DF_CmdSpecList spec_candidates = df_cmd_spec_list_from_binding(scratch.arena, binding); @@ -159,7 +236,7 @@ update_and_render(OS_Handle repaint_window_handle, void *user_data) df_cmd_params_mark_slot(¶ms, DF_CmdParamSlot_CmdSpec); } U32 hit_char = os_codepoint_from_event_flags_and_key(event->flags, event->key); - os_eat_event(&events, event); + take = 1; df_push_cmd__root(¶ms, run_spec); if(event->flags & OS_EventFlag_Alt) { @@ -172,7 +249,9 @@ update_and_render(OS_Handle repaint_window_handle, void *user_data) } df_gfx_request_frame(); } - else if(event->kind == OS_EventKind_Text) + + //- rjf: try text events + if(!take && event->kind == OS_EventKind_Text) { String32 insertion32 = str32(&event->character, 1); String8 insertion8 = str8_from_32(scratch.arena, insertion32); @@ -181,87 +260,51 @@ update_and_render(OS_Handle repaint_window_handle, void *user_data) df_cmd_params_mark_slot(¶ms, DF_CmdParamSlot_String); df_push_cmd__root(¶ms, spec); df_gfx_request_frame(); - os_eat_event(&events, event); + take = 1; if(event->flags & OS_EventFlag_Alt) { window->menu_bar_focus_press_started = 0; } } - } - } - - //- rjf: menu bar focus - { - for(OS_Event *event = events.first, *next = 0; event != 0; event = next) - { - next = event->next; - DF_Window *ws = df_window_from_os_handle(event->window); - if(ws == 0) - { - continue; - } - B32 take = 0; - if(event->kind == OS_EventKind_Press && event->key == OS_Key_Alt && event->flags == 0 && event->is_repeat == 0) + + //- rjf: do fall-through + if(!take) { take = 1; - df_gfx_request_frame(); - ws->menu_bar_focused_on_press = ws->menu_bar_focused; - ws->menu_bar_key_held = 1; - ws->menu_bar_focus_press_started = 1; + params.os_event = event; + df_push_cmd__root(¶ms, df_cmd_spec_from_core_cmd_kind(DF_CoreCmdKind_OSEvent)); } - if(event->kind == OS_EventKind_Release && event->key == OS_Key_Alt && event->flags == 0 && event->is_repeat == 0) - { - take = 1; - df_gfx_request_frame(); - ws->menu_bar_key_held = 0; - } - if(ws->menu_bar_focused && event->kind == OS_EventKind_Press && event->key == OS_Key_Alt && event->flags == 0 && event->is_repeat == 0) - { - take = 1; - df_gfx_request_frame(); - ws->menu_bar_focused = 0; - } - else if(ws->menu_bar_focus_press_started && !ws->menu_bar_focused && event->kind == OS_EventKind_Release && event->flags == 0 && event->key == OS_Key_Alt && event->is_repeat == 0) - { - take = 1; - df_gfx_request_frame(); - ws->menu_bar_focused = !ws->menu_bar_focused_on_press; - ws->menu_bar_focus_press_started = 0; - } - else if(event->kind == OS_EventKind_Press && event->key == OS_Key_Esc && ws->menu_bar_focused && !ui_any_ctx_menu_is_open()) - { - take = 1; - df_gfx_request_frame(); - ws->menu_bar_focused = 0; - } - if(take) + + //- rjf: take + if(take && !skip) { os_eat_event(&events, event); } } } + ////////////////////////////// //- rjf: gather root-level commands + // DF_CmdList cmds = df_core_gather_root_cmds(scratch.arena); + ////////////////////////////// //- rjf: begin frame + // df_core_begin_frame(scratch.arena, &cmds, dt); df_gfx_begin_frame(scratch.arena, &cmds); + ////////////////////////////// //- rjf: queue drop for drag/drop - if(df_drag_is_active()) + // + if(queue_drag_drop) { - for(OS_Event *event = events.first; event != 0; event = event->next) - { - if(event->kind == OS_EventKind_Release && event->key == OS_Key_LeftMouseButton) - { - df_queue_drag_drop(); - break; - } - } + df_queue_drag_drop(); } + ////////////////////////////// //- rjf: auto-focus moused-over windows while dragging + // if(df_drag_is_active()) { B32 over_focused_window = 0; @@ -292,20 +335,26 @@ update_and_render(OS_Handle repaint_window_handle, void *user_data) } } + ////////////////////////////// //- rjf: update & render + // { d_begin_frame(); for(DF_Window *w = df_gfx_state->first_window; w != 0; w = w->next) { - df_window_update_and_render(scratch.arena, &events, w, &cmds); + df_window_update_and_render(scratch.arena, w, &cmds); } } + ////////////////////////////// //- rjf: end frontend frame, send signals, etc. + // df_gfx_end_frame(); df_core_end_frame(); + ////////////////////////////// //- rjf: submit rendering to all windows + // { r_begin_frame(); for(DF_Window *w = df_gfx_state->first_window; w != 0; w = w->next) @@ -317,32 +366,17 @@ update_and_render(OS_Handle repaint_window_handle, void *user_data) r_end_frame(); } - //- rjf: take window closing events - for(OS_Event *e = events.first, *next = 0; e; e = next) - { - next = e->next; - if(e->kind == OS_EventKind_WindowClose) - { - for(DF_Window *w = df_gfx_state->first_window; w != 0; w = w->next) - { - if(os_handle_match(w->os, e->window)) - { - DF_CmdParams params = df_cmd_params_from_window(w); - df_push_cmd__root(¶ms, df_cmd_spec_from_core_cmd_kind(DF_CoreCmdKind_CloseWindow)); - break; - } - } - os_eat_event(&events, e); - } - } - + ////////////////////////////// //- rjf: determine frame time, record into history + // U64 end_time_us = os_now_microseconds(); U64 frame_time_us = end_time_us-begin_time_us; frame_time_us_history[frame_time_us_history_idx%ArrayCount(frame_time_us_history)] = frame_time_us; frame_time_us_history_idx += 1; + ////////////////////////////// //- rjf: end logging + // { String8 log = log_scope_end(scratch.arena); os_append_data_to_file_path(main_thread_log_path, log); diff --git a/src/ui/ui_basic_widgets.c b/src/ui/ui_basic_widgets.c index 3aced18d..2b7dfa72 100644 --- a/src/ui/ui_basic_widgets.c +++ b/src/ui/ui_basic_widgets.c @@ -200,7 +200,7 @@ ui_line_edit(TxtPt *cursor, TxtPt *mark, U8 *edit_buffer, U64 edit_buffer_size, next = n->next; // rjf: do not consume anything that doesn't fit a single-line's operations - if(n->v.delta_2s32.y != 0) + if((n->v.kind != UI_EventKind_Edit && n->v.kind != UI_EventKind_Navigate && n->v.kind != UI_EventKind_Text) || n->v.delta_2s32.y != 0) { continue; } diff --git a/src/ui/ui_core.c b/src/ui/ui_core.c index 14b4c54f..9892f329 100644 --- a/src/ui/ui_core.c +++ b/src/ui/ui_core.c @@ -95,7 +95,7 @@ ui_key_match(UI_Key a, UI_Key b) } //////////////////////////////// -//~ rjf: Event Functions +//~ rjf: Event Type Functions internal UI_EventNode * ui_event_list_push(Arena *arena, UI_EventList *list, UI_Event *v) @@ -115,57 +115,6 @@ ui_eat_event(UI_EventList *list, UI_EventNode *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: Text Operation Functions @@ -397,255 +346,6 @@ ui_push_string_replace_range(Arena *arena, String8 string, Rng1S64 col_range, St return result; } -//////////////////////////////// -//~ rjf: Navigation Action List Building & Consumption Functions - -#if 0 -internal void -ui_nav_action_list_push(Arena *arena, UI_NavActionList *list, UI_NavAction action) -{ - UI_NavActionNode *node = push_array(arena, UI_NavActionNode, 1); - DLLPushBack(list->first, list->last, node); - MemoryCopyStruct(&node->v, &action); - list->count += 1; -} - -internal void -ui_nav_eat_action_node(UI_NavActionList *list, UI_NavActionNode *node) -{ - DLLRemove(list->first, list->last, node); - list->count -= 1; -} - -//////////////////////////////// -//~ rjf: High Level Navigation Action => Text Operations - -internal B32 -ui_nav_char_is_scan_boundary(U8 c) -{ - return (char_is_alpha(c) || char_is_digit(c, 10) || c == '_'); -} - -internal S64 -ui_nav_scanned_column_from_column(String8 string, S64 start_column, Side side) -{ - S64 new_column = start_column; - S64 delta = (!!side)*2 - 1; - B32 found_text = 0; - B32 found_non_space = 0; - S64 start_off = delta < 0 ? delta : 0; - for(S64 col = start_column+start_off; 1 <= col && col <= string.size+1; col += delta) - { - U8 byte = (col <= string.size) ? string.str[col-1] : 0; - B32 is_non_space = !char_is_space(byte); - B32 is_name = ui_nav_char_is_scan_boundary(byte); - - if (((side == Side_Min) && (col == 1)) || - ((side == Side_Max) && (col == string.size+1)) || - (found_non_space && !is_non_space) || - (found_text && !is_name)) - { - new_column = col + (!side && col != 1); - break; - } else if (!found_text && is_name) { - found_text = 1; - } else if (!found_non_space && is_non_space ) { - found_non_space = 1; - } - } - return new_column; -} - -internal UI_NavTxtOp -ui_nav_single_line_txt_op_from_action(Arena *arena, UI_NavAction action, String8 line, TxtPt cursor, TxtPt mark) -{ - TxtPt next_cursor = cursor; - TxtPt next_mark = mark; - TxtRng range = {0}; - String8 replace = {0}; - String8 copy = {0}; - UI_NavTxtOpFlags flags = 0; - Vec2S32 delta = action.delta; - Vec2S32 original_delta = delta; - - //- rjf: resolve high-level delta into byte delta, based on unit - switch(action.delta_unit) - { - default:{}break; - case UI_NavDeltaUnit_Element: - { - // TODO(rjf): this should account for multi-byte characters in UTF-8... for now, just assume ASCII and - // no-op - }break; - case UI_NavDeltaUnit_Chunk: - { - delta.x = (S32)ui_nav_scanned_column_from_column(line, cursor.column, delta.x > 0 ? Side_Max : Side_Min) - cursor.column; - }break; - case UI_NavDeltaUnit_Whole: - case UI_NavDeltaUnit_EndPoint: - { - S64 first_nonwhitespace_column = 1; - for(U64 idx = 0; idx < line.size; idx += 1) - { - if(!char_is_space(line.str[idx])) - { - first_nonwhitespace_column = (S64)idx + 1; - break; - } - } - S64 home_dest_column = (cursor.column == first_nonwhitespace_column) ? 1 : first_nonwhitespace_column; - delta.x = (delta.x > 0) ? ((S64)line.size+1 - cursor.column) : (home_dest_column - cursor.column); - }break; - } - - //- rjf: zero delta - if(!txt_pt_match(cursor, mark) && action.flags & UI_NavActionFlag_ZeroDeltaOnSelect) - { - delta = v2s32(0, 0); - } - - //- rjf: form next cursor - if(txt_pt_match(cursor, mark) || !(action.flags & UI_NavActionFlag_ZeroDeltaOnSelect)) - { - next_cursor.column += delta.x; - } - - //- rjf: cap at line - if(action.flags & UI_NavActionFlag_CapAtLine) - { - next_cursor.column = Clamp(1, next_cursor.column, (S64)(line.size+1)); - } - - //- rjf: in some cases, we want to pick a selection side based on the delta - if(!txt_pt_match(cursor, mark) && action.flags & UI_NavActionFlag_PickSelectSide) - { - if(original_delta.x < 0 || original_delta.y < 0) - { - next_cursor = next_mark = txt_pt_min(cursor, mark); - } - else if(original_delta.x > 0 || original_delta.y > 0) - { - next_cursor = next_mark = txt_pt_max(cursor, mark); - } - } - - //- rjf: copying - if(action.flags & UI_NavActionFlag_Copy) - { - if(cursor.line == mark.line) - { - copy = str8_substr(line, r1u64(cursor.column-1, mark.column-1)); - flags |= UI_NavTxtOpFlag_Copy; - } - else - { - flags |= UI_NavTxtOpFlag_Invalid; - } - } - - //- rjf: pasting - if(action.flags & UI_NavActionFlag_Paste) - { - range = txt_rng(cursor, mark); - replace = os_get_clipboard_text(arena); - next_cursor = next_mark = txt_pt(cursor.line, cursor.column+replace.size); - } - - //- rjf: deletion - if(action.flags & UI_NavActionFlag_Delete) - { - TxtPt new_pos = txt_pt_min(next_cursor, next_mark); - range = txt_rng(next_cursor, next_mark); - replace = str8_lit(""); - next_cursor = next_mark = new_pos; - } - - //- rjf: stick mark to cursor, when we don't want to keep it in the same spot - if(!(action.flags & UI_NavActionFlag_KeepMark)) - { - next_mark = next_cursor; - } - - //- rjf: insertion - if(action.insertion.size != 0) - { - range = txt_rng(cursor, mark); - replace = push_str8_copy(arena, action.insertion); - next_cursor = next_mark = txt_pt(range.min.line, range.min.column + action.insertion.size); - } - - //- rjf: replace & commit -> replace entire range - if(action.flags & UI_NavActionFlag_ReplaceAndCommit) - { - range = txt_rng(txt_pt(cursor.line, 1), txt_pt(cursor.line, line.size+1)); - } - - //- rjf: determine if this event should be taken, based on bounds of cursor - { - if(next_cursor.column > line.size+1 || 1 > next_cursor.column || action.delta.y != 0) - { - flags |= UI_NavTxtOpFlag_Invalid; - } - next_cursor.column = Clamp(1, next_cursor.column, line.size+replace.size+1); - next_mark.column = Clamp(1, next_mark.column, line.size+replace.size+1); - } - - //- rjf: build+fill - UI_NavTxtOp op = {0}; - { - op.flags = flags; - op.replace = replace; - op.copy = copy; - op.range = range; - op.cursor = next_cursor; - op.mark = next_mark; - } - return op; -} - -//////////////////////////////// -//~ rjf: Single-Line String Modification - -internal String8 -ui_nav_push_string_replace_range(Arena *arena, String8 string, Rng1S64 col_range, String8 replace) -{ - //- rjf: convert to offset range - Rng1U64 range = - { - (U64)(col_range.min-1), - (U64)(col_range.max-1), - }; - - //- rjf: clamp range - if(range.min > string.size) - { - range.min = 0; - } - if(range.max > string.size) - { - range.max = string.size; - } - - //- rjf: calculate new size - U64 old_size = string.size; - U64 new_size = old_size - (range.max - range.min) + replace.size; - - //- rjf: push+fill new string storage - U8 *push_base = push_array(arena, U8, new_size); - { - MemoryCopy(push_base+0, string.str, range.min); - MemoryCopy(push_base+range.min+replace.size, string.str+range.max, string.size-range.max); - if(replace.str != 0) - { - MemoryCopy(push_base+range.min, replace.str, replace.size); - } - } - - return str8(push_base, new_size); -} - -#endif - //////////////////////////////// //~ rjf: Sizes @@ -826,6 +526,62 @@ ui_dt(void) return ui_state->animation_dt; } +//- rjf: event consumption helpers + +internal B32 +ui_key_press(OS_EventFlags mods, OS_Key key) +{ + UI_EventList *list = ui_events(); + 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(OS_EventFlags mods, OS_Key key) +{ + UI_EventList *list = ui_events(); + 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(U32 character) +{ + UI_EventList *list = ui_events(); + 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: drag data internal Vec2F32 @@ -1008,11 +764,11 @@ ui_begin_build(OS_Handle window, UI_EventList *events, UI_IconInfo *icon_info, F B32 nav_next = 0; B32 nav_prev = 0; Axis2 axis_lock = Axis2_Invalid; - if(ui_key_press(events, 0, OS_Key_Tab)) + if(ui_key_press(0, OS_Key_Tab)) { nav_next = 1; } - if(ui_key_press(events, OS_EventFlag_Shift, OS_Key_Tab)) + if(ui_key_press(OS_EventFlag_Shift, OS_Key_Tab)) { nav_prev = 1; } @@ -1170,7 +926,7 @@ ui_begin_build(OS_Handle window, UI_EventList *events, UI_IconInfo *icon_info, F //- rjf: some child has the active focus -> accept escape keys to pop from the active key stack if(!ui_key_match(ui_key_zero(), nav_root->default_nav_focus_active_key)) { - for(;ui_key_press(events, 0, OS_Key_Esc);) + for(;ui_key_press(0, OS_Key_Esc);) { UI_Box *prev_focus_root = nav_root; for(UI_Box *focus_root = ui_box_from_key(nav_root->default_nav_focus_active_key); @@ -1201,7 +957,7 @@ ui_begin_build(OS_Handle window, UI_EventList *events, UI_IconInfo *icon_info, F for(UI_EventNode *n = events->first; n != 0; n = n->next) { UI_Event *event = &n->v; - if(event->kind == OS_EventKind_Press && + if(event->kind == UI_EventKind_Press && event->key == OS_Key_LeftMouseButton && !contains_2f32(active_box->rect, ui_mouse())) { @@ -1318,7 +1074,7 @@ ui_end_build(void) ProfBeginFunction(); //- rjf: escape -> close context menu - if(ui_state->ctx_menu_open != 0 && ui_key_press(ui_events(), 0, OS_Key_Esc)) + if(ui_state->ctx_menu_open != 0 && ui_key_press(0, OS_Key_Esc)) { ui_ctx_menu_close(); } @@ -2627,7 +2383,7 @@ ui_do_single_line_string_edits(TxtPt *cursor, TxtPt *mark, U64 string_max, Strin next = n->next; // rjf: do not consume anything that doesn't fit a single-line's operations - if(n->v.delta_2s32.y != 0) + if((n->v.kind != UI_EventKind_Edit && n->v.kind != UI_EventKind_Navigate && n->v.kind != UI_EventKind_Text) || n->v.delta_2s32.y != 0) { continue; } @@ -2742,7 +2498,7 @@ ui_signal_from_box(UI_Box *box) //- rjf: mouse presses in box -> set hot/active; mark signal accordingly if(box->flags & UI_BoxFlag_MouseClickable && - evt->kind == OS_EventKind_Press && + evt->kind == UI_EventKind_Press && evt_mouse_in_bounds && evt_key_is_mouse) { @@ -2776,7 +2532,7 @@ ui_signal_from_box(UI_Box *box) //- rjf: mouse releases in active box -> unset active; mark signal accordingly if(box->flags & UI_BoxFlag_MouseClickable && - evt->kind == OS_EventKind_Release && + evt->kind == UI_EventKind_Release && ui_key_match(ui_state->active_box_key[evt_mouse_button_kind], box->key) && evt_mouse_in_bounds && evt_key_is_mouse) @@ -2789,7 +2545,7 @@ ui_signal_from_box(UI_Box *box) //- rjf: mouse releases outside active box -> unset hot/active if(box->flags & UI_BoxFlag_MouseClickable && - evt->kind == OS_EventKind_Release && + evt->kind == UI_EventKind_Release && ui_key_match(ui_state->active_box_key[evt_mouse_button_kind], box->key) && !evt_mouse_in_bounds && evt_key_is_mouse) @@ -2803,7 +2559,7 @@ ui_signal_from_box(UI_Box *box) //- rjf: focus is hot & keyboard click -> mark signal if(box->flags & UI_BoxFlag_KeyboardClickable && is_focus_hot && - evt->kind == OS_EventKind_Press && + evt->kind == UI_EventKind_Press && evt->key == OS_Key_Return) { sig.f |= UI_SignalFlag_KeyboardPressed; @@ -2850,7 +2606,7 @@ ui_signal_from_box(UI_Box *box) //- rjf: scrolling if(box->flags & UI_BoxFlag_Scroll && - evt->kind == OS_EventKind_Scroll && + evt->kind == UI_EventKind_Scroll && evt->modifiers != OS_EventFlag_Ctrl && evt_mouse_in_bounds) { @@ -2871,7 +2627,7 @@ ui_signal_from_box(UI_Box *box) //- rjf: view scrolling if(box->flags & UI_BoxFlag_ViewScroll && box->first_touched_build_index != box->last_touched_build_index && - evt->kind == OS_EventKind_Scroll && + evt->kind == UI_EventKind_Scroll && evt->modifiers != OS_EventFlag_Ctrl && evt_mouse_in_bounds) { diff --git a/src/ui/ui_core.h b/src/ui/ui_core.h index 57106585..3f664541 100644 --- a/src/ui/ui_core.h +++ b/src/ui/ui_core.h @@ -88,6 +88,7 @@ enum typedef enum UI_EventDeltaUnit { + UI_EventDeltaUnit_Null, UI_EventDeltaUnit_Char, UI_EventDeltaUnit_Word, UI_EventDeltaUnit_Line, @@ -149,78 +150,6 @@ struct UI_TxtOp TxtPt mark; }; -#if 0 -//////////////////////////////// -//~ rjf: Navigation Types - -typedef enum UI_NavDeltaUnit -{ - UI_NavDeltaUnit_Element, - UI_NavDeltaUnit_Chunk, - UI_NavDeltaUnit_Whole, - UI_NavDeltaUnit_EndPoint, - UI_NavDeltaUnit_COUNT, -} -UI_NavDeltaUnit; - -typedef U32 UI_NavActionFlags; -enum -{ - UI_NavActionFlag_KeepMark = (1<<0), - UI_NavActionFlag_Delete = (1<<1), - UI_NavActionFlag_Copy = (1<<2), - UI_NavActionFlag_Paste = (1<<3), - UI_NavActionFlag_ZeroDeltaOnSelect = (1<<4), - UI_NavActionFlag_PickSelectSide = (1<<5), - UI_NavActionFlag_CapAtLine = (1<<6), - UI_NavActionFlag_ExplicitDirectional = (1<<7), - UI_NavActionFlag_ReplaceAndCommit = (1<<8), -}; - -typedef struct UI_NavAction UI_NavAction; -struct UI_NavAction -{ - UI_NavActionFlags flags; - Vec2S32 delta; - UI_NavDeltaUnit delta_unit; - String8 insertion; -}; - -typedef struct UI_NavActionNode UI_NavActionNode; -struct UI_NavActionNode -{ - UI_NavActionNode *next; - UI_NavActionNode *prev; - UI_NavAction v; -}; - -typedef struct UI_NavActionList UI_NavActionList; -struct UI_NavActionList -{ - UI_NavActionNode *first; - UI_NavActionNode *last; - U64 count; -}; - -typedef U32 UI_NavTxtOpFlags; -enum -{ - UI_NavTxtOpFlag_Invalid = (1<<0), - UI_NavTxtOpFlag_Copy = (1<<1), -}; - -typedef struct UI_NavTxtOp UI_NavTxtOp; -struct UI_NavTxtOp -{ - UI_NavTxtOpFlags flags; - String8 replace; - String8 copy; - TxtRng range; - TxtPt cursor; - TxtPt mark; -}; -#endif - //////////////////////////////// //~ rjf: Keys @@ -636,13 +565,10 @@ 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 +//~ rjf: Event Type 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: Text Operation Functions @@ -652,26 +578,6 @@ internal S64 ui_scanned_column_from_column(String8 string, S64 start_column, Sid internal UI_TxtOp ui_single_line_txt_op_from_event(Arena *arena, UI_Event *event, String8 string, TxtPt cursor, TxtPt mark); internal String8 ui_push_string_replace_range(Arena *arena, String8 string, Rng1S64 range, String8 replace); -#if 0 -//////////////////////////////// -//~ rjf: Navigation Action List Building & Consumption Functions - -internal void ui_nav_action_list_push(Arena *arena, UI_NavActionList *list, UI_NavAction action); -internal void ui_nav_eat_action_node(UI_NavActionList *list, UI_NavActionNode *node); - -//////////////////////////////// -//~ rjf: High Level Navigation Action => Text Operations - -internal B32 ui_nav_char_is_scan_boundary(U8 c); -internal S64 ui_nav_scanned_column_from_column(String8 string, S64 start_column, Side side); -internal UI_NavTxtOp ui_nav_single_line_txt_op_from_action(Arena *arena, UI_NavAction action, String8 line, TxtPt cursor, TxtPt mark); - -//////////////////////////////// -//~ rjf: Single-Line String Modification - -internal String8 ui_nav_push_string_replace_range(Arena *arena, String8 string, Rng1S64 col_range, String8 replace); -#endif - //////////////////////////////// //~ rjf: Size Type Functions @@ -730,6 +636,11 @@ internal F_Tag ui_icon_font(void); internal String8 ui_icon_string_from_kind(UI_IconKind icon_kind); internal F32 ui_dt(void); +//- rjf: event consumption helpers +internal B32 ui_key_press(OS_EventFlags mods, OS_Key key); +internal B32 ui_key_release(OS_EventFlags mods, OS_Key key); +internal B32 ui_text(U32 character); + //- rjf: drag data internal Vec2F32 ui_drag_start_mouse(void); internal Vec2F32 ui_drag_delta(void); From e59d71893b6a58f0571f291377f5df052b5b3703 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Mon, 13 May 2024 12:57:45 -0700 Subject: [PATCH 06/30] bugfix copying & other accidental event consumption issues with new ui events --- src/df/gfx/df_gfx.c | 7 ++++++- src/ui/ui_core.c | 10 ++++++---- 2 files changed, 12 insertions(+), 5 deletions(-) diff --git a/src/df/gfx/df_gfx.c b/src/df/gfx/df_gfx.c index ee7acbba..1f6e8078 100644 --- a/src/df/gfx/df_gfx.c +++ b/src/df/gfx/df_gfx.c @@ -11609,6 +11609,7 @@ df_do_txt_controls(TXT_TextInfo *info, String8 data, U64 line_count_per_page, Tx { String8 text = txt_string_from_info_data_txt_rng(info, data, txt_rng(*cursor, *mark)); os_set_clipboard_text(text); + taken = 1; } //- rjf: consume @@ -11633,7 +11634,10 @@ df_do_txti_controls(TXTI_Handle handle, U64 line_count_per_page, TxtPt *cursor, { next = n->next; B32 taken = 0; - + if(n->v.kind != UI_EventKind_Navigate && n->v.kind != UI_EventKind_Edit) + { + continue; + } String8 line = txti_string_from_handle_line_num(scratch.arena, handle, cursor->line); UI_TxtOp single_line_op = ui_single_line_txt_op_from_event(scratch.arena, &n->v, line, *cursor, *mark); @@ -11787,6 +11791,7 @@ df_do_txti_controls(TXTI_Handle handle, U64 line_count_per_page, TxtPt *cursor, { String8 text = txti_string_from_handle_txt_rng(scratch.arena, handle, txt_rng(*cursor, *mark)); os_set_clipboard_text(text); + taken = 1; } //- rjf: consume diff --git a/src/ui/ui_core.c b/src/ui/ui_core.c index 9892f329..905591ec 100644 --- a/src/ui/ui_core.c +++ b/src/ui/ui_core.c @@ -1355,10 +1355,11 @@ ui_end_build(void) //- rjf: clipboard commits { - Temp scratch = scratch_begin(0, 0); UI_Box *box = ui_box_from_key(ui_state->clipboard_copy_key); - String8List strs = {0}; + if(!ui_box_is_nil(box)) { + Temp scratch = scratch_begin(0, 0); + String8List strs = {0}; UI_BoxRec rec = {0}; for(UI_Box *b = box; !ui_box_is_nil(b); rec = ui_box_rec_df_pre(b, box), b = rec.next) { @@ -1375,8 +1376,8 @@ ui_end_build(void) String8 string = str8_list_join(scratch.arena, &strs, &join); os_set_clipboard_text(string); } + scratch_end(scratch); } - scratch_end(scratch); } //- rjf: hovering possibly-truncated drawn text -> store text @@ -2568,7 +2569,8 @@ ui_signal_from_box(UI_Box *box) //- rjf: focus is hot & copy event -> remember to copy this box tree's text content if(is_focus_hot && - evt->flags & UI_EventFlag_Copy) + evt->flags & UI_EventFlag_Copy && + !ui_key_match(ui_key_zero(), box->key)) { ui_state->clipboard_copy_key = box->key; taken = 1; From 05f2cde2ee72742f27740fab813f26cebb9e86e7 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Mon, 13 May 2024 13:10:49 -0700 Subject: [PATCH 07/30] fix clang --- src/ctrl/ctrl_core.c | 2 + src/dasm_cache/dasm_cache.c | 2 +- src/demon/win32/demon_core_win32.c | 1 + src/df/gfx/df_gfx.c | 99 ++++++++++++------------------ src/df/gfx/df_gfx.h | 10 ++- src/df/gfx/df_gfx.mdesk | 13 ---- src/df/gfx/generated/df_gfx.meta.h | 7 --- src/raddbg/raddbg.h | 2 +- 8 files changed, 53 insertions(+), 83 deletions(-) diff --git a/src/ctrl/ctrl_core.c b/src/ctrl/ctrl_core.c index daa2e619..541c7f0d 100644 --- a/src/ctrl/ctrl_core.c +++ b/src/ctrl/ctrl_core.c @@ -743,6 +743,8 @@ ctrl_entity_store_apply_events(CTRL_EntityStore *store, CTRL_EventList *list) CTRL_Event *event = &n->v; switch(event->kind) { + default:{}break; + //- rjf: processes case CTRL_EventKind_NewProc: { diff --git a/src/dasm_cache/dasm_cache.c b/src/dasm_cache/dasm_cache.c index 75b694c9..b150acd7 100644 --- a/src/dasm_cache/dasm_cache.c +++ b/src/dasm_cache/dasm_cache.c @@ -440,7 +440,7 @@ dasm_parse_thread__entry_point(void *p) U64 jump_dst_vaddr = rel_voff; // rjf: push strings derived from voff -> line info - if(params.style_flags & DASM_StyleFlag_SourceFilesNames|DASM_StyleFlag_SourceLines) + if(params.style_flags & (DASM_StyleFlag_SourceFilesNames|DASM_StyleFlag_SourceLines)) { if(dbgi != &dbgi_parse_nil) { diff --git a/src/demon/win32/demon_core_win32.c b/src/demon/win32/demon_core_win32.c index 578edffa..28abb910 100644 --- a/src/demon/win32/demon_core_win32.c +++ b/src/demon/win32/demon_core_win32.c @@ -1732,6 +1732,7 @@ dmn_ctrl_run(Arena *arena, DMN_CtrlCtx *ctx, DMN_RunCtrls *ctrls) { switch(child->kind) { + default:{}break; case DMN_W32_EntityKind_Thread: { DMN_Event *e = dmn_event_list_push(arena, &events); diff --git a/src/df/gfx/df_gfx.c b/src/df/gfx/df_gfx.c index 1f6e8078..beec8414 100644 --- a/src/df/gfx/df_gfx.c +++ b/src/df/gfx/df_gfx.c @@ -1125,7 +1125,7 @@ df_window_update_and_render(Arena *arena, DF_Window *ws, DF_CmdList *cmds) OS_Event *os_event = params.os_event; if(os_event != 0 && os_handle_match(os_event->window, ws->os)) { - UI_Event ui_event = {0}; + UI_Event ui_event = zero_struct; UI_EventKind kind = UI_EventKind_Null; { switch(os_event->kind) @@ -2114,7 +2114,7 @@ df_window_update_and_render(Arena *arena, DF_Window *ws, DF_CmdList *cmds) // case DF_CoreCmdKind_MoveLeft: { - UI_Event evt = {0}; + UI_Event evt = zero_struct; evt.kind = UI_EventKind_Navigate; evt.flags = UI_EventFlag_PickSelectSide|UI_EventFlag_ZeroDeltaOnSelect|UI_EventFlag_ExplicitDirectional; evt.delta_unit = UI_EventDeltaUnit_Char; @@ -2123,7 +2123,7 @@ df_window_update_and_render(Arena *arena, DF_Window *ws, DF_CmdList *cmds) }break; case DF_CoreCmdKind_MoveRight: { - UI_Event evt = {0}; + UI_Event evt = zero_struct; evt.kind = UI_EventKind_Navigate; evt.flags = UI_EventFlag_PickSelectSide|UI_EventFlag_ZeroDeltaOnSelect|UI_EventFlag_ExplicitDirectional; evt.delta_unit = UI_EventDeltaUnit_Char; @@ -2132,7 +2132,7 @@ df_window_update_and_render(Arena *arena, DF_Window *ws, DF_CmdList *cmds) }break; case DF_CoreCmdKind_MoveUp: { - UI_Event evt = {0}; + UI_Event evt = zero_struct; evt.kind = UI_EventKind_Navigate; evt.flags = UI_EventFlag_ExplicitDirectional; evt.delta_unit = UI_EventDeltaUnit_Char; @@ -2141,7 +2141,7 @@ df_window_update_and_render(Arena *arena, DF_Window *ws, DF_CmdList *cmds) }break; case DF_CoreCmdKind_MoveDown: { - UI_Event evt = {0}; + UI_Event evt = zero_struct; evt.kind = UI_EventKind_Navigate; evt.flags = UI_EventFlag_ExplicitDirectional; evt.delta_unit = UI_EventDeltaUnit_Char; @@ -2150,7 +2150,7 @@ df_window_update_and_render(Arena *arena, DF_Window *ws, DF_CmdList *cmds) }break; case DF_CoreCmdKind_MoveLeftSelect: { - UI_Event evt = {0}; + UI_Event evt = zero_struct; evt.kind = UI_EventKind_Navigate; evt.flags = UI_EventFlag_KeepMark|UI_EventFlag_ExplicitDirectional; evt.delta_unit = UI_EventDeltaUnit_Char; @@ -2159,7 +2159,7 @@ df_window_update_and_render(Arena *arena, DF_Window *ws, DF_CmdList *cmds) }break; case DF_CoreCmdKind_MoveRightSelect: { - UI_Event evt = {0}; + UI_Event evt = zero_struct; evt.kind = UI_EventKind_Navigate; evt.flags = UI_EventFlag_KeepMark|UI_EventFlag_ExplicitDirectional; evt.delta_unit = UI_EventDeltaUnit_Char; @@ -2168,7 +2168,7 @@ df_window_update_and_render(Arena *arena, DF_Window *ws, DF_CmdList *cmds) }break; case DF_CoreCmdKind_MoveUpSelect: { - UI_Event evt = {0}; + UI_Event evt = zero_struct; evt.kind = UI_EventKind_Navigate; evt.flags = UI_EventFlag_KeepMark|UI_EventFlag_ExplicitDirectional; evt.delta_unit = UI_EventDeltaUnit_Char; @@ -2177,7 +2177,7 @@ df_window_update_and_render(Arena *arena, DF_Window *ws, DF_CmdList *cmds) }break; case DF_CoreCmdKind_MoveDownSelect: { - UI_Event evt = {0}; + UI_Event evt = zero_struct; evt.kind = UI_EventKind_Navigate; evt.flags = UI_EventFlag_KeepMark|UI_EventFlag_ExplicitDirectional; evt.delta_unit = UI_EventDeltaUnit_Char; @@ -2186,7 +2186,7 @@ df_window_update_and_render(Arena *arena, DF_Window *ws, DF_CmdList *cmds) }break; case DF_CoreCmdKind_MoveLeftChunk: { - UI_Event evt = {0}; + UI_Event evt = zero_struct; evt.kind = UI_EventKind_Navigate; evt.flags = UI_EventFlag_ExplicitDirectional; evt.delta_unit = UI_EventDeltaUnit_Word; @@ -2195,7 +2195,7 @@ df_window_update_and_render(Arena *arena, DF_Window *ws, DF_CmdList *cmds) }break; case DF_CoreCmdKind_MoveRightChunk: { - UI_Event evt = {0}; + UI_Event evt = zero_struct; evt.kind = UI_EventKind_Navigate; evt.flags = UI_EventFlag_ExplicitDirectional; evt.delta_unit = UI_EventDeltaUnit_Word; @@ -2204,7 +2204,7 @@ df_window_update_and_render(Arena *arena, DF_Window *ws, DF_CmdList *cmds) }break; case DF_CoreCmdKind_MoveUpChunk: { - UI_Event evt = {0}; + UI_Event evt = zero_struct; evt.kind = UI_EventKind_Navigate; evt.flags = UI_EventFlag_ExplicitDirectional; evt.delta_unit = UI_EventDeltaUnit_Word; @@ -2213,7 +2213,7 @@ df_window_update_and_render(Arena *arena, DF_Window *ws, DF_CmdList *cmds) }break; case DF_CoreCmdKind_MoveDownChunk: { - UI_Event evt = {0}; + UI_Event evt = zero_struct; evt.kind = UI_EventKind_Navigate; evt.flags = UI_EventFlag_ExplicitDirectional; evt.delta_unit = UI_EventDeltaUnit_Word; @@ -2222,7 +2222,7 @@ df_window_update_and_render(Arena *arena, DF_Window *ws, DF_CmdList *cmds) }break; case DF_CoreCmdKind_MoveUpPage: { - UI_Event evt = {0}; + UI_Event evt = zero_struct; evt.kind = UI_EventKind_Navigate; evt.delta_unit = UI_EventDeltaUnit_Page; evt.delta_2s32 = v2s32(+0, -1); @@ -2230,7 +2230,7 @@ df_window_update_and_render(Arena *arena, DF_Window *ws, DF_CmdList *cmds) }break; case DF_CoreCmdKind_MoveDownPage: { - UI_Event evt = {0}; + UI_Event evt = zero_struct; evt.kind = UI_EventKind_Navigate; evt.delta_unit = UI_EventDeltaUnit_Page; evt.delta_2s32 = v2s32(+0, +1); @@ -2238,7 +2238,7 @@ df_window_update_and_render(Arena *arena, DF_Window *ws, DF_CmdList *cmds) }break; case DF_CoreCmdKind_MoveUpWhole: { - UI_Event evt = {0}; + UI_Event evt = zero_struct; evt.kind = UI_EventKind_Navigate; evt.delta_unit = UI_EventDeltaUnit_Whole; evt.delta_2s32 = v2s32(+0, -1); @@ -2246,7 +2246,7 @@ df_window_update_and_render(Arena *arena, DF_Window *ws, DF_CmdList *cmds) }break; case DF_CoreCmdKind_MoveDownWhole: { - UI_Event evt = {0}; + UI_Event evt = zero_struct; evt.kind = UI_EventKind_Navigate; evt.delta_unit = UI_EventDeltaUnit_Whole; evt.delta_2s32 = v2s32(+0, +1); @@ -2254,7 +2254,7 @@ df_window_update_and_render(Arena *arena, DF_Window *ws, DF_CmdList *cmds) }break; case DF_CoreCmdKind_MoveLeftChunkSelect: { - UI_Event evt = {0}; + UI_Event evt = zero_struct; evt.kind = UI_EventKind_Navigate; evt.flags = UI_EventFlag_KeepMark|UI_EventFlag_ExplicitDirectional; evt.delta_unit = UI_EventDeltaUnit_Word; @@ -2263,7 +2263,7 @@ df_window_update_and_render(Arena *arena, DF_Window *ws, DF_CmdList *cmds) }break; case DF_CoreCmdKind_MoveRightChunkSelect: { - UI_Event evt = {0}; + UI_Event evt = zero_struct; evt.kind = UI_EventKind_Navigate; evt.flags = UI_EventFlag_KeepMark|UI_EventFlag_ExplicitDirectional; evt.delta_unit = UI_EventDeltaUnit_Word; @@ -2272,7 +2272,7 @@ df_window_update_and_render(Arena *arena, DF_Window *ws, DF_CmdList *cmds) }break; case DF_CoreCmdKind_MoveUpChunkSelect: { - UI_Event evt = {0}; + UI_Event evt = zero_struct; evt.kind = UI_EventKind_Navigate; evt.flags = UI_EventFlag_KeepMark|UI_EventFlag_ExplicitDirectional; evt.delta_unit = UI_EventDeltaUnit_Word; @@ -2281,7 +2281,7 @@ df_window_update_and_render(Arena *arena, DF_Window *ws, DF_CmdList *cmds) }break; case DF_CoreCmdKind_MoveDownChunkSelect: { - UI_Event evt = {0}; + UI_Event evt = zero_struct; evt.kind = UI_EventKind_Navigate; evt.flags = UI_EventFlag_KeepMark|UI_EventFlag_ExplicitDirectional; evt.delta_unit = UI_EventDeltaUnit_Word; @@ -2290,7 +2290,7 @@ df_window_update_and_render(Arena *arena, DF_Window *ws, DF_CmdList *cmds) }break; case DF_CoreCmdKind_MoveUpPageSelect: { - UI_Event evt = {0}; + UI_Event evt = zero_struct; evt.kind = UI_EventKind_Navigate; evt.flags = UI_EventFlag_KeepMark; evt.delta_unit = UI_EventDeltaUnit_Page; @@ -2299,7 +2299,7 @@ df_window_update_and_render(Arena *arena, DF_Window *ws, DF_CmdList *cmds) }break; case DF_CoreCmdKind_MoveDownPageSelect: { - UI_Event evt = {0}; + UI_Event evt = zero_struct; evt.kind = UI_EventKind_Navigate; evt.flags = UI_EventFlag_KeepMark; evt.delta_unit = UI_EventDeltaUnit_Page; @@ -2308,7 +2308,7 @@ df_window_update_and_render(Arena *arena, DF_Window *ws, DF_CmdList *cmds) }break; case DF_CoreCmdKind_MoveUpWholeSelect: { - UI_Event evt = {0}; + UI_Event evt = zero_struct; evt.kind = UI_EventKind_Navigate; evt.flags = UI_EventFlag_KeepMark; evt.delta_unit = UI_EventDeltaUnit_Whole; @@ -2317,7 +2317,7 @@ df_window_update_and_render(Arena *arena, DF_Window *ws, DF_CmdList *cmds) }break; case DF_CoreCmdKind_MoveDownWholeSelect: { - UI_Event evt = {0}; + UI_Event evt = zero_struct; evt.kind = UI_EventKind_Navigate; evt.flags = UI_EventFlag_KeepMark; evt.delta_unit = UI_EventDeltaUnit_Whole; @@ -2326,7 +2326,7 @@ df_window_update_and_render(Arena *arena, DF_Window *ws, DF_CmdList *cmds) }break; case DF_CoreCmdKind_MoveHome: { - UI_Event evt = {0}; + UI_Event evt = zero_struct; evt.kind = UI_EventKind_Navigate; evt.delta_unit = UI_EventDeltaUnit_Line; evt.delta_2s32 = v2s32(-1, +0); @@ -2334,7 +2334,7 @@ df_window_update_and_render(Arena *arena, DF_Window *ws, DF_CmdList *cmds) }break; case DF_CoreCmdKind_MoveEnd: { - UI_Event evt = {0}; + UI_Event evt = zero_struct; evt.kind = UI_EventKind_Navigate; evt.delta_unit = UI_EventDeltaUnit_Line; evt.delta_2s32 = v2s32(+1, +0); @@ -2342,7 +2342,7 @@ df_window_update_and_render(Arena *arena, DF_Window *ws, DF_CmdList *cmds) }break; case DF_CoreCmdKind_MoveHomeSelect: { - UI_Event evt = {0}; + UI_Event evt = zero_struct; evt.kind = UI_EventKind_Navigate; evt.flags = UI_EventFlag_KeepMark; evt.delta_unit = UI_EventDeltaUnit_Line; @@ -2351,7 +2351,7 @@ df_window_update_and_render(Arena *arena, DF_Window *ws, DF_CmdList *cmds) }break; case DF_CoreCmdKind_MoveEndSelect: { - UI_Event evt = {0}; + UI_Event evt = zero_struct; evt.kind = UI_EventKind_Navigate; evt.flags = UI_EventFlag_KeepMark; evt.delta_unit = UI_EventDeltaUnit_Line; @@ -2360,12 +2360,12 @@ df_window_update_and_render(Arena *arena, DF_Window *ws, DF_CmdList *cmds) }break; case DF_CoreCmdKind_SelectAll: { - UI_Event evt1 = {0}; + UI_Event evt1 = zero_struct; evt1.kind = UI_EventKind_Navigate; evt1.delta_unit = UI_EventDeltaUnit_Whole; evt1.delta_2s32 = v2s32(-1, +0); ui_event_list_push(ui_build_arena(), &events, &evt1); - UI_Event evt2 = {0}; + UI_Event evt2 = zero_struct; evt2.kind = UI_EventKind_Navigate; evt2.flags = UI_EventFlag_KeepMark; evt2.delta_unit = UI_EventDeltaUnit_Whole; @@ -2374,7 +2374,7 @@ df_window_update_and_render(Arena *arena, DF_Window *ws, DF_CmdList *cmds) }break; case DF_CoreCmdKind_DeleteSingle: { - UI_Event evt = {0}; + UI_Event evt = zero_struct; evt.kind = UI_EventKind_Edit; evt.flags = UI_EventFlag_Delete; evt.delta_unit = UI_EventDeltaUnit_Char; @@ -2383,7 +2383,7 @@ df_window_update_and_render(Arena *arena, DF_Window *ws, DF_CmdList *cmds) }break; case DF_CoreCmdKind_DeleteChunk: { - UI_Event evt = {0}; + UI_Event evt = zero_struct; evt.kind = UI_EventKind_Edit; evt.flags = UI_EventFlag_Delete; evt.delta_unit = UI_EventDeltaUnit_Word; @@ -2392,7 +2392,7 @@ df_window_update_and_render(Arena *arena, DF_Window *ws, DF_CmdList *cmds) }break; case DF_CoreCmdKind_BackspaceSingle: { - UI_Event evt = {0}; + UI_Event evt = zero_struct; evt.kind = UI_EventKind_Edit; evt.flags = UI_EventFlag_Delete|UI_EventFlag_ZeroDeltaOnSelect; evt.delta_unit = UI_EventDeltaUnit_Char; @@ -2401,7 +2401,7 @@ df_window_update_and_render(Arena *arena, DF_Window *ws, DF_CmdList *cmds) }break; case DF_CoreCmdKind_BackspaceChunk: { - UI_Event evt = {0}; + UI_Event evt = zero_struct; evt.kind = UI_EventKind_Edit; evt.flags = UI_EventFlag_Delete; evt.delta_unit = UI_EventDeltaUnit_Word; @@ -2410,28 +2410,28 @@ df_window_update_and_render(Arena *arena, DF_Window *ws, DF_CmdList *cmds) }break; case DF_CoreCmdKind_Copy: { - UI_Event evt = {0}; + UI_Event evt = zero_struct; evt.kind = UI_EventKind_Edit; evt.flags = UI_EventFlag_Copy|UI_EventFlag_KeepMark; ui_event_list_push(ui_build_arena(), &events, &evt); }break; case DF_CoreCmdKind_Cut: { - UI_Event evt = {0}; + UI_Event evt = zero_struct; evt.kind = UI_EventKind_Edit; evt.flags = UI_EventFlag_Copy|UI_EventFlag_Delete; ui_event_list_push(ui_build_arena(), &events, &evt); }break; case DF_CoreCmdKind_Paste: { - UI_Event evt = {0}; + UI_Event evt = zero_struct; evt.kind = UI_EventKind_Text; evt.string = os_get_clipboard_text(ui_build_arena()); ui_event_list_push(ui_build_arena(), &events, &evt); }break; case DF_CoreCmdKind_InsertText: { - UI_Event evt = {0}; + UI_Event evt = zero_struct; evt.kind = UI_EventKind_Text; evt.string = params.string; ui_event_list_push(ui_build_arena(), &events, &evt); @@ -7049,27 +7049,6 @@ df_window_update_and_render(Arena *arena, DF_Window *ws, DF_CmdList *cmds) tab_bar_box->flags |= UI_BoxFlag_DrawOverlay; tab_bar_box->overlay_color = df_rgba_from_theme_color(DF_ThemeColor_DropSiteOverlay); } - - // rjf: drop - DF_DragDropPayload payload = df_g_drag_drop_payload; - if(catchall_drop_site_hovered && (active_drop_site != 0 && df_drag_drop(&payload)) || (df_panel_from_handle(payload.panel) == panel && 0)) - { - DF_View *view = df_view_from_handle(payload.view); - DF_Panel *src_panel = df_panel_from_handle(payload.panel); - if(!df_panel_is_nil(panel) && !df_view_is_nil(view)) - { - DF_CmdParams params = df_cmd_params_from_window(ws); - params.panel = df_handle_from_panel(src_panel); - params.dest_panel = df_handle_from_panel(panel); - params.view = df_handle_from_view(view); - params.prev_view = df_handle_from_view(active_drop_site->prev_view); - df_cmd_params_mark_slot(¶ms, DF_CmdParamSlot_Panel); - df_cmd_params_mark_slot(¶ms, DF_CmdParamSlot_DestPanel); - df_cmd_params_mark_slot(¶ms, DF_CmdParamSlot_View); - df_cmd_params_mark_slot(¶ms, DF_CmdParamSlot_PrevView); - df_push_cmd__root(¶ms, df_cmd_spec_from_core_cmd_kind(DF_CoreCmdKind_MoveTab)); - } - } } } diff --git a/src/df/gfx/df_gfx.h b/src/df/gfx/df_gfx.h index 2859b9ac..1ac1afa6 100644 --- a/src/df/gfx/df_gfx.h +++ b/src/df/gfx/df_gfx.h @@ -108,13 +108,21 @@ enum DF_ViewSpecFlag_TypingAutomaticallyFilters = (1<<6), }; +typedef enum DF_NameKind +{ + DF_NameKind_Null, + DF_NameKind_EntityName, + DF_NameKind_COUNT +} +DF_NameKind; + typedef struct DF_ViewSpecInfo DF_ViewSpecInfo; struct DF_ViewSpecInfo { DF_ViewSpecFlags flags; String8 name; String8 display_string; - enum DF_NameKind name_kind; + DF_NameKind name_kind; DF_IconKind icon_kind; DF_ViewSetupFunctionType *setup_hook; DF_ViewStringFromStateFunctionType *string_from_state_hook; diff --git a/src/df/gfx/df_gfx.mdesk b/src/df/gfx/df_gfx.mdesk index e255649a..45bfe758 100644 --- a/src/df/gfx/df_gfx.mdesk +++ b/src/df/gfx/df_gfx.mdesk @@ -178,13 +178,6 @@ DF_BindingVersionRemapTable: //////////////////////////////// //~ rjf: Gfx Layer View Kinds -@table(name) -DF_NameKindTable: -{ - {Null} - {EntityName} -} - @table(name, name_lower, display_string, name_kind, icon, parameterized_by_entity, can_serialize, can_serialize_entity_path, can_filter, filter_is_code, typing_automatically_filters, inc_in_docs, docs_desc) DF_GfxViewTable: { @@ -412,12 +405,6 @@ DF_ThemePresetColorTable: //- rjf: enums -@enum DF_NameKind: -{ - @expand(DF_NameKindTable, a) `$(a.name)`, - COUNT, -} - @enum DF_GfxViewKind: { @expand(DF_GfxViewTable a) `$(a.name)`, diff --git a/src/df/gfx/generated/df_gfx.meta.h b/src/df/gfx/generated/df_gfx.meta.h index 96d7f8be..68f2fd8e 100644 --- a/src/df/gfx/generated/df_gfx.meta.h +++ b/src/df/gfx/generated/df_gfx.meta.h @@ -6,13 +6,6 @@ #ifndef DF_GFX_META_H #define DF_GFX_META_H -typedef enum DF_NameKind -{ -DF_NameKind_Null, -DF_NameKind_EntityName, -DF_NameKind_COUNT, -} DF_NameKind; - typedef enum DF_GfxViewKind { DF_GfxViewKind_Null, diff --git a/src/raddbg/raddbg.h b/src/raddbg/raddbg.h index e9c83a4a..c14a076b 100644 --- a/src/raddbg/raddbg.h +++ b/src/raddbg/raddbg.h @@ -6,7 +6,7 @@ // // [ ] n-row table selection, in watch window & other UIs, multi-selection // ctrl+C -// [ ] UI_NavActions, OS_Event -> UI_Event (single event stream) +// [x] UI_NavActions, OS_Event -> UI_Event (single event stream) // // [ ] better discoverability for view rules - have better help hover tooltip, // info on arguments, and better autocomplete lister From 37dd5cea2d5c3e80837a5ff5dd8a240f4c4c31e6 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Mon, 13 May 2024 13:11:34 -0700 Subject: [PATCH 08/30] oops - this was not dead code! --- src/df/gfx/df_gfx.c | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/src/df/gfx/df_gfx.c b/src/df/gfx/df_gfx.c index beec8414..c1536d4a 100644 --- a/src/df/gfx/df_gfx.c +++ b/src/df/gfx/df_gfx.c @@ -7049,6 +7049,27 @@ df_window_update_and_render(Arena *arena, DF_Window *ws, DF_CmdList *cmds) tab_bar_box->flags |= UI_BoxFlag_DrawOverlay; tab_bar_box->overlay_color = df_rgba_from_theme_color(DF_ThemeColor_DropSiteOverlay); } + + // rjf: drop + DF_DragDropPayload payload = df_g_drag_drop_payload; + if(catchall_drop_site_hovered && (active_drop_site != 0 && df_drag_drop(&payload))) + { + DF_View *view = df_view_from_handle(payload.view); + DF_Panel *src_panel = df_panel_from_handle(payload.panel); + if(!df_panel_is_nil(panel) && !df_view_is_nil(view)) + { + DF_CmdParams params = df_cmd_params_from_window(ws); + params.panel = df_handle_from_panel(src_panel); + params.dest_panel = df_handle_from_panel(panel); + params.view = df_handle_from_view(view); + params.prev_view = df_handle_from_view(active_drop_site->prev_view); + df_cmd_params_mark_slot(¶ms, DF_CmdParamSlot_Panel); + df_cmd_params_mark_slot(¶ms, DF_CmdParamSlot_DestPanel); + df_cmd_params_mark_slot(¶ms, DF_CmdParamSlot_View); + df_cmd_params_mark_slot(¶ms, DF_CmdParamSlot_PrevView); + df_push_cmd__root(¶ms, df_cmd_spec_from_core_cmd_kind(DF_CoreCmdKind_MoveTab)); + } + } } } From 036d94fff04fec6ab2b8b1859fc462312234aaec Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Mon, 13 May 2024 14:24:28 -0700 Subject: [PATCH 09/30] autocompletion lister improvements - completions now can be used for sub-expression parts --- src/df/gfx/df_gfx.c | 125 +++++++++++++++++++++++++++++++++++++++--- src/df/gfx/df_gfx.h | 5 +- src/df/gfx/df_views.c | 10 ++-- src/ui/ui_core.h | 1 + 4 files changed, 129 insertions(+), 12 deletions(-) diff --git a/src/df/gfx/df_gfx.c b/src/df/gfx/df_gfx.c index c1536d4a..64aabcd2 100644 --- a/src/df/gfx/df_gfx.c +++ b/src/df/gfx/df_gfx.c @@ -4305,7 +4305,7 @@ df_window_update_and_render(Arena *arena, DF_Window *ws, DF_CmdList *cmds) // rjf: animate target # of rows { F32 rate = 1 - pow_f32(2, (-60.f * df_dt())); - F32 target = Min((F32)item_array.count, 8.f); + F32 target = Min((F32)item_array.count, 16.f); if(abs_f32(target - ws->autocomp_num_visible_rows_t) > 0.01f) { df_gfx_request_frame(); @@ -4350,6 +4350,11 @@ df_window_update_and_render(Arena *arena, DF_Window *ws, DF_CmdList *cmds) UI_Transparency(1.f-ws->autocomp_open_t) { 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"); + if(ws->autocomp_query_dirty) + { + ws->autocomp_query_dirty = 0; + autocomp_box->default_nav_focus_hot_key = autocomp_box->default_nav_focus_active_key = autocomp_box->default_nav_focus_next_hot_key = autocomp_box->default_nav_focus_next_active_key = ui_key_zero(); + } } 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) @@ -4360,7 +4365,11 @@ df_window_update_and_render(Arena *arena, DF_Window *ws, DF_CmdList *cmds) UI_Box *item_box = ui_build_box_from_stringf(UI_BoxFlag_DrawBorder|UI_BoxFlag_DrawBackground|UI_BoxFlag_DrawHotEffects|UI_BoxFlag_DrawActiveEffects|UI_BoxFlag_Clickable, "autocomp_%I64x", idx); UI_Parent(item_box) { - UI_WidthFill ui_label(item->string); + UI_WidthFill + { + UI_Box *box = ui_label(item->string).box; + ui_box_equip_fuzzy_match_ranges(box, &item->matches); + } UI_Font(df_font_from_slot(DF_FontSlot_Main)) UI_PrefWidth(ui_text_dim(10, 1)) UI_TextColor(df_rgba_from_theme_color(DF_ThemeColor_WeakText)) @@ -4369,8 +4378,23 @@ df_window_update_and_render(Arena *arena, DF_Window *ws, DF_CmdList *cmds) UI_Signal item_sig = ui_signal_from_box(item_box); if(ui_clicked(item_sig)) { - // UI_NavAction autocomp_action = {UI_NavActionFlag_ReplaceAndCommit, {0}, (UI_NavDeltaUnit)0, push_str8_copy(ui_build_arena(), item->string)}; - // ui_nav_action_list_push(ui_build_arena(), ui_nav_actions(), autocomp_action); + UI_Event move_back_evt = zero_struct; + move_back_evt.kind = UI_EventKind_Navigate; + move_back_evt.flags = UI_EventFlag_KeepMark; + move_back_evt.delta_2s32.x = -(S32)query.size; + ui_event_list_push(ui_build_arena(), &events, &move_back_evt); + UI_Event paste_evt = zero_struct; + paste_evt.kind = UI_EventKind_Text; + paste_evt.string = item->string; + ui_event_list_push(ui_build_arena(), &events, &paste_evt); + autocomp_box->default_nav_focus_hot_key = autocomp_box->default_nav_focus_active_key = autocomp_box->default_nav_focus_next_hot_key = autocomp_box->default_nav_focus_next_active_key = ui_key_zero(); + } + else if(item_box->flags & UI_BoxFlag_FocusHot && !(item_box->flags & UI_BoxFlag_FocusHotDisabled)) + { + UI_Event evt = zero_struct; + evt.kind = UI_EventKind_AutocompleteHint; + evt.string = item->string; + ui_event_list_push(ui_build_arena(), &events, &evt); } } } @@ -6633,7 +6657,7 @@ df_window_update_and_render(Arena *arena, DF_Window *ws, DF_CmdList *cmds) df_push_cmd__root(&p, df_cmd_spec_from_core_cmd_kind(DF_CoreCmdKind_Filter)); df_push_cmd__root(&p, df_cmd_spec_from_core_cmd_kind(DF_CoreCmdKind_Paste)); } - else if(n->v.string.size != 0) + else if(n->v.string.size != 0 && n->v.kind == UI_EventKind_Text) { ui_eat_event(events, n); df_push_cmd__root(&p, df_cmd_spec_from_core_cmd_kind(DF_CoreCmdKind_Filter)); @@ -8677,10 +8701,31 @@ df_autocomp_lister_item_array_sort__in_place(DF_AutoCompListerItemArray *array) qsort(array->v, array->count, sizeof(array->v[0]), (int (*)(const void*, const void*))df_autocomp_lister_item_qsort_compare); } -internal void -df_set_autocomp_lister_query(DF_Window *ws, UI_Key root_key, DF_CtrlCtx ctrl_ctx, DF_AutoCompListerFlags flags, String8 query) +internal String8 +df_autocomp_query_word_from_input_string_off(String8 input, U64 cursor_off) { + U64 word_start_off = 0; + for(U64 off = 0; off < input.size && off < cursor_off; off += 1) + { + if(!char_is_alpha(input.str[off]) && !char_is_digit(input.str[off], 10) && input.str[off] != '_') + { + word_start_off = off+1; + } + } + String8 query = str8_skip(input, word_start_off); + return query; +} + +internal void +df_set_autocomp_lister_query(DF_Window *ws, UI_Key root_key, DF_CtrlCtx ctrl_ctx, DF_AutoCompListerFlags flags, String8 input, U64 cursor_off) +{ + String8 query = df_autocomp_query_word_from_input_string_off(input, cursor_off); String8 current_query = str8(ws->autocomp_lister_query_buffer, ws->autocomp_lister_query_size); + if(cursor_off != ws->autocomp_cursor_off) + { + ws->autocomp_query_dirty = 1; + ws->autocomp_cursor_off = cursor_off; + } if(!str8_match(query, current_query, 0)) { ws->autocomp_force_closed = 0; @@ -12159,6 +12204,19 @@ df_line_edit(DF_LineEditFlags flags, S32 depth, FuzzyMatchRangeList *matches, Tx sig.f |= UI_SignalFlag_Commit; } + //- rjf: determine autocompletion string + String8 autocomplete_hint_string = {0}; + { + UI_EventList *events = ui_events(); + for(UI_EventNode *n = events->first; n != 0; n = n->next) + { + if(n->v.kind == UI_EventKind_AutocompleteHint) + { + autocomplete_hint_string = n->v.string; + } + } + } + //- rjf: take navigation actions for editing B32 changes_made = 0; if(!(flags & DF_LineEditFlag_DisableEdit) && (is_focus_active || focus_started)) @@ -12179,6 +12237,21 @@ df_line_edit(DF_LineEditFlags flags, S32 depth, FuzzyMatchRangeList *matches, Tx // rjf: map this action to an op UI_TxtOp op = ui_single_line_txt_op_from_event(scratch.arena, &n->v, edit_string, *cursor, *mark); + // rjf: any valid op & autocomplete hint? -> perform autocomplete first, then re-compute op + if(autocomplete_hint_string.size != 0) + { + String8 word_query = df_autocomp_query_word_from_input_string_off(edit_string, cursor->column-1); + U64 word_off = (U64)(word_query.str - edit_string.str); + String8 new_string = ui_push_string_replace_range(scratch.arena, edit_string, r1s64(word_off+1, word_off+1+word_query.size), autocomplete_hint_string); + new_string.size = Min(edit_buffer_size, new_string.size); + MemoryCopy(edit_buffer, new_string.str, new_string.size); + edit_string_size_out[0] = new_string.size; + *cursor = *mark = txt_pt(1, word_off+1+autocomplete_hint_string.size); + edit_string = str8(edit_buffer, edit_string_size_out[0]); + op = ui_single_line_txt_op_from_event(scratch.arena, &n->v, edit_string, *cursor, *mark); + MemoryZeroStruct(&autocomplete_hint_string); + } + // rjf: perform replace range if(!txt_pt_match(op.range.min, op.range.max) || op.replace.size != 0) { @@ -12268,6 +12341,44 @@ df_line_edit(DF_LineEditFlags flags, S32 depth, FuzzyMatchRangeList *matches, Tx ui_set_next_pref_width(ui_px(total_editstr_width+ui_top_font_size()*2, 0.f)); UI_Box *editstr_box = ui_build_box_from_stringf(UI_BoxFlag_DrawText|UI_BoxFlag_DisableTextTrunc, "###editstr"); D_FancyStringList code_fancy_strings = df_fancy_string_list_from_code_string(scratch.arena, 1.f, 0, ui_top_text_color(), edit_string); + if(autocomplete_hint_string.size != 0) + { + String8 query_word = df_autocomp_query_word_from_input_string_off(edit_string, cursor->column-1); + String8 autocomplete_append_string = str8_skip(autocomplete_hint_string, query_word.size); + U64 off = 0; + U64 cursor_off = cursor->column-1; + D_FancyStringNode *prev_n = 0; + for(D_FancyStringNode *n = code_fancy_strings.first; n != 0; n = n->next) + { + if(off <= cursor_off && cursor_off <= off+n->v.string.size) + { + prev_n = n; + break; + } + off += n->v.string.size; + } + { + D_FancyStringNode *autocomp_fstr_n = push_array(scratch.arena, D_FancyStringNode, 1); + D_FancyString *fstr = &autocomp_fstr_n->v; + fstr->font = ui_top_font(); + fstr->string = autocomplete_append_string; + fstr->color = ui_top_text_color(); + fstr->color.w *= 0.5f; + fstr->size = ui_top_font_size(); + autocomp_fstr_n->next = prev_n ? prev_n->next : 0; + prev_n ? (prev_n->next = autocomp_fstr_n) : (void)0; + if(prev_n == 0) + { + code_fancy_strings.first = code_fancy_strings.last = autocomp_fstr_n; + } + if(prev_n != 0 && prev_n->next == 0) + { + code_fancy_strings.last = autocomp_fstr_n; + } + code_fancy_strings.node_count += 1; + code_fancy_strings.total_size += autocomplete_hint_string.size; + } + } ui_box_equip_display_fancy_strings(editstr_box, &code_fancy_strings); UI_LineEditDrawData *draw_data = push_array(ui_build_arena(), UI_LineEditDrawData, 1); draw_data->edited_string = push_str8_copy(ui_build_arena(), edit_string); diff --git a/src/df/gfx/df_gfx.h b/src/df/gfx/df_gfx.h index 1ac1afa6..2e18bae8 100644 --- a/src/df/gfx/df_gfx.h +++ b/src/df/gfx/df_gfx.h @@ -525,9 +525,11 @@ struct DF_Window // rjf: autocomplete lister state U64 autocomp_last_frame_idx; B32 autocomp_force_closed; + B32 autocomp_query_dirty; UI_Key autocomp_root_key; DF_CtrlCtx autocomp_ctrl_ctx; DF_AutoCompListerFlags autocomp_lister_flags; + U64 autocomp_cursor_off; U8 autocomp_lister_query_buffer[1024]; U64 autocomp_lister_query_size; F32 autocomp_open_t; @@ -929,7 +931,8 @@ internal DF_AutoCompListerItemArray df_autocomp_lister_item_array_from_chunk_lis internal int df_autocomp_lister_item_qsort_compare(DF_AutoCompListerItem *a, DF_AutoCompListerItem *b); internal void df_autocomp_lister_item_array_sort__in_place(DF_AutoCompListerItemArray *array); -internal void df_set_autocomp_lister_query(DF_Window *ws, UI_Key root_key, DF_CtrlCtx ctrl_ctx, DF_AutoCompListerFlags flags, String8 query); +internal String8 df_autocomp_query_word_from_input_string_off(String8 input, U64 cursor_off); +internal void df_set_autocomp_lister_query(DF_Window *ws, UI_Key root_key, DF_CtrlCtx ctrl_ctx, DF_AutoCompListerFlags flags, String8 input, U64 cursor_off); //////////////////////////////// //~ rjf: Search Strings diff --git a/src/df/gfx/df_views.c b/src/df/gfx/df_views.c index 9c10ba6f..d32e4b79 100644 --- a/src/df/gfx/df_views.c +++ b/src/df/gfx/df_views.c @@ -1266,9 +1266,10 @@ df_eval_watch_view_build(DF_Window *ws, DF_Panel *panel, DF_View *view, DF_EvalW scratch_end(scratch); } - if(expr_editing_active && !edit_end) + if(expr_editing_active && !edit_end && txt_pt_match(ewv->input_cursor, ewv->input_mark)) { - df_set_autocomp_lister_query(ws, sig.box->key, ctrl_ctx, DF_AutoCompListerFlag_Locals, str8(ewv->input_buffer, ewv->input_size)); + String8 input = str8(ewv->input_buffer, ewv->input_size); + df_set_autocomp_lister_query(ws, sig.box->key, ctrl_ctx, DF_AutoCompListerFlag_Locals, input, ewv->input_cursor.column-1); } } @@ -1477,9 +1478,10 @@ df_eval_watch_view_build(DF_Window *ws, DF_Panel *panel, DF_View *view, DF_EvalW } // rjf: autocomplete lister - if(rule_editing_active && !edit_end) + if(rule_editing_active && !edit_end && txt_pt_match(ewv->input_cursor, ewv->input_mark)) { - df_set_autocomp_lister_query(ws, sig.box->key, ctrl_ctx, DF_AutoCompListerFlag_ViewRules, str8(ewv->input_buffer, ewv->input_size)); + String8 input = str8(ewv->input_buffer, ewv->input_size); + df_set_autocomp_lister_query(ws, sig.box->key, ctrl_ctx, DF_AutoCompListerFlag_ViewRules|DF_AutoCompListerFlag_Locals, input, ewv->input_cursor.column-1); } } } diff --git a/src/ui/ui_core.h b/src/ui/ui_core.h index 3f664541..3553eaa4 100644 --- a/src/ui/ui_core.h +++ b/src/ui/ui_core.h @@ -69,6 +69,7 @@ typedef enum UI_EventKind UI_EventKind_Edit, UI_EventKind_MouseMove, UI_EventKind_Scroll, + UI_EventKind_AutocompleteHint, UI_EventKind_COUNT } UI_EventKind; From 7c0f92ab3d518052275bebf7276b3f3eb17e4fa9 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Mon, 13 May 2024 15:45:35 -0700 Subject: [PATCH 10/30] sketch out view rule schemas; use them to determine autocompletion lister flags via partial parse of view rule input & matching to cursor; expand autocompletion lister to support lists of various things used in view rule arguments --- src/df/core/df_core.h | 1 + src/df/core/df_core.mdesk | 38 ++++---- src/df/core/generated/df_core.meta.c | 34 +++---- src/df/gfx/df_gfx.c | 140 +++++++++++++++++++++++++++ src/df/gfx/df_gfx.h | 11 ++- src/df/gfx/df_views.c | 7 +- 6 files changed, 191 insertions(+), 40 deletions(-) diff --git a/src/df/core/df_core.h b/src/df/core/df_core.h index 485cc0b9..302d030c 100644 --- a/src/df/core/df_core.h +++ b/src/df/core/df_core.h @@ -354,6 +354,7 @@ struct DF_CoreViewRuleSpecInfo { String8 string; String8 display_string; + String8 schema; String8 description; DF_CoreViewRuleSpecInfoFlags flags; DF_CoreViewRuleEvalResolutionHookFunctionType *eval_resolution; diff --git a/src/df/core/df_core.mdesk b/src/df/core/df_core.mdesk index c37e1d23..6d2f761c 100644 --- a/src/df/core/df_core.mdesk +++ b/src/df/core/df_core.mdesk @@ -497,26 +497,26 @@ DF_CoreCmdTable:// | | | // For any view rules in this layer which also have graphical features, they // are specified in both tables under the same name. -@table(name name_lower string ih ex er vb display_name docs description) +@table(name name_lower string ih ex er vb display_name docs schema description) DF_CoreViewRuleTable: { - {Null null "" - - - - "" - "" } - {Array array "array" - - x - "Array" x "Specifies that a pointer points to N elements, rather than only 1." } - {List list "list" - - - x "List" x "Specifies that some struct, union, or class forms the top of a linked list, and the member which points at the following element in the list." } - {ByteSwap bswap "bswap" x - x - "Byte Swap" x "Specifies that all integer primitives should be byte-swapped, such that their endianness is reversed." } - {BaseDec base_dec "dec" x - - - "Decimal Base (Base 10)" x "Specifies that all integral evaluations should appear in base-10 form." } - {BaseBin base_bin "bin" x - - - "Binary Base (Base 2)" x "Specifies that all integral evaluations should appear in base-2 form." } - {BaseOct base_oct "oct" x - - - "Octal Base (Base 8)" x "Specifies that all integral evaluations should appear in base-8 form." } - {BaseHex base_hex "hex" x - - - "Hexadecimal Base (Base 16)" x "Specifies that all integral evaluations should appear in base-16 form." } - {Only only "only" x - - x "Only Specified Members" x "Specifies that only the specified members should appear in struct, union, or class evaluations." } - {Omit omit "omit" x - - x "Omit Specified Members" x "Omits a list of member names from appearing in struct, union, or class evaluations." } - {NoAddr no_addr "no_addr" x - - - "Disable Address Values" x "Displays only what pointers point to, if possible, without the pointer's address value." } - {RGBA rgba "rgba" - x - x "Color (RGBA)" x "Displays as a color, interpreting the data as encoding R, G, B, and A values." } - {Text text "text" - x - x "Text" x "Displays as text." } - {Disasm disasm "disasm" - x - x "Disassembly" x "Displays as disassembled instructions, interpreting the data as raw machine code." } - {Graph graph "graph" - x - x "Graph" x "Displays as a pointer graph, visualizing nodes and edges formed by pointers directly." } - {Bitmap bitmap "bitmap" - x - x "Bitmap" x "Displays as a bitmap, interpreting the data as raw pixel data." } - {Geo geo "geo" - x - x "Geometry" x "Displays as geometry, interpreting the data as vertex data." } + {Null null "" - - - - "" - "" "" } + {Array array "array" - - x - "Array" x "x:{expr}" "Specifies that a pointer points to N elements, rather than only 1." } + {List list "list" - - - x "List" x "x:{member}" "Specifies that some struct, union, or class forms the top of a linked list, and the member which points at the following element in the list." } + {ByteSwap bswap "bswap" x - x - "Byte Swap" x "" "Specifies that all integer primitives should be byte-swapped, such that their endianness is reversed." } + {BaseDec base_dec "dec" x - - - "Decimal Base (Base 10)" x "" "Specifies that all integral evaluations should appear in base-10 form." } + {BaseBin base_bin "bin" x - - - "Binary Base (Base 2)" x "" "Specifies that all integral evaluations should appear in base-2 form." } + {BaseOct base_oct "oct" x - - - "Octal Base (Base 8)" x "" "Specifies that all integral evaluations should appear in base-8 form." } + {BaseHex base_hex "hex" x - - - "Hexadecimal Base (Base 16)" x "" "Specifies that all integral evaluations should appear in base-16 form." } + {Only only "only" x - - x "Only Specified Members" x "x:{member}" "Specifies that only the specified members should appear in struct, union, or class evaluations." } + {Omit omit "omit" x - - x "Omit Specified Members" x "x:{member}" "Omits a list of member names from appearing in struct, union, or class evaluations." } + {NoAddr no_addr "no_addr" x - - - "Disable Address Values" x "" "Displays only what pointers point to, if possible, without the pointer's address value." } + {RGBA rgba "rgba" - x - x "Color (RGBA)" x "" "Displays as a color, interpreting the data as encoding R, G, B, and A values." } + {Text text "text" - x - x "Text" x "x:{'lang':lang, 'size':expr}" "Displays as text." } + {Disasm disasm "disasm" - x - x "Disassembly" x "x:{'arch':arch, 'size':expr}" "Displays as disassembled instructions, interpreting the data as raw machine code." } + {Graph graph "graph" - x - x "Graph" x "" "Displays as a pointer graph, visualizing nodes and edges formed by pointers directly." } + {Bitmap bitmap "bitmap" - x - x "Bitmap" x "x:{'w':expr, 'h':expr, 'fmt':tex2dformat}" "Displays as a bitmap, interpreting the data as raw pixel data." } + {Geo geo "geo" - x - x "Geometry" x "x:{'count':expr, 'vertices_base':expr, 'vertices_size':expr}" "Displays as geometry, interpreting the data as vertex data." } } //////////////////////////////// @@ -1825,7 +1825,7 @@ DF_DevToggleTable: @data(DF_CoreViewRuleSpecInfo) @c_file df_g_core_view_rule_spec_info_table: { @expand(DF_CoreViewRuleTable a) - ```{str8_lit_comp("$(a.string)"), str8_lit_comp("$(a.display_name)"), str8_lit_comp("$(a.description)"), (DF_CoreViewRuleSpecInfoFlag_Inherited*$(a.ih == "x"))|(DF_CoreViewRuleSpecInfoFlag_Expandable*$(a.ex == "x"))|(DF_CoreViewRuleSpecInfoFlag_EvalResolution*$(a.er == "x"))|(DF_CoreViewRuleSpecInfoFlag_VizBlockProd*$(a.vb == "x")), $(a.er == "x" -> "DF_CORE_VIEW_RULE_EVAL_RESOLUTION_FUNCTION_NAME("..a.name_lower..")") $(a.er != "x" -> 0), $(a.vb == "x" -> "DF_CORE_VIEW_RULE_VIZ_BLOCK_PROD_FUNCTION_NAME("..a.name_lower..")") $(a.vb != "x" -> 0), }```; + ```{str8_lit_comp("$(a.string)"), str8_lit_comp("$(a.display_name)"), str8_lit_comp("$(a.schema)"), str8_lit_comp("$(a.description)"), (DF_CoreViewRuleSpecInfoFlag_Inherited*$(a.ih == "x"))|(DF_CoreViewRuleSpecInfoFlag_Expandable*$(a.ex == "x"))|(DF_CoreViewRuleSpecInfoFlag_EvalResolution*$(a.er == "x"))|(DF_CoreViewRuleSpecInfoFlag_VizBlockProd*$(a.vb == "x")), $(a.er == "x" -> "DF_CORE_VIEW_RULE_EVAL_RESOLUTION_FUNCTION_NAME("..a.name_lower..")") $(a.er != "x" -> 0), $(a.vb == "x" -> "DF_CORE_VIEW_RULE_VIZ_BLOCK_PROD_FUNCTION_NAME("..a.name_lower..")") $(a.vb != "x" -> 0), }```; } //- rjf: icon kinds diff --git a/src/df/core/generated/df_core.meta.c b/src/df/core/generated/df_core.meta.c index 4057bad1..739df9ae 100644 --- a/src/df/core/generated/df_core.meta.c +++ b/src/df/core/generated/df_core.meta.c @@ -438,23 +438,23 @@ DF_CmdSpecInfo df_g_core_cmd_kind_spec_info_table[215] = DF_CoreViewRuleSpecInfo df_g_core_view_rule_spec_info_table[17] = { -{str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp(""), (DF_CoreViewRuleSpecInfoFlag_Inherited*0)|(DF_CoreViewRuleSpecInfoFlag_Expandable*0)|(DF_CoreViewRuleSpecInfoFlag_EvalResolution*0)|(DF_CoreViewRuleSpecInfoFlag_VizBlockProd*0), 0, 0, }, -{str8_lit_comp("array"), str8_lit_comp("Array"), str8_lit_comp("Specifies that a pointer points to N elements, rather than only 1."), (DF_CoreViewRuleSpecInfoFlag_Inherited*0)|(DF_CoreViewRuleSpecInfoFlag_Expandable*0)|(DF_CoreViewRuleSpecInfoFlag_EvalResolution*1)|(DF_CoreViewRuleSpecInfoFlag_VizBlockProd*0), DF_CORE_VIEW_RULE_EVAL_RESOLUTION_FUNCTION_NAME(array) , 0, }, -{str8_lit_comp("list"), str8_lit_comp("List"), str8_lit_comp("Specifies that some struct, union, or class forms the top of a linked list, and the member which points at the following element in the list."), (DF_CoreViewRuleSpecInfoFlag_Inherited*0)|(DF_CoreViewRuleSpecInfoFlag_Expandable*0)|(DF_CoreViewRuleSpecInfoFlag_EvalResolution*0)|(DF_CoreViewRuleSpecInfoFlag_VizBlockProd*1), 0, DF_CORE_VIEW_RULE_VIZ_BLOCK_PROD_FUNCTION_NAME(list) , }, -{str8_lit_comp("bswap"), str8_lit_comp("Byte Swap"), str8_lit_comp("Specifies that all integer primitives should be byte-swapped, such that their endianness is reversed."), (DF_CoreViewRuleSpecInfoFlag_Inherited*1)|(DF_CoreViewRuleSpecInfoFlag_Expandable*0)|(DF_CoreViewRuleSpecInfoFlag_EvalResolution*1)|(DF_CoreViewRuleSpecInfoFlag_VizBlockProd*0), DF_CORE_VIEW_RULE_EVAL_RESOLUTION_FUNCTION_NAME(bswap) , 0, }, -{str8_lit_comp("dec"), str8_lit_comp("Decimal Base (Base 10)"), str8_lit_comp("Specifies that all integral evaluations should appear in base-10 form."), (DF_CoreViewRuleSpecInfoFlag_Inherited*1)|(DF_CoreViewRuleSpecInfoFlag_Expandable*0)|(DF_CoreViewRuleSpecInfoFlag_EvalResolution*0)|(DF_CoreViewRuleSpecInfoFlag_VizBlockProd*0), 0, 0, }, -{str8_lit_comp("bin"), str8_lit_comp("Binary Base (Base 2)"), str8_lit_comp("Specifies that all integral evaluations should appear in base-2 form."), (DF_CoreViewRuleSpecInfoFlag_Inherited*1)|(DF_CoreViewRuleSpecInfoFlag_Expandable*0)|(DF_CoreViewRuleSpecInfoFlag_EvalResolution*0)|(DF_CoreViewRuleSpecInfoFlag_VizBlockProd*0), 0, 0, }, -{str8_lit_comp("oct"), str8_lit_comp("Octal Base (Base 8)"), str8_lit_comp("Specifies that all integral evaluations should appear in base-8 form."), (DF_CoreViewRuleSpecInfoFlag_Inherited*1)|(DF_CoreViewRuleSpecInfoFlag_Expandable*0)|(DF_CoreViewRuleSpecInfoFlag_EvalResolution*0)|(DF_CoreViewRuleSpecInfoFlag_VizBlockProd*0), 0, 0, }, -{str8_lit_comp("hex"), str8_lit_comp("Hexadecimal Base (Base 16)"), str8_lit_comp("Specifies that all integral evaluations should appear in base-16 form."), (DF_CoreViewRuleSpecInfoFlag_Inherited*1)|(DF_CoreViewRuleSpecInfoFlag_Expandable*0)|(DF_CoreViewRuleSpecInfoFlag_EvalResolution*0)|(DF_CoreViewRuleSpecInfoFlag_VizBlockProd*0), 0, 0, }, -{str8_lit_comp("only"), str8_lit_comp("Only Specified Members"), str8_lit_comp("Specifies that only the specified members should appear in struct, union, or class evaluations."), (DF_CoreViewRuleSpecInfoFlag_Inherited*1)|(DF_CoreViewRuleSpecInfoFlag_Expandable*0)|(DF_CoreViewRuleSpecInfoFlag_EvalResolution*0)|(DF_CoreViewRuleSpecInfoFlag_VizBlockProd*1), 0, DF_CORE_VIEW_RULE_VIZ_BLOCK_PROD_FUNCTION_NAME(only) , }, -{str8_lit_comp("omit"), str8_lit_comp("Omit Specified Members"), str8_lit_comp("Omits a list of member names from appearing in struct, union, or class evaluations."), (DF_CoreViewRuleSpecInfoFlag_Inherited*1)|(DF_CoreViewRuleSpecInfoFlag_Expandable*0)|(DF_CoreViewRuleSpecInfoFlag_EvalResolution*0)|(DF_CoreViewRuleSpecInfoFlag_VizBlockProd*1), 0, DF_CORE_VIEW_RULE_VIZ_BLOCK_PROD_FUNCTION_NAME(omit) , }, -{str8_lit_comp("no_addr"), str8_lit_comp("Disable Address Values"), str8_lit_comp("Displays only what pointers point to, if possible, without the pointer's address value."), (DF_CoreViewRuleSpecInfoFlag_Inherited*1)|(DF_CoreViewRuleSpecInfoFlag_Expandable*0)|(DF_CoreViewRuleSpecInfoFlag_EvalResolution*0)|(DF_CoreViewRuleSpecInfoFlag_VizBlockProd*0), 0, 0, }, -{str8_lit_comp("rgba"), str8_lit_comp("Color (RGBA)"), str8_lit_comp("Displays as a color, interpreting the data as encoding R, G, B, and A values."), (DF_CoreViewRuleSpecInfoFlag_Inherited*0)|(DF_CoreViewRuleSpecInfoFlag_Expandable*1)|(DF_CoreViewRuleSpecInfoFlag_EvalResolution*0)|(DF_CoreViewRuleSpecInfoFlag_VizBlockProd*1), 0, DF_CORE_VIEW_RULE_VIZ_BLOCK_PROD_FUNCTION_NAME(rgba) , }, -{str8_lit_comp("text"), str8_lit_comp("Text"), str8_lit_comp("Displays as text."), (DF_CoreViewRuleSpecInfoFlag_Inherited*0)|(DF_CoreViewRuleSpecInfoFlag_Expandable*1)|(DF_CoreViewRuleSpecInfoFlag_EvalResolution*0)|(DF_CoreViewRuleSpecInfoFlag_VizBlockProd*1), 0, DF_CORE_VIEW_RULE_VIZ_BLOCK_PROD_FUNCTION_NAME(text) , }, -{str8_lit_comp("disasm"), str8_lit_comp("Disassembly"), str8_lit_comp("Displays as disassembled instructions, interpreting the data as raw machine code."), (DF_CoreViewRuleSpecInfoFlag_Inherited*0)|(DF_CoreViewRuleSpecInfoFlag_Expandable*1)|(DF_CoreViewRuleSpecInfoFlag_EvalResolution*0)|(DF_CoreViewRuleSpecInfoFlag_VizBlockProd*1), 0, DF_CORE_VIEW_RULE_VIZ_BLOCK_PROD_FUNCTION_NAME(disasm) , }, -{str8_lit_comp("graph"), str8_lit_comp("Graph"), str8_lit_comp("Displays as a pointer graph, visualizing nodes and edges formed by pointers directly."), (DF_CoreViewRuleSpecInfoFlag_Inherited*0)|(DF_CoreViewRuleSpecInfoFlag_Expandable*1)|(DF_CoreViewRuleSpecInfoFlag_EvalResolution*0)|(DF_CoreViewRuleSpecInfoFlag_VizBlockProd*1), 0, DF_CORE_VIEW_RULE_VIZ_BLOCK_PROD_FUNCTION_NAME(graph) , }, -{str8_lit_comp("bitmap"), str8_lit_comp("Bitmap"), str8_lit_comp("Displays as a bitmap, interpreting the data as raw pixel data."), (DF_CoreViewRuleSpecInfoFlag_Inherited*0)|(DF_CoreViewRuleSpecInfoFlag_Expandable*1)|(DF_CoreViewRuleSpecInfoFlag_EvalResolution*0)|(DF_CoreViewRuleSpecInfoFlag_VizBlockProd*1), 0, DF_CORE_VIEW_RULE_VIZ_BLOCK_PROD_FUNCTION_NAME(bitmap) , }, -{str8_lit_comp("geo"), str8_lit_comp("Geometry"), str8_lit_comp("Displays as geometry, interpreting the data as vertex data."), (DF_CoreViewRuleSpecInfoFlag_Inherited*0)|(DF_CoreViewRuleSpecInfoFlag_Expandable*1)|(DF_CoreViewRuleSpecInfoFlag_EvalResolution*0)|(DF_CoreViewRuleSpecInfoFlag_VizBlockProd*1), 0, DF_CORE_VIEW_RULE_VIZ_BLOCK_PROD_FUNCTION_NAME(geo) , }, +{str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp(""), (DF_CoreViewRuleSpecInfoFlag_Inherited*0)|(DF_CoreViewRuleSpecInfoFlag_Expandable*0)|(DF_CoreViewRuleSpecInfoFlag_EvalResolution*0)|(DF_CoreViewRuleSpecInfoFlag_VizBlockProd*0), 0, 0, }, +{str8_lit_comp("array"), str8_lit_comp("Array"), str8_lit_comp("x:{expr}"), str8_lit_comp("Specifies that a pointer points to N elements, rather than only 1."), (DF_CoreViewRuleSpecInfoFlag_Inherited*0)|(DF_CoreViewRuleSpecInfoFlag_Expandable*0)|(DF_CoreViewRuleSpecInfoFlag_EvalResolution*1)|(DF_CoreViewRuleSpecInfoFlag_VizBlockProd*0), DF_CORE_VIEW_RULE_EVAL_RESOLUTION_FUNCTION_NAME(array) , 0, }, +{str8_lit_comp("list"), str8_lit_comp("List"), str8_lit_comp("x:{member}"), str8_lit_comp("Specifies that some struct, union, or class forms the top of a linked list, and the member which points at the following element in the list."), (DF_CoreViewRuleSpecInfoFlag_Inherited*0)|(DF_CoreViewRuleSpecInfoFlag_Expandable*0)|(DF_CoreViewRuleSpecInfoFlag_EvalResolution*0)|(DF_CoreViewRuleSpecInfoFlag_VizBlockProd*1), 0, DF_CORE_VIEW_RULE_VIZ_BLOCK_PROD_FUNCTION_NAME(list) , }, +{str8_lit_comp("bswap"), str8_lit_comp("Byte Swap"), str8_lit_comp(""), str8_lit_comp("Specifies that all integer primitives should be byte-swapped, such that their endianness is reversed."), (DF_CoreViewRuleSpecInfoFlag_Inherited*1)|(DF_CoreViewRuleSpecInfoFlag_Expandable*0)|(DF_CoreViewRuleSpecInfoFlag_EvalResolution*1)|(DF_CoreViewRuleSpecInfoFlag_VizBlockProd*0), DF_CORE_VIEW_RULE_EVAL_RESOLUTION_FUNCTION_NAME(bswap) , 0, }, +{str8_lit_comp("dec"), str8_lit_comp("Decimal Base (Base 10)"), str8_lit_comp(""), str8_lit_comp("Specifies that all integral evaluations should appear in base-10 form."), (DF_CoreViewRuleSpecInfoFlag_Inherited*1)|(DF_CoreViewRuleSpecInfoFlag_Expandable*0)|(DF_CoreViewRuleSpecInfoFlag_EvalResolution*0)|(DF_CoreViewRuleSpecInfoFlag_VizBlockProd*0), 0, 0, }, +{str8_lit_comp("bin"), str8_lit_comp("Binary Base (Base 2)"), str8_lit_comp(""), str8_lit_comp("Specifies that all integral evaluations should appear in base-2 form."), (DF_CoreViewRuleSpecInfoFlag_Inherited*1)|(DF_CoreViewRuleSpecInfoFlag_Expandable*0)|(DF_CoreViewRuleSpecInfoFlag_EvalResolution*0)|(DF_CoreViewRuleSpecInfoFlag_VizBlockProd*0), 0, 0, }, +{str8_lit_comp("oct"), str8_lit_comp("Octal Base (Base 8)"), str8_lit_comp(""), str8_lit_comp("Specifies that all integral evaluations should appear in base-8 form."), (DF_CoreViewRuleSpecInfoFlag_Inherited*1)|(DF_CoreViewRuleSpecInfoFlag_Expandable*0)|(DF_CoreViewRuleSpecInfoFlag_EvalResolution*0)|(DF_CoreViewRuleSpecInfoFlag_VizBlockProd*0), 0, 0, }, +{str8_lit_comp("hex"), str8_lit_comp("Hexadecimal Base (Base 16)"), str8_lit_comp(""), str8_lit_comp("Specifies that all integral evaluations should appear in base-16 form."), (DF_CoreViewRuleSpecInfoFlag_Inherited*1)|(DF_CoreViewRuleSpecInfoFlag_Expandable*0)|(DF_CoreViewRuleSpecInfoFlag_EvalResolution*0)|(DF_CoreViewRuleSpecInfoFlag_VizBlockProd*0), 0, 0, }, +{str8_lit_comp("only"), str8_lit_comp("Only Specified Members"), str8_lit_comp("x:{member}"), str8_lit_comp("Specifies that only the specified members should appear in struct, union, or class evaluations."), (DF_CoreViewRuleSpecInfoFlag_Inherited*1)|(DF_CoreViewRuleSpecInfoFlag_Expandable*0)|(DF_CoreViewRuleSpecInfoFlag_EvalResolution*0)|(DF_CoreViewRuleSpecInfoFlag_VizBlockProd*1), 0, DF_CORE_VIEW_RULE_VIZ_BLOCK_PROD_FUNCTION_NAME(only) , }, +{str8_lit_comp("omit"), str8_lit_comp("Omit Specified Members"), str8_lit_comp("x:{member}"), str8_lit_comp("Omits a list of member names from appearing in struct, union, or class evaluations."), (DF_CoreViewRuleSpecInfoFlag_Inherited*1)|(DF_CoreViewRuleSpecInfoFlag_Expandable*0)|(DF_CoreViewRuleSpecInfoFlag_EvalResolution*0)|(DF_CoreViewRuleSpecInfoFlag_VizBlockProd*1), 0, DF_CORE_VIEW_RULE_VIZ_BLOCK_PROD_FUNCTION_NAME(omit) , }, +{str8_lit_comp("no_addr"), str8_lit_comp("Disable Address Values"), str8_lit_comp(""), str8_lit_comp("Displays only what pointers point to, if possible, without the pointer's address value."), (DF_CoreViewRuleSpecInfoFlag_Inherited*1)|(DF_CoreViewRuleSpecInfoFlag_Expandable*0)|(DF_CoreViewRuleSpecInfoFlag_EvalResolution*0)|(DF_CoreViewRuleSpecInfoFlag_VizBlockProd*0), 0, 0, }, +{str8_lit_comp("rgba"), str8_lit_comp("Color (RGBA)"), str8_lit_comp(""), str8_lit_comp("Displays as a color, interpreting the data as encoding R, G, B, and A values."), (DF_CoreViewRuleSpecInfoFlag_Inherited*0)|(DF_CoreViewRuleSpecInfoFlag_Expandable*1)|(DF_CoreViewRuleSpecInfoFlag_EvalResolution*0)|(DF_CoreViewRuleSpecInfoFlag_VizBlockProd*1), 0, DF_CORE_VIEW_RULE_VIZ_BLOCK_PROD_FUNCTION_NAME(rgba) , }, +{str8_lit_comp("text"), str8_lit_comp("Text"), str8_lit_comp("x:{'lang':lang, 'size':expr}"), str8_lit_comp("Displays as text."), (DF_CoreViewRuleSpecInfoFlag_Inherited*0)|(DF_CoreViewRuleSpecInfoFlag_Expandable*1)|(DF_CoreViewRuleSpecInfoFlag_EvalResolution*0)|(DF_CoreViewRuleSpecInfoFlag_VizBlockProd*1), 0, DF_CORE_VIEW_RULE_VIZ_BLOCK_PROD_FUNCTION_NAME(text) , }, +{str8_lit_comp("disasm"), str8_lit_comp("Disassembly"), str8_lit_comp("x:{'arch':arch, 'size':expr}"), str8_lit_comp("Displays as disassembled instructions, interpreting the data as raw machine code."), (DF_CoreViewRuleSpecInfoFlag_Inherited*0)|(DF_CoreViewRuleSpecInfoFlag_Expandable*1)|(DF_CoreViewRuleSpecInfoFlag_EvalResolution*0)|(DF_CoreViewRuleSpecInfoFlag_VizBlockProd*1), 0, DF_CORE_VIEW_RULE_VIZ_BLOCK_PROD_FUNCTION_NAME(disasm) , }, +{str8_lit_comp("graph"), str8_lit_comp("Graph"), str8_lit_comp(""), str8_lit_comp("Displays as a pointer graph, visualizing nodes and edges formed by pointers directly."), (DF_CoreViewRuleSpecInfoFlag_Inherited*0)|(DF_CoreViewRuleSpecInfoFlag_Expandable*1)|(DF_CoreViewRuleSpecInfoFlag_EvalResolution*0)|(DF_CoreViewRuleSpecInfoFlag_VizBlockProd*1), 0, DF_CORE_VIEW_RULE_VIZ_BLOCK_PROD_FUNCTION_NAME(graph) , }, +{str8_lit_comp("bitmap"), str8_lit_comp("Bitmap"), str8_lit_comp("x:{'w':expr, 'h':expr, 'fmt':tex2dformat}"), str8_lit_comp("Displays as a bitmap, interpreting the data as raw pixel data."), (DF_CoreViewRuleSpecInfoFlag_Inherited*0)|(DF_CoreViewRuleSpecInfoFlag_Expandable*1)|(DF_CoreViewRuleSpecInfoFlag_EvalResolution*0)|(DF_CoreViewRuleSpecInfoFlag_VizBlockProd*1), 0, DF_CORE_VIEW_RULE_VIZ_BLOCK_PROD_FUNCTION_NAME(bitmap) , }, +{str8_lit_comp("geo"), str8_lit_comp("Geometry"), str8_lit_comp("x:{'count':expr, 'vertices_base':expr, 'vertices_size':expr}"), str8_lit_comp("Displays as geometry, interpreting the data as vertex data."), (DF_CoreViewRuleSpecInfoFlag_Inherited*0)|(DF_CoreViewRuleSpecInfoFlag_Expandable*1)|(DF_CoreViewRuleSpecInfoFlag_EvalResolution*0)|(DF_CoreViewRuleSpecInfoFlag_VizBlockProd*1), 0, DF_CORE_VIEW_RULE_VIZ_BLOCK_PROD_FUNCTION_NAME(geo) , }, }; String8 df_g_icon_kind_text_table[69] = diff --git a/src/df/gfx/df_gfx.c b/src/df/gfx/df_gfx.c index 64aabcd2..1d6d20eb 100644 --- a/src/df/gfx/df_gfx.c +++ b/src/df/gfx/df_gfx.c @@ -4218,6 +4218,7 @@ df_window_update_and_render(Arena *arena, DF_Window *ws, DF_CmdList *cmds) //- rjf: gather lister items DF_AutoCompListerItemChunkList item_list = {0}; { + //- rjf: gather locals if(ws->autocomp_lister_flags & DF_AutoCompListerFlag_Locals) { EVAL_String2NumMap *locals_map = df_query_cached_locals_map_from_binary_voff(binary, thread_rip_voff); @@ -4235,6 +4236,8 @@ df_window_update_and_render(Arena *arena, DF_Window *ws, DF_CmdList *cmds) } } } + + //- rjf: gather registers if(ws->autocomp_lister_flags & DF_AutoCompListerFlag_Registers) { Architecture arch = df_architecture_from_entity(thread); @@ -4275,6 +4278,8 @@ df_window_update_and_render(Arena *arena, DF_Window *ws, DF_CmdList *cmds) } } } + + //- rjf: gather view rules if(ws->autocomp_lister_flags & DF_AutoCompListerFlag_ViewRules) { for(U64 slot_idx = 0; slot_idx < df_state->view_rule_spec_table_size; slot_idx += 1) @@ -4294,6 +4299,60 @@ df_window_update_and_render(Arena *arena, DF_Window *ws, DF_CmdList *cmds) } } } + + //- rjf: gather languages + if(ws->autocomp_lister_flags & DF_AutoCompListerFlag_Languages) + { + for(EachNonZeroEnumVal(TXT_LangKind, lang)) + { + DF_AutoCompListerItem item = {0}; + { + item.string = txt_extension_from_lang_kind(lang); + item.kind_string = str8_lit("Language"); + item.matches = fuzzy_match_find(scratch.arena, query, item.string); + } + if(query.size == 0 || item.matches.count != 0) + { + df_autocomp_lister_item_chunk_list_push(scratch.arena, &item_list, 256, &item); + } + } + } + + //- rjf: gather architectures + if(ws->autocomp_lister_flags & DF_AutoCompListerFlag_Architectures) + { + for(EachNonZeroEnumVal(Architecture, arch)) + { + DF_AutoCompListerItem item = {0}; + { + item.string = string_from_architecture(arch); + item.kind_string = str8_lit("Architecture"); + item.matches = fuzzy_match_find(scratch.arena, query, item.string); + } + if(query.size == 0 || item.matches.count != 0) + { + df_autocomp_lister_item_chunk_list_push(scratch.arena, &item_list, 256, &item); + } + } + } + + //- rjf: gather tex2dformats + if(ws->autocomp_lister_flags & DF_AutoCompListerFlag_Tex2DFormats) + { + for(EachNonZeroEnumVal(R_Tex2DFormat, fmt)) + { + DF_AutoCompListerItem item = {0}; + { + item.string = lower_from_str8(scratch.arena, r_tex2d_format_display_string_table[fmt]); + item.kind_string = str8_lit("Format"); + item.matches = fuzzy_match_find(scratch.arena, query, item.string); + } + if(query.size == 0 || item.matches.count != 0) + { + df_autocomp_lister_item_chunk_list_push(scratch.arena, &item_list, 256, &item); + } + } + } } //- rjf: lister item list -> sorted array @@ -8716,6 +8775,87 @@ df_autocomp_query_word_from_input_string_off(String8 input, U64 cursor_off) return query; } +internal DF_AutoCompListerFlags +df_view_rule_autocomp_lister_flags_from_input_cursor(String8 string, U64 cursor_off) +{ + DF_AutoCompListerFlags flags = 0; + { + Temp scratch = scratch_begin(0, 0); + + //- rjf: do partial parse of input + MD_TokenizeResult input_tokenize = md_tokenize_from_text(scratch.arena, string); + + //- rjf: find descension steps to cursor + typedef struct DescendStep DescendStep; + struct DescendStep + { + DescendStep *next; + String8 string; + }; + DescendStep *first_step = 0; + DescendStep *last_step = 0; + DescendStep *free_step = 0; + for(U64 idx = 0; idx < input_tokenize.tokens.count; idx += 1) + { + MD_Token *token = &input_tokenize.tokens.v[idx]; + if(token->range.min < cursor_off && token->flags & (MD_TokenFlag_Identifier|MD_TokenFlag_StringLiteral)) + { + DescendStep *step = free_step; + if(step != 0) + { + SLLStackPop(free_step); + MemoryZeroStruct(step); + } + else + { + step = push_array(scratch.arena, DescendStep, 1); + } + step->string = str8_substr(string, token->range); + SLLQueuePush(first_step, last_step, step); + } + } + + //- rjf: map view rule root to spec + DF_CoreViewRuleSpec *spec = df_core_view_rule_spec_from_string(first_step ? first_step->string : str8_zero()); + + //- rjf: do parse of schema + MD_TokenizeResult schema_tokenize = md_tokenize_from_text(scratch.arena, spec->info.schema); + MD_ParseResult schema_parse = md_parse_from_text_tokens(scratch.arena, str8_zero(), spec->info.schema, schema_tokenize.tokens); + MD_Node *schema_rule_root = md_child_from_string(schema_parse.root, str8_lit("x"), 0); + + //- rjf: follow schema according to descend steps, gather flags from schema node matching cursor node + if(first_step != 0) + { + MD_Node *schema_node = schema_rule_root; + for(DescendStep *step = first_step->next;;) + { + if(md_node_is_nil(schema_node->first)) + { + if(str8_match(schema_node->string, str8_lit("expr"), StringMatchFlag_CaseInsensitive)) {flags |= DF_AutoCompListerFlag_Locals;} + if(str8_match(schema_node->string, str8_lit("member"), StringMatchFlag_CaseInsensitive)) {flags |= DF_AutoCompListerFlag_Members;} + if(str8_match(schema_node->string, str8_lit("lang"), StringMatchFlag_CaseInsensitive)) {flags |= DF_AutoCompListerFlag_Languages;} + if(str8_match(schema_node->string, str8_lit("arch"), StringMatchFlag_CaseInsensitive)) {flags |= DF_AutoCompListerFlag_Architectures;} + if(str8_match(schema_node->string, str8_lit("tex2dformat"), StringMatchFlag_CaseInsensitive)) {flags |= DF_AutoCompListerFlag_Tex2DFormats;} + break; + } + if(step != 0) + { + MD_Node *next_node = md_child_from_string(schema_node, step->string, StringMatchFlag_CaseInsensitive); + schema_node = next_node; + step = step->next; + } + else + { + schema_node = schema_node->first; + } + } + } + + scratch_end(scratch); + } + return flags; +} + internal void df_set_autocomp_lister_query(DF_Window *ws, UI_Key root_key, DF_CtrlCtx ctrl_ctx, DF_AutoCompListerFlags flags, String8 input, U64 cursor_off) { diff --git a/src/df/gfx/df_gfx.h b/src/df/gfx/df_gfx.h index 2e18bae8..f26138ee 100644 --- a/src/df/gfx/df_gfx.h +++ b/src/df/gfx/df_gfx.h @@ -442,9 +442,13 @@ struct DF_CodeSliceSignal typedef U32 DF_AutoCompListerFlags; enum { - DF_AutoCompListerFlag_Locals = (1<<0), - DF_AutoCompListerFlag_Registers = (1<<1), - DF_AutoCompListerFlag_ViewRules = (1<<2), + DF_AutoCompListerFlag_Locals = (1<<0), + DF_AutoCompListerFlag_Registers = (1<<1), + DF_AutoCompListerFlag_ViewRules = (1<<2), + DF_AutoCompListerFlag_Members = (1<<3), + DF_AutoCompListerFlag_Languages = (1<<4), + DF_AutoCompListerFlag_Architectures = (1<<5), + DF_AutoCompListerFlag_Tex2DFormats = (1<<6), }; typedef struct DF_AutoCompListerItem DF_AutoCompListerItem; @@ -932,6 +936,7 @@ internal int df_autocomp_lister_item_qsort_compare(DF_AutoCompListerItem *a, DF_ internal void df_autocomp_lister_item_array_sort__in_place(DF_AutoCompListerItemArray *array); internal String8 df_autocomp_query_word_from_input_string_off(String8 input, U64 cursor_off); +internal DF_AutoCompListerFlags df_view_rule_autocomp_lister_flags_from_input_cursor(String8 string, U64 cursor_off); internal void df_set_autocomp_lister_query(DF_Window *ws, UI_Key root_key, DF_CtrlCtx ctrl_ctx, DF_AutoCompListerFlags flags, String8 input, U64 cursor_off); //////////////////////////////// diff --git a/src/df/gfx/df_views.c b/src/df/gfx/df_views.c index d32e4b79..787c6465 100644 --- a/src/df/gfx/df_views.c +++ b/src/df/gfx/df_views.c @@ -1481,7 +1481,12 @@ df_eval_watch_view_build(DF_Window *ws, DF_Panel *panel, DF_View *view, DF_EvalW if(rule_editing_active && !edit_end && txt_pt_match(ewv->input_cursor, ewv->input_mark)) { String8 input = str8(ewv->input_buffer, ewv->input_size); - df_set_autocomp_lister_query(ws, sig.box->key, ctrl_ctx, DF_AutoCompListerFlag_ViewRules|DF_AutoCompListerFlag_Locals, input, ewv->input_cursor.column-1); + DF_AutoCompListerFlags flags = df_view_rule_autocomp_lister_flags_from_input_cursor(input, ewv->input_cursor.column-1); + if(flags == 0) + { + flags = DF_AutoCompListerFlag_ViewRules; + } + df_set_autocomp_lister_query(ws, sig.box->key, ctrl_ctx, flags, input, ewv->input_cursor.column-1); } } } From 90fc289ef0f64498f01697e51057dc4d320e655b Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Mon, 13 May 2024 16:19:32 -0700 Subject: [PATCH 11/30] extend autocompletion lister parameter detection, based on cursor position; feed through view rule parameters; correctly support cursor position with multi-arguments, regardless of which argument the cursor is on --- src/df/gfx/df_gfx.c | 130 ++++++++++++++++++++++++++++++++---------- src/df/gfx/df_gfx.h | 23 +++++--- src/df/gfx/df_views.c | 11 ++-- 3 files changed, 123 insertions(+), 41 deletions(-) diff --git a/src/df/gfx/df_gfx.c b/src/df/gfx/df_gfx.c index 1d6d20eb..9d80ac9e 100644 --- a/src/df/gfx/df_gfx.c +++ b/src/df/gfx/df_gfx.c @@ -968,6 +968,7 @@ df_window_open(Vec2F32 size, OS_Handle preferred_monitor, DF_CfgSrc cfg_src) window->entity_ctx_menu_key = ui_key_from_string(ui_key_zero(), str8_lit("_entity_ctx_menu_")); window->tab_ctx_menu_key = ui_key_from_string(ui_key_zero(), str8_lit("_tab_ctx_menu_")); window->hover_eval_arena = arena_alloc(); + window->autocomp_lister_params_arena = arena_alloc(); window->free_panel = &df_g_nil_panel; window->root_panel = df_panel_alloc(window); window->focused_panel = window->root_panel; @@ -4219,7 +4220,7 @@ df_window_update_and_render(Arena *arena, DF_Window *ws, DF_CmdList *cmds) DF_AutoCompListerItemChunkList item_list = {0}; { //- rjf: gather locals - if(ws->autocomp_lister_flags & DF_AutoCompListerFlag_Locals) + if(ws->autocomp_lister_params.flags & DF_AutoCompListerFlag_Locals) { EVAL_String2NumMap *locals_map = df_query_cached_locals_map_from_binary_voff(binary, thread_rip_voff); for(EVAL_String2NumMapNode *n = locals_map->first; n != 0; n = n->order_next) @@ -4238,7 +4239,7 @@ df_window_update_and_render(Arena *arena, DF_Window *ws, DF_CmdList *cmds) } //- rjf: gather registers - if(ws->autocomp_lister_flags & DF_AutoCompListerFlag_Registers) + if(ws->autocomp_lister_params.flags & DF_AutoCompListerFlag_Registers) { Architecture arch = df_architecture_from_entity(thread); U64 reg_names_count = regs_reg_code_count_from_architecture(arch); @@ -4280,7 +4281,7 @@ df_window_update_and_render(Arena *arena, DF_Window *ws, DF_CmdList *cmds) } //- rjf: gather view rules - if(ws->autocomp_lister_flags & DF_AutoCompListerFlag_ViewRules) + if(ws->autocomp_lister_params.flags & DF_AutoCompListerFlag_ViewRules) { for(U64 slot_idx = 0; slot_idx < df_state->view_rule_spec_table_size; slot_idx += 1) { @@ -4301,7 +4302,7 @@ df_window_update_and_render(Arena *arena, DF_Window *ws, DF_CmdList *cmds) } //- rjf: gather languages - if(ws->autocomp_lister_flags & DF_AutoCompListerFlag_Languages) + if(ws->autocomp_lister_params.flags & DF_AutoCompListerFlag_Languages) { for(EachNonZeroEnumVal(TXT_LangKind, lang)) { @@ -4319,7 +4320,7 @@ df_window_update_and_render(Arena *arena, DF_Window *ws, DF_CmdList *cmds) } //- rjf: gather architectures - if(ws->autocomp_lister_flags & DF_AutoCompListerFlag_Architectures) + if(ws->autocomp_lister_params.flags & DF_AutoCompListerFlag_Architectures) { for(EachNonZeroEnumVal(Architecture, arch)) { @@ -4337,7 +4338,7 @@ df_window_update_and_render(Arena *arena, DF_Window *ws, DF_CmdList *cmds) } //- rjf: gather tex2dformats - if(ws->autocomp_lister_flags & DF_AutoCompListerFlag_Tex2DFormats) + if(ws->autocomp_lister_params.flags & DF_AutoCompListerFlag_Tex2DFormats) { for(EachNonZeroEnumVal(R_Tex2DFormat, fmt)) { @@ -4353,6 +4354,25 @@ df_window_update_and_render(Arena *arena, DF_Window *ws, DF_CmdList *cmds) } } } + + //- rjf: gather view rule params + if(ws->autocomp_lister_params.flags & DF_AutoCompListerFlag_ViewRuleParams) + { + for(String8Node *n = ws->autocomp_lister_params.strings.first; n != 0; n = n->next) + { + String8 string = n->string; + DF_AutoCompListerItem item = {0}; + { + item.string = string; + item.kind_string = str8_lit("Parameter"); + item.matches = fuzzy_match_find(scratch.arena, query, item.string); + } + if(query.size == 0 || item.matches.count != 0) + { + df_autocomp_lister_item_chunk_list_push(scratch.arena, &item_list, 256, &item); + } + } + } } //- rjf: lister item list -> sorted array @@ -8775,12 +8795,12 @@ df_autocomp_query_word_from_input_string_off(String8 input, U64 cursor_off) return query; } -internal DF_AutoCompListerFlags -df_view_rule_autocomp_lister_flags_from_input_cursor(String8 string, U64 cursor_off) +internal DF_AutoCompListerParams +df_view_rule_autocomp_lister_params_from_input_cursor(Arena *arena, String8 string, U64 cursor_off) { - DF_AutoCompListerFlags flags = 0; + DF_AutoCompListerParams params = {0}; { - Temp scratch = scratch_begin(0, 0); + Temp scratch = scratch_begin(&arena, 1); //- rjf: do partial parse of input MD_TokenizeResult input_tokenize = md_tokenize_from_text(scratch.arena, string); @@ -8790,28 +8810,68 @@ df_view_rule_autocomp_lister_flags_from_input_cursor(String8 string, U64 cursor_ struct DescendStep { DescendStep *next; + DescendStep *prev; String8 string; }; DescendStep *first_step = 0; DescendStep *last_step = 0; DescendStep *free_step = 0; + S32 paren_nest = 0; + S32 colon_nest = 0; + String8 last_step_string = {0}; for(U64 idx = 0; idx < input_tokenize.tokens.count; idx += 1) { MD_Token *token = &input_tokenize.tokens.v[idx]; - if(token->range.min < cursor_off && token->flags & (MD_TokenFlag_Identifier|MD_TokenFlag_StringLiteral)) + if(token->range.min > cursor_off) { - DescendStep *step = free_step; - if(step != 0) + break; + } + String8 token_string = str8_substr(string, token->range); + if(token->flags & (MD_TokenFlag_Identifier|MD_TokenFlag_StringLiteral)) + { + last_step_string = token_string; + } + if(str8_match(token_string, str8_lit("("), 0) || str8_match(token_string, str8_lit("["), 0) || str8_match(token_string, str8_lit("{"), 0)) + { + paren_nest += 1; + } + if(str8_match(token_string, str8_lit(")"), 0) || str8_match(token_string, str8_lit("]"), 0) || str8_match(token_string, str8_lit("}"), 0)) + { + paren_nest -= 1; + if(paren_nest == 0 && last_step != 0) { - SLLStackPop(free_step); - MemoryZeroStruct(step); + DescendStep *step = last_step; + DLLRemove(first_step, last_step, step); + SLLStackPush(free_step, step); } - else + } + if(str8_match(token_string, str8_lit(":"), 0)) + { + colon_nest += 1; + if(last_step_string.size != 0) { - step = push_array(scratch.arena, DescendStep, 1); + DescendStep *step = free_step; + if(step != 0) + { + SLLStackPop(free_step); + MemoryZeroStruct(step); + } + else + { + step = push_array(scratch.arena, DescendStep, 1); + } + step->string = last_step_string; + DLLPushBack(first_step, last_step, step); + } + } + if(str8_match(token_string, str8_lit(";"), 0) || str8_match(token_string, str8_lit(","), 0)) + { + for(;colon_nest > paren_nest; colon_nest -= 1) + { + DescendStep *step = last_step; + DLLRemove(first_step, last_step, step); + SLLStackPush(free_step, step); } - step->string = str8_substr(string, token->range); - SLLQueuePush(first_step, last_step, step); } } @@ -8823,19 +8883,28 @@ df_view_rule_autocomp_lister_flags_from_input_cursor(String8 string, U64 cursor_ MD_ParseResult schema_parse = md_parse_from_text_tokens(scratch.arena, str8_zero(), spec->info.schema, schema_tokenize.tokens); MD_Node *schema_rule_root = md_child_from_string(schema_parse.root, str8_lit("x"), 0); - //- rjf: follow schema according to descend steps, gather flags from schema node matching cursor node + //- rjf: follow schema according to descend steps, gather flags from schema node matching cursor descension steps if(first_step != 0) { MD_Node *schema_node = schema_rule_root; for(DescendStep *step = first_step->next;;) { - if(md_node_is_nil(schema_node->first)) + if(step == 0) { - if(str8_match(schema_node->string, str8_lit("expr"), StringMatchFlag_CaseInsensitive)) {flags |= DF_AutoCompListerFlag_Locals;} - if(str8_match(schema_node->string, str8_lit("member"), StringMatchFlag_CaseInsensitive)) {flags |= DF_AutoCompListerFlag_Members;} - if(str8_match(schema_node->string, str8_lit("lang"), StringMatchFlag_CaseInsensitive)) {flags |= DF_AutoCompListerFlag_Languages;} - if(str8_match(schema_node->string, str8_lit("arch"), StringMatchFlag_CaseInsensitive)) {flags |= DF_AutoCompListerFlag_Architectures;} - if(str8_match(schema_node->string, str8_lit("tex2dformat"), StringMatchFlag_CaseInsensitive)) {flags |= DF_AutoCompListerFlag_Tex2DFormats;} + for(MD_EachNode(child, schema_node->first)) + { + if(0){} + else if(str8_match(child->string, str8_lit("expr"), StringMatchFlag_CaseInsensitive)) {params.flags |= DF_AutoCompListerFlag_Locals;} + else if(str8_match(child->string, str8_lit("member"), StringMatchFlag_CaseInsensitive)) {params.flags |= DF_AutoCompListerFlag_Members;} + else if(str8_match(child->string, str8_lit("lang"), StringMatchFlag_CaseInsensitive)) {params.flags |= DF_AutoCompListerFlag_Languages;} + else if(str8_match(child->string, str8_lit("arch"), StringMatchFlag_CaseInsensitive)) {params.flags |= DF_AutoCompListerFlag_Architectures;} + else if(str8_match(child->string, str8_lit("tex2dformat"), StringMatchFlag_CaseInsensitive)) {params.flags |= DF_AutoCompListerFlag_Tex2DFormats;} + else if(child->flags & (MD_NodeFlag_StringSingleQuote|MD_NodeFlag_StringDoubleQuote|MD_NodeFlag_StringTick)) + { + str8_list_push(arena, ¶ms.strings, child->string); + params.flags |= DF_AutoCompListerFlag_ViewRuleParams; + } + } break; } if(step != 0) @@ -8853,11 +8922,11 @@ df_view_rule_autocomp_lister_flags_from_input_cursor(String8 string, U64 cursor_ scratch_end(scratch); } - return flags; + return params; } internal void -df_set_autocomp_lister_query(DF_Window *ws, UI_Key root_key, DF_CtrlCtx ctrl_ctx, DF_AutoCompListerFlags flags, String8 input, U64 cursor_off) +df_set_autocomp_lister_query(DF_Window *ws, UI_Key root_key, DF_CtrlCtx ctrl_ctx, DF_AutoCompListerParams *params, String8 input, U64 cursor_off) { String8 query = df_autocomp_query_word_from_input_string_off(input, cursor_off); String8 current_query = str8(ws->autocomp_lister_query_buffer, ws->autocomp_lister_query_size); @@ -8884,7 +8953,9 @@ df_set_autocomp_lister_query(DF_Window *ws, UI_Key root_key, DF_CtrlCtx ctrl_ctx } ws->autocomp_ctrl_ctx = ctrl_ctx; ws->autocomp_root_key = root_key; - ws->autocomp_lister_flags = flags; + arena_clear(ws->autocomp_lister_params_arena); + MemoryCopyStruct(&ws->autocomp_lister_params, params); + ws->autocomp_lister_params.strings = str8_list_copy(ws->autocomp_lister_params_arena, &ws->autocomp_lister_params.strings); ws->autocomp_lister_query_size = Min(query.size, sizeof(ws->autocomp_lister_query_buffer)); MemoryCopy(ws->autocomp_lister_query_buffer, query.str, ws->autocomp_lister_query_size); ws->autocomp_last_frame_idx = df_frame_index(); @@ -12896,6 +12967,7 @@ df_gfx_begin_frame(Arena *arena, DF_CmdList *cmds) os_window_close(ws->os); arena_release(ws->query_cmd_arena); arena_release(ws->hover_eval_arena); + arena_release(ws->autocomp_lister_params_arena); arena_release(ws->arena); SLLStackPush(df_gfx_state->free_window, ws); ws->gen += 1; diff --git a/src/df/gfx/df_gfx.h b/src/df/gfx/df_gfx.h index f26138ee..83c79ce6 100644 --- a/src/df/gfx/df_gfx.h +++ b/src/df/gfx/df_gfx.h @@ -445,10 +445,11 @@ enum DF_AutoCompListerFlag_Locals = (1<<0), DF_AutoCompListerFlag_Registers = (1<<1), DF_AutoCompListerFlag_ViewRules = (1<<2), - DF_AutoCompListerFlag_Members = (1<<3), - DF_AutoCompListerFlag_Languages = (1<<4), - DF_AutoCompListerFlag_Architectures = (1<<5), - DF_AutoCompListerFlag_Tex2DFormats = (1<<6), + DF_AutoCompListerFlag_ViewRuleParams= (1<<3), + DF_AutoCompListerFlag_Members = (1<<4), + DF_AutoCompListerFlag_Languages = (1<<5), + DF_AutoCompListerFlag_Architectures = (1<<6), + DF_AutoCompListerFlag_Tex2DFormats = (1<<7), }; typedef struct DF_AutoCompListerItem DF_AutoCompListerItem; @@ -484,6 +485,13 @@ struct DF_AutoCompListerItemArray U64 count; }; +typedef struct DF_AutoCompListerParams DF_AutoCompListerParams; +struct DF_AutoCompListerParams +{ + DF_AutoCompListerFlags flags; + String8List strings; +}; + //////////////////////////////// //~ rjf: Per-Window State @@ -532,7 +540,8 @@ struct DF_Window B32 autocomp_query_dirty; UI_Key autocomp_root_key; DF_CtrlCtx autocomp_ctrl_ctx; - DF_AutoCompListerFlags autocomp_lister_flags; + Arena *autocomp_lister_params_arena; + DF_AutoCompListerParams autocomp_lister_params; U64 autocomp_cursor_off; U8 autocomp_lister_query_buffer[1024]; U64 autocomp_lister_query_size; @@ -936,8 +945,8 @@ internal int df_autocomp_lister_item_qsort_compare(DF_AutoCompListerItem *a, DF_ internal void df_autocomp_lister_item_array_sort__in_place(DF_AutoCompListerItemArray *array); internal String8 df_autocomp_query_word_from_input_string_off(String8 input, U64 cursor_off); -internal DF_AutoCompListerFlags df_view_rule_autocomp_lister_flags_from_input_cursor(String8 string, U64 cursor_off); -internal void df_set_autocomp_lister_query(DF_Window *ws, UI_Key root_key, DF_CtrlCtx ctrl_ctx, DF_AutoCompListerFlags flags, String8 input, U64 cursor_off); +internal DF_AutoCompListerParams df_view_rule_autocomp_lister_params_from_input_cursor(Arena *arena, String8 string, U64 cursor_off); +internal void df_set_autocomp_lister_query(DF_Window *ws, UI_Key root_key, DF_CtrlCtx ctrl_ctx, DF_AutoCompListerParams *params, String8 input, U64 cursor_off); //////////////////////////////// //~ rjf: Search Strings diff --git a/src/df/gfx/df_views.c b/src/df/gfx/df_views.c index 787c6465..20731bed 100644 --- a/src/df/gfx/df_views.c +++ b/src/df/gfx/df_views.c @@ -1269,7 +1269,8 @@ df_eval_watch_view_build(DF_Window *ws, DF_Panel *panel, DF_View *view, DF_EvalW if(expr_editing_active && !edit_end && txt_pt_match(ewv->input_cursor, ewv->input_mark)) { String8 input = str8(ewv->input_buffer, ewv->input_size); - df_set_autocomp_lister_query(ws, sig.box->key, ctrl_ctx, DF_AutoCompListerFlag_Locals, input, ewv->input_cursor.column-1); + DF_AutoCompListerParams params = {DF_AutoCompListerFlag_Locals}; + df_set_autocomp_lister_query(ws, sig.box->key, ctrl_ctx, ¶ms, input, ewv->input_cursor.column-1); } } @@ -1481,12 +1482,12 @@ df_eval_watch_view_build(DF_Window *ws, DF_Panel *panel, DF_View *view, DF_EvalW if(rule_editing_active && !edit_end && txt_pt_match(ewv->input_cursor, ewv->input_mark)) { String8 input = str8(ewv->input_buffer, ewv->input_size); - DF_AutoCompListerFlags flags = df_view_rule_autocomp_lister_flags_from_input_cursor(input, ewv->input_cursor.column-1); - if(flags == 0) + DF_AutoCompListerParams params = df_view_rule_autocomp_lister_params_from_input_cursor(scratch.arena, input, ewv->input_cursor.column-1); + if(params.flags == 0) { - flags = DF_AutoCompListerFlag_ViewRules; + params.flags = DF_AutoCompListerFlag_ViewRules; } - df_set_autocomp_lister_query(ws, sig.box->key, ctrl_ctx, flags, input, ewv->input_cursor.column-1); + df_set_autocomp_lister_query(ws, sig.box->key, ctrl_ctx, ¶ms, input, ewv->input_cursor.column-1); } } } From 70479e039912cd2cbd7b3a57a3672ba16530bd93 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Mon, 13 May 2024 16:26:54 -0700 Subject: [PATCH 12/30] fix autocompletion query word calculation --- src/df/gfx/df_gfx.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/df/gfx/df_gfx.c b/src/df/gfx/df_gfx.c index 9d80ac9e..3cee338b 100644 --- a/src/df/gfx/df_gfx.c +++ b/src/df/gfx/df_gfx.c @@ -8791,7 +8791,7 @@ df_autocomp_query_word_from_input_string_off(String8 input, U64 cursor_off) word_start_off = off+1; } } - String8 query = str8_skip(input, word_start_off); + String8 query = str8_skip(str8_prefix(input, cursor_off), word_start_off); return query; } @@ -8822,7 +8822,7 @@ df_view_rule_autocomp_lister_params_from_input_cursor(Arena *arena, String8 stri for(U64 idx = 0; idx < input_tokenize.tokens.count; idx += 1) { MD_Token *token = &input_tokenize.tokens.v[idx]; - if(token->range.min > cursor_off) + if(token->range.min >= cursor_off) { break; } From 897949d33a3481b5e64ca3680bc9eadd155d90fe Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Mon, 13 May 2024 16:27:15 -0700 Subject: [PATCH 13/30] notes --- src/raddbg/raddbg.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/raddbg/raddbg.h b/src/raddbg/raddbg.h index c14a076b..76d0b1d1 100644 --- a/src/raddbg/raddbg.h +++ b/src/raddbg/raddbg.h @@ -16,7 +16,7 @@ // & scrollbars etc. // [ ] target/breakpoint/watch-pin reordering // [ ] watch window reordering -// [ ] standard way to filter +// [x] standard way to filter // [ ] visualize remapped files (via path map) // [ ] theme lister -> fonts & font sizes // [ ] font lister @@ -32,7 +32,7 @@ // that you use to tag them. Just some way that would make it easier to // focus on your own threads. // -// [ ] autocomplete lister should respect position in edited expression, +// [x] autocomplete lister should respect position in edited expression, // tabbing through should autocomplete but not exit, etc. // // [ ] it would be nice to have "show in explorer" for right click on source From 362bcbcda5b44b1bff233e68f36e61671bdcc9b3 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Mon, 13 May 2024 16:28:13 -0700 Subject: [PATCH 14/30] fix clang --- src/df/gfx/df_gfx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/df/gfx/df_gfx.c b/src/df/gfx/df_gfx.c index 3cee338b..e9f99a36 100644 --- a/src/df/gfx/df_gfx.c +++ b/src/df/gfx/df_gfx.c @@ -12577,7 +12577,7 @@ df_line_edit(DF_LineEditFlags flags, S32 depth, FuzzyMatchRangeList *matches, Tx fstr->color.w *= 0.5f; fstr->size = ui_top_font_size(); autocomp_fstr_n->next = prev_n ? prev_n->next : 0; - prev_n ? (prev_n->next = autocomp_fstr_n) : (void)0; + if(prev_n != 0) {prev_n->next = autocomp_fstr_n;} if(prev_n == 0) { code_fancy_strings.first = code_fancy_strings.last = autocomp_fstr_n; From 6c200a59cdc9935aad8127c87adaae29347d24e9 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Tue, 14 May 2024 07:50:13 -0700 Subject: [PATCH 15/30] bugfixes for new autocompletion system --- src/df/gfx/df_gfx.c | 46 +++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 42 insertions(+), 4 deletions(-) diff --git a/src/df/gfx/df_gfx.c b/src/df/gfx/df_gfx.c index e9f99a36..7c2c4eba 100644 --- a/src/df/gfx/df_gfx.c +++ b/src/df/gfx/df_gfx.c @@ -8838,6 +8838,15 @@ df_view_rule_autocomp_lister_params_from_input_cursor(Arena *arena, String8 stri if(str8_match(token_string, str8_lit(")"), 0) || str8_match(token_string, str8_lit("]"), 0) || str8_match(token_string, str8_lit("}"), 0)) { paren_nest -= 1; + for(;colon_nest > paren_nest; colon_nest -= 1) + { + if(last_step != 0) + { + DescendStep *step = last_step; + DLLRemove(first_step, last_step, step); + SLLStackPush(free_step, step); + } + } if(paren_nest == 0 && last_step != 0) { DescendStep *step = last_step; @@ -8868,9 +8877,12 @@ df_view_rule_autocomp_lister_params_from_input_cursor(Arena *arena, String8 stri { for(;colon_nest > paren_nest; colon_nest -= 1) { - DescendStep *step = last_step; - DLLRemove(first_step, last_step, step); - SLLStackPush(free_step, step); + if(last_step != 0) + { + DescendStep *step = last_step; + DLLRemove(first_step, last_step, step); + SLLStackPush(free_step, step); + } } } } @@ -12577,7 +12589,10 @@ df_line_edit(DF_LineEditFlags flags, S32 depth, FuzzyMatchRangeList *matches, Tx fstr->color.w *= 0.5f; fstr->size = ui_top_font_size(); autocomp_fstr_n->next = prev_n ? prev_n->next : 0; - if(prev_n != 0) {prev_n->next = autocomp_fstr_n;} + if(prev_n != 0) + { + prev_n->next = autocomp_fstr_n; + } if(prev_n == 0) { code_fancy_strings.first = code_fancy_strings.last = autocomp_fstr_n; @@ -12588,6 +12603,29 @@ df_line_edit(DF_LineEditFlags flags, S32 depth, FuzzyMatchRangeList *matches, Tx } code_fancy_strings.node_count += 1; code_fancy_strings.total_size += autocomplete_hint_string.size; + if(prev_n != 0 && cursor_off - off < prev_n->v.string.size) + { + String8 full_string = prev_n->v.string; + U64 chop_amt = full_string.size - (cursor_off - off); + prev_n->v.string = str8_chop(full_string, chop_amt); + code_fancy_strings.total_size -= chop_amt; + if(chop_amt != 0) + { + String8 post_cursor = str8_skip(full_string, cursor_off - off); + D_FancyStringNode *post_fstr_n = push_array(scratch.arena, D_FancyStringNode, 1); + D_FancyString *post_fstr = &post_fstr_n->v; + MemoryCopyStruct(post_fstr, &prev_n->v); + post_fstr->string = post_cursor; + if(autocomp_fstr_n->next == 0) + { + code_fancy_strings.last = post_fstr_n; + } + post_fstr_n->next = autocomp_fstr_n->next; + autocomp_fstr_n->next = post_fstr_n; + code_fancy_strings.node_count += 1; + code_fancy_strings.total_size += post_cursor.size; + } + } } } ui_box_equip_display_fancy_strings(editstr_box, &code_fancy_strings); From 3085482e34afa4c6f9d84e79c8177399d3a03532 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Tue, 14 May 2024 08:10:02 -0700 Subject: [PATCH 16/30] expand base layer logging mechanism with bucketing info; make one bucket for passive log collection, another for user-facing errors; always consume user errors at the top-level and display; use user-error mechanism to communicate bad 32-bit app launches from demon --- src/base/base_log.c | 17 ++++---- src/base/base_log.h | 26 ++++++++++-- src/ctrl/ctrl_core.c | 65 +++++++++++++++++------------- src/ctrl/ctrl_core.h | 6 +-- src/demon/win32/demon_core_win32.c | 2 +- src/df/core/df_core.c | 39 ++++++++++-------- src/raddbg/raddbg.c | 10 ++++- 7 files changed, 104 insertions(+), 61 deletions(-) diff --git a/src/base/base_log.c b/src/base/base_log.c index af7b25ec..b04a041e 100644 --- a/src/base/base_log.c +++ b/src/base/base_log.c @@ -37,17 +37,17 @@ log_select(Log *log) //~ rjf: Log Building/Clearing internal void -log_msg(String8 string) +log_msg(LogMsgKind kind, String8 string) { if(log_active != 0 && log_active->top_scope != 0) { String8 string_copy = push_str8_copy(log_active->arena, string); - str8_list_push(log_active->arena, &log_active->top_scope->strings, string_copy); + str8_list_push(log_active->arena, &log_active->top_scope->strings[kind], string_copy); } } internal void -log_msgf(char *fmt, ...) +log_msgf(LogMsgKind kind, char *fmt, ...) { if(log_active != 0) { @@ -55,7 +55,7 @@ log_msgf(char *fmt, ...) va_list args; va_start(args, fmt); String8 string = push_str8fv(scratch.arena, fmt, args); - log_msg(string); + log_msg(kind, string); va_end(args); scratch_end(scratch); } @@ -76,10 +76,10 @@ log_scope_begin(void) } } -internal String8 +internal LogScopeResult log_scope_end(Arena *arena) { - String8 result = {0}; + LogScopeResult result = {0}; if(log_active != 0) { LogScope *scope = log_active->top_scope; @@ -88,7 +88,10 @@ log_scope_end(Arena *arena) SLLStackPop(log_active->top_scope); if(arena != 0) { - result = str8_list_join(arena, &scope->strings, 0); + for(EachEnumVal(LogMsgKind, kind)) + { + result.strings[kind] = str8_list_join(arena, &scope->strings[kind], 0); + } } arena_pop_to(log_active->arena, scope->pos); } diff --git a/src/base/base_log.h b/src/base/base_log.h index ff4ac6e4..b5054b40 100644 --- a/src/base/base_log.h +++ b/src/base/base_log.h @@ -7,12 +7,26 @@ //////////////////////////////// //~ rjf: Log Types +typedef enum LogMsgKind +{ + LogMsgKind_Info, + LogMsgKind_UserError, + LogMsgKind_COUNT +} +LogMsgKind; + typedef struct LogScope LogScope; struct LogScope { LogScope *next; U64 pos; - String8List strings; + String8List strings[LogMsgKind_COUNT]; +}; + +typedef struct LogScopeResult LogScopeResult; +struct LogScopeResult +{ + String8 strings[LogMsgKind_COUNT]; }; typedef struct Log Log; @@ -32,13 +46,17 @@ internal void log_select(Log *log); //////////////////////////////// //~ rjf: Log Building -internal void log_msg(String8 string); -internal void log_msgf(char *fmt, ...); +internal void log_msg(LogMsgKind kind, String8 string); +internal void log_msgf(LogMsgKind kind, char *fmt, ...); +#define log_info(s) log_msg(LogMsgKind_Info, (s)) +#define log_infof(fmt, ...) log_msgf(LogMsgKind_Info, (fmt), __VA_ARGS__) +#define log_user_error(s) log_msg(LogMsgKind_UserError, (s)) +#define log_user_errorf(fmt, ...) log_msgf(LogMsgKind_UserError, (fmt), __VA_ARGS__) //////////////////////////////// //~ rjf: Log Scopes internal void log_scope_begin(void); -internal String8 log_scope_end(Arena *arena); +internal LogScopeResult log_scope_end(Arena *arena); #endif // BASE_LOG_H diff --git a/src/ctrl/ctrl_core.c b/src/ctrl/ctrl_core.c index 541c7f0d..625b6485 100644 --- a/src/ctrl/ctrl_core.c +++ b/src/ctrl/ctrl_core.c @@ -1796,8 +1796,17 @@ ctrl_thread__entry_point(void *p) } } - String8 log = log_scope_end(scratch.arena); - ctrl_thread__flush_log(log); + //- rjf: gather & output logs + LogScopeResult log = log_scope_end(scratch.arena); + ctrl_thread__flush_info_log(log.strings[LogMsgKind_Info]); + if(log.strings[LogMsgKind_UserError].size != 0) + { + CTRL_EventList evts = {0}; + CTRL_Event *evt = ctrl_event_list_push(scratch.arena, &evts); + evt->kind = CTRL_EventKind_Error; + evt->string = log.strings[LogMsgKind_UserError]; + ctrl_c2u_push_events(&evts); + } } scratch_end(scratch); @@ -1944,16 +1953,16 @@ ctrl_thread__next_dmn_event(Arena *arena, DMN_CtrlCtx *ctrl_ctx, CTRL_Msg *msg, if(next_event_node != 0) CTRL_CtrlThreadLogScope { DMN_Event *ev = &next_event_node->v; - log_msgf("--- event ---\n"); - log_msgf("kind: %S\n", dmn_event_kind_string_table[ev->kind]); - log_msgf("exception_kind: %S\n", dmn_exception_kind_string_table[ev->exception_kind]); - log_msgf("process: [%I64u]\n", ev->process.u64[0]); - log_msgf("thread: [%I64u]\n", ev->thread.u64[0]); - log_msgf("module: [%I64u]\n", ev->module.u64[0]); - log_msgf("arch: %S\n", string_from_architecture(ev->arch)); - log_msgf("address: 0x%I64x\n", ev->address); - log_msgf("string: \"%S\"\n", ev->string); - log_msgf("ip_vaddr: 0x%I64x\n", ev->instruction_pointer); + log_infof("--- event ---\n"); + log_infof("kind: %S\n", dmn_event_kind_string_table[ev->kind]); + log_infof("exception_kind: %S\n", dmn_exception_kind_string_table[ev->exception_kind]); + log_infof("process: [%I64u]\n", ev->process.u64[0]); + log_infof("thread: [%I64u]\n", ev->thread.u64[0]); + log_infof("module: [%I64u]\n", ev->module.u64[0]); + log_infof("arch: %S\n", string_from_architecture(ev->arch)); + log_infof("address: 0x%I64x\n", ev->address); + log_infof("string: \"%S\"\n", ev->string); + log_infof("ip_vaddr: 0x%I64x\n", ev->instruction_pointer); } // rjf: determine if we should filter @@ -2106,9 +2115,9 @@ ctrl_thread__next_dmn_event(Arena *arena, DMN_CtrlCtx *ctrl_ctx, CTRL_Msg *msg, // rjf: run for new events ProfScope("run for new events") { - CTRL_CtrlThreadLogScope log_msgf("{dmn_ctrl_run ..."); + CTRL_CtrlThreadLogScope log_infof("{dmn_ctrl_run ..."); DMN_EventList events = dmn_ctrl_run(scratch.arena, ctrl_ctx, run_ctrls); - CTRL_CtrlThreadLogScope log_msgf("}\n"); + CTRL_CtrlThreadLogScope log_infof("}\n"); for(DMN_EventNode *src_n = events.first; src_n != 0; src_n = src_n->next) { DMN_EventNode *dst_n = ctrl_state->free_dmn_event_node; @@ -2298,17 +2307,17 @@ ctrl_eval_memory_read(void *u, void *out, U64 addr, U64 size) //- rjf: log flusher internal void -ctrl_thread__flush_log(String8 string) +ctrl_thread__flush_info_log(String8 string) { os_append_data_to_file_path(ctrl_state->ctrl_thread_log_path, string); } internal void -ctrl_thread__end_and_flush_log(void) +ctrl_thread__end_and_flush_info_log(void) { Temp scratch = scratch_begin(0, 0); - String8 log = log_scope_end(scratch.arena); - ctrl_thread__flush_log(log); + LogScopeResult log = log_scope_end(scratch.arena); + ctrl_thread__flush_info_log(log.strings[LogMsgKind_Info]); scratch_end(scratch); } @@ -2754,25 +2763,25 @@ ctrl_thread__run(DMN_CtrlCtx *ctrl_ctx, CTRL_Msg *msg) case DMN_EventKind_Trap: { hard_stop = 1; - log_msgf(">>> stepping >>> hard stop\n"); + log_infof(">>> stepping >>> hard stop\n"); }break; case DMN_EventKind_Exception: case DMN_EventKind_Breakpoint: { use_stepping_logic = 1; - log_msgf(">>> stepping >>> exception or breakpoint - begin stepping logic\n"); + log_infof(">>> stepping >>> exception or breakpoint - begin stepping logic\n"); }break; case DMN_EventKind_CreateProcess: { DMN_TrapChunkList new_traps = {0}; ctrl_thread__append_resolved_process_user_bp_traps(scratch.arena, CTRL_MachineID_Local, event->process, &msg->user_bps, &new_traps); - log_msgf(">>> stepping >>> create process -> resolve new BPs\n"); + log_infof(">>> stepping >>> create process -> resolve new BPs\n"); for(DMN_TrapChunkNode *n = new_traps.first; n != 0; n = n->next) { for(U64 idx = 0; idx < n->count; idx += 1) { DMN_Trap *trap = &n->v[idx]; - log_msgf(" trap: {process:%I64d, vaddr:0x%I64x}\n", trap->process.u64[0], trap->vaddr); + log_infof(" trap: {process:%I64d, vaddr:0x%I64x}\n", trap->process.u64[0], trap->vaddr); } } dmn_trap_chunk_list_concat_shallow_copy(scratch.arena, &joined_traps, &new_traps); @@ -2784,7 +2793,7 @@ ctrl_thread__run(DMN_CtrlCtx *ctrl_ctx, CTRL_Msg *msg) ctrl_thread__append_resolved_module_user_bp_traps(scratch.arena, CTRL_MachineID_Local, event->process, event->module, &msg->user_bps, &new_traps); dmn_trap_chunk_list_concat_shallow_copy(scratch.arena, &joined_traps, &new_traps); dmn_trap_chunk_list_concat_shallow_copy(scratch.arena, &user_traps, &new_traps); - log_msgf(">>> stepping >>> load module -> resolve new BPs\n"); + log_infof(">>> stepping >>> load module -> resolve new BPs\n"); }break; } @@ -3158,13 +3167,13 @@ ctrl_thread__run(DMN_CtrlCtx *ctrl_ctx, CTRL_Msg *msg) { hit_user_bp = 0; hit_conditional_bp_but_filtered = 1; - log_msgf(">>> stepping >>> conditional breakpoint hit, but condition eval'd to 0, and so filtered\n"); + log_infof(">>> stepping >>> conditional breakpoint hit, but condition eval'd to 0, and so filtered\n"); } else { hit_user_bp = 1; hit_conditional_bp_but_filtered = 0; - log_msgf(">>> stepping >>> conditional breakpoint hit\n"); + log_infof(">>> stepping >>> conditional breakpoint hit\n"); break; } } @@ -3185,8 +3194,8 @@ ctrl_thread__run(DMN_CtrlCtx *ctrl_ctx, CTRL_Msg *msg) } } - log_msgf(">>> stepping >>> stepping logic - BP event -> hit_user_bp: %i\n", hit_user_bp); - log_msgf(">>> stepping >>> stepping logic - BP event -> hit_entry: %i\n", hit_entry); + log_infof(">>> stepping >>> stepping logic - BP event -> hit_user_bp: %i\n", hit_user_bp); + log_infof(">>> stepping >>> stepping logic - BP event -> hit_entry: %i\n", hit_entry); temp_end(temp); } } @@ -3420,7 +3429,7 @@ ctrl_thread__run(DMN_CtrlCtx *ctrl_ctx, CTRL_Msg *msg) { stage_stop_cause = CTRL_EventCause_Finished; } - log_msgf(">>> stepping >>> stage stop cause -> %i\n", stage_stop_cause); + log_infof(">>> stepping >>> stage stop cause -> %i\n", stage_stop_cause); if(stage_stop_cause != CTRL_EventCause_Null) { stop_event = event; diff --git a/src/ctrl/ctrl_core.h b/src/ctrl/ctrl_core.h index 2c078221..0666e237 100644 --- a/src/ctrl/ctrl_core.h +++ b/src/ctrl/ctrl_core.h @@ -556,7 +556,7 @@ read_only global CTRL_Entity ctrl_entity_nil = //////////////////////////////// //~ rjf: Logging Markup -#define CTRL_CtrlThreadLogScope DeferLoop(log_scope_begin(), ctrl_thread__end_and_flush_log()) +#define CTRL_CtrlThreadLogScope DeferLoop(log_scope_begin(), ctrl_thread__end_and_flush_info_log()) //////////////////////////////// //~ rjf: Basic Type Functions @@ -716,8 +716,8 @@ internal DMN_Event *ctrl_thread__next_dmn_event(Arena *arena, DMN_CtrlCtx *ctrl_ internal B32 ctrl_eval_memory_read(void *u, void *out, U64 addr, U64 size); //- rjf: log flusher -internal void ctrl_thread__flush_log(String8 string); -internal void ctrl_thread__end_and_flush_log(void); +internal void ctrl_thread__flush_info_log(String8 string); +internal void ctrl_thread__end_and_flush_info_log(void); //- rjf: msg kind implementations internal void ctrl_thread__launch(DMN_CtrlCtx *ctrl_ctx, CTRL_Msg *msg); diff --git a/src/demon/win32/demon_core_win32.c b/src/demon/win32/demon_core_win32.c index 28abb910..5e765be6 100644 --- a/src/demon/win32/demon_core_win32.c +++ b/src/demon/win32/demon_core_win32.c @@ -1205,7 +1205,7 @@ dmn_ctrl_launch(DMN_CtrlCtx *ctx, OS_LaunchOptions *options) IsWow64Process(process_info.hProcess, &is_wow); if(is_wow) { - MessageBox(0, "Sorry, The RAD Debugger only debugs 64-bit applications currently.", "Process error", MB_OK|MB_ICONSTOP); + log_user_errorf("Only 64-bit applications can be debugged currently."); DebugActiveProcessStop(process_info.dwProcessId); TerminateProcess(process_info.hProcess,0xffffffff); } diff --git a/src/df/core/df_core.c b/src/df/core/df_core.c index 29055c8d..3e1c986e 100644 --- a/src/df/core/df_core.c +++ b/src/df/core/df_core.c @@ -1799,7 +1799,7 @@ df_entity_alloc(DF_StateDeltaHistory *hist, DF_Entity *parent, DF_EntityKind kin df_entity_notify_mutation(entity); // rjf: log - log_msgf("new entity: %S $%I64d\n", df_g_entity_kind_display_string_table[kind], entity->id); + log_infof("new entity: %S $%I64d\n", df_g_entity_kind_display_string_table[kind], entity->id); return entity; } @@ -1844,7 +1844,7 @@ df_entity_release(DF_StateDeltaHistory *hist, DF_Entity *entity) t->e = child; SLLQueuePush(first_task, last_task, t); } - log_msgf("end entity: %S $%I64d\n", df_g_entity_kind_display_string_table[task->e->kind], task->e->id); + log_infof("end entity: %S $%I64d\n", df_g_entity_kind_display_string_table[task->e->kind], task->e->id); df_state_delta_history_push_struct_delta(hist, &task->e->first); df_state_delta_history_push_struct_delta(hist, &task->e->last); df_state_delta_history_push_struct_delta(hist, &task->e->next); @@ -6457,8 +6457,8 @@ df_push_cmd__root(DF_CmdParams *params, DF_CmdSpec *spec) { Temp scratch = scratch_begin(0, 0); DF_Entity *entity = df_entity_from_handle(params->entity); - log_msgf("debug frontend command pushed: \"%S\"\n", spec->info.string); -#define HandleParamPrint(mem_name) if(!df_handle_match(df_handle_zero(), params->mem_name)) { log_msgf("| %s: [0x%I64x, 0x%I64x]\n", #mem_name, params->mem_name.u64[0], params->mem_name.u64[1]); } + log_infof("debug frontend command pushed: \"%S\"\n", spec->info.string); +#define HandleParamPrint(mem_name) if(!df_handle_match(df_handle_zero(), params->mem_name)) { log_infof("| %s: [0x%I64x, 0x%I64x]\n", #mem_name, params->mem_name.u64[0], params->mem_name.u64[1]); } HandleParamPrint(window); HandleParamPrint(panel); HandleParamPrint(dest_panel); @@ -6467,7 +6467,7 @@ df_push_cmd__root(DF_CmdParams *params, DF_CmdSpec *spec) if(!df_entity_is_nil(entity)) { String8 entity_name = df_display_string_from_entity(scratch.arena, entity); - log_msgf("| entity: \"%S\"\n", entity_name); + log_infof("| entity: \"%S\"\n", entity_name); } U64 idx = 0; for(DF_HandleNode *n = params->entity_list.first; n != 0; n = n->next, idx += 1) @@ -6476,20 +6476,20 @@ df_push_cmd__root(DF_CmdParams *params, DF_CmdSpec *spec) if(!df_entity_is_nil(entity)) { String8 entity_name = df_display_string_from_entity(scratch.arena, entity); - log_msgf("| entity_list[%I64u]: \"%S\"\n", idx, entity_name); + log_infof("| entity_list[%I64u]: \"%S\"\n", idx, entity_name); } } if(!df_cmd_spec_is_nil(params->cmd_spec)) { - log_msgf("| cmd_spec: \"%S\"\n", params->cmd_spec->info.string); + log_infof("| cmd_spec: \"%S\"\n", params->cmd_spec->info.string); } - if(params->string.size != 0) { log_msgf("| string: \"%S\"\n", params->string); } - if(params->file_path.size != 0) { log_msgf("| file_path: \"%S\"\n", params->file_path); } - if(params->text_point.line != 0){ log_msgf("| text_point: [line:%I64d, col:%I64d]\n", params->text_point.line, params->text_point.column); } - if(params->vaddr != 0) { log_msgf("| vaddr: 0x%I64x\n", params->vaddr); } - if(params->voff != 0) { log_msgf("| voff: 0x%I64x\n", params->voff); } - if(params->index != 0) { log_msgf("| index: 0x%I64x\n", params->index); } - if(params->id != 0) { log_msgf("| id: 0x%I64x\n", params->id); } + if(params->string.size != 0) { log_infof("| string: \"%S\"\n", params->string); } + if(params->file_path.size != 0) { log_infof("| file_path: \"%S\"\n", params->file_path); } + if(params->text_point.line != 0){ log_infof("| text_point: [line:%I64d, col:%I64d]\n", params->text_point.line, params->text_point.column); } + if(params->vaddr != 0) { log_infof("| vaddr: 0x%I64x\n", params->vaddr); } + if(params->voff != 0) { log_infof("| voff: 0x%I64x\n", params->voff); } + if(params->index != 0) { log_infof("| index: 0x%I64x\n", params->index); } + if(params->id != 0) { log_infof("| id: 0x%I64x\n", params->id); } if(params->os_event != 0) { String8 kind_string = str8_lit(""); @@ -6506,10 +6506,10 @@ df_push_cmd__root(DF_CmdParams *params, DF_CmdSpec *spec) case OS_EventKind_FileDrop: {kind_string = str8_lit("filedrop");}break; case OS_EventKind_Wakeup: {kind_string = str8_lit("wakeup");}break; } - log_msgf("| os_event->kind: %S\n", kind_string); + log_infof("| os_event->kind: %S\n", kind_string); } #undef HandleParamPrint - log_msgf("--------------------------------\n"); + log_infof("--------------------------------\n"); scratch_end(scratch); } df_cmd_list_push(df_state->root_cmd_arena, &df_state->root_cmds, params, spec); @@ -6703,6 +6703,13 @@ df_core_begin_frame(Arena *arena, DF_CmdList *cmds, F32 dt) { default:{}break; + //- rjf: errors + + case CTRL_EventKind_Error: + { + log_user_error(event->string); + }break; + //- rjf: starts/stops case CTRL_EventKind_Started: diff --git a/src/raddbg/raddbg.c b/src/raddbg/raddbg.c index 465fa1b0..e68ef468 100644 --- a/src/raddbg/raddbg.c +++ b/src/raddbg/raddbg.c @@ -378,8 +378,14 @@ update_and_render(OS_Handle repaint_window_handle, void *user_data) //- rjf: end logging // { - String8 log = log_scope_end(scratch.arena); - os_append_data_to_file_path(main_thread_log_path, log); + LogScopeResult log = log_scope_end(scratch.arena); + os_append_data_to_file_path(main_thread_log_path, log.strings[LogMsgKind_Info]); + if(log.strings[LogMsgKind_UserError].size != 0) + { + DF_CmdParams p = df_cmd_params_from_gfx(); + p.string = log.strings[LogMsgKind_UserError]; + df_push_cmd__root(&p, df_cmd_spec_from_core_cmd_kind(DF_CoreCmdKind_Error)); + } } scratch_end(scratch); From 5d459d9b7afc55cd8db62f4e9a94b63aeb49d5e4 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Tue, 14 May 2024 08:23:28 -0700 Subject: [PATCH 17/30] skip/chop whitespace on launch parameters --- src/df/core/df_core.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/df/core/df_core.c b/src/df/core/df_core.c index 3e1c986e..165b3fc8 100644 --- a/src/df/core/df_core.c +++ b/src/df/core/df_core.c @@ -7229,6 +7229,10 @@ df_core_begin_frame(Arena *arena, DF_CmdList *cmds, F32 dt) String8 args = df_entity_child_from_kind(target, DF_EntityKind_Arguments)->name; String8 path = df_entity_child_from_kind(target, DF_EntityKind_ExecutionPath)->name; String8 entry= df_entity_child_from_kind(target, DF_EntityKind_EntryPointName)->name; + name = str8_skip_chop_whitespace(name); + args = str8_skip_chop_whitespace(args); + path = str8_skip_chop_whitespace(path); + entry = str8_skip_chop_whitespace(entry); if(path.size == 0) { String8List current_path_strs = {0}; From ac9a9084641afa70c1c5869ec6e7f88491df8eab Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Tue, 14 May 2024 08:27:59 -0700 Subject: [PATCH 18/30] automatically support insert-based copy/paste shortcuts --- src/df/gfx/df_gfx.mdesk | 2 ++ src/df/gfx/generated/df_gfx.meta.c | 4 +++- src/df/gfx/generated/df_gfx.meta.h | 2 +- 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/src/df/gfx/df_gfx.mdesk b/src/df/gfx/df_gfx.mdesk index 45bfe758..cb6859b0 100644 --- a/src/df/gfx/df_gfx.mdesk +++ b/src/df/gfx/df_gfx.mdesk @@ -125,8 +125,10 @@ DF_DefaultBindingTable: { "backspace_single" Backspace 0 0 0 } { "backspace_chunk" Backspace ctrl 0 0 } { "copy" C ctrl 0 0 } + { "copy" Insert ctrl 0 0 } { "cut" X ctrl 0 0 } { "paste" V ctrl 0 0 } + { "paste" Insert 0 shift 0 } { "insert_text" Null 0 0 0 } //- rjf: code navigation diff --git a/src/df/gfx/generated/df_gfx.meta.c b/src/df/gfx/generated/df_gfx.meta.c index b54e4e6d..fd95865b 100644 --- a/src/df/gfx/generated/df_gfx.meta.c +++ b/src/df/gfx/generated/df_gfx.meta.c @@ -598,7 +598,7 @@ str8_lit_comp("goto_name"), str8_lit_comp("function_breakpoint"), }; -DF_StringBindingPair df_g_default_binding_table[97] = +DF_StringBindingPair df_g_default_binding_table[99] = { {str8_lit_comp("kill_all"), {OS_Key_F5, 0 |OS_EventFlag_Shift }}, {str8_lit_comp("step_into_inst"), {OS_Key_F11, 0 |OS_EventFlag_Alt}}, @@ -678,8 +678,10 @@ DF_StringBindingPair df_g_default_binding_table[97] = {str8_lit_comp("backspace_single"), {OS_Key_Backspace, 0 }}, {str8_lit_comp("backspace_chunk"), {OS_Key_Backspace, 0 |OS_EventFlag_Ctrl }}, {str8_lit_comp("copy"), {OS_Key_C, 0 |OS_EventFlag_Ctrl }}, +{str8_lit_comp("copy"), {OS_Key_Insert, 0 |OS_EventFlag_Ctrl }}, {str8_lit_comp("cut"), {OS_Key_X, 0 |OS_EventFlag_Ctrl }}, {str8_lit_comp("paste"), {OS_Key_V, 0 |OS_EventFlag_Ctrl }}, +{str8_lit_comp("paste"), {OS_Key_Insert, 0 |OS_EventFlag_Shift }}, {str8_lit_comp("insert_text"), {OS_Key_Null, 0 }}, {str8_lit_comp("goto_line"), {OS_Key_G, 0 |OS_EventFlag_Ctrl }}, {str8_lit_comp("goto_address"), {OS_Key_G, 0 |OS_EventFlag_Alt}}, diff --git a/src/df/gfx/generated/df_gfx.meta.h b/src/df/gfx/generated/df_gfx.meta.h index 68f2fd8e..adb55bec 100644 --- a/src/df/gfx/generated/df_gfx.meta.h +++ b/src/df/gfx/generated/df_gfx.meta.h @@ -290,7 +290,7 @@ extern Vec4F32* df_g_theme_preset_colors_table[9]; extern DF_CmdParamSlot df_g_cmd_param_slot_2_view_spec_src_map[7]; extern String8 df_g_cmd_param_slot_2_view_spec_dst_map[7]; extern String8 df_g_cmd_param_slot_2_view_spec_cmd_map[7]; -extern DF_StringBindingPair df_g_default_binding_table[97]; +extern DF_StringBindingPair df_g_default_binding_table[99]; extern String8 df_g_binding_version_remap_old_name_table[3]; extern String8 df_g_binding_version_remap_new_name_table[3]; extern DF_ViewSpecInfo df_g_gfx_view_kind_spec_info_table[31]; From 58b8ed89746dbe7754aab071de118effe279ede1 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Tue, 14 May 2024 09:07:44 -0700 Subject: [PATCH 19/30] floating line-nums/margins in source & disasm views, when horizontally scrolled --- src/df/gfx/df_gfx.c | 21 ++++++++++++++++++++- src/df/gfx/df_gfx.h | 1 + src/df/gfx/df_views.c | 15 +++++++++++++++ src/raddbg/raddbg.h | 4 +++- 4 files changed, 39 insertions(+), 2 deletions(-) diff --git a/src/df/gfx/df_gfx.c b/src/df/gfx/df_gfx.c index 7c2c4eba..6cbed85d 100644 --- a/src/df/gfx/df_gfx.c +++ b/src/df/gfx/df_gfx.c @@ -10501,6 +10501,14 @@ df_code_slice(DF_Window *ws, DF_CtrlCtx *ctrl_ctx, EVAL_ParseCtx *parse_ctx, DF_ UI_Box *margin_container_box = &ui_g_nil_box; if(params->flags & DF_CodeSliceFlag_Margin) UI_Focus(UI_FocusKind_Off) UI_Parent(top_container_box) ProfScope("build margins") { + if(params->margin_float_off_px != 0) + { + ui_set_next_pref_width(ui_px(params->margin_width_px, 1)); + ui_set_next_pref_height(ui_px(params->line_height_px*(dim_1s64(params->line_num_range)+1), 1.f)); + ui_build_box_from_key(0, ui_key_zero()); + ui_set_next_fixed_x(params->margin_float_off_px); + ui_set_next_flags(UI_BoxFlag_DrawBackground); + } ui_set_next_pref_width(ui_px(params->margin_width_px, 1)); ui_set_next_pref_height(ui_px(params->line_height_px*(dim_1s64(params->line_num_range)+1), 1.f)); ui_set_next_child_layout_axis(Axis2_Y); @@ -11291,9 +11299,20 @@ df_code_slice(DF_Window *ws, DF_CtrlCtx *ctrl_ctx, EVAL_ParseCtx *parse_ctx, DF_ TxtRng select_rng = txt_rng(*cursor, *mark); Vec4F32 inactive_color = df_rgba_from_theme_color(DF_ThemeColor_WeakText); Vec4F32 active_color = df_rgba_from_theme_color(DF_ThemeColor_PlainText); + if(params->margin_float_off_px != 0) + { + ui_set_next_pref_width(ui_px(params->line_num_width_px, 1.f)); + ui_set_next_pref_height(ui_px(params->line_height_px*(dim_1s64(params->line_num_range)+1), 1.f)); + ui_build_box_from_key(0, ui_key_zero()); + ui_set_next_fixed_x(params->margin_float_off_px); + ui_set_next_flags(UI_BoxFlag_DrawDropShadow|UI_BoxFlag_DrawBackground|UI_BoxFlag_DrawSideRight|UI_BoxFlag_DrawSideLeft); + } + else + { + ui_set_next_flags(UI_BoxFlag_DrawSideRight|UI_BoxFlag_DrawSideLeft); + } ui_set_next_pref_width(ui_px(params->line_num_width_px, 1.f)); ui_set_next_pref_height(ui_px(params->line_height_px*(dim_1s64(params->line_num_range)+1), 1.f)); - ui_set_next_flags(UI_BoxFlag_DrawSideRight|UI_BoxFlag_DrawSideLeft); UI_Column UI_PrefHeight(ui_px(params->line_height_px, 1.f)) UI_Font(params->font) diff --git a/src/df/gfx/df_gfx.h b/src/df/gfx/df_gfx.h index 83c79ce6..a7c1b964 100644 --- a/src/df/gfx/df_gfx.h +++ b/src/df/gfx/df_gfx.h @@ -416,6 +416,7 @@ struct DF_CodeSliceParams F32 line_num_width_px; F32 line_text_max_width_px; DF_EntityList flash_ranges; + F32 margin_float_off_px; }; typedef struct DF_CodeSliceSignal DF_CodeSliceSignal; diff --git a/src/df/gfx/df_views.c b/src/df/gfx/df_views.c index 20731bed..a667c053 100644 --- a/src/df/gfx/df_views.c +++ b/src/df/gfx/df_views.c @@ -5411,6 +5411,11 @@ DF_VIEW_UI_FUNCTION_DEF(Code) code_slice_params.line_num_width_px = line_num_width_px; code_slice_params.line_text_max_width_px = (F32)line_size_x; code_slice_params.flash_ranges = df_push_entity_child_list_with_kind(scratch.arena, entity, DF_EntityKind_FlashMarker); + code_slice_params.margin_float_off_px = view->scroll_pos.x.idx + view->scroll_pos.x.off; + if(code_slice_params.margin_float_off_px < 1) + { + code_slice_params.margin_float_off_px = 0; + } // rjf: fill text info { @@ -6494,6 +6499,11 @@ DF_VIEW_UI_FUNCTION_DEF(Disassembly) code_slice_params.line_num_width_px = line_num_width_px; code_slice_params.line_text_max_width_px = (F32)line_size_x; code_slice_params.flash_ranges = df_push_entity_child_list_with_kind(scratch.arena, process, DF_EntityKind_FlashMarker); + code_slice_params.margin_float_off_px = view->scroll_pos.x.idx + view->scroll_pos.x.off; + if(code_slice_params.margin_float_off_px < 1) + { + code_slice_params.margin_float_off_px = 0; + } df_entity_list_push(scratch.arena, &code_slice_params.relevant_binaries, binary); // rjf: fill text info @@ -7329,6 +7339,11 @@ DF_VIEW_UI_FUNCTION_DEF(Output) code_slice_params.line_num_width_px = line_num_width_px; code_slice_params.line_text_max_width_px = (F32)line_size_x; code_slice_params.flash_ranges = df_push_entity_child_list_with_kind(scratch.arena, entity, DF_EntityKind_FlashMarker); + code_slice_params.margin_float_off_px = view->scroll_pos.x.idx + view->scroll_pos.x.off; + if(code_slice_params.margin_float_off_px < 1) + { + code_slice_params.margin_float_off_px = 0; + } } ////////////////////////////// diff --git a/src/raddbg/raddbg.h b/src/raddbg/raddbg.h index 76d0b1d1..ecc89863 100644 --- a/src/raddbg/raddbg.h +++ b/src/raddbg/raddbg.h @@ -4,6 +4,8 @@ //////////////////////////////// //~ rjf: Frontend/UI Pass Tasks // +// [ ] editing multiple bindings for commands +// // [ ] n-row table selection, in watch window & other UIs, multi-selection // ctrl+C // [x] UI_NavActions, OS_Event -> UI_Event (single event stream) @@ -11,7 +13,7 @@ // [ ] better discoverability for view rules - have better help hover tooltip, // info on arguments, and better autocomplete lister // -// [ ] source view -> floating margin/line-nums +// [x] source view -> floating margin/line-nums // [ ] theme colors -> more explicit about e.g. opaque backgrounds vs. floating // & scrollbars etc. // [ ] target/breakpoint/watch-pin reordering From 4dd1f6f5792d9ede12fd540106fbf45c06fe6c65 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Tue, 14 May 2024 10:33:03 -0700 Subject: [PATCH 20/30] eval watch -> watch; prep for more organized event-driven editing path for watch windows, beginning of multi-selection support --- src/df/gfx/df_views.c | 315 ++++++++++++++++++++++++++------------ src/df/gfx/df_views.h | 70 ++++----- src/ui/ui_basic_widgets.c | 13 +- src/ui/ui_basic_widgets.h | 4 +- 4 files changed, 266 insertions(+), 136 deletions(-) diff --git a/src/df/gfx/df_views.c b/src/df/gfx/df_views.c index a667c053..64b568bd 100644 --- a/src/df/gfx/df_views.c +++ b/src/df/gfx/df_views.c @@ -370,12 +370,12 @@ df_entity_lister_item_array_sort_by_strength__in_place(DF_EntityListerItemArray } //////////////////////////////// -//~ rjf: Eval/Watch Views +//~ rjf: Watch Views //- rjf: eval watch view instance -> eval view key internal DF_EvalViewKey -df_eval_view_key_from_eval_watch_view(DF_EvalWatchViewState *ewv) +df_eval_view_key_from_eval_watch_view(DF_WatchViewState *ewv) { DF_EvalViewKey key = df_eval_view_key_make((U64)ewv, df_hash_from_string(str8_struct(&ewv))); return key; @@ -384,7 +384,7 @@ df_eval_view_key_from_eval_watch_view(DF_EvalWatchViewState *ewv) //- rjf: root allocation/deallocation/mutation internal DF_EvalRoot * -df_eval_root_alloc(DF_View *view, DF_EvalWatchViewState *ews) +df_eval_root_alloc(DF_View *view, DF_WatchViewState *ews) { DF_EvalRoot *result = ews->first_free_root; if(result != 0) @@ -404,7 +404,7 @@ df_eval_root_alloc(DF_View *view, DF_EvalWatchViewState *ews) } internal void -df_eval_root_release(DF_EvalWatchViewState *ews, DF_EvalRoot *root) +df_eval_root_release(DF_WatchViewState *ews, DF_EvalRoot *root) { DLLRemove(ews->first_root, ews->last_root, root); SLLStackPush(ews->first_free_root, root); @@ -419,7 +419,7 @@ df_eval_root_equip_string(DF_EvalRoot *root, String8 string) } internal DF_EvalRoot * -df_eval_root_from_string(DF_EvalWatchViewState *ews, String8 string) +df_eval_root_from_string(DF_WatchViewState *ews, String8 string) { DF_EvalRoot *root = 0; for(DF_EvalRoot *r = ews->first_root; r != 0; r = r->next) @@ -435,7 +435,7 @@ df_eval_root_from_string(DF_EvalWatchViewState *ews, String8 string) } internal DF_EvalRoot * -df_eval_root_from_expand_key(DF_EvalWatchViewState *ews, DF_EvalView *eval_view, DF_ExpandKey expand_key) +df_eval_root_from_expand_key(DF_WatchViewState *ews, DF_EvalView *eval_view, DF_ExpandKey expand_key) { DF_EvalRoot *root = 0; for(DF_EvalRoot *r = ews->first_root; r != 0; r = r->next) @@ -475,7 +475,7 @@ df_expand_key_from_eval_root(DF_EvalRoot *root) //- rjf: windowed watch tree visualization (both single-line and multi-line) internal DF_EvalVizBlockList -df_eval_viz_block_list_from_watch_view_state(Arena *arena, DBGI_Scope *scope, DF_CtrlCtx *ctrl_ctx, EVAL_ParseCtx *parse_ctx, EVAL_String2ExprMap *macro_map, DF_View *view, DF_EvalWatchViewState *ews) +df_eval_viz_block_list_from_watch_view_state(Arena *arena, DBGI_Scope *scope, DF_CtrlCtx *ctrl_ctx, EVAL_ParseCtx *parse_ctx, EVAL_String2ExprMap *macro_map, DF_View *view, DF_WatchViewState *ews) { ProfBeginFunction(); Temp scratch = scratch_begin(&arena, 1); @@ -490,7 +490,7 @@ df_eval_viz_block_list_from_watch_view_state(Arena *arena, DBGI_Scope *scope, DF //- rjf: mutable watch fill -> build blocks from top-level mutable root expressions // default: - case DF_EvalWatchViewFillKind_Mutable: + case DF_WatchViewFillKind_Mutable: { for(DF_EvalRoot *root = ews->first_root; root != 0; root = root->next) { @@ -509,7 +509,7 @@ df_eval_viz_block_list_from_watch_view_state(Arena *arena, DBGI_Scope *scope, DF //////////////////////////// //- rjf: registers fill -> build blocks via iterating all registers/aliases as root-level expressions // - case DF_EvalWatchViewFillKind_Registers: + case DF_WatchViewFillKind_Registers: { DF_Entity *thread = df_entity_from_handle(ctrl_ctx->thread); Architecture arch = df_architecture_from_entity(thread); @@ -547,7 +547,7 @@ df_eval_viz_block_list_from_watch_view_state(Arena *arena, DBGI_Scope *scope, DF //////////////////////////// //- rjf: locals fill -> build blocks via iterating all locals as root-level expressions // - case DF_EvalWatchViewFillKind_Locals: + case DF_WatchViewFillKind_Locals: { U64 num = 1; for(EVAL_String2NumMapNode *n = parse_ctx->locals_map->first; n != 0; n = n->order_next, num += 1) @@ -567,10 +567,10 @@ df_eval_viz_block_list_from_watch_view_state(Arena *arena, DBGI_Scope *scope, DF //////////////////////////// //- rjf: debug info table fill -> build split debug info table blocks // - case DF_EvalWatchViewFillKind_Globals: dbgi_target = DBGI_FuzzySearchTarget_GlobalVariables; goto dbgi_table; - case DF_EvalWatchViewFillKind_ThreadLocals: dbgi_target = DBGI_FuzzySearchTarget_ThreadVariables; goto dbgi_table; - case DF_EvalWatchViewFillKind_Types: dbgi_target = DBGI_FuzzySearchTarget_UDTs; goto dbgi_table; - case DF_EvalWatchViewFillKind_Procedures: dbgi_target = DBGI_FuzzySearchTarget_Procedures; goto dbgi_table; + case DF_WatchViewFillKind_Globals: dbgi_target = DBGI_FuzzySearchTarget_GlobalVariables; goto dbgi_table; + case DF_WatchViewFillKind_ThreadLocals: dbgi_target = DBGI_FuzzySearchTarget_ThreadVariables; goto dbgi_table; + case DF_WatchViewFillKind_Types: dbgi_target = DBGI_FuzzySearchTarget_UDTs; goto dbgi_table; + case DF_WatchViewFillKind_Procedures: dbgi_target = DBGI_FuzzySearchTarget_Procedures; goto dbgi_table; dbgi_table:; { //- rjf: unpack context @@ -699,7 +699,7 @@ df_eval_viz_block_list_from_watch_view_state(Arena *arena, DBGI_Scope *scope, DF //- rjf: eval/watch views main hooks internal void -df_eval_watch_view_init(DF_EvalWatchViewState *ewv, DF_View *view, DF_EvalWatchViewFillKind fill_kind) +df_watch_view_init(DF_WatchViewState *ewv, DF_View *view, DF_WatchViewFillKind fill_kind) { if(ewv->initialized == 0) { @@ -713,7 +713,7 @@ df_eval_watch_view_init(DF_EvalWatchViewState *ewv, DF_View *view, DF_EvalWatchV } internal void -df_eval_watch_view_cmds(DF_Window *ws, DF_Panel *panel, DF_View *view, DF_EvalWatchViewState *ewv, DF_CmdList *cmds) +df_watch_view_cmds(DF_Window *ws, DF_Panel *panel, DF_View *view, DF_WatchViewState *ewv, DF_CmdList *cmds) { for(DF_CmdNode *n = cmds->first; n != 0; n = n->next) { @@ -745,7 +745,7 @@ df_eval_watch_view_cmds(DF_Window *ws, DF_Panel *panel, DF_View *view, DF_EvalWa } internal void -df_eval_watch_view_build(DF_Window *ws, DF_Panel *panel, DF_View *view, DF_EvalWatchViewState *ewv, B32 modifiable, U32 default_radix, Rng2F32 rect) +df_watch_view_build(DF_Window *ws, DF_Panel *panel, DF_View *view, DF_WatchViewState *ewv, B32 modifiable, U32 default_radix, Rng2F32 rect) { ProfBeginFunction(); DBGI_Scope *scope = dbgi_scope_open(); @@ -755,7 +755,6 @@ df_eval_watch_view_build(DF_Window *ws, DF_Panel *panel, DF_View *view, DF_EvalW //- rjf: unpack arguments // F_Tag code_font = df_font_from_slot(DF_FontSlot_Code); - F32 code_font_size = df_font_size_from_slot(ws, DF_FontSlot_Code); DF_CtrlCtx ctrl_ctx = df_ctrl_ctx_from_view(ws, view); DF_Entity *thread = df_entity_from_handle(ctrl_ctx.thread); DF_Entity *process = df_entity_ancestor_from_kind(thread, DF_EntityKind_Process); @@ -830,13 +829,63 @@ df_eval_watch_view_build(DF_Window *ws, DF_Panel *panel, DF_View *view, DF_EvalW // Vec2S64 cursor_tbl = {0}; Vec2S64 mark_tbl = {0}; + Rng2S64 selection_tbl = {0}; { cursor_tbl.x = ewv->cursor.column_kind; cursor_tbl.y = df_row_num_from_viz_block_list_key(&blocks, ewv->cursor.key); mark_tbl.x = ewv->mark.column_kind; mark_tbl.y = df_row_num_from_viz_block_list_key(&blocks, ewv->mark.key); + mark_tbl = cursor_tbl; + selection_tbl = r2s64p(Min(cursor_tbl.x, mark_tbl.x), Min(cursor_tbl.y, mark_tbl.y), + Max(cursor_tbl.x, mark_tbl.x), Max(cursor_tbl.y, mark_tbl.y)); } +#if 0 + ////////////////////////////// + //- rjf: consume events & perform navigations/edits + // + UI_Focus(UI_FocusKind_On) if(ui_is_focus_active()) + { + Vec2S64 cursor = cursor_tbl; + Vec2S64 mark = mark_tbl; + UI_EventList *events = ui_events(); + for(UI_EventNode *n = events->first, *next = 0; n != 0; n = next) + { + next = n->next; + UI_Event *evt = &n->v; + B32 taken = 0; + + //- rjf: navigations + switch(evt->delta_unit) + { + case UI_EventDeltaUnit_Char: + { + + }break; + case UI_EventDeltaUnit_Line: + { + + }break; + case UI_EventDeltaUnit_Whole: + { + for(Axis2 axis = (Axis2)0; axis < Axis2_COUNT; axis = (Axis2)(axis+1)) + { + cursor.v[axis] = (evt->delta_2s32.v[axis]>0 ? params->cursor_range.max.v[axis] : evt->delta_2s32.v[axis]<0 ? params->cursor_range.min.v[axis] + !!params->cursor_min_is_empty_selection[axis] : cursor.v[axis]); + } + }break; + } + + //- rjf: consume + if(taken) + { + ui_eat_event(events, n); + } + } + cursor_tbl = cursor; + mark_tbl = mark; + } +#endif + ////////////////////////////// //- rjf: do start/end editing interaction // @@ -845,7 +894,6 @@ df_eval_watch_view_build(DF_Window *ws, DF_Panel *panel, DF_View *view, DF_EvalW B32 edit_commit = 0; B32 edit_end = 0; B32 edit_submit = 0; - String8 edit_autocomplete_string = {0}; UI_Focus(UI_FocusKind_On) { if(!ewv->input_editing && ui_is_focus_active()) @@ -881,20 +929,6 @@ df_eval_watch_view_build(DF_Window *ws, DF_Panel *panel, DF_View *view, DF_EvalW edit_commit = 1; edit_submit = 1; } -#if 0 - UI_EventList *events = ui_events(); - for(UI_EventNode *n = events->first; n != 0; n = n->next) - { - if(n->v.flags & UI_EventFlag_ReplaceAndCommit) - { - edit_commit = 1; - edit_end = 1; - edit_autocomplete_string = n->v.insertion; - ui_nav_eat_action_node(nav_actions, n); - break; - } - } -#endif } } @@ -938,7 +972,11 @@ df_eval_watch_view_build(DF_Window *ws, DF_Panel *panel, DF_View *view, DF_EvalW } UI_ScrollListSignal scroll_list_sig = {0}; UI_Focus(UI_FocusKind_On) - UI_ScrollList(&scroll_list_params, &view->scroll_pos.y, ewv->input_editing ? 0 : &cursor_tbl, &visible_row_rng, &scroll_list_sig) + UI_ScrollList(&scroll_list_params, &view->scroll_pos.y, + ewv->input_editing ? 0 : &cursor_tbl, + 0, + &visible_row_rng, + &scroll_list_sig) UI_Focus(UI_FocusKind_Null) UI_TableF(ArrayCount(col_pcts), col_pcts, "table_header") { @@ -988,7 +1026,7 @@ df_eval_watch_view_build(DF_Window *ws, DF_Panel *panel, DF_View *view, DF_EvalW //- rjf: viz blocks -> rows DF_EvalVizWindowedRowList rows = {0}; { - rows = df_eval_viz_windowed_row_list_from_viz_block_list(scratch.arena, scope, &ctrl_ctx, &parse_ctx, ¯o_map, eval_view, default_radix, code_font, code_font_size, r1s64(visible_row_rng.min-1, visible_row_rng.max), &blocks); + rows = df_eval_viz_windowed_row_list_from_viz_block_list(scratch.arena, scope, &ctrl_ctx, &parse_ctx, ¯o_map, eval_view, default_radix, code_font, ui_top_font_size(), r1s64(visible_row_rng.min-1, visible_row_rng.max), &blocks); } //- rjf: build table @@ -1001,7 +1039,7 @@ df_eval_watch_view_build(DF_Window *ws, DF_Panel *panel, DF_View *view, DF_EvalW U64 row_hash = df_hash_from_expand_key(row->key); U64 expr_hash = df_hash_from_string(row->display_expr); df_expand_tree_table_animate(&eval_view->expand_tree_table, df_dt()); - B32 row_selected = ((semantic_idx+1) == cursor_tbl.y); + B32 row_selected = (selection_tbl.min.y <= (semantic_idx+1) && (semantic_idx+1) <= selection_tbl.max.y); B32 row_expanded = df_expand_key_is_set(&eval_view->expand_tree_table, row->key); //- rjf: determine if row's data is fresh and/or bad @@ -1068,7 +1106,7 @@ df_eval_watch_view_build(DF_Window *ws, DF_Panel *panel, DF_View *view, DF_EvalW if(ui_pressed(sig)) { edit_commit = edit_commit || (!row_selected && ewv->input_editing); - next_cursor_tbl = v2s64(DF_EvalWatchViewColumnKind_Expr, (semantic_idx+1)); + next_cursor_tbl = v2s64(DF_WatchViewColumnKind_Expr, (semantic_idx+1)); pressed = 1; } @@ -1144,7 +1182,7 @@ df_eval_watch_view_build(DF_Window *ws, DF_Panel *panel, DF_View *view, DF_EvalW //- rjf: expression ProfScope("expr") { - B32 cell_selected = (row_selected && cursor_tbl.x == DF_EvalWatchViewColumnKind_Expr); + B32 cell_selected = (row_selected && selection_tbl.min.x <= DF_WatchViewColumnKind_Expr && DF_WatchViewColumnKind_Expr <= selection_tbl.max.x); B32 can_edit_expr = !(row->depth > 0 || modifiable == 0); // rjf: begin editing @@ -1278,7 +1316,7 @@ df_eval_watch_view_build(DF_Window *ws, DF_Panel *panel, DF_View *view, DF_EvalW if(ui_pressed(sig)) { edit_commit = edit_commit || (!cell_selected && ewv->input_editing); - next_cursor_tbl = v2s64(DF_EvalWatchViewColumnKind_Expr, (semantic_idx+1)); + next_cursor_tbl = v2s64(DF_WatchViewColumnKind_Expr, (semantic_idx+1)); pressed = 1; } @@ -1309,7 +1347,7 @@ df_eval_watch_view_build(DF_Window *ws, DF_Panel *panel, DF_View *view, DF_EvalW //- rjf: value ProfScope("value") { - B32 cell_selected = (row_selected && cursor_tbl.x == DF_EvalWatchViewColumnKind_Value); + B32 cell_selected = (row_selected && selection_tbl.min.x <= DF_WatchViewColumnKind_Value && DF_WatchViewColumnKind_Value <= selection_tbl.max.x); B32 value_is_error = (row->eval.errors.count != 0); B32 value_is_hook = (!value_is_error && row->value_ui_rule_spec != &df_g_nil_gfx_view_rule_spec && row->value_ui_rule_spec != 0); B32 value_is_complex = (!value_is_error && !value_is_hook && !(row->flags & DF_EvalVizRowFlag_CanEditValue)); @@ -1390,7 +1428,7 @@ df_eval_watch_view_build(DF_Window *ws, DF_Panel *panel, DF_View *view, DF_EvalW { pressed = 1; edit_commit = edit_commit || (ewv->input_editing && !cell_selected); - next_cursor_tbl = v2s64(DF_EvalWatchViewColumnKind_Value, (semantic_idx+1)); + next_cursor_tbl = v2s64(DF_WatchViewColumnKind_Value, (semantic_idx+1)); } // rjf: double-click -> start editing @@ -1408,7 +1446,7 @@ df_eval_watch_view_build(DF_Window *ws, DF_Panel *panel, DF_View *view, DF_EvalW //- rjf: type ProfScope("type") { - B32 cell_selected = (row_selected && cursor_tbl.x == DF_EvalWatchViewColumnKind_Type); + B32 cell_selected = (row_selected && selection_tbl.min.x <= DF_WatchViewColumnKind_Type && DF_WatchViewColumnKind_Type <= selection_tbl.max.x); UI_TableCell UI_Font(code_font) UI_FocusHot(cell_selected ? UI_FocusKind_On : UI_FocusKind_Off) UI_FocusActive((cell_selected && ewv->input_editing) ? UI_FocusKind_On : UI_FocusKind_Off) @@ -1426,7 +1464,7 @@ df_eval_watch_view_build(DF_Window *ws, DF_Panel *panel, DF_View *view, DF_EvalW { pressed = 1; edit_commit = edit_commit || (ewv->input_editing && !cell_selected); - next_cursor_tbl = v2s64(DF_EvalWatchViewColumnKind_Type, (semantic_idx+1)); + next_cursor_tbl = v2s64(DF_WatchViewColumnKind_Type, (semantic_idx+1)); } } } @@ -1434,7 +1472,7 @@ df_eval_watch_view_build(DF_Window *ws, DF_Panel *panel, DF_View *view, DF_EvalW //- rjf: view rule ProfScope("view rule") { - B32 cell_selected = (row_selected && cursor_tbl.x == DF_EvalWatchViewColumnKind_ViewRule); + B32 cell_selected = (row_selected && selection_tbl.min.x <= DF_WatchViewColumnKind_ViewRule && DF_WatchViewColumnKind_ViewRule <= selection_tbl.max.x); String8 view_rule = df_eval_view_rule_from_key(eval_view, row->key); // rjf: begin editing @@ -1464,7 +1502,7 @@ df_eval_watch_view_build(DF_Window *ws, DF_Panel *panel, DF_View *view, DF_EvalW { pressed = 1; edit_commit = edit_commit || (ewv->input_editing && !cell_selected); - next_cursor_tbl = v2s64(DF_EvalWatchViewColumnKind_ViewRule, (semantic_idx+1)); + next_cursor_tbl = v2s64(DF_WatchViewColumnKind_ViewRule, (semantic_idx+1)); } // rjf: double-click -> begin editing @@ -1509,22 +1547,22 @@ df_eval_watch_view_build(DF_Window *ws, DF_Panel *panel, DF_View *view, DF_EvalW //- rjf: commit edits // { - DF_EvalWatchViewColumnKind commit_column = (DF_EvalWatchViewColumnKind)cursor_tbl.x; + DF_WatchViewColumnKind commit_column = (DF_WatchViewColumnKind)cursor_tbl.x; + if(!MemoryMatchStruct(&cursor_tbl, &next_cursor_tbl)) + { + mark_tbl = next_cursor_tbl; + } cursor_tbl = next_cursor_tbl; if(commit_row != 0 && edit_commit) { ewv->input_editing = 0; String8 commit_string = str8(ewv->input_buffer, ewv->input_size); - if(edit_autocomplete_string.size != 0) - { - commit_string = edit_autocomplete_string; - } switch(commit_column) { default:break; //- rjf: expression commits - case DF_EvalWatchViewColumnKind_Expr: if(modifiable) + case DF_WatchViewColumnKind_Expr: if(modifiable) { if(commit_string.size == 0) { @@ -1553,7 +1591,7 @@ df_eval_watch_view_build(DF_Window *ws, DF_Panel *panel, DF_View *view, DF_EvalW }break; //- rjf: value commits - case DF_EvalWatchViewColumnKind_Value: + case DF_WatchViewColumnKind_Value: { Temp scratch = scratch_begin(0, 0); DF_Eval write_eval = df_eval_from_string(scratch.arena, scope, &ctrl_ctx, &parse_ctx, ¯o_map, commit_string); @@ -1569,12 +1607,12 @@ df_eval_watch_view_build(DF_Window *ws, DF_Panel *panel, DF_View *view, DF_EvalW }break; //- rjf: type commits - case DF_EvalWatchViewColumnKind_Type: + case DF_WatchViewColumnKind_Type: { }break; //- rjf: view rule commits - case DF_EvalWatchViewColumnKind_ViewRule: + case DF_WatchViewColumnKind_ViewRule: { df_eval_view_set_key_rule(eval_view, commit_row->key, commit_string); }break; @@ -1613,7 +1651,7 @@ df_eval_watch_view_build(DF_Window *ws, DF_Panel *panel, DF_View *view, DF_EvalW // struct { - DF_EvalWatchViewPoint *pt_state; + DF_WatchViewPoint *pt_state; Vec2S64 pt_tbl; } points[] = @@ -1625,7 +1663,7 @@ df_eval_watch_view_build(DF_Window *ws, DF_Panel *panel, DF_View *view, DF_EvalW { DF_ExpandKey last_key = points[point_idx].pt_state->key; DF_ExpandKey last_parent_key = points[point_idx].pt_state->parent_key; - points[point_idx].pt_state->column_kind= (DF_EvalWatchViewColumnKind)points[point_idx].pt_tbl.x; + points[point_idx].pt_state->column_kind= (DF_WatchViewColumnKind)points[point_idx].pt_tbl.x; points[point_idx].pt_state->key = df_key_from_viz_block_list_row_num(&blocks, points[point_idx].pt_tbl.y); points[point_idx].pt_state->parent_key = df_parent_key_from_viz_block_list_row_num(&blocks, points[point_idx].pt_tbl.y); if(df_expand_key_match(df_expand_key_zero(), points[point_idx].pt_state->key)) @@ -1902,7 +1940,13 @@ DF_VIEW_UI_FUNCTION_DEF(Commands) scroll_list_params.cursor_min_is_empty_selection[Axis2_Y] = 1; } UI_ScrollListSignal scroll_list_sig = {0}; - UI_Focus(UI_FocusKind_On) UI_ScrollList(&scroll_list_params, &view->scroll_pos.y, &cursor, &visible_row_range, &scroll_list_sig) + UI_Focus(UI_FocusKind_On) + UI_ScrollList(&scroll_list_params, + &view->scroll_pos.y, + &cursor, + 0, + &visible_row_range, + &scroll_list_sig) UI_Focus(UI_FocusKind_Null) { //- rjf: build buttons @@ -2346,7 +2390,13 @@ DF_VIEW_UI_FUNCTION_DEF(FileSystem) scroll_list_params.cursor_min_is_empty_selection[Axis2_Y] = 1; } UI_ScrollListSignal scroll_list_sig = {0}; - UI_Focus(UI_FocusKind_On) UI_ScrollList(&scroll_list_params, &view->scroll_pos.y, &ps->cursor, &visible_row_range, &scroll_list_sig) + UI_Focus(UI_FocusKind_On) + UI_ScrollList(&scroll_list_params, + &view->scroll_pos.y, + &ps->cursor, + 0, + &visible_row_range, + &scroll_list_sig) UI_Focus(UI_FocusKind_Null) { // rjf: up-one-directory button (at idx 0) @@ -2579,7 +2629,12 @@ DF_VIEW_UI_FUNCTION_DEF(SystemProcesses) } UI_ScrollListSignal scroll_list_sig = {0}; UI_Focus(UI_FocusKind_On) - UI_ScrollList(&scroll_list_params, &view->scroll_pos.y, &cursor, &visible_row_range, &scroll_list_sig) + UI_ScrollList(&scroll_list_params, + &view->scroll_pos.y, + &cursor, + 0, + &visible_row_range, + &scroll_list_sig) UI_Focus(UI_FocusKind_Null) { //- rjf: build rows @@ -2738,7 +2793,12 @@ DF_VIEW_UI_FUNCTION_DEF(EntityLister) } UI_ScrollListSignal scroll_list_sig = {0}; UI_Focus(UI_FocusKind_On) - UI_ScrollList(&scroll_list_params, &view->scroll_pos.y, &cursor, &visible_row_range, &scroll_list_sig) + UI_ScrollList(&scroll_list_params, + &view->scroll_pos.y, + &cursor, + 0, + &visible_row_range, + &scroll_list_sig) UI_Focus(UI_FocusKind_Null) { for(S64 idx = visible_row_range.min; @@ -2882,7 +2942,12 @@ DF_VIEW_UI_FUNCTION_DEF(SymbolLister) } UI_ScrollListSignal scroll_list_sig = {0}; UI_Focus(UI_FocusKind_On) - UI_ScrollList(&scroll_list_params, &view->scroll_pos.y, &slv->cursor, &visible_row_range, &scroll_list_sig) + UI_ScrollList(&scroll_list_params, + &view->scroll_pos.y, + &slv->cursor, + 0, + &visible_row_range, + &scroll_list_sig) UI_Focus(UI_FocusKind_Null) UI_Font(df_font_from_slot(DF_FontSlot_Code)) { @@ -3102,7 +3167,12 @@ DF_VIEW_UI_FUNCTION_DEF(Target) Vec2S64 next_cursor = tv->cursor; UI_ScrollListSignal scroll_list_sig = {0}; UI_Focus(UI_FocusKind_On) - UI_ScrollList(&scroll_list_params, &view->scroll_pos.y, tv->input_editing ? 0 : &tv->cursor, &visible_row_range, &scroll_list_sig) + UI_ScrollList(&scroll_list_params, + &view->scroll_pos.y, + tv->input_editing ? 0 : &tv->cursor, + 0, + &visible_row_range, + &scroll_list_sig) UI_Focus(UI_FocusKind_Null) { next_cursor = tv->cursor; @@ -3344,7 +3414,12 @@ DF_VIEW_UI_FUNCTION_DEF(Targets) } UI_ScrollListSignal scroll_list_sig = {0}; UI_Focus(UI_FocusKind_On) - UI_ScrollList(&scroll_list_params, &view->scroll_pos.y, &cursor, &visible_row_range, &scroll_list_sig) + UI_ScrollList(&scroll_list_params, + &view->scroll_pos.y, + &cursor, + 0, + &visible_row_range, + &scroll_list_sig) UI_Focus(UI_FocusKind_Null) { // rjf: add new ctrl @@ -3575,7 +3650,12 @@ DF_VIEW_UI_FUNCTION_DEF(FilePathMap) } UI_ScrollListSignal scroll_list_sig = {0}; UI_Focus(UI_FocusKind_On) - UI_ScrollList(&scroll_list_params, &view->scroll_pos.y, fpms->input_editing ? 0 : &fpms->cursor, &visible_row_range, &scroll_list_sig) + UI_ScrollList(&scroll_list_params, + &view->scroll_pos.y, + fpms->input_editing ? 0 : &fpms->cursor, + 0, + &visible_row_range, + &scroll_list_sig) UI_Focus(UI_FocusKind_Null) UI_TableF(ArrayCount(col_pcts), col_pcts, "###tbl") { @@ -3893,7 +3973,12 @@ DF_VIEW_UI_FUNCTION_DEF(AutoViewRules) } UI_ScrollListSignal scroll_list_sig = {0}; UI_Focus(UI_FocusKind_On) - UI_ScrollList(&scroll_list_params, &view->scroll_pos.y, avrs->input_editing ? 0 : &avrs->cursor, &visible_row_range, &scroll_list_sig) + UI_ScrollList(&scroll_list_params, + &view->scroll_pos.y, + avrs->input_editing ? 0 : &avrs->cursor, + 0, + &visible_row_range, + &scroll_list_sig) UI_Focus(UI_FocusKind_Null) UI_TableF(ArrayCount(col_pcts), col_pcts, "###tbl") { @@ -4179,7 +4264,12 @@ DF_VIEW_UI_FUNCTION_DEF(Scheduler) } UI_ScrollListSignal scroll_list_sig = {0}; UI_Focus(UI_FocusKind_On) - UI_ScrollList(&scroll_list_params, &view->scroll_pos.y, &cursor, &visible_row_range, &scroll_list_sig) + UI_ScrollList(&scroll_list_params, + &view->scroll_pos.y, + &cursor, + 0, + &visible_row_range, + &scroll_list_sig) UI_Focus(UI_FocusKind_Null) UI_TableF(0, 0, "scheduler_table") { @@ -4348,6 +4438,7 @@ DF_VIEW_UI_FUNCTION_DEF(CallStack) { B32 initialized; Vec2S64 cursor; + Vec2S64 mark; F32 selection_col_pct; F32 module_col_pct; F32 function_name_col_pct; @@ -4376,7 +4467,12 @@ DF_VIEW_UI_FUNCTION_DEF(CallStack) } UI_ScrollListSignal scroll_list_sig = {0}; UI_Focus(UI_FocusKind_On) - UI_ScrollList(&scroll_list_params, &view->scroll_pos.y, &cs->cursor, &visible_row_range, &scroll_list_sig) + UI_ScrollList(&scroll_list_params, + &view->scroll_pos.y, + &cs->cursor, + &cs->mark, + &visible_row_range, + &scroll_list_sig) UI_Focus(UI_FocusKind_Null) { Vec2S64 next_cursor = cs->cursor; @@ -4706,7 +4802,12 @@ DF_VIEW_UI_FUNCTION_DEF(Modules) } UI_ScrollListSignal scroll_list_sig = {0}; UI_Focus(UI_FocusKind_On) - UI_ScrollList(&scroll_list_params, &view->scroll_pos.y, mv->txt_editing ? 0 : &cursor, &visible_row_range, &scroll_list_sig) + UI_ScrollList(&scroll_list_params, + &view->scroll_pos.y, + mv->txt_editing ? 0 : &cursor, + 0, + &visible_row_range, + &scroll_list_sig) UI_Focus(UI_FocusKind_Null) UI_TableF(ArrayCount(col_pcts), col_pcts, "modules_table") { @@ -6955,8 +7056,8 @@ DF_VIEW_UI_FUNCTION_DEF(Disassembly) DF_VIEW_SETUP_FUNCTION_DEF(Watch) { ProfBeginFunction(); - DF_EvalWatchViewState *ewv = df_view_user_state(view, DF_EvalWatchViewState); - df_eval_watch_view_init(ewv, view, DF_EvalWatchViewFillKind_Mutable); + DF_WatchViewState *ewv = df_view_user_state(view, DF_WatchViewState); + df_watch_view_init(ewv, view, DF_WatchViewFillKind_Mutable); // rjf: add roots for watches { @@ -6988,7 +7089,7 @@ DF_VIEW_STRING_FROM_STATE_FUNCTION_DEF(Watch) { Temp scratch = scratch_begin(&arena, 1); String8List strs = {0}; - DF_EvalWatchViewState *ewv = df_view_user_state(view, DF_EvalWatchViewState); + DF_WatchViewState *ewv = df_view_user_state(view, DF_WatchViewState); DF_EvalViewKey eval_view_key = df_eval_view_key_from_eval_watch_view(ewv); DF_EvalView *eval_view = df_eval_view_from_key(eval_view_key); { @@ -7018,16 +7119,16 @@ DF_VIEW_STRING_FROM_STATE_FUNCTION_DEF(Watch) DF_VIEW_CMD_FUNCTION_DEF(Watch) { ProfBeginFunction(); - DF_EvalWatchViewState *ewv = df_view_user_state(view, DF_EvalWatchViewState); - df_eval_watch_view_cmds(ws, panel, view, ewv, cmds); + DF_WatchViewState *ewv = df_view_user_state(view, DF_WatchViewState); + df_watch_view_cmds(ws, panel, view, ewv, cmds); ProfEnd(); } DF_VIEW_UI_FUNCTION_DEF(Watch) { ProfBeginFunction(); - DF_EvalWatchViewState *ewv = df_view_user_state(view, DF_EvalWatchViewState); - df_eval_watch_view_build(ws, panel, view, ewv, 1*(view->query_string_size == 0), 10, rect); + DF_WatchViewState *ewv = df_view_user_state(view, DF_WatchViewState); + df_watch_view_build(ws, panel, view, ewv, 1*(view->query_string_size == 0), 10, rect); ProfEnd(); } @@ -7040,9 +7141,9 @@ DF_VIEW_CMD_FUNCTION_DEF(Locals) {} DF_VIEW_UI_FUNCTION_DEF(Locals) { ProfBeginFunction(); - DF_EvalWatchViewState *ewv = df_view_user_state(view, DF_EvalWatchViewState); - df_eval_watch_view_init(ewv, view, DF_EvalWatchViewFillKind_Locals); - df_eval_watch_view_build(ws, panel, view, ewv, 0, 10, rect); + DF_WatchViewState *ewv = df_view_user_state(view, DF_WatchViewState); + df_watch_view_init(ewv, view, DF_WatchViewFillKind_Locals); + df_watch_view_build(ws, panel, view, ewv, 0, 10, rect); ProfEnd(); } @@ -7055,9 +7156,9 @@ DF_VIEW_CMD_FUNCTION_DEF(Registers) {} DF_VIEW_UI_FUNCTION_DEF(Registers) { ProfBeginFunction(); - DF_EvalWatchViewState *ewv = df_view_user_state(view, DF_EvalWatchViewState); - df_eval_watch_view_init(ewv, view, DF_EvalWatchViewFillKind_Registers); - df_eval_watch_view_build(ws, panel, view, ewv, 0, 16, rect); + DF_WatchViewState *ewv = df_view_user_state(view, DF_WatchViewState); + df_watch_view_init(ewv, view, DF_WatchViewFillKind_Registers); + df_watch_view_build(ws, panel, view, ewv, 0, 16, rect); ProfEnd(); } @@ -7070,9 +7171,9 @@ DF_VIEW_CMD_FUNCTION_DEF(Globals) {} DF_VIEW_UI_FUNCTION_DEF(Globals) { ProfBeginFunction(); - DF_EvalWatchViewState *ewv = df_view_user_state(view, DF_EvalWatchViewState); - df_eval_watch_view_init(ewv, view, DF_EvalWatchViewFillKind_Globals); - df_eval_watch_view_build(ws, panel, view, ewv, 0, 10, rect); + DF_WatchViewState *ewv = df_view_user_state(view, DF_WatchViewState); + df_watch_view_init(ewv, view, DF_WatchViewFillKind_Globals); + df_watch_view_build(ws, panel, view, ewv, 0, 10, rect); ProfEnd(); } @@ -7085,9 +7186,9 @@ DF_VIEW_CMD_FUNCTION_DEF(ThreadLocals) {} DF_VIEW_UI_FUNCTION_DEF(ThreadLocals) { ProfBeginFunction(); - DF_EvalWatchViewState *ewv = df_view_user_state(view, DF_EvalWatchViewState); - df_eval_watch_view_init(ewv, view, DF_EvalWatchViewFillKind_ThreadLocals); - df_eval_watch_view_build(ws, panel, view, ewv, 0, 10, rect); + DF_WatchViewState *ewv = df_view_user_state(view, DF_WatchViewState); + df_watch_view_init(ewv, view, DF_WatchViewFillKind_ThreadLocals); + df_watch_view_build(ws, panel, view, ewv, 0, 10, rect); ProfEnd(); } @@ -7100,9 +7201,9 @@ DF_VIEW_CMD_FUNCTION_DEF(Types) {} DF_VIEW_UI_FUNCTION_DEF(Types) { ProfBeginFunction(); - DF_EvalWatchViewState *ewv = df_view_user_state(view, DF_EvalWatchViewState); - df_eval_watch_view_init(ewv, view, DF_EvalWatchViewFillKind_Types); - df_eval_watch_view_build(ws, panel, view, ewv, 0, 10, rect); + DF_WatchViewState *ewv = df_view_user_state(view, DF_WatchViewState); + df_watch_view_init(ewv, view, DF_WatchViewFillKind_Types); + df_watch_view_build(ws, panel, view, ewv, 0, 10, rect); ProfEnd(); } @@ -7115,9 +7216,9 @@ DF_VIEW_CMD_FUNCTION_DEF(Procedures) {} DF_VIEW_UI_FUNCTION_DEF(Procedures) { ProfBeginFunction(); - DF_EvalWatchViewState *ewv = df_view_user_state(view, DF_EvalWatchViewState); - df_eval_watch_view_init(ewv, view, DF_EvalWatchViewFillKind_Procedures); - df_eval_watch_view_build(ws, panel, view, ewv, 0, 10, rect); + DF_WatchViewState *ewv = df_view_user_state(view, DF_WatchViewState); + df_watch_view_init(ewv, view, DF_WatchViewFillKind_Procedures); + df_watch_view_build(ws, panel, view, ewv, 0, 10, rect); ProfEnd(); } @@ -8669,7 +8770,12 @@ DF_VIEW_UI_FUNCTION_DEF(Breakpoints) } UI_ScrollListSignal scroll_list_sig = {0}; UI_Focus(UI_FocusKind_On) - UI_ScrollList(&scroll_list_params, &view->scroll_pos.y, &cursor, &visible_row_range, &scroll_list_sig) + UI_ScrollList(&scroll_list_params, + &view->scroll_pos.y, + &cursor, + 0, + &visible_row_range, + &scroll_list_sig) UI_Focus(UI_FocusKind_Null) UI_TableF(ArrayCount(col_pcts), col_pcts, "breakpoints_table") { @@ -8839,7 +8945,12 @@ DF_VIEW_UI_FUNCTION_DEF(WatchPins) } UI_ScrollListSignal scroll_list_sig = {0}; UI_Focus(UI_FocusKind_On) - UI_ScrollList(&scroll_list_params, &view->scroll_pos.y, &cursor, &visible_row_range, &scroll_list_sig) + UI_ScrollList(&scroll_list_params, + &view->scroll_pos.y, + &cursor, + 0, + &visible_row_range, + &scroll_list_sig) UI_Focus(UI_FocusKind_Null) UI_TableF(ArrayCount(col_pcts), col_pcts, "pins_table") { @@ -9013,7 +9124,12 @@ DF_VIEW_UI_FUNCTION_DEF(ExceptionFilters) } UI_ScrollListSignal scroll_list_sig = {0}; UI_Focus(UI_FocusKind_On) - UI_ScrollList(&scroll_list_params, &view->scroll_pos.y, &sv->cursor, &visible_row_range, &scroll_list_sig) + UI_ScrollList(&scroll_list_params, + &view->scroll_pos.y, + &sv->cursor, + 0, + &visible_row_range, + &scroll_list_sig) UI_Focus(UI_FocusKind_Null) { for(S64 row = visible_row_range.min; row <= visible_row_range.max && row < opts.count; row += 1) @@ -9369,7 +9485,12 @@ DF_VIEW_UI_FUNCTION_DEF(Theme) } UI_ScrollListSignal scroll_list_sig = {0}; UI_Focus(UI_FocusKind_On) - UI_ScrollList(&scroll_list_params, &view->scroll_pos.y, &sv->cursor, &visible_row_range, &scroll_list_sig) + UI_ScrollList(&scroll_list_params, + &view->scroll_pos.y, + &sv->cursor, + 0, + &visible_row_range, + &scroll_list_sig) UI_Focus(UI_FocusKind_Null) { for(S64 row = visible_row_range.min; row <= visible_row_range.max; row += 1) diff --git a/src/df/gfx/df_views.h b/src/df/gfx/df_views.h index fabaa30b..a477ba6d 100644 --- a/src/df/gfx/df_views.h +++ b/src/df/gfx/df_views.h @@ -281,48 +281,48 @@ struct DF_EvalRoot U8 *expr_buffer; }; -typedef enum DF_EvalWatchViewColumnKind +typedef enum DF_WatchViewColumnKind { - DF_EvalWatchViewColumnKind_Expr, - DF_EvalWatchViewColumnKind_Value, - DF_EvalWatchViewColumnKind_Type, - DF_EvalWatchViewColumnKind_ViewRule, - DF_EvalWatchViewColumnKind_COUNT + DF_WatchViewColumnKind_Expr, + DF_WatchViewColumnKind_Value, + DF_WatchViewColumnKind_Type, + DF_WatchViewColumnKind_ViewRule, + DF_WatchViewColumnKind_COUNT } -DF_EvalWatchViewColumnKind; +DF_WatchViewColumnKind; -typedef enum DF_EvalWatchViewFillKind +typedef enum DF_WatchViewFillKind { - DF_EvalWatchViewFillKind_Mutable, - DF_EvalWatchViewFillKind_Registers, - DF_EvalWatchViewFillKind_Locals, - DF_EvalWatchViewFillKind_Globals, - DF_EvalWatchViewFillKind_ThreadLocals, - DF_EvalWatchViewFillKind_Types, - DF_EvalWatchViewFillKind_Procedures, - DF_EvalWatchViewFillKind_COUNT + DF_WatchViewFillKind_Mutable, + DF_WatchViewFillKind_Registers, + DF_WatchViewFillKind_Locals, + DF_WatchViewFillKind_Globals, + DF_WatchViewFillKind_ThreadLocals, + DF_WatchViewFillKind_Types, + DF_WatchViewFillKind_Procedures, + DF_WatchViewFillKind_COUNT } -DF_EvalWatchViewFillKind; +DF_WatchViewFillKind; -typedef struct DF_EvalWatchViewPoint DF_EvalWatchViewPoint; -struct DF_EvalWatchViewPoint +typedef struct DF_WatchViewPoint DF_WatchViewPoint; +struct DF_WatchViewPoint { - DF_EvalWatchViewColumnKind column_kind; + DF_WatchViewColumnKind column_kind; DF_ExpandKey parent_key; DF_ExpandKey key; }; -typedef struct DF_EvalWatchViewState DF_EvalWatchViewState; -struct DF_EvalWatchViewState +typedef struct DF_WatchViewState DF_WatchViewState; +struct DF_WatchViewState { B32 initialized; // rjf: fill kind (way that the contents of the watch view are computed) - DF_EvalWatchViewFillKind fill_kind; + DF_WatchViewFillKind fill_kind; // rjf; table cursor state - DF_EvalWatchViewPoint cursor; - DF_EvalWatchViewPoint mark; + DF_WatchViewPoint cursor; + DF_WatchViewPoint mark; // rjf: text input state TxtPt input_cursor; @@ -454,27 +454,27 @@ internal DF_EntityListerItemArray df_entity_lister_item_array_from_list(Arena *a internal void df_entity_lister_item_array_sort_by_strength__in_place(DF_EntityListerItemArray array); //////////////////////////////// -//~ rjf: Eval/Watch Views +//~ rjf: Watch Views //- rjf: eval watch view instance -> eval view key -internal DF_EvalViewKey df_eval_view_key_from_eval_watch_view(DF_EvalWatchViewState *ewv); +internal DF_EvalViewKey df_eval_view_key_from_eval_watch_view(DF_WatchViewState *ewv); //- rjf: root allocation/deallocation/mutation -internal DF_EvalRoot * df_eval_root_alloc(DF_View *view, DF_EvalWatchViewState *ews); -internal void df_eval_root_release(DF_EvalWatchViewState *ews, DF_EvalRoot *root); +internal DF_EvalRoot * df_eval_root_alloc(DF_View *view, DF_WatchViewState *ews); +internal void df_eval_root_release(DF_WatchViewState *ews, DF_EvalRoot *root); internal void df_eval_root_equip_string(DF_EvalRoot *root, String8 string); -internal DF_EvalRoot * df_eval_root_from_string(DF_EvalWatchViewState *ews, String8 string); -internal DF_EvalRoot * df_eval_root_from_expand_key(DF_EvalWatchViewState *ews, DF_EvalView *eval_view, DF_ExpandKey expand_key); +internal DF_EvalRoot * df_eval_root_from_string(DF_WatchViewState *ews, String8 string); +internal DF_EvalRoot * df_eval_root_from_expand_key(DF_WatchViewState *ews, DF_EvalView *eval_view, DF_ExpandKey expand_key); internal String8 df_string_from_eval_root(DF_EvalRoot *root); internal DF_ExpandKey df_parent_expand_key_from_eval_root(DF_EvalRoot *root); internal DF_ExpandKey df_expand_key_from_eval_root(DF_EvalRoot *root); //- rjf: windowed watch tree visualization -internal DF_EvalVizBlockList df_eval_viz_block_list_from_watch_view_state(Arena *arena, DBGI_Scope *scope, DF_CtrlCtx *ctrl_ctx, EVAL_ParseCtx *parse_ctx, EVAL_String2ExprMap *macro_map, DF_View *view, DF_EvalWatchViewState *ews); +internal DF_EvalVizBlockList df_eval_viz_block_list_from_watch_view_state(Arena *arena, DBGI_Scope *scope, DF_CtrlCtx *ctrl_ctx, EVAL_ParseCtx *parse_ctx, EVAL_String2ExprMap *macro_map, DF_View *view, DF_WatchViewState *ews); //- rjf: eval/watch views main hooks -internal void df_eval_watch_view_init(DF_EvalWatchViewState *ewv, DF_View *view, DF_EvalWatchViewFillKind fill_kind); -internal void df_eval_watch_view_cmds(DF_Window *ws, DF_Panel *panel, DF_View *view, DF_EvalWatchViewState *ewv, DF_CmdList *cmds); -internal void df_eval_watch_view_build(DF_Window *ws, DF_Panel *panel, DF_View *view, DF_EvalWatchViewState *ewv, B32 modifiable, U32 default_radix, Rng2F32 rect); +internal void df_watch_view_init(DF_WatchViewState *ewv, DF_View *view, DF_WatchViewFillKind fill_kind); +internal void df_watch_view_cmds(DF_Window *ws, DF_Panel *panel, DF_View *view, DF_WatchViewState *ewv, DF_CmdList *cmds); +internal void df_watch_view_build(DF_Window *ws, DF_Panel *panel, DF_View *view, DF_WatchViewState *ewv, B32 modifiable, U32 default_radix, Rng2F32 rect); #endif // DEBUG_FRONTEND_VIEWS_H diff --git a/src/ui/ui_basic_widgets.c b/src/ui/ui_basic_widgets.c index 2b7dfa72..c1fa8983 100644 --- a/src/ui/ui_basic_widgets.c +++ b/src/ui/ui_basic_widgets.c @@ -1335,7 +1335,7 @@ thread_static Vec2F32 ui_scroll_list_dim_px = {0}; thread_static Rng1S64 ui_scroll_list_scroll_idx_rng = {0}; internal void -ui_scroll_list_begin(UI_ScrollListParams *params, UI_ScrollPt *scroll_pt, Vec2S64 *cursor_out, Rng1S64 *visible_row_range_out, UI_ScrollListSignal *signal_out) +ui_scroll_list_begin(UI_ScrollListParams *params, UI_ScrollPt *scroll_pt, Vec2S64 *cursor_out, Vec2S64 *mark_out, Rng1S64 *visible_row_range_out, UI_ScrollListSignal *signal_out) { //- rjf: unpack arguments Rng1S64 scroll_row_idx_range = r1s64(params->item_range.min, ClampBot(params->item_range.min, params->item_range.max-1)); @@ -1347,12 +1347,13 @@ ui_scroll_list_begin(UI_ScrollListParams *params, UI_ScrollPt *scroll_pt, Vec2S6 { UI_EventList *events = ui_events(); Vec2S64 cursor = *cursor_out; + Vec2S64 mark = mark_out ? *mark_out : cursor; for(UI_EventNode *n = events->first, *next = 0; n != 0; n = next) { next = n->next; UI_Event *evt = &n->v; if((evt->delta_2s32.x == 0 && evt->delta_2s32.y == 0) || - evt->flags & (UI_EventFlag_KeepMark|UI_EventFlag_Delete)) + evt->flags & UI_EventFlag_Delete) { continue; } @@ -1393,10 +1394,18 @@ ui_scroll_list_begin(UI_ScrollListParams *params, UI_ScrollPt *scroll_pt, Vec2S6 } }break; } + if(!(evt->flags & UI_EventFlag_KeepMark)) + { + mark = cursor; + } } if(moved) { *cursor_out = cursor; + if(mark_out) + { + *mark_out = mark; + } } } diff --git a/src/ui/ui_basic_widgets.h b/src/ui/ui_basic_widgets.h index cc934a52..dc8c2394 100644 --- a/src/ui/ui_basic_widgets.h +++ b/src/ui/ui_basic_widgets.h @@ -157,7 +157,7 @@ internal U64 ui_scroll_list_row_from_item(UI_ScrollListRowBlockArray *blocks, U6 internal U64 ui_scroll_list_item_from_row(UI_ScrollListRowBlockArray *blocks, U64 row); internal UI_ScrollPt ui_scroll_bar(Axis2 axis, UI_Size off_axis_size, UI_ScrollPt pt, Rng1S64 idx_range, S64 view_num_indices); -internal void ui_scroll_list_begin(UI_ScrollListParams *params, UI_ScrollPt *scroll_pt_out, Vec2S64 *cursor_out, Rng1S64 *visible_row_range_out, UI_ScrollListSignal *signal_out); +internal void ui_scroll_list_begin(UI_ScrollListParams *params, UI_ScrollPt *scroll_pt_out, Vec2S64 *cursor_out, Vec2S64 *mark_out, Rng1S64 *visible_row_range_out, UI_ScrollListSignal *signal_out); internal void ui_scroll_list_end(void); //////////////////////////////// @@ -180,6 +180,6 @@ internal void ui_scroll_list_end(void); #define UI_TableCell DeferLoop(ui_table_cell_begin(), ui_table_cell_end()) #define UI_TableCellSized(size) DeferLoop(ui_table_cell_sized_begin(size), ui_table_cell_end()) -#define UI_ScrollList(params, scroll_pt_out, cursor_out, visible_row_range_out, signal_out) DeferLoop(ui_scroll_list_begin((params), (scroll_pt_out), (cursor_out), (visible_row_range_out), (signal_out)), ui_scroll_list_end()) +#define UI_ScrollList(params, scroll_pt_out, cursor_out, mark_out, visible_row_range_out, signal_out) DeferLoop(ui_scroll_list_begin((params), (scroll_pt_out), (cursor_out), (mark_out), (visible_row_range_out), (signal_out)), ui_scroll_list_end()) #endif // UI_BASIC_WIDGETS_H From f8b688096a7da53221dd378c116210936fe7f054 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Tue, 14 May 2024 11:39:18 -0700 Subject: [PATCH 21/30] fix crash on tpi-less pdbs --- src/raddbgi_from_pdb/raddbgi_from_pdb.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/raddbgi_from_pdb/raddbgi_from_pdb.c b/src/raddbgi_from_pdb/raddbgi_from_pdb.c index 26901abb..a85e1105 100644 --- a/src/raddbgi_from_pdb/raddbgi_from_pdb.c +++ b/src/raddbgi_from_pdb/raddbgi_from_pdb.c @@ -2057,7 +2057,7 @@ internal TS_TASK_FUNCTION_DEF(p2r_symbol_stream_convert_task__entry_point) // rjf: unpack proc's container type RDIM_Type *container_type = 0; U64 container_name_opl = p2r_end_of_cplusplus_container_name(name); - if(container_name_opl > 2) + if(container_name_opl > 2 && in->tpi_hash != 0 && in->tpi_leaf != 0) { String8 container_name = str8(name.str, container_name_opl - 2); CV_TypeId cv_type_id = pdb_tpi_first_itype_from_name(in->tpi_hash, in->tpi_leaf, container_name, 0); From 16de33245c3e51c2abb64e70d84639289272bcbb Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Tue, 14 May 2024 16:25:24 -0700 Subject: [PATCH 22/30] first half of first pass at multi-cursor watch window --- src/df/gfx/df_views.c | 749 ++++++++++++++++++++++++++++++++---------- src/df/gfx/df_views.h | 27 +- 2 files changed, 602 insertions(+), 174 deletions(-) diff --git a/src/df/gfx/df_views.c b/src/df/gfx/df_views.c index 64b568bd..f5c9aecf 100644 --- a/src/df/gfx/df_views.c +++ b/src/df/gfx/df_views.c @@ -472,6 +472,43 @@ df_expand_key_from_eval_root(DF_EvalRoot *root) return key; } +//- rjf: watch view points <-> table coordinates + +internal DF_WatchViewPoint +df_watch_view_point_from_tbl(DF_EvalVizBlockList *blocks, Vec2S64 tbl) +{ + DF_WatchViewPoint pt = {0}; + pt.column_kind = (DF_WatchViewColumnKind)(tbl.x%DF_WatchViewColumnKind_COUNT); + pt.key = df_key_from_viz_block_list_row_num(blocks, tbl.y); + pt.parent_key = df_parent_key_from_viz_block_list_row_num(blocks, tbl.y); + return pt; +} + +internal Vec2S64 +df_tbl_from_watch_view_point(DF_EvalVizBlockList *blocks, DF_WatchViewPoint pt) +{ + Vec2S64 tbl = {0}; + tbl.x = (S64)pt.column_kind; + tbl.y = df_row_num_from_viz_block_list_key(blocks, pt.key); + return tbl; +} + +//- rjf: table coordinates -> strings + +internal String8 +df_string_from_eval_viz_row_column_kind(Arena *arena, DF_EvalView *ev, TG_Graph *graph, RDI_Parsed *rdi, DF_EvalVizRow *row, DF_WatchViewColumnKind col_kind, B32 editable) +{ + String8 result = {0}; + switch(col_kind) + { + case DF_WatchViewColumnKind_Expr: {result = editable ? row->edit_expr : row->display_expr;}break; + case DF_WatchViewColumnKind_Value: {result = editable ? row->edit_value : row->display_value;}break; + case DF_WatchViewColumnKind_Type: {result = tg_string_from_key(arena, graph, rdi, row->eval.type_key);}break; + case DF_WatchViewColumnKind_ViewRule:{result = df_eval_view_rule_from_key(ev, row->key);}break; + } + return result; +} + //- rjf: windowed watch tree visualization (both single-line and multi-line) internal DF_EvalVizBlockList @@ -709,6 +746,7 @@ df_watch_view_init(DF_WatchViewState *ewv, DF_View *view, DF_WatchViewFillKind f ewv->type_column_pct = 0.15f; ewv->view_rule_column_pct = 0.30f; ewv->fill_kind = fill_kind; + ewv->text_edit_arena = df_view_push_arena_ext(view); } } @@ -762,6 +800,8 @@ df_watch_view_build(DF_Window *ws, DF_Panel *panel, DF_View *view, DF_WatchViewS DF_EvalViewKey eval_view_key = df_eval_view_key_from_eval_watch_view(ewv); DF_EvalView *eval_view = df_eval_view_from_key(eval_view_key); String8 filter = str8(view->query_buffer, view->query_string_size); + F32 row_height_px = floor_f32(ui_top_font_size()*2.5f); + S64 num_possible_visible_rows = (S64)(dim_2f32(rect).y/row_height_px); ////////////////////////////// //- rjf: process * thread info -> parse_ctx @@ -769,165 +809,489 @@ df_watch_view_build(DF_Window *ws, DF_Panel *panel, DF_View *view, DF_WatchViewS EVAL_ParseCtx parse_ctx = df_eval_parse_ctx_from_process_vaddr(scope, process, thread_ip_vaddr); ////////////////////////////// - //- rjf: state -> macro map - // - EVAL_String2ExprMap macro_map = eval_string2expr_map_make(scratch.arena, 256); - for(DF_EvalRoot *root = ewv->first_root; root != 0; root = root->next) - { - String8 root_expr = str8(root->expr_buffer, root->expr_buffer_string_size); - - //- rjf: unpack arguments - DF_Entity *process = thread->parent; - U64 unwind_count = ctrl_ctx.unwind_count; - CTRL_Unwind unwind = df_query_cached_unwind_from_thread(thread); - Architecture arch = df_architecture_from_entity(thread); - U64 reg_size = regs_block_size_from_architecture(arch); - U64 thread_unwind_ip_vaddr = 0; - void *thread_unwind_regs_block = push_array(scratch.arena, U8, reg_size); - { - U64 idx = 0; - for(CTRL_UnwindFrame *f = unwind.first; f != 0; f = f->next, idx += 1) - { - if(idx == unwind_count) - { - thread_unwind_ip_vaddr = f->rip; - thread_unwind_regs_block = f->regs; - break; - } - } - } - - //- rjf: lex & parse - EVAL_TokenArray tokens = eval_token_array_from_text(scratch.arena, root_expr); - EVAL_ParseResult parse = eval_parse_expr_from_text_tokens(scratch.arena, &parse_ctx, root_expr, &tokens); - EVAL_ErrorList errors = parse.errors; - if(errors.count == 0) - { - eval_push_leaf_ident_exprs_from_expr__in_place(scratch.arena, ¯o_map, parse.expr, &errors); - } - } - - ////////////////////////////// - //- rjf: state -> viz blocks - // - DF_EvalVizBlockList blocks = df_eval_viz_block_list_from_watch_view_state(scratch.arena, scope, &ctrl_ctx, &parse_ctx, ¯o_map, view, ewv); - - ////////////////////////////// - //- rjf: does this eval watch view allow mutation? -> add extra block for editable empty row - // - DF_ExpandKey empty_row_parent_key = df_expand_key_make(max_U64, max_U64); - DF_ExpandKey empty_row_key = df_expand_key_make(df_hash_from_expand_key(empty_row_parent_key), 0); - if(modifiable) - { - DF_EvalVizBlock *b = df_eval_viz_block_begin(scratch.arena, DF_EvalVizBlockKind_Null, empty_row_parent_key, empty_row_key, 0); - b->visual_idx_range = b->semantic_idx_range = r1u64(0, 1); - df_eval_viz_block_end(&blocks, b); - } - - ////////////////////////////// - //- rjf: selection state * blocks -> 2D table coordinates + //- rjf: consume events & perform navigations/edits - calculate state // + EVAL_String2ExprMap macro_map = {0}; + DF_EvalVizBlockList blocks = {0}; + UI_ScrollListRowBlockArray row_blocks = {0}; Vec2S64 cursor_tbl = {0}; Vec2S64 mark_tbl = {0}; Rng2S64 selection_tbl = {0}; - { - cursor_tbl.x = ewv->cursor.column_kind; - cursor_tbl.y = df_row_num_from_viz_block_list_key(&blocks, ewv->cursor.key); - mark_tbl.x = ewv->mark.column_kind; - mark_tbl.y = df_row_num_from_viz_block_list_key(&blocks, ewv->mark.key); - mark_tbl = cursor_tbl; - selection_tbl = r2s64p(Min(cursor_tbl.x, mark_tbl.x), Min(cursor_tbl.y, mark_tbl.y), - Max(cursor_tbl.x, mark_tbl.x), Max(cursor_tbl.y, mark_tbl.y)); - } - -#if 0 - ////////////////////////////// - //- rjf: consume events & perform navigations/edits - // - UI_Focus(UI_FocusKind_On) if(ui_is_focus_active()) - { - Vec2S64 cursor = cursor_tbl; - Vec2S64 mark = mark_tbl; - UI_EventList *events = ui_events(); - for(UI_EventNode *n = events->first, *next = 0; n != 0; n = next) - { - next = n->next; - UI_Event *evt = &n->v; - B32 taken = 0; - - //- rjf: navigations - switch(evt->delta_unit) - { - case UI_EventDeltaUnit_Char: - { - - }break; - case UI_EventDeltaUnit_Line: - { - - }break; - case UI_EventDeltaUnit_Whole: - { - for(Axis2 axis = (Axis2)0; axis < Axis2_COUNT; axis = (Axis2)(axis+1)) - { - cursor.v[axis] = (evt->delta_2s32.v[axis]>0 ? params->cursor_range.max.v[axis] : evt->delta_2s32.v[axis]<0 ? params->cursor_range.min.v[axis] + !!params->cursor_min_is_empty_selection[axis] : cursor.v[axis]); - } - }break; - } - - //- rjf: consume - if(taken) - { - ui_eat_event(events, n); - } - } - cursor_tbl = cursor; - mark_tbl = mark; - } -#endif - - ////////////////////////////// - //- rjf: do start/end editing interaction - // - B32 edit_begin = 0; - B32 edit_begin_or_expand = 0; - B32 edit_commit = 0; - B32 edit_end = 0; - B32 edit_submit = 0; UI_Focus(UI_FocusKind_On) { - if(!ewv->input_editing && ui_is_focus_active()) + UI_EventList *events = ui_events(); + B32 state_dirty = 1; + B32 cursor_dirty__tbl = 0; + for(UI_EventNode *event_n = events->first, *next = 0;; event_n = next) { - UI_EventList *events = ui_events(); - for(UI_EventNode *n = events->first; n != 0; n = n->next) + ////////////////////////// + //- rjf: state -> macro map + // + if(state_dirty) { - if(!str8_match(n->v.string, str8_lit(" "), 0) && (n->v.string.size != 0 || n->v.flags & UI_EventFlag_Paste)) + macro_map = eval_string2expr_map_make(scratch.arena, 256); + for(DF_EvalRoot *root = ewv->first_root; root != 0; root = root->next) { - edit_begin = 1; - break; + String8 root_expr = str8(root->expr_buffer, root->expr_buffer_string_size); + + //- rjf: unpack arguments + DF_Entity *process = thread->parent; + U64 unwind_count = ctrl_ctx.unwind_count; + CTRL_Unwind unwind = df_query_cached_unwind_from_thread(thread); + Architecture arch = df_architecture_from_entity(thread); + U64 reg_size = regs_block_size_from_architecture(arch); + U64 thread_unwind_ip_vaddr = 0; + void *thread_unwind_regs_block = push_array(scratch.arena, U8, reg_size); + { + U64 idx = 0; + for(CTRL_UnwindFrame *f = unwind.first; f != 0; f = f->next, idx += 1) + { + if(idx == unwind_count) + { + thread_unwind_ip_vaddr = f->rip; + thread_unwind_regs_block = f->regs; + break; + } + } + } + + //- rjf: lex & parse + EVAL_TokenArray tokens = eval_token_array_from_text(scratch.arena, root_expr); + EVAL_ParseResult parse = eval_parse_expr_from_text_tokens(scratch.arena, &parse_ctx, root_expr, &tokens); + EVAL_ErrorList errors = parse.errors; + if(errors.count == 0) + { + eval_push_leaf_ident_exprs_from_expr__in_place(scratch.arena, ¯o_map, parse.expr, &errors); + } } } - if(ui_key_press(0, OS_Key_F2)) + + ////////////////////////// + //- rjf: state -> viz blocks + // + if(state_dirty) { - edit_begin = 1; + blocks = df_eval_viz_block_list_from_watch_view_state(scratch.arena, scope, &ctrl_ctx, &parse_ctx, ¯o_map, view, ewv); } - if(ui_key_press(0, OS_Key_Return)) + + ////////////////////////// + //- rjf: does this eval watch view allow mutation? -> add extra block for editable empty row + // + DF_ExpandKey empty_row_parent_key = df_expand_key_make(max_U64, max_U64); + DF_ExpandKey empty_row_key = df_expand_key_make(df_hash_from_expand_key(empty_row_parent_key), 1); + if(state_dirty && modifiable) { - edit_begin_or_expand = 1; + DF_EvalVizBlock *b = df_eval_viz_block_begin(scratch.arena, DF_EvalVizBlockKind_Null, empty_row_parent_key, empty_row_key, 0); + b->visual_idx_range = b->semantic_idx_range = r1u64(0, 1); + df_eval_viz_block_end(&blocks, b); } - } - if(ewv->input_editing && ui_is_focus_active()) - { - if(ui_key_press(0, OS_Key_Esc)) + + ////////////////////////// + //- rjf: viz blocks -> ui row blocks + // { - edit_end = 1; - edit_commit = 0; + UI_ScrollListRowBlockChunkList row_block_chunks = {0}; + for(DF_EvalVizBlockNode *n = blocks.first; n != 0; n = n->next) + { + DF_EvalVizBlock *vb = &n->v; + UI_ScrollListRowBlock block = {0}; + block.row_count = dim_1u64(vb->visual_idx_range); + block.item_count = dim_1u64(vb->semantic_idx_range); + ui_scroll_list_row_block_chunk_list_push(scratch.arena, &row_block_chunks, 256, &block); + } + row_blocks = ui_scroll_list_row_block_array_from_chunk_list(scratch.arena, &row_block_chunks); } - if(ui_key_press(0, OS_Key_Return)) + + ////////////////////////// + //- rjf: conclude state update + // + if(state_dirty) { - edit_end = 1; - edit_commit = 1; - edit_submit = 1; + state_dirty = 0; + } + + ////////////////////////////// + //- rjf: 2D table coordinates * blocks -> stable cursor state + // + if(cursor_dirty__tbl) + { + cursor_dirty__tbl = 0; + struct + { + DF_WatchViewPoint *pt_state; + Vec2S64 pt_tbl; + } + points[] = + { + {&ewv->cursor, cursor_tbl}, + {&ewv->mark, mark_tbl}, + }; + for(U64 point_idx = 0; point_idx < ArrayCount(points); point_idx += 1) + { + DF_ExpandKey last_key = points[point_idx].pt_state->key; + DF_ExpandKey last_parent_key = points[point_idx].pt_state->parent_key; + points[point_idx].pt_state[0] = df_watch_view_point_from_tbl(&blocks, points[point_idx].pt_tbl); + if(df_expand_key_match(df_expand_key_zero(), points[point_idx].pt_state->key)) + { + points[point_idx].pt_state->key = last_parent_key; + DF_ExpandNode *node = df_expand_node_from_key(&eval_view->expand_tree_table, last_parent_key); + for(DF_ExpandNode *n = node; n != 0; n = n->parent) + { + points[point_idx].pt_state->key = n->key; + if(n->expanded == 0) + { + break; + } + } + } + if(point_idx == 0 && + (!df_expand_key_match(ewv->cursor.key, last_key) || + !df_expand_key_match(ewv->cursor.parent_key, last_parent_key))) + { + ewv->text_editing = 0; + } + } + } + + ////////////////////////// + //- rjf: stable cursor state * blocks -> 2D table coordinates + // + { + cursor_tbl = df_tbl_from_watch_view_point(&blocks, ewv->cursor); + mark_tbl = df_tbl_from_watch_view_point(&blocks, ewv->mark); + selection_tbl = r2s64p(Min(cursor_tbl.x, mark_tbl.x), Min(cursor_tbl.y, mark_tbl.y), + Max(cursor_tbl.x, mark_tbl.x), Max(cursor_tbl.y, mark_tbl.y)); + } + + ////////////////////////// + //- rjf: grab next event, if any - otherwise exit the loop, as we now have + // the most up-to-date state + // + if(event_n == 0 || !ui_is_focus_active()) + { + break; + } + next = event_n->next; + UI_Event *evt = &event_n->v; + B32 taken = 0; + + ////////////////////////// + //- rjf: begin editing on some operations + // + if(!ewv->text_editing && + (evt->kind == UI_EventKind_Text || + evt->flags & UI_EventFlag_Paste || + (evt->kind == UI_EventKind_Press && evt->key == OS_Key_Return || evt->key == OS_Key_F2))) + { + Vec2S64 selection_dim = dim_2s64(selection_tbl); + ewv->text_editing = 1; + arena_clear(ewv->text_edit_arena); + ewv->text_edit_count = (selection_dim.x+1)*(selection_dim.y+1); + ewv->text_edit_states = push_array(ewv->text_edit_arena, DF_WatchViewTextEditState, ewv->text_edit_count); + DF_EvalVizWindowedRowList rows = df_eval_viz_windowed_row_list_from_viz_block_list(scratch.arena, scope, &ctrl_ctx, &parse_ctx, ¯o_map, eval_view, default_radix, code_font, ui_top_font_size(), + r1s64(ui_scroll_list_row_from_item(&row_blocks, selection_tbl.min.y-1), + ui_scroll_list_row_from_item(&row_blocks, selection_tbl.max.y-1)+1), &blocks); + DF_EvalVizRow *row = rows.first; + U64 edit_idx = 0; + for(S64 y = selection_tbl.min.y; y <= selection_tbl.max.y; y += 1, row = row->next) + { + for(S64 x = selection_tbl.min.x; x <= selection_tbl.max.x; x += 1, edit_idx += 1) + { + String8 string = df_string_from_eval_viz_row_column_kind(scratch.arena, eval_view, parse_ctx.type_graph, parse_ctx.rdi, row, (DF_WatchViewColumnKind)x, 1); + string.size = Min(string.size, sizeof(ewv->text_edit_states[edit_idx].input_buffer)); + ewv->text_edit_states[edit_idx].cursor = txt_pt(1, string.size+1); + ewv->text_edit_states[edit_idx].mark = txt_pt(1, 1); + ewv->text_edit_states[edit_idx].input_size = string.size; + MemoryCopy(ewv->text_edit_states[edit_idx].input_buffer, string.str, string.size); + ewv->text_edit_states[edit_idx].initial_size = string.size; + MemoryCopy(ewv->text_edit_states[edit_idx].initial_buffer, string.str, string.size); + } + } + } + + ////////////////////////// + //- rjf: [text] apply textual edits + // + if(ewv->text_editing) + { + B32 editing_complete = ((evt->kind == UI_EventKind_Press && evt->key == OS_Key_Esc || evt->key == OS_Key_Return) || + (evt->kind == UI_EventKind_Navigate && evt->delta_2s32.y != 0)); + if(editing_complete || + (evt->kind == UI_EventKind_Edit || + evt->kind == UI_EventKind_Navigate || + evt->kind == UI_EventKind_Text) && + evt->delta_2s32.y == 0) + { + taken = 1; + U64 edit_idx = 0; + for(S64 y = selection_tbl.min.y; y <= selection_tbl.max.y; y += 1) + { + for(S64 x = selection_tbl.min.x; x <= selection_tbl.max.x && edit_idx < ewv->text_edit_count; x += 1, edit_idx += 1) + { + DF_WatchViewTextEditState *edit_state = &ewv->text_edit_states[edit_idx]; + String8 string = str8(edit_state->input_buffer, edit_state->input_size); + UI_TxtOp op = ui_single_line_txt_op_from_event(scratch.arena, evt, string, edit_state->cursor, edit_state->mark); + + // rjf: cancel? -> revert to initial string + if(editing_complete && evt->key == OS_Key_Esc) + { + string = str8(edit_state->initial_buffer, edit_state->initial_size); + } + + // rjf: obtain edited string + String8 new_string = string; + if(!txt_pt_match(op.range.min, op.range.max) || op.replace.size != 0) + { + new_string = ui_push_string_replace_range(scratch.arena, string, r1s64(op.range.min.column, op.range.max.column), op.replace); + } + + // rjf: commit to edit state + new_string.size = Min(new_string.size, sizeof(edit_state->input_buffer)); + MemoryCopy(edit_state->input_buffer, new_string.str, new_string.size); + edit_state->input_size = new_string.size; + edit_state->cursor = op.cursor; + edit_state->mark = op.mark; + + // rjf: commit edited cell string + Vec2S64 tbl = v2s64(x, y); + switch((DF_WatchViewColumnKind)x) + { + case DF_WatchViewColumnKind_Expr: + { + DF_WatchViewPoint pt = df_watch_view_point_from_tbl(&blocks, tbl); + DF_EvalRoot *root = df_eval_root_from_expand_key(ewv, eval_view, pt.key); + if(root != 0) + { + df_eval_root_equip_string(root, new_string); + state_dirty = 1; + } + else if(editing_complete && new_string.size != 0 && df_expand_key_match(pt.key, empty_row_key)) + { + root = df_eval_root_alloc(view, ewv); + df_eval_root_equip_string(root, new_string); + state_dirty = 1; + } + }break; + case DF_WatchViewColumnKind_Value: + if(editing_complete) + { + DF_EvalVizWindowedRowList rows = df_eval_viz_windowed_row_list_from_viz_block_list(scratch.arena, scope, &ctrl_ctx, &parse_ctx, ¯o_map, eval_view, default_radix, code_font, ui_top_font_size(), + r1s64(ui_scroll_list_row_from_item(&row_blocks, y-1), + ui_scroll_list_row_from_item(&row_blocks, y-1)+1), &blocks); + B32 success = 0; + if(rows.first != 0) + { + DF_Eval write_eval = df_eval_from_string(scratch.arena, scope, &ctrl_ctx, &parse_ctx, ¯o_map, new_string); + success = df_commit_eval_value(parse_ctx.type_graph, parse_ctx.rdi, &ctrl_ctx, rows.first->eval, write_eval); + } + if(!success) + { + DF_CmdParams params = df_cmd_params_from_view(ws, panel, view); + params.string = str8_lit("Could not commit value successfully."); + df_cmd_params_mark_slot(¶ms, DF_CmdParamSlot_String); + df_push_cmd__root(¶ms, df_cmd_spec_from_core_cmd_kind(DF_CoreCmdKind_Error)); + } + }break; + case DF_WatchViewColumnKind_Type:{}break; + case DF_WatchViewColumnKind_ViewRule: + if(editing_complete) + { + DF_WatchViewPoint pt = df_watch_view_point_from_tbl(&blocks, tbl); + df_eval_view_set_key_rule(eval_view, pt.key, new_string); + state_dirty = 1; + }break; + } + } + } + } + if(editing_complete) + { + ewv->text_editing = 0; + } + } + + ////////////////////////// + //- rjf: [table] do cell-granularity copies + // + if(!ewv->text_editing && evt->flags & UI_EventFlag_Copy) + { + taken = 1; + String8List strs = {0}; + DF_EvalVizWindowedRowList rows = df_eval_viz_windowed_row_list_from_viz_block_list(scratch.arena, scope, &ctrl_ctx, &parse_ctx, ¯o_map, eval_view, default_radix, code_font, ui_top_font_size(), + r1s64(ui_scroll_list_row_from_item(&row_blocks, selection_tbl.min.y-1), + ui_scroll_list_row_from_item(&row_blocks, selection_tbl.max.y-1)+1), &blocks); + DF_EvalVizRow *row = rows.first; + for(S64 y = selection_tbl.min.y; y <= selection_tbl.max.y && row != 0; y += 1, row = row->next) + { + for(S64 x = selection_tbl.min.x; x <= selection_tbl.max.x; x += 1) + { + String8 cell_string = df_string_from_eval_viz_row_column_kind(scratch.arena, eval_view, parse_ctx.type_graph, parse_ctx.rdi, row, (DF_WatchViewColumnKind)x, 0); + str8_list_pushf(scratch.arena, &strs, "%S%s", cell_string, x+1 <= selection_tbl.max.x ? " " : ""); + } + if(y+1 <= selection_tbl.max.y) + { + str8_list_push(scratch.arena, &strs, str8_lit("\n")); + } + } + String8 string = str8_list_join(scratch.arena, &strs, 0); + os_set_clipboard_text(string); + } + + ////////////////////////// + //- rjf: [table] do cell-granularity deletions + // + if(!ewv->text_editing && evt->flags & UI_EventFlag_Delete) + { + taken = 1; + for(S64 y = selection_tbl.min.y; y <= selection_tbl.max.y; y += 1) + { + DF_WatchViewPoint pt = df_watch_view_point_from_tbl(&blocks, v2s64(0, y)); + DF_EvalRoot *root = df_eval_root_from_expand_key(ewv, eval_view, pt.key); + if(root != 0) + { + DF_ExpandKey new_cursor_key = empty_row_key; + DF_ExpandKey new_cursor_parent_key = empty_row_parent_key; + if((evt->delta_2s32.x < 0 || evt->delta_2s32.y < 0) && root->prev != 0) + { + new_cursor_key = df_expand_key_from_eval_root(root->prev); + new_cursor_parent_key = df_parent_expand_key_from_eval_root(root->prev); + } + else if(root->next != 0) + { + new_cursor_key = df_expand_key_from_eval_root(root->next); + new_cursor_parent_key = df_parent_expand_key_from_eval_root(root->next); + } + DF_WatchViewPoint new_cursor_pt = {DF_WatchViewColumnKind_Expr, new_cursor_parent_key, new_cursor_key}; + df_eval_root_release(ewv, root); + ewv->cursor = ewv->mark = new_cursor_pt; + } + } + } + + ////////////////////////// + //- rjf: [table] apply deltas to cursor & mark + // + if(!ewv->text_editing && !(evt->flags & UI_EventFlag_Delete)) + { + B32 cursor_tbl_min_is_empty_selection[Axis2_COUNT] = {0, 1}; + Rng2S64 cursor_tbl_range = r2s64(v2s64(0, 0), v2s64(3, blocks.total_semantic_row_count)); + Rng1S64 item_range = r1s64(0, 1 + blocks.total_visual_row_count); + Vec2S32 delta = evt->delta_2s32; + if(evt->flags & UI_EventFlag_PickSelectSide && !MemoryMatchStruct(&selection_tbl.min, &selection_tbl.max)) + { + if(delta.x > 0 || delta.y > 0) + { + cursor_tbl.x = selection_tbl.max.x; + cursor_tbl.y = selection_tbl.max.y; + } + else if(delta.x < 0 || delta.y < 0) + { + cursor_tbl.x = selection_tbl.min.x; + cursor_tbl.y = selection_tbl.min.y; + } + } + if(evt->flags & UI_EventFlag_ZeroDeltaOnSelect && !MemoryMatchStruct(&selection_tbl.min, &selection_tbl.max)) + { + MemoryZeroStruct(&delta); + } + B32 moved = 1; + switch(evt->delta_unit) + { + default:{moved = 0;}break; + case UI_EventDeltaUnit_Char: + { + for(EachEnumVal(Axis2, axis)) + { + cursor_tbl.v[axis] += delta.v[axis]; + if(cursor_tbl.v[axis] < cursor_tbl_range.min.v[axis]) + { + cursor_tbl.v[axis] = cursor_tbl_range.max.v[axis]; + } + if(cursor_tbl.v[axis] > cursor_tbl_range.max.v[axis]) + { + cursor_tbl.v[axis] = cursor_tbl_range.min.v[axis]; + } + cursor_tbl.v[axis] = clamp_1s64(r1s64(cursor_tbl_range.min.v[axis], cursor_tbl_range.max.v[axis]), cursor_tbl.v[axis]); + } + }break; + case UI_EventDeltaUnit_Word: + case UI_EventDeltaUnit_Line: + case UI_EventDeltaUnit_Page: + { + cursor_tbl.x = (delta.x>0 ? (cursor_tbl_range.max.x) : + delta.x<0 ? (cursor_tbl_range.min.x + !!cursor_tbl_min_is_empty_selection[Axis2_X]) : + cursor_tbl.x); + cursor_tbl.y += ((delta.y>0 ? +(num_possible_visible_rows-3) : + delta.y<0 ? -(num_possible_visible_rows-3) : + 0)); + cursor_tbl.y = clamp_1s64(r1s64(cursor_tbl_range.min.y + !!cursor_tbl_min_is_empty_selection[Axis2_Y], + cursor_tbl_range.max.y), + cursor_tbl.y); + }break; + case UI_EventDeltaUnit_Whole: + { + for(EachEnumVal(Axis2, axis)) + { + cursor_tbl.v[axis] = (delta.v[axis]>0 ? cursor_tbl_range.max.v[axis] : delta.v[axis]<0 ? cursor_tbl_range.min.v[axis] + !!cursor_tbl_min_is_empty_selection[axis] : cursor_tbl.v[axis]); + } + }break; + } + if(moved) + { + taken = 1; + cursor_dirty__tbl = 1; + { + Rng1S64 scroll_row_idx_range = r1s64(item_range.min, ClampBot(item_range.min, item_range.max-1)); + S64 cursor_item_idx = cursor_tbl.y-1; + if(item_range.min <= cursor_item_idx && cursor_item_idx <= item_range.max) + { + UI_ScrollPt *scroll_pt = &view->scroll_pos.y; + + //- rjf: compute visible row range + Rng1S64 visible_row_range = r1s64(scroll_pt->idx + 0 - !!(scroll_pt->off < 0), + scroll_pt->idx + 0 + num_possible_visible_rows + 1); + + //- rjf: compute cursor row range from cursor item + Rng1S64 cursor_visibility_row_range = {0}; + if(row_blocks.count == 0) + { + cursor_visibility_row_range = r1s64(cursor_item_idx-1, cursor_item_idx+3); + } + else + { + cursor_visibility_row_range.min = (S64)ui_scroll_list_row_from_item(&row_blocks, (U64)cursor_item_idx); + cursor_visibility_row_range.max = cursor_visibility_row_range.min + 4; + } + + //- rjf: compute deltas & apply + S64 min_delta = Min(0, cursor_visibility_row_range.min-visible_row_range.min); + S64 max_delta = Max(0, cursor_visibility_row_range.max-visible_row_range.max); + S64 new_idx = scroll_pt->idx+min_delta+max_delta; + new_idx = clamp_1s64(scroll_row_idx_range, new_idx); + ui_scroll_pt_target_idx(scroll_pt, new_idx); + } + } + + } + } + + ////////////////////////// + //- rjf: [table] stick table mark to cursor if needed + // + if(!ewv->text_editing) + { + if(taken && !(evt->flags & UI_EventFlag_KeepMark)) + { + mark_tbl = cursor_tbl; + } + } + + ////////////////////////// + //- rjf: consume event, if taken + // + if(taken) + { + ui_eat_event(events, event_n); } } } @@ -973,7 +1337,7 @@ df_watch_view_build(DF_Window *ws, DF_Panel *panel, DF_View *view, DF_WatchViewS UI_ScrollListSignal scroll_list_sig = {0}; UI_Focus(UI_FocusKind_On) UI_ScrollList(&scroll_list_params, &view->scroll_pos.y, - ewv->input_editing ? 0 : &cursor_tbl, + 0, 0, &visible_row_rng, &scroll_list_sig) @@ -1033,6 +1397,7 @@ df_watch_view_build(DF_Window *ws, DF_Panel *panel, DF_View *view, DF_WatchViewS ProfScope("build table") { //- rjf: build rows + DF_WatchViewTextEditState dummy_edit_state = {0}; U64 semantic_idx = rows.count_before_semantic; for(DF_EvalVizRow *row = rows.first; row != 0; row = row->next, semantic_idx += 1) { @@ -1105,7 +1470,7 @@ df_watch_view_build(DF_Window *ws, DF_Panel *panel, DF_View *view, DF_WatchViewS //- rjf: press -> focus if(ui_pressed(sig)) { - edit_commit = edit_commit || (!row_selected && ewv->input_editing); + // TODO(rjf): edit_commit = edit_commit || (!row_selected && ewv->text_editing); next_cursor_tbl = v2s64(DF_WatchViewColumnKind_Expr, (semantic_idx+1)); pressed = 1; } @@ -1144,7 +1509,7 @@ df_watch_view_build(DF_Window *ws, DF_Panel *panel, DF_View *view, DF_WatchViewS { ui_set_next_flags(disabled_flags); } - UI_NamedTableVectorF("row_%I64x_%I64x_%I64x", row_hash, expr_hash, ewv->root_count) + UI_NamedTableVectorF("row_%I64x_%I64x", row_hash, ewv->root_count) { //- rjf: draw start of cache lines in expansions if((row->eval.mode == EVAL_EvalMode_Addr || row->eval.mode == EVAL_EvalMode_NULL) && @@ -1185,15 +1550,24 @@ df_watch_view_build(DF_Window *ws, DF_Panel *panel, DF_View *view, DF_WatchViewS B32 cell_selected = (row_selected && selection_tbl.min.x <= DF_WatchViewColumnKind_Expr && DF_WatchViewColumnKind_Expr <= selection_tbl.max.x); B32 can_edit_expr = !(row->depth > 0 || modifiable == 0); + // rjf: obtain edit state for this cell + DF_WatchViewTextEditState *edit_state = &dummy_edit_state; + if(ewv->text_editing && cell_selected) + { + edit_state = &ewv->text_edit_states[(semantic_idx+1 - selection_tbl.min.y)*(dim_2s64(selection_tbl).x+1) + DF_WatchViewColumnKind_Expr-selection_tbl.min.x]; + } + // rjf: begin editing +#if 0 if(cell_selected && (edit_begin || (edit_begin_or_expand && !(row->flags & DF_EvalVizRowFlag_CanExpand))) && can_edit_expr) { - ewv->input_editing = 1; + ewv->text_editing = 1; ewv->input_size = Min(sizeof(ewv->input_buffer), row->display_expr.size); MemoryCopy(ewv->input_buffer, row->display_expr.str, ewv->input_size); ewv->input_cursor = txt_pt(1, 1+ewv->input_size); ewv->input_mark = txt_pt(1, 1); } +#endif // rjf: build UI_Signal sig = {0}; @@ -1205,7 +1579,7 @@ df_watch_view_build(DF_Window *ws, DF_Panel *panel, DF_View *view, DF_WatchViewS } UI_TableCell UI_FocusHot(cell_selected ? UI_FocusKind_On : UI_FocusKind_Off) - UI_FocusActive((cell_selected && ewv->input_editing) ? UI_FocusKind_On : UI_FocusKind_Off) + UI_FocusActive((cell_selected && ewv->text_editing) ? UI_FocusKind_On : UI_FocusKind_Off) { B32 expr_editing_active = ui_is_focus_active(); B32 is_inherited = (row->inherited_type_key_chain.count != 0); @@ -1232,11 +1606,11 @@ df_watch_view_build(DF_Window *ws, DF_Panel *panel, DF_View *view, DF_WatchViewS DF_LineEditFlag_ExpanderSpace*(row->depth!=0)), row->depth, filter.size ? &matches : 0, - &ewv->input_cursor, &ewv->input_mark, ewv->input_buffer, sizeof(ewv->input_buffer), &ewv->input_size, &next_expanded, + &edit_state->cursor, &edit_state->mark, edit_state->input_buffer, sizeof(edit_state->input_buffer), &edit_state->input_size, &next_expanded, row->display_expr, "###row_%I64x", row_hash); } - edit_commit = edit_commit || ui_committed(sig); + // TODO(rjf): edit_commit = edit_commit || ui_committed(sig); if(is_inherited && ui_hovering(sig)) UI_Tooltip { String8List inheritance_chain_type_names = {0}; @@ -1304,38 +1678,47 @@ df_watch_view_build(DF_Window *ws, DF_Panel *panel, DF_View *view, DF_WatchViewS scratch_end(scratch); } +#if 0 // TODO(rjf): if(expr_editing_active && !edit_end && txt_pt_match(ewv->input_cursor, ewv->input_mark)) { String8 input = str8(ewv->input_buffer, ewv->input_size); DF_AutoCompListerParams params = {DF_AutoCompListerFlag_Locals}; df_set_autocomp_lister_query(ws, sig.box->key, ctrl_ctx, ¶ms, input, ewv->input_cursor.column-1); } +#endif } // rjf: press -> commit if editing & select +#if 0 // TODO(rjf): if(ui_pressed(sig)) { - edit_commit = edit_commit || (!cell_selected && ewv->input_editing); + edit_commit = edit_commit || (!cell_selected && ewv->text_editing); next_cursor_tbl = v2s64(DF_WatchViewColumnKind_Expr, (semantic_idx+1)); pressed = 1; } +#endif // rjf: keyboard-click & expandable -> expand +#if 0// TODO(rjf): if(cell_selected && edit_begin_or_expand && row->flags & DF_EvalVizRowFlag_CanExpand) { next_expanded ^= 1; } +#endif // rjf: double-click -> start editing - if(ui_double_clicked(sig) && !ewv->input_editing && can_edit_expr) + // TODO(rjf): +#if 0 + if(ui_double_clicked(sig) && !ewv->text_editing && can_edit_expr) { ui_kill_action(); - ewv->input_editing = 1; + ewv->text_editing = 1; ewv->input_size = Min(sizeof(ewv->input_buffer), row->display_expr.size); MemoryCopy(ewv->input_buffer, row->display_expr.str, ewv->input_size); ewv->input_cursor = txt_pt(1, 1+ewv->input_size); ewv->input_mark = txt_pt(1, 1); } +#endif // rjf: commit expansion state if(next_expanded != row_expanded) @@ -1353,15 +1736,24 @@ df_watch_view_build(DF_Window *ws, DF_Panel *panel, DF_View *view, DF_WatchViewS B32 value_is_complex = (!value_is_error && !value_is_hook && !(row->flags & DF_EvalVizRowFlag_CanEditValue)); B32 value_is_simple = (!value_is_error && !value_is_hook && (row->flags & DF_EvalVizRowFlag_CanEditValue)); + // rjf: obtain edit state for this cell + DF_WatchViewTextEditState *edit_state = &dummy_edit_state; + if(ewv->text_editing && cell_selected) + { + edit_state = &ewv->text_edit_states[(semantic_idx+1 - selection_tbl.min.y)*(dim_2s64(selection_tbl).x+1) + DF_WatchViewColumnKind_Value-selection_tbl.min.x]; + } + // rjf: begin editing +#if 0 // TODO(rjf): if(cell_selected && (edit_begin || edit_begin_or_expand) && value_is_simple) { - ewv->input_editing = 1; + ewv->text_editing = 1; ewv->input_size = Min(sizeof(ewv->input_buffer), row->edit_value.size); MemoryCopy(ewv->input_buffer, row->edit_value.str, ewv->input_size); ewv->input_cursor = txt_pt(1, 1+ewv->input_size); ewv->input_mark = txt_pt(1, 1); } +#endif // rjf: build UI_Signal sig = {0}; @@ -1372,7 +1764,7 @@ df_watch_view_build(DF_Window *ws, DF_Panel *panel, DF_View *view, DF_WatchViewS } UI_TableCell UI_Font(code_font) UI_FocusHot(cell_selected ? UI_FocusKind_On : UI_FocusKind_Off) - UI_FocusActive((cell_selected && ewv->input_editing) ? UI_FocusKind_On : UI_FocusKind_Off) + UI_FocusActive((cell_selected && ewv->text_editing) ? UI_FocusKind_On : UI_FocusKind_Off) { // rjf: errors? -> show errors if(value_is_error) UI_TextColor(df_rgba_from_theme_color(DF_ThemeColor_FailureBackground)) UI_Font(df_font_from_slot(DF_FontSlot_Main)) @@ -1412,8 +1804,8 @@ df_watch_view_build(DF_Window *ws, DF_Panel *panel, DF_View *view, DF_WatchViewS // rjf: simple values (editable) if(value_is_simple) { - sig = df_line_editf(DF_LineEditFlag_CodeContents|DF_LineEditFlag_NoBackground, 0, 0, &ewv->input_cursor, &ewv->input_mark, ewv->input_buffer, sizeof(ewv->input_buffer), &ewv->input_size, 0, row->display_value, "%S###val_%I64x", row->display_value, row_hash); - edit_commit = (edit_commit || ui_committed(sig)); + sig = df_line_editf(DF_LineEditFlag_CodeContents|DF_LineEditFlag_NoBackground, 0, 0, &edit_state->cursor, &edit_state->mark, edit_state->input_buffer, sizeof(edit_state->input_buffer), &edit_state->input_size, 0, row->display_value, "%S###val_%I64x", row->display_value, row_hash); + // TODO(rjf): edit_commit = (edit_commit || ui_committed(sig)); } } @@ -1427,20 +1819,22 @@ df_watch_view_build(DF_Window *ws, DF_Panel *panel, DF_View *view, DF_WatchViewS if(ui_pressed(sig)) { pressed = 1; - edit_commit = edit_commit || (ewv->input_editing && !cell_selected); + // TODO(rjf): edit_commit = edit_commit || (ewv->text_editing && !cell_selected); next_cursor_tbl = v2s64(DF_WatchViewColumnKind_Value, (semantic_idx+1)); } // rjf: double-click -> start editing +#if 0 if(ui_double_clicked(sig) && value_is_simple) { ui_kill_action(); - ewv->input_editing = 1; + ewv->text_editing = 1; ewv->input_size = Min(sizeof(ewv->input_buffer), row->edit_value.size); MemoryCopy(ewv->input_buffer, row->edit_value.str, ewv->input_size); ewv->input_cursor = txt_pt(1, 1+ewv->input_size); ewv->input_mark = txt_pt(1, 1); } +#endif } //- rjf: type @@ -1449,7 +1843,7 @@ df_watch_view_build(DF_Window *ws, DF_Panel *panel, DF_View *view, DF_WatchViewS B32 cell_selected = (row_selected && selection_tbl.min.x <= DF_WatchViewColumnKind_Type && DF_WatchViewColumnKind_Type <= selection_tbl.max.x); UI_TableCell UI_Font(code_font) UI_FocusHot(cell_selected ? UI_FocusKind_On : UI_FocusKind_Off) - UI_FocusActive((cell_selected && ewv->input_editing) ? UI_FocusKind_On : UI_FocusKind_Off) + UI_FocusActive((cell_selected && ewv->text_editing) ? UI_FocusKind_On : UI_FocusKind_Off) { TG_Key key = row->eval.type_key; String8 string = tg_string_from_key(scratch.arena, parse_ctx.type_graph, parse_ctx.rdi, key); @@ -1463,7 +1857,7 @@ df_watch_view_build(DF_Window *ws, DF_Panel *panel, DF_View *view, DF_WatchViewS if(ui_pressed(sig)) { pressed = 1; - edit_commit = edit_commit || (ewv->input_editing && !cell_selected); + // TODO(rjf): edit_commit = edit_commit || (ewv->text_editing && !cell_selected); next_cursor_tbl = v2s64(DF_WatchViewColumnKind_Type, (semantic_idx+1)); } } @@ -1475,48 +1869,62 @@ df_watch_view_build(DF_Window *ws, DF_Panel *panel, DF_View *view, DF_WatchViewS B32 cell_selected = (row_selected && selection_tbl.min.x <= DF_WatchViewColumnKind_ViewRule && DF_WatchViewColumnKind_ViewRule <= selection_tbl.max.x); String8 view_rule = df_eval_view_rule_from_key(eval_view, row->key); + // rjf: obtain edit state for this cell + DF_WatchViewTextEditState *edit_state = &dummy_edit_state; + if(ewv->text_editing && cell_selected) + { + edit_state = &ewv->text_edit_states[(semantic_idx+1 - selection_tbl.min.y)*(dim_2s64(selection_tbl).x+1) + DF_WatchViewColumnKind_ViewRule-selection_tbl.min.x]; + } + // rjf: begin editing +#if 0 // TODO(rjf): if(cell_selected && (edit_begin || edit_begin_or_expand)) { - ewv->input_editing = 1; + ewv->text_editing = 1; ewv->input_size = Min(sizeof(ewv->input_buffer), view_rule.size); MemoryCopy(ewv->input_buffer, view_rule.str, ewv->input_size); ewv->input_cursor = txt_pt(1, 1+ewv->input_size); ewv->input_mark = txt_pt(1, 1); } +#endif // rjf: build UI_Signal sig = {0}; B32 rule_editing_active = 0; UI_TableCell UI_Font(code_font) UI_FocusHot(cell_selected ? UI_FocusKind_On : UI_FocusKind_Off) - UI_FocusActive((cell_selected && ewv->input_editing) ? UI_FocusKind_On : UI_FocusKind_Off) + UI_FocusActive((cell_selected && ewv->text_editing) ? UI_FocusKind_On : UI_FocusKind_Off) { rule_editing_active = ui_is_focus_active(); - sig = df_line_editf(DF_LineEditFlag_CodeContents|DF_LineEditFlag_NoBackground, 0, 0, &ewv->input_cursor, &ewv->input_mark, ewv->input_buffer, sizeof(ewv->input_buffer), &ewv->input_size, 0, view_rule, "###view_rule_%I64x", row_hash); - edit_commit = edit_commit || ui_committed(sig); + sig = df_line_editf(DF_LineEditFlag_CodeContents|DF_LineEditFlag_NoBackground, 0, 0, &edit_state->cursor, &edit_state->mark, edit_state->input_buffer, sizeof(edit_state->input_buffer), &edit_state->input_size, 0, view_rule, "###view_rule_%I64x", row_hash); + // TODO(rjf): edit_commit = edit_commit || ui_committed(sig); } // rjf: press -> commit if not selected, select this cell if(ui_pressed(sig)) { pressed = 1; - edit_commit = edit_commit || (ewv->input_editing && !cell_selected); + // TODO(rjf): edit_commit = edit_commit || (ewv->text_editing && !cell_selected); next_cursor_tbl = v2s64(DF_WatchViewColumnKind_ViewRule, (semantic_idx+1)); } // rjf: double-click -> begin editing - if(ui_double_clicked(sig) && !ewv->input_editing) + // TODO(rjf): +#if 0 + if(ui_double_clicked(sig) && !ewv->text_editing) { ui_kill_action(); - ewv->input_editing = 1; + ewv->text_editing = 1; ewv->input_size = Min(sizeof(ewv->input_buffer), view_rule.size); MemoryCopy(ewv->input_buffer, view_rule.str, ewv->input_size); ewv->input_cursor = txt_pt(1, 1+ewv->input_size); ewv->input_mark = txt_pt(1, 1); } +#endif // rjf: autocomplete lister + // TODO(rjf): +#if 0 if(rule_editing_active && !edit_end && txt_pt_match(ewv->input_cursor, ewv->input_mark)) { String8 input = str8(ewv->input_buffer, ewv->input_size); @@ -1527,6 +1935,7 @@ df_watch_view_build(DF_Window *ws, DF_Panel *panel, DF_View *view, DF_WatchViewS } df_set_autocomp_lister_query(ws, sig.box->key, ctrl_ctx, ¶ms, input, ewv->input_cursor.column-1); } +#endif } } } @@ -1546,6 +1955,7 @@ df_watch_view_build(DF_Window *ws, DF_Panel *panel, DF_View *view, DF_WatchViewS ////////////////////////////// //- rjf: commit edits // +#if 0 { DF_WatchViewColumnKind commit_column = (DF_WatchViewColumnKind)cursor_tbl.x; if(!MemoryMatchStruct(&cursor_tbl, &next_cursor_tbl)) @@ -1555,7 +1965,7 @@ df_watch_view_build(DF_Window *ws, DF_Panel *panel, DF_View *view, DF_WatchViewS cursor_tbl = next_cursor_tbl; if(commit_row != 0 && edit_commit) { - ewv->input_editing = 0; + ewv->text_editing = 0; String8 commit_string = str8(ewv->input_buffer, ewv->input_size); switch(commit_column) { @@ -1629,7 +2039,7 @@ df_watch_view_build(DF_Window *ws, DF_Panel *panel, DF_View *view, DF_WatchViewS // if(edit_end) { - ewv->input_editing = 0; + ewv->text_editing = 0; } ////////////////////////////// @@ -1683,9 +2093,10 @@ df_watch_view_build(DF_Window *ws, DF_Panel *panel, DF_View *view, DF_WatchViewS (!df_expand_key_match(ewv->cursor.key, last_key) || !df_expand_key_match(ewv->cursor.parent_key, last_parent_key))) { - ewv->input_editing = 0; + ewv->text_editing = 0; } } +#endif scratch_end(scratch); dbgi_scope_close(scope); diff --git a/src/df/gfx/df_views.h b/src/df/gfx/df_views.h index a477ba6d..ac56cac9 100644 --- a/src/df/gfx/df_views.h +++ b/src/df/gfx/df_views.h @@ -312,6 +312,17 @@ struct DF_WatchViewPoint DF_ExpandKey key; }; +typedef struct DF_WatchViewTextEditState DF_WatchViewTextEditState; +struct DF_WatchViewTextEditState +{ + TxtPt cursor; + TxtPt mark; + U8 input_buffer[1024]; + U64 input_size; + U8 initial_buffer[1024]; + U64 initial_size; +}; + typedef struct DF_WatchViewState DF_WatchViewState; struct DF_WatchViewState { @@ -325,11 +336,10 @@ struct DF_WatchViewState DF_WatchViewPoint mark; // rjf: text input state - TxtPt input_cursor; - TxtPt input_mark; - U8 input_buffer[1024]; - U64 input_size; - B32 input_editing; + Arena *text_edit_arena; + U64 text_edit_count; + DF_WatchViewTextEditState *text_edit_states; + B32 text_editing; // rjf: table column width state F32 expr_column_pct; @@ -469,6 +479,13 @@ internal String8 df_string_from_eval_root(DF_EvalRoot *root); internal DF_ExpandKey df_parent_expand_key_from_eval_root(DF_EvalRoot *root); internal DF_ExpandKey df_expand_key_from_eval_root(DF_EvalRoot *root); +//- rjf: watch view points <-> table coordinates +internal DF_WatchViewPoint df_watch_view_point_from_tbl(DF_EvalVizBlockList *blocks, Vec2S64 tbl); +internal Vec2S64 df_tbl_from_watch_view_point(DF_EvalVizBlockList *blocks, DF_WatchViewPoint pt); + +//- rjf: table coordinates -> strings +internal String8 df_string_from_eval_viz_row_column_kind(Arena *arena, DF_EvalView *ev, TG_Graph *graph, RDI_Parsed *rdi, DF_EvalVizRow *row, DF_WatchViewColumnKind col_kind, B32 editable); + //- rjf: windowed watch tree visualization internal DF_EvalVizBlockList df_eval_viz_block_list_from_watch_view_state(Arena *arena, DBGI_Scope *scope, DF_CtrlCtx *ctrl_ctx, EVAL_ParseCtx *parse_ctx, EVAL_String2ExprMap *macro_map, DF_View *view, DF_WatchViewState *ews); From aa73e62240f6d3fa5074a6ea10df0c67a724b1ce Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Tue, 14 May 2024 16:31:34 -0700 Subject: [PATCH 23/30] fix clang --- src/df/gfx/df_views.c | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/src/df/gfx/df_views.c b/src/df/gfx/df_views.c index f5c9aecf..c0c3dcea 100644 --- a/src/df/gfx/df_views.c +++ b/src/df/gfx/df_views.c @@ -477,7 +477,7 @@ df_expand_key_from_eval_root(DF_EvalRoot *root) internal DF_WatchViewPoint df_watch_view_point_from_tbl(DF_EvalVizBlockList *blocks, Vec2S64 tbl) { - DF_WatchViewPoint pt = {0}; + DF_WatchViewPoint pt = zero_struct; pt.column_kind = (DF_WatchViewColumnKind)(tbl.x%DF_WatchViewColumnKind_COUNT); pt.key = df_key_from_viz_block_list_row_num(blocks, tbl.y); pt.parent_key = df_parent_key_from_viz_block_list_row_num(blocks, tbl.y); @@ -501,6 +501,7 @@ df_string_from_eval_viz_row_column_kind(Arena *arena, DF_EvalView *ev, TG_Graph String8 result = {0}; switch(col_kind) { + default:{}break; case DF_WatchViewColumnKind_Expr: {result = editable ? row->edit_expr : row->display_expr;}break; case DF_WatchViewColumnKind_Value: {result = editable ? row->edit_value : row->display_value;}break; case DF_WatchViewColumnKind_Type: {result = tg_string_from_key(arena, graph, rdi, row->eval.type_key);}break; @@ -981,7 +982,7 @@ df_watch_view_build(DF_Window *ws, DF_Panel *panel, DF_View *view, DF_WatchViewS if(!ewv->text_editing && (evt->kind == UI_EventKind_Text || evt->flags & UI_EventFlag_Paste || - (evt->kind == UI_EventKind_Press && evt->key == OS_Key_Return || evt->key == OS_Key_F2))) + (evt->kind == UI_EventKind_Press && (evt->key == OS_Key_Return || evt->key == OS_Key_F2)))) { Vec2S64 selection_dim = dim_2s64(selection_tbl); ewv->text_editing = 1; @@ -1014,13 +1015,13 @@ df_watch_view_build(DF_Window *ws, DF_Panel *panel, DF_View *view, DF_WatchViewS // if(ewv->text_editing) { - B32 editing_complete = ((evt->kind == UI_EventKind_Press && evt->key == OS_Key_Esc || evt->key == OS_Key_Return) || + B32 editing_complete = ((evt->kind == UI_EventKind_Press && (evt->key == OS_Key_Esc || evt->key == OS_Key_Return)) || (evt->kind == UI_EventKind_Navigate && evt->delta_2s32.y != 0)); if(editing_complete || - (evt->kind == UI_EventKind_Edit || - evt->kind == UI_EventKind_Navigate || - evt->kind == UI_EventKind_Text) && - evt->delta_2s32.y == 0) + ((evt->kind == UI_EventKind_Edit || + evt->kind == UI_EventKind_Navigate || + evt->kind == UI_EventKind_Text) && + evt->delta_2s32.y == 0)) { taken = 1; U64 edit_idx = 0; @@ -1056,6 +1057,7 @@ df_watch_view_build(DF_Window *ws, DF_Panel *panel, DF_View *view, DF_WatchViewS Vec2S64 tbl = v2s64(x, y); switch((DF_WatchViewColumnKind)x) { + default:{}break; case DF_WatchViewColumnKind_Expr: { DF_WatchViewPoint pt = df_watch_view_point_from_tbl(&blocks, tbl); From 03844d81d2ff66771135535b56657deaaffd507e Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Wed, 15 May 2024 09:26:16 -0700 Subject: [PATCH 24/30] further progress on watch window pass; multi-cursor, multi-selection, autocomplete lister, etc --- src/df/gfx/df_views.c | 213 ++++++++++++++++++++++++++++++------------ src/df/gfx/df_views.h | 10 +- 2 files changed, 159 insertions(+), 64 deletions(-) diff --git a/src/df/gfx/df_views.c b/src/df/gfx/df_views.c index c0c3dcea..e18d64b8 100644 --- a/src/df/gfx/df_views.c +++ b/src/df/gfx/df_views.c @@ -510,6 +510,30 @@ df_string_from_eval_viz_row_column_kind(Arena *arena, DF_EvalView *ev, TG_Graph return result; } +//- rjf: table coordinates -> text edit state + +internal DF_WatchViewTextEditState * +df_watch_view_text_edit_state_from_pt(DF_WatchViewState *wv, DF_WatchViewPoint pt) +{ + DF_WatchViewTextEditState *result = &wv->dummy_text_edit_state; + if(wv->text_edit_state_slots_count != 0 && wv->text_editing != 0) + { + U64 hash = df_hash_from_expand_key(pt.key); + U64 slot_idx = hash%wv->text_edit_state_slots_count; + for(DF_WatchViewTextEditState *s = wv->text_edit_state_slots[slot_idx]; s != 0; s = s->pt_hash_next) + { + if(pt.column_kind == s->pt.column_kind && + df_expand_key_match(pt.parent_key, s->pt.parent_key) && + df_expand_key_match(pt.key, s->pt.key)) + { + result = s; + break; + } + } + } + return result; +} + //- rjf: windowed watch tree visualization (both single-line and multi-line) internal DF_EvalVizBlockList @@ -809,6 +833,22 @@ df_watch_view_build(DF_Window *ws, DF_Panel *panel, DF_View *view, DF_WatchViewS // EVAL_ParseCtx parse_ctx = df_eval_parse_ctx_from_process_vaddr(scope, process, thread_ip_vaddr); + ////////////////////////////// + //- rjf: determine autocompletion string + // + String8 autocomplete_hint_string = {0}; + { + UI_EventList *events = ui_events(); + for(UI_EventNode *n = events->first; n != 0; n = n->next) + { + if(n->v.kind == UI_EventKind_AutocompleteHint) + { + autocomplete_hint_string = n->v.string; + break; + } + } + } + ////////////////////////////// //- rjf: consume events & perform navigations/edits - calculate state // @@ -823,6 +863,7 @@ df_watch_view_build(DF_Window *ws, DF_Panel *panel, DF_View *view, DF_WatchViewS UI_EventList *events = ui_events(); B32 state_dirty = 1; B32 cursor_dirty__tbl = 0; + B32 take_autocomplete = 0; for(UI_EventNode *event_n = events->first, *next = 0;; event_n = next) { ////////////////////////// @@ -987,25 +1028,31 @@ df_watch_view_build(DF_Window *ws, DF_Panel *panel, DF_View *view, DF_WatchViewS Vec2S64 selection_dim = dim_2s64(selection_tbl); ewv->text_editing = 1; arena_clear(ewv->text_edit_arena); - ewv->text_edit_count = (selection_dim.x+1)*(selection_dim.y+1); - ewv->text_edit_states = push_array(ewv->text_edit_arena, DF_WatchViewTextEditState, ewv->text_edit_count); + ewv->text_edit_state_slots_count = u64_up_to_pow2(selection_dim.y+1); + ewv->text_edit_state_slots_count = Max(ewv->text_edit_state_slots_count, 64); + ewv->text_edit_state_slots = push_array(ewv->text_edit_arena, DF_WatchViewTextEditState*, ewv->text_edit_state_slots_count); DF_EvalVizWindowedRowList rows = df_eval_viz_windowed_row_list_from_viz_block_list(scratch.arena, scope, &ctrl_ctx, &parse_ctx, ¯o_map, eval_view, default_radix, code_font, ui_top_font_size(), r1s64(ui_scroll_list_row_from_item(&row_blocks, selection_tbl.min.y-1), ui_scroll_list_row_from_item(&row_blocks, selection_tbl.max.y-1)+1), &blocks); DF_EvalVizRow *row = rows.first; - U64 edit_idx = 0; for(S64 y = selection_tbl.min.y; y <= selection_tbl.max.y; y += 1, row = row->next) { - for(S64 x = selection_tbl.min.x; x <= selection_tbl.max.x; x += 1, edit_idx += 1) + for(S64 x = selection_tbl.min.x; x <= selection_tbl.max.x; x += 1) { String8 string = df_string_from_eval_viz_row_column_kind(scratch.arena, eval_view, parse_ctx.type_graph, parse_ctx.rdi, row, (DF_WatchViewColumnKind)x, 1); - string.size = Min(string.size, sizeof(ewv->text_edit_states[edit_idx].input_buffer)); - ewv->text_edit_states[edit_idx].cursor = txt_pt(1, string.size+1); - ewv->text_edit_states[edit_idx].mark = txt_pt(1, 1); - ewv->text_edit_states[edit_idx].input_size = string.size; - MemoryCopy(ewv->text_edit_states[edit_idx].input_buffer, string.str, string.size); - ewv->text_edit_states[edit_idx].initial_size = string.size; - MemoryCopy(ewv->text_edit_states[edit_idx].initial_buffer, string.str, string.size); + string.size = Min(string.size, sizeof(ewv->dummy_text_edit_state.input_buffer)); + DF_WatchViewPoint pt = {(DF_WatchViewColumnKind)x, row->parent_key, row->key}; + U64 hash = df_hash_from_expand_key(pt.key); + U64 slot_idx = hash%ewv->text_edit_state_slots_count; + DF_WatchViewTextEditState *edit_state = push_array(ewv->text_edit_arena, DF_WatchViewTextEditState, 1); + SLLStackPush_N(ewv->text_edit_state_slots[slot_idx], edit_state, pt_hash_next); + edit_state->pt = pt; + edit_state->cursor = txt_pt(1, string.size+1); + edit_state->mark = txt_pt(1, 1); + edit_state->input_size = string.size; + MemoryCopy(edit_state->input_buffer, string.str, string.size); + edit_state->initial_size = string.size; + MemoryCopy(edit_state->initial_buffer, string.str, string.size); } } } @@ -1024,15 +1071,30 @@ df_watch_view_build(DF_Window *ws, DF_Panel *panel, DF_View *view, DF_WatchViewS evt->delta_2s32.y == 0)) { taken = 1; - U64 edit_idx = 0; for(S64 y = selection_tbl.min.y; y <= selection_tbl.max.y; y += 1) { - for(S64 x = selection_tbl.min.x; x <= selection_tbl.max.x && edit_idx < ewv->text_edit_count; x += 1, edit_idx += 1) + for(S64 x = selection_tbl.min.x; x <= selection_tbl.max.x; x += 1) { - DF_WatchViewTextEditState *edit_state = &ewv->text_edit_states[edit_idx]; + DF_WatchViewPoint pt = df_watch_view_point_from_tbl(&blocks, v2s64(x, y)); + DF_WatchViewTextEditState *edit_state = df_watch_view_text_edit_state_from_pt(ewv, pt); String8 string = str8(edit_state->input_buffer, edit_state->input_size); UI_TxtOp op = ui_single_line_txt_op_from_event(scratch.arena, evt, string, edit_state->cursor, edit_state->mark); + // rjf: any valid op & autocomplete hint? -> perform autocomplete first, then re-compute op + if(autocomplete_hint_string.size != 0) + { + take_autocomplete = 1; + String8 word_query = df_autocomp_query_word_from_input_string_off(string, edit_state->cursor.column-1); + U64 word_off = (U64)(word_query.str - string.str); + String8 new_string = ui_push_string_replace_range(scratch.arena, string, r1s64(word_off+1, word_off+1+word_query.size), autocomplete_hint_string); + new_string.size = Min(sizeof(edit_state->input_buffer), new_string.size); + MemoryCopy(edit_state->input_buffer, new_string.str, new_string.size); + edit_state->input_size = new_string.size; + edit_state->cursor = edit_state->mark = txt_pt(1, word_off+1+autocomplete_hint_string.size); + string = str8(edit_state->input_buffer, edit_state->input_size); + op = ui_single_line_txt_op_from_event(scratch.arena, evt, string, edit_state->cursor, edit_state->mark); + } + // rjf: cancel? -> revert to initial string if(editing_complete && evt->key == OS_Key_Esc) { @@ -1148,24 +1210,35 @@ df_watch_view_build(DF_Window *ws, DF_Panel *panel, DF_View *view, DF_WatchViewS for(S64 y = selection_tbl.min.y; y <= selection_tbl.max.y; y += 1) { DF_WatchViewPoint pt = df_watch_view_point_from_tbl(&blocks, v2s64(0, y)); - DF_EvalRoot *root = df_eval_root_from_expand_key(ewv, eval_view, pt.key); - if(root != 0) + + // rjf: row deletions + if(selection_tbl.min.x <= 0) { - DF_ExpandKey new_cursor_key = empty_row_key; - DF_ExpandKey new_cursor_parent_key = empty_row_parent_key; - if((evt->delta_2s32.x < 0 || evt->delta_2s32.y < 0) && root->prev != 0) + DF_EvalRoot *root = df_eval_root_from_expand_key(ewv, eval_view, pt.key); + if(root != 0) { - new_cursor_key = df_expand_key_from_eval_root(root->prev); - new_cursor_parent_key = df_parent_expand_key_from_eval_root(root->prev); + DF_ExpandKey new_cursor_key = empty_row_key; + DF_ExpandKey new_cursor_parent_key = empty_row_parent_key; + if((evt->delta_2s32.x < 0 || evt->delta_2s32.y < 0) && root->prev != 0) + { + new_cursor_key = df_expand_key_from_eval_root(root->prev); + new_cursor_parent_key = df_parent_expand_key_from_eval_root(root->prev); + } + else if(root->next != 0) + { + new_cursor_key = df_expand_key_from_eval_root(root->next); + new_cursor_parent_key = df_parent_expand_key_from_eval_root(root->next); + } + DF_WatchViewPoint new_cursor_pt = {DF_WatchViewColumnKind_Expr, new_cursor_parent_key, new_cursor_key}; + df_eval_root_release(ewv, root); + ewv->cursor = ewv->mark = new_cursor_pt; } - else if(root->next != 0) - { - new_cursor_key = df_expand_key_from_eval_root(root->next); - new_cursor_parent_key = df_parent_expand_key_from_eval_root(root->next); - } - DF_WatchViewPoint new_cursor_pt = {DF_WatchViewColumnKind_Expr, new_cursor_parent_key, new_cursor_key}; - df_eval_root_release(ewv, root); - ewv->cursor = ewv->mark = new_cursor_pt; + } + + // rjf: view rule deletions + else if(selection_tbl.min.x <= DF_WatchViewColumnKind_ViewRule && DF_WatchViewColumnKind_ViewRule <= selection_tbl.max.x) + { + df_eval_view_set_key_rule(eval_view, pt.key, str8_zero()); } } } @@ -1296,6 +1369,17 @@ df_watch_view_build(DF_Window *ws, DF_Panel *panel, DF_View *view, DF_WatchViewS ui_eat_event(events, event_n); } } + if(take_autocomplete) + { + for(UI_EventNode *n = events->first; n != 0; n = n->next) + { + if(n->v.kind == UI_EventKind_AutocompleteHint) + { + ui_eat_event(events, n); + break; + } + } + } } ////////////////////////////// @@ -1309,7 +1393,6 @@ df_watch_view_build(DF_Window *ws, DF_Panel *panel, DF_View *view, DF_WatchViewS &ewv->view_rule_column_pct, }; B32 pressed = 0; - DF_EvalVizRow *commit_row = 0; Vec2S64 next_cursor_tbl = cursor_tbl; Rng1S64 visible_row_rng = {0}; UI_ScrollListParams scroll_list_params = {0}; @@ -1399,10 +1482,10 @@ df_watch_view_build(DF_Window *ws, DF_Panel *panel, DF_View *view, DF_WatchViewS ProfScope("build table") { //- rjf: build rows - DF_WatchViewTextEditState dummy_edit_state = {0}; U64 semantic_idx = rows.count_before_semantic; for(DF_EvalVizRow *row = rows.first; row != 0; row = row->next, semantic_idx += 1) { + //- rjf: unpack row info U64 row_hash = df_hash_from_expand_key(row->key); U64 expr_hash = df_hash_from_string(row->display_expr); df_expand_tree_table_animate(&eval_view->expand_tree_table, df_dt()); @@ -1435,12 +1518,6 @@ df_watch_view_build(DF_Window *ws, DF_Panel *panel, DF_View *view, DF_WatchViewS }break; } - //- rjf: store root edit commit info - if(row_selected) - { - commit_row = row; - } - //- rjf: build canvas row if(row->flags & DF_EvalVizRowFlag_Canvas) UI_FocusHot(row_selected ? UI_FocusKind_On : UI_FocusKind_Off) ProfScope("canvas row") { @@ -1549,16 +1626,11 @@ df_watch_view_build(DF_Window *ws, DF_Panel *panel, DF_View *view, DF_WatchViewS //- rjf: expression ProfScope("expr") { - B32 cell_selected = (row_selected && selection_tbl.min.x <= DF_WatchViewColumnKind_Expr && DF_WatchViewColumnKind_Expr <= selection_tbl.max.x); + DF_WatchViewPoint pt = {DF_WatchViewColumnKind_Expr, row->parent_key, row->key}; + DF_WatchViewTextEditState *edit_state = df_watch_view_text_edit_state_from_pt(ewv, pt); + B32 cell_selected = (row_selected && selection_tbl.min.x <= pt.column_kind && pt.column_kind <= selection_tbl.max.x); B32 can_edit_expr = !(row->depth > 0 || modifiable == 0); - // rjf: obtain edit state for this cell - DF_WatchViewTextEditState *edit_state = &dummy_edit_state; - if(ewv->text_editing && cell_selected) - { - edit_state = &ewv->text_edit_states[(semantic_idx+1 - selection_tbl.min.y)*(dim_2s64(selection_tbl).x+1) + DF_WatchViewColumnKind_Expr-selection_tbl.min.x]; - } - // rjf: begin editing #if 0 if(cell_selected && (edit_begin || (edit_begin_or_expand && !(row->flags & DF_EvalVizRowFlag_CanExpand))) && can_edit_expr) @@ -1680,6 +1752,17 @@ df_watch_view_build(DF_Window *ws, DF_Panel *panel, DF_View *view, DF_WatchViewS scratch_end(scratch); } + + // rjf: autocomplete lister + if(expr_editing_active && + selection_tbl.min.x == selection_tbl.max.x && selection_tbl.min.y == selection_tbl.max.y && + txt_pt_match(edit_state->cursor, edit_state->mark)) + { + String8 input = str8(edit_state->input_buffer, edit_state->input_size); + DF_AutoCompListerParams params = {DF_AutoCompListerFlag_Locals}; + df_set_autocomp_lister_query(ws, sig.box->key, ctrl_ctx, ¶ms, input, edit_state->cursor.column-1); + } + #if 0 // TODO(rjf): if(expr_editing_active && !edit_end && txt_pt_match(ewv->input_cursor, ewv->input_mark)) { @@ -1732,19 +1815,14 @@ df_watch_view_build(DF_Window *ws, DF_Panel *panel, DF_View *view, DF_WatchViewS //- rjf: value ProfScope("value") { - B32 cell_selected = (row_selected && selection_tbl.min.x <= DF_WatchViewColumnKind_Value && DF_WatchViewColumnKind_Value <= selection_tbl.max.x); + DF_WatchViewPoint pt = {DF_WatchViewColumnKind_Value, row->parent_key, row->key}; + DF_WatchViewTextEditState *edit_state = df_watch_view_text_edit_state_from_pt(ewv, pt); + B32 cell_selected = (row_selected && selection_tbl.min.x <= pt.column_kind && pt.column_kind <= selection_tbl.max.x); B32 value_is_error = (row->eval.errors.count != 0); B32 value_is_hook = (!value_is_error && row->value_ui_rule_spec != &df_g_nil_gfx_view_rule_spec && row->value_ui_rule_spec != 0); B32 value_is_complex = (!value_is_error && !value_is_hook && !(row->flags & DF_EvalVizRowFlag_CanEditValue)); B32 value_is_simple = (!value_is_error && !value_is_hook && (row->flags & DF_EvalVizRowFlag_CanEditValue)); - // rjf: obtain edit state for this cell - DF_WatchViewTextEditState *edit_state = &dummy_edit_state; - if(ewv->text_editing && cell_selected) - { - edit_state = &ewv->text_edit_states[(semantic_idx+1 - selection_tbl.min.y)*(dim_2s64(selection_tbl).x+1) + DF_WatchViewColumnKind_Value-selection_tbl.min.x]; - } - // rjf: begin editing #if 0 // TODO(rjf): if(cell_selected && (edit_begin || edit_begin_or_expand) && value_is_simple) @@ -1842,7 +1920,9 @@ df_watch_view_build(DF_Window *ws, DF_Panel *panel, DF_View *view, DF_WatchViewS //- rjf: type ProfScope("type") { - B32 cell_selected = (row_selected && selection_tbl.min.x <= DF_WatchViewColumnKind_Type && DF_WatchViewColumnKind_Type <= selection_tbl.max.x); + DF_WatchViewPoint pt = {DF_WatchViewColumnKind_Type, row->parent_key, row->key}; + DF_WatchViewTextEditState *edit_state = df_watch_view_text_edit_state_from_pt(ewv, pt); + B32 cell_selected = (row_selected && selection_tbl.min.x <= pt.column_kind && pt.column_kind <= selection_tbl.max.x); UI_TableCell UI_Font(code_font) UI_FocusHot(cell_selected ? UI_FocusKind_On : UI_FocusKind_Off) UI_FocusActive((cell_selected && ewv->text_editing) ? UI_FocusKind_On : UI_FocusKind_Off) @@ -1868,16 +1948,11 @@ df_watch_view_build(DF_Window *ws, DF_Panel *panel, DF_View *view, DF_WatchViewS //- rjf: view rule ProfScope("view rule") { - B32 cell_selected = (row_selected && selection_tbl.min.x <= DF_WatchViewColumnKind_ViewRule && DF_WatchViewColumnKind_ViewRule <= selection_tbl.max.x); + DF_WatchViewPoint pt = {DF_WatchViewColumnKind_ViewRule, row->parent_key, row->key}; + DF_WatchViewTextEditState *edit_state = df_watch_view_text_edit_state_from_pt(ewv, pt); + B32 cell_selected = (row_selected && selection_tbl.min.x <= pt.column_kind && pt.column_kind <= selection_tbl.max.x); String8 view_rule = df_eval_view_rule_from_key(eval_view, row->key); - // rjf: obtain edit state for this cell - DF_WatchViewTextEditState *edit_state = &dummy_edit_state; - if(ewv->text_editing && cell_selected) - { - edit_state = &ewv->text_edit_states[(semantic_idx+1 - selection_tbl.min.y)*(dim_2s64(selection_tbl).x+1) + DF_WatchViewColumnKind_ViewRule-selection_tbl.min.x]; - } - // rjf: begin editing #if 0 // TODO(rjf): if(cell_selected && (edit_begin || edit_begin_or_expand)) @@ -1910,6 +1985,20 @@ df_watch_view_build(DF_Window *ws, DF_Panel *panel, DF_View *view, DF_WatchViewS next_cursor_tbl = v2s64(DF_WatchViewColumnKind_ViewRule, (semantic_idx+1)); } + // rjf: autocomplete lister + if(rule_editing_active && + selection_tbl.min.x == selection_tbl.max.x && selection_tbl.min.y == selection_tbl.max.y && + txt_pt_match(edit_state->cursor, edit_state->mark)) + { + String8 input = str8(edit_state->input_buffer, edit_state->input_size); + DF_AutoCompListerParams params = df_view_rule_autocomp_lister_params_from_input_cursor(scratch.arena, input, edit_state->cursor.column-1); + if(params.flags == 0) + { + params.flags = DF_AutoCompListerFlag_ViewRules; + } + df_set_autocomp_lister_query(ws, sig.box->key, ctrl_ctx, ¶ms, input, edit_state->cursor.column-1); + } + // rjf: double-click -> begin editing // TODO(rjf): #if 0 diff --git a/src/df/gfx/df_views.h b/src/df/gfx/df_views.h index ac56cac9..e10ebf1e 100644 --- a/src/df/gfx/df_views.h +++ b/src/df/gfx/df_views.h @@ -315,6 +315,8 @@ struct DF_WatchViewPoint typedef struct DF_WatchViewTextEditState DF_WatchViewTextEditState; struct DF_WatchViewTextEditState { + DF_WatchViewTextEditState *pt_hash_next; + DF_WatchViewPoint pt; TxtPt cursor; TxtPt mark; U8 input_buffer[1024]; @@ -337,8 +339,9 @@ struct DF_WatchViewState // rjf: text input state Arena *text_edit_arena; - U64 text_edit_count; - DF_WatchViewTextEditState *text_edit_states; + U64 text_edit_state_slots_count; + DF_WatchViewTextEditState dummy_text_edit_state; + DF_WatchViewTextEditState **text_edit_state_slots; B32 text_editing; // rjf: table column width state @@ -486,6 +489,9 @@ internal Vec2S64 df_tbl_from_watch_view_point(DF_EvalVizBlockList *blocks, DF_Wa //- rjf: table coordinates -> strings internal String8 df_string_from_eval_viz_row_column_kind(Arena *arena, DF_EvalView *ev, TG_Graph *graph, RDI_Parsed *rdi, DF_EvalVizRow *row, DF_WatchViewColumnKind col_kind, B32 editable); +//- rjf: table coordinates -> text edit state +internal DF_WatchViewTextEditState *df_watch_view_text_edit_state_from_pt(DF_WatchViewState *wv, DF_WatchViewPoint pt); + //- rjf: windowed watch tree visualization internal DF_EvalVizBlockList df_eval_viz_block_list_from_watch_view_state(Arena *arena, DBGI_Scope *scope, DF_CtrlCtx *ctrl_ctx, EVAL_ParseCtx *parse_ctx, EVAL_String2ExprMap *macro_map, DF_View *view, DF_WatchViewState *ews); From f1af166fd48f954e5bd8363e92aa6392c551c0e6 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Wed, 15 May 2024 10:53:26 -0700 Subject: [PATCH 25/30] expand ui events to contain semantic 'controls' info, to eliminate most hardcoded escs/returns/f2s/etc; formalize these things as proper commands; keyboard-driven expansions; other various fixes --- src/df/core/df_core.mdesk | 5 ++ src/df/core/generated/df_core.meta.c | 5 +- src/df/core/generated/df_core.meta.h | 3 ++ src/df/gfx/df_gfx.c | 72 ++++++++++++++++++++++---- src/df/gfx/df_gfx.mdesk | 5 ++ src/df/gfx/df_views.c | 77 +++++++++++++++++++--------- src/df/gfx/generated/df_gfx.meta.c | 5 +- src/df/gfx/generated/df_gfx.meta.h | 2 +- src/raddbg/raddbg.c | 1 + src/ui/ui_core.c | 23 +++++++-- src/ui/ui_core.h | 14 +++++ 11 files changed, 171 insertions(+), 41 deletions(-) diff --git a/src/df/core/df_core.mdesk b/src/df/core/df_core.mdesk index 6d2f761c..355a3a15 100644 --- a/src/df/core/df_core.mdesk +++ b/src/df/core/df_core.mdesk @@ -251,6 +251,11 @@ DF_CoreCmdTable:// | | | {WriteUserData 1 Null Nil 0 0 0 0 0 0 Null "write_user_data" "Write User Data" "Writes user data to the active user file." "" } {WriteProfileData 1 Null Nil 0 0 0 0 0 0 Null "write_profile_data" "Write Profile Data" "Writes profile data to the active profile file." "" } + //- rjf: meta controls + {Edit 0 Null Nil 0 0 0 0 0 0 Pencil "edit" "Edit" "Edits the current selection." "" } + {Accept 0 Null Nil 0 0 0 0 0 0 CheckFilled "accept" "Accept" "Accepts current changes, or answers prompts in the affirmative." "" } + {Cancel 0 Null Nil 0 0 0 0 0 0 X "cancel" "Cancel" "Rejects current changes, exits temporary menus, or answers prompts in the negative." "" } + //- rjf: directional movement & text controls {MoveLeft 0 Null Nil 0 0 0 0 0 0 Null "move_left" "Move Left" "Moves the cursor or selection left." "" } {MoveRight 0 Null Nil 0 0 0 0 0 0 Null "move_right" "Move Right" "Moves the cursor or selection right." "" } diff --git a/src/df/core/generated/df_core.meta.c b/src/df/core/generated/df_core.meta.c index 739df9ae..9638f520 100644 --- a/src/df/core/generated/df_core.meta.c +++ b/src/df/core/generated/df_core.meta.c @@ -217,7 +217,7 @@ DF_CoreCmdKind_Null, DF_CoreCmdKind_Null, }; -DF_CmdSpecInfo df_g_core_cmd_kind_spec_info_table[215] = +DF_CmdSpecInfo df_g_core_cmd_kind_spec_info_table[218] = { { str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp(""), (DF_CmdSpecFlag_OmitFromLists*1), {DF_CmdParamSlot_Null, DF_EntityKind_Nil, (DF_CmdQueryFlag_AllowFiles*0)|(DF_CmdQueryFlag_AllowFolders*0)|(DF_CmdQueryFlag_CodeInput*0)|(DF_CmdQueryFlag_KeepOldInput*0)|(DF_CmdQueryFlag_SelectOldInput*0)|(DF_CmdQueryFlag_Required*0)}, DF_IconKind_Null}, { str8_lit_comp("exit"), str8_lit_comp("Exits the debugger."), str8_lit_comp("quit,close,abort"), str8_lit_comp("Exit"), (DF_CmdSpecFlag_OmitFromLists*0), {DF_CmdParamSlot_Null, DF_EntityKind_Nil, (DF_CmdQueryFlag_AllowFiles*0)|(DF_CmdQueryFlag_AllowFolders*0)|(DF_CmdQueryFlag_CodeInput*0)|(DF_CmdQueryFlag_KeepOldInput*0)|(DF_CmdQueryFlag_SelectOldInput*0)|(DF_CmdQueryFlag_Required*0)}, DF_IconKind_X}, @@ -317,6 +317,9 @@ DF_CmdSpecInfo df_g_core_cmd_kind_spec_info_table[215] = { str8_lit_comp("apply_profile_data"), str8_lit_comp("Applies profile data from the active profile file."), str8_lit_comp(""), str8_lit_comp("Apply Profile Data"), (DF_CmdSpecFlag_OmitFromLists*1), {DF_CmdParamSlot_Null, DF_EntityKind_Nil, (DF_CmdQueryFlag_AllowFiles*0)|(DF_CmdQueryFlag_AllowFolders*0)|(DF_CmdQueryFlag_CodeInput*0)|(DF_CmdQueryFlag_KeepOldInput*0)|(DF_CmdQueryFlag_SelectOldInput*0)|(DF_CmdQueryFlag_Required*0)}, DF_IconKind_Null}, { str8_lit_comp("write_user_data"), str8_lit_comp("Writes user data to the active user file."), str8_lit_comp(""), str8_lit_comp("Write User Data"), (DF_CmdSpecFlag_OmitFromLists*1), {DF_CmdParamSlot_Null, DF_EntityKind_Nil, (DF_CmdQueryFlag_AllowFiles*0)|(DF_CmdQueryFlag_AllowFolders*0)|(DF_CmdQueryFlag_CodeInput*0)|(DF_CmdQueryFlag_KeepOldInput*0)|(DF_CmdQueryFlag_SelectOldInput*0)|(DF_CmdQueryFlag_Required*0)}, DF_IconKind_Null}, { str8_lit_comp("write_profile_data"), str8_lit_comp("Writes profile data to the active profile file."), str8_lit_comp(""), str8_lit_comp("Write Profile Data"), (DF_CmdSpecFlag_OmitFromLists*1), {DF_CmdParamSlot_Null, DF_EntityKind_Nil, (DF_CmdQueryFlag_AllowFiles*0)|(DF_CmdQueryFlag_AllowFolders*0)|(DF_CmdQueryFlag_CodeInput*0)|(DF_CmdQueryFlag_KeepOldInput*0)|(DF_CmdQueryFlag_SelectOldInput*0)|(DF_CmdQueryFlag_Required*0)}, DF_IconKind_Null}, +{ str8_lit_comp("edit"), str8_lit_comp("Edits the current selection."), str8_lit_comp(""), str8_lit_comp("Edit"), (DF_CmdSpecFlag_OmitFromLists*0), {DF_CmdParamSlot_Null, DF_EntityKind_Nil, (DF_CmdQueryFlag_AllowFiles*0)|(DF_CmdQueryFlag_AllowFolders*0)|(DF_CmdQueryFlag_CodeInput*0)|(DF_CmdQueryFlag_KeepOldInput*0)|(DF_CmdQueryFlag_SelectOldInput*0)|(DF_CmdQueryFlag_Required*0)}, DF_IconKind_Pencil}, +{ str8_lit_comp("accept"), str8_lit_comp("Accepts current changes, or answers prompts in the affirmative."), str8_lit_comp(""), str8_lit_comp("Accept"), (DF_CmdSpecFlag_OmitFromLists*0), {DF_CmdParamSlot_Null, DF_EntityKind_Nil, (DF_CmdQueryFlag_AllowFiles*0)|(DF_CmdQueryFlag_AllowFolders*0)|(DF_CmdQueryFlag_CodeInput*0)|(DF_CmdQueryFlag_KeepOldInput*0)|(DF_CmdQueryFlag_SelectOldInput*0)|(DF_CmdQueryFlag_Required*0)}, DF_IconKind_CheckFilled}, +{ str8_lit_comp("cancel"), str8_lit_comp("Rejects current changes, exits temporary menus, or answers prompts in the negative."), str8_lit_comp(""), str8_lit_comp("Cancel"), (DF_CmdSpecFlag_OmitFromLists*0), {DF_CmdParamSlot_Null, DF_EntityKind_Nil, (DF_CmdQueryFlag_AllowFiles*0)|(DF_CmdQueryFlag_AllowFolders*0)|(DF_CmdQueryFlag_CodeInput*0)|(DF_CmdQueryFlag_KeepOldInput*0)|(DF_CmdQueryFlag_SelectOldInput*0)|(DF_CmdQueryFlag_Required*0)}, DF_IconKind_X}, { str8_lit_comp("move_left"), str8_lit_comp("Moves the cursor or selection left."), str8_lit_comp(""), str8_lit_comp("Move Left"), (DF_CmdSpecFlag_OmitFromLists*0), {DF_CmdParamSlot_Null, DF_EntityKind_Nil, (DF_CmdQueryFlag_AllowFiles*0)|(DF_CmdQueryFlag_AllowFolders*0)|(DF_CmdQueryFlag_CodeInput*0)|(DF_CmdQueryFlag_KeepOldInput*0)|(DF_CmdQueryFlag_SelectOldInput*0)|(DF_CmdQueryFlag_Required*0)}, DF_IconKind_Null}, { str8_lit_comp("move_right"), str8_lit_comp("Moves the cursor or selection right."), str8_lit_comp(""), str8_lit_comp("Move Right"), (DF_CmdSpecFlag_OmitFromLists*0), {DF_CmdParamSlot_Null, DF_EntityKind_Nil, (DF_CmdQueryFlag_AllowFiles*0)|(DF_CmdQueryFlag_AllowFolders*0)|(DF_CmdQueryFlag_CodeInput*0)|(DF_CmdQueryFlag_KeepOldInput*0)|(DF_CmdQueryFlag_SelectOldInput*0)|(DF_CmdQueryFlag_Required*0)}, DF_IconKind_Null}, { str8_lit_comp("move_up"), str8_lit_comp("Moves the cursor or selection up."), str8_lit_comp(""), str8_lit_comp("Move Up"), (DF_CmdSpecFlag_OmitFromLists*0), {DF_CmdParamSlot_Null, DF_EntityKind_Nil, (DF_CmdQueryFlag_AllowFiles*0)|(DF_CmdQueryFlag_AllowFolders*0)|(DF_CmdQueryFlag_CodeInput*0)|(DF_CmdQueryFlag_KeepOldInput*0)|(DF_CmdQueryFlag_SelectOldInput*0)|(DF_CmdQueryFlag_Required*0)}, DF_IconKind_Null}, diff --git a/src/df/core/generated/df_core.meta.h b/src/df/core/generated/df_core.meta.h index d8ea126f..ebdb155f 100644 --- a/src/df/core/generated/df_core.meta.h +++ b/src/df/core/generated/df_core.meta.h @@ -147,6 +147,9 @@ DF_CoreCmdKind_ApplyUserData, DF_CoreCmdKind_ApplyProfileData, DF_CoreCmdKind_WriteUserData, DF_CoreCmdKind_WriteProfileData, +DF_CoreCmdKind_Edit, +DF_CoreCmdKind_Accept, +DF_CoreCmdKind_Cancel, DF_CoreCmdKind_MoveLeft, DF_CoreCmdKind_MoveRight, DF_CoreCmdKind_MoveUp, diff --git a/src/df/gfx/df_gfx.c b/src/df/gfx/df_gfx.c index 6cbed85d..36968c75 100644 --- a/src/df/gfx/df_gfx.c +++ b/src/df/gfx/df_gfx.c @@ -2107,6 +2107,29 @@ df_window_update_and_render(Arena *arena, DF_Window *ws, DF_CmdList *cmds) } }break; + //- rjf: meta controls + case DF_CoreCmdKind_Edit: + { + UI_Event evt = zero_struct; + evt.kind = UI_EventKind_Press; + evt.slot = UI_EventActionSlot_Edit; + ui_event_list_push(ui_build_arena(), &events, &evt); + }break; + case DF_CoreCmdKind_Accept: + { + UI_Event evt = zero_struct; + evt.kind = UI_EventKind_Press; + evt.slot = UI_EventActionSlot_Accept; + ui_event_list_push(ui_build_arena(), &events, &evt); + }break; + case DF_CoreCmdKind_Cancel: + { + UI_Event evt = zero_struct; + evt.kind = UI_EventKind_Press; + evt.slot = UI_EventActionSlot_Cancel; + ui_event_list_push(ui_build_arena(), &events, &evt); + }break; + //- rjf: directional movement & text controls // // NOTE(rjf): These all get funneled into a separate intermediate that @@ -4175,14 +4198,14 @@ df_window_update_and_render(Arena *arena, DF_Window *ws, DF_CmdList *cmds) UI_BackgroundColor(df_rgba_from_theme_color(DF_ThemeColor_ActionBackground)) UI_TextColor(df_rgba_from_theme_color(DF_ThemeColor_ActionText)) UI_BorderColor(df_rgba_from_theme_color(DF_ThemeColor_ActionBorder)) - if(ui_clicked(ui_buttonf("OK")) || (ui_key_match(bg_box->default_nav_focus_hot_key, ui_key_zero()) && ui_key_press(0, OS_Key_Return))) + if(ui_clicked(ui_buttonf("OK")) || (ui_key_match(bg_box->default_nav_focus_hot_key, ui_key_zero()) && ui_slot_press(UI_EventActionSlot_Accept))) { DF_CmdParams p = df_cmd_params_zero(); df_push_cmd__root(&p, df_cmd_spec_from_core_cmd_kind(DF_CoreCmdKind_ConfirmAccept)); } UI_CornerRadius10(ui_top_font_size()*0.25f) UI_CornerRadius11(ui_top_font_size()*0.25f) - if(ui_clicked(ui_buttonf("Cancel")) || ui_key_press(0, OS_Key_Esc)) + if(ui_clicked(ui_buttonf("Cancel")) || ui_slot_press(UI_EventActionSlot_Cancel)) { DF_CmdParams p = df_cmd_params_zero(); df_push_cmd__root(&p, df_cmd_spec_from_core_cmd_kind(DF_CoreCmdKind_ConfirmCancel)); @@ -4441,7 +4464,7 @@ df_window_update_and_render(Arena *arena, DF_Window *ws, DF_CmdList *cmds) for(U64 idx = 0; idx < item_array.count; idx += 1) { DF_AutoCompListerItem *item = &item_array.v[idx]; - UI_Box *item_box = ui_build_box_from_stringf(UI_BoxFlag_DrawBorder|UI_BoxFlag_DrawBackground|UI_BoxFlag_DrawHotEffects|UI_BoxFlag_DrawActiveEffects|UI_BoxFlag_Clickable, "autocomp_%I64x", idx); + UI_Box *item_box = ui_build_box_from_stringf(UI_BoxFlag_DrawBorder|UI_BoxFlag_DrawBackground|UI_BoxFlag_DrawHotEffects|UI_BoxFlag_DrawActiveEffects|UI_BoxFlag_MouseClickable, "autocomp_%I64x", idx); UI_Parent(item_box) { UI_WidthFill @@ -5579,14 +5602,14 @@ df_window_update_and_render(Arena *arena, DF_Window *ws, DF_CmdList *cmds) //- rjf: query submission if((ui_is_focus_active() || (window_is_focused && !ui_any_ctx_menu_is_open() && !ws->menu_bar_focused && !ws->query_view_selected)) && - ui_key_press(0, OS_Key_Esc)) + ui_slot_press(UI_EventActionSlot_Cancel)) { DF_CmdParams params = df_cmd_params_from_window(ws); df_push_cmd__root(¶ms, df_cmd_spec_from_core_cmd_kind(DF_CoreCmdKind_CancelQuery)); } if(ui_is_focus_active()) { - if(ui_key_press(0, OS_Key_Return)) + if(ui_slot_press(UI_EventActionSlot_Accept)) { Temp scratch = scratch_begin(&arena, 1); DF_View *view = ws->query_view_stack_top; @@ -5621,6 +5644,10 @@ df_window_update_and_render(Arena *arena, DF_Window *ws, DF_CmdList *cmds) ui_build_box_from_key(UI_BoxFlag_DrawBackground, ui_key_zero()); } } + else + { + ws->query_view_selected = 0; + } //////////////////////////// //- rjf: build hover eval @@ -6507,7 +6534,7 @@ df_window_update_and_render(Arena *arena, DF_Window *ws, DF_CmdList *cmds) DF_View *view = df_view_from_handle(panel->selected_tab_view); UI_Focus(UI_FocusKind_On) { - if(view->is_filtering && ui_is_focus_active() && ui_key_press(0, OS_Key_Return)) + if(view->is_filtering && ui_is_focus_active() && ui_slot_press(UI_EventActionSlot_Accept)) { DF_CmdParams p = df_cmd_params_from_view(ws, panel, view); df_push_cmd__root(&p, df_cmd_spec_from_core_cmd_kind(DF_CoreCmdKind_ApplyFilter)); @@ -6745,7 +6772,7 @@ df_window_update_and_render(Arena *arena, DF_Window *ws, DF_CmdList *cmds) } } } - if((view->query_string_size != 0 || view->is_filtering) && ui_is_focus_active() && ui_key_press(0, OS_Key_Esc)) + if((view->query_string_size != 0 || view->is_filtering) && ui_is_focus_active() && ui_slot_press(UI_EventActionSlot_Cancel)) { DF_CmdParams p = df_cmd_params_from_view(ws, panel, view); df_push_cmd__root(&p, df_cmd_spec_from_core_cmd_kind(DF_CoreCmdKind_ClearFilter)); @@ -7316,7 +7343,7 @@ df_window_update_and_render(Arena *arena, DF_Window *ws, DF_CmdList *cmds) //////////////////////////// //- rjf: drag/drop cancelling // - if(df_drag_is_active() && ui_key_press(0, OS_Key_Esc)) + if(df_drag_is_active() && ui_slot_press(UI_EventActionSlot_Cancel)) { df_drag_kill(); ui_kill_action(); @@ -7399,7 +7426,7 @@ df_window_update_and_render(Arena *arena, DF_Window *ws, DF_CmdList *cmds) ////////////////////////////// //- rjf: hover eval cancelling // - if(ws->hover_eval_string.size != 0 && ui_key_press(0, OS_Key_Esc)) + if(ws->hover_eval_string.size != 0 && ui_slot_press(UI_EventActionSlot_Cancel)) { MemoryZeroStruct(&ws->hover_eval_string); arena_clear(ws->hover_eval_arena); @@ -12423,7 +12450,7 @@ df_line_edit(DF_LineEditFlags flags, S32 depth, FuzzyMatchRangeList *matches, Tx } } } - if(is_focus_hot && ui_key_press(0, OS_Key_F2)) + if(is_focus_hot && ui_slot_press(UI_EventActionSlot_Edit)) { start_editing_via_typing = 1; } @@ -13636,6 +13663,31 @@ df_gfx_begin_frame(Arena *arena, DF_CmdList *cmds) df_bind_spec(cmd_spec, pair->binding); } } + + //- rjf: always ensure that the meta controls have bindings + if(src == DF_CfgSrc_User) + { + struct + { + DF_CmdSpec *spec; + OS_Key fallback_key; + } + meta_ctrls[] = + { + { df_cmd_spec_from_core_cmd_kind(DF_CoreCmdKind_Edit), OS_Key_F2 }, + { df_cmd_spec_from_core_cmd_kind(DF_CoreCmdKind_Accept), OS_Key_Return }, + { df_cmd_spec_from_core_cmd_kind(DF_CoreCmdKind_Cancel), OS_Key_Esc }, + }; + for(U64 idx = 0; idx < ArrayCount(meta_ctrls); idx += 1) + { + DF_BindingList bindings = df_bindings_from_spec(scratch.arena, meta_ctrls[idx].spec); + if(bindings.count == 0) + { + DF_Binding binding = {meta_ctrls[idx].fallback_key, 0}; + df_bind_spec(meta_ctrls[idx].spec, binding); + } + } + } }break; //- rjf: writing config changes diff --git a/src/df/gfx/df_gfx.mdesk b/src/df/gfx/df_gfx.mdesk index cb6859b0..38470bad 100644 --- a/src/df/gfx/df_gfx.mdesk +++ b/src/df/gfx/df_gfx.mdesk @@ -90,6 +90,11 @@ DF_DefaultBindingTable: { "load_user" O ctrl shift alt } { "load_profile" O ctrl 0 alt } + //- rjf: meta controls + { "edit" F2 0 0 0 } + { "accept" Return 0 0 0 } + { "cancel" Esc 0 0 0 } + //- rjf: directional movement & text controls { "move_left" Left 0 0 0 } { "move_right" Right 0 0 0 } diff --git a/src/df/gfx/df_views.c b/src/df/gfx/df_views.c index e18d64b8..abf2dd66 100644 --- a/src/df/gfx/df_views.c +++ b/src/df/gfx/df_views.c @@ -504,7 +504,7 @@ df_string_from_eval_viz_row_column_kind(Arena *arena, DF_EvalView *ev, TG_Graph default:{}break; case DF_WatchViewColumnKind_Expr: {result = editable ? row->edit_expr : row->display_expr;}break; case DF_WatchViewColumnKind_Value: {result = editable ? row->edit_value : row->display_value;}break; - case DF_WatchViewColumnKind_Type: {result = tg_string_from_key(arena, graph, rdi, row->eval.type_key);}break; + case DF_WatchViewColumnKind_Type: {result = !tg_key_match(row->eval.type_key, tg_key_zero()) ? tg_string_from_key(arena, graph, rdi, row->eval.type_key) : str8_zero();}break; case DF_WatchViewColumnKind_ViewRule:{result = df_eval_view_rule_from_key(ev, row->key);}break; } return result; @@ -1023,7 +1023,8 @@ df_watch_view_build(DF_Window *ws, DF_Panel *panel, DF_View *view, DF_WatchViewS if(!ewv->text_editing && (evt->kind == UI_EventKind_Text || evt->flags & UI_EventFlag_Paste || - (evt->kind == UI_EventKind_Press && (evt->key == OS_Key_Return || evt->key == OS_Key_F2)))) + (evt->kind == UI_EventKind_Press && (evt->slot == UI_EventActionSlot_Accept || evt->slot == UI_EventActionSlot_Edit))) && + selection_tbl.min.x == selection_tbl.max.x) { Vec2S64 selection_dim = dim_2s64(selection_tbl); ewv->text_editing = 1; @@ -1062,7 +1063,7 @@ df_watch_view_build(DF_Window *ws, DF_Panel *panel, DF_View *view, DF_WatchViewS // if(ewv->text_editing) { - B32 editing_complete = ((evt->kind == UI_EventKind_Press && (evt->key == OS_Key_Esc || evt->key == OS_Key_Return)) || + B32 editing_complete = ((evt->kind == UI_EventKind_Press && (evt->slot == UI_EventActionSlot_Cancel || evt->slot == UI_EventActionSlot_Accept)) || (evt->kind == UI_EventKind_Navigate && evt->delta_2s32.y != 0)); if(editing_complete || ((evt->kind == UI_EventKind_Edit || @@ -1096,7 +1097,7 @@ df_watch_view_build(DF_Window *ws, DF_Panel *panel, DF_View *view, DF_WatchViewS } // rjf: cancel? -> revert to initial string - if(editing_complete && evt->key == OS_Key_Esc) + if(editing_complete && evt->slot == UI_EventActionSlot_Cancel) { string = str8(edit_state->initial_buffer, edit_state->initial_size); } @@ -1137,7 +1138,7 @@ df_watch_view_build(DF_Window *ws, DF_Panel *panel, DF_View *view, DF_WatchViewS } }break; case DF_WatchViewColumnKind_Value: - if(editing_complete) + if(editing_complete && evt->slot != UI_EventActionSlot_Cancel) { DF_EvalVizWindowedRowList rows = df_eval_viz_windowed_row_list_from_viz_block_list(scratch.arena, scope, &ctrl_ctx, &parse_ctx, ¯o_map, eval_view, default_radix, code_font, ui_top_font_size(), r1s64(ui_scroll_list_row_from_item(&row_blocks, y-1), @@ -1190,7 +1191,13 @@ df_watch_view_build(DF_Window *ws, DF_Panel *panel, DF_View *view, DF_WatchViewS for(S64 x = selection_tbl.min.x; x <= selection_tbl.max.x; x += 1) { String8 cell_string = df_string_from_eval_viz_row_column_kind(scratch.arena, eval_view, parse_ctx.type_graph, parse_ctx.rdi, row, (DF_WatchViewColumnKind)x, 0); - str8_list_pushf(scratch.arena, &strs, "%S%s", cell_string, x+1 <= selection_tbl.max.x ? " " : ""); + cell_string = str8_skip_chop_whitespace(cell_string); + U64 comma_pos = str8_find_needle(cell_string, 0, str8_lit(","), 0); + str8_list_pushf(scratch.arena, &strs, "%s%S%s%s", + comma_pos < cell_string.size ? "\"" : "", + cell_string, + comma_pos < cell_string.size ? "\"" : "", + x+1 <= selection_tbl.max.x ? "," : ""); } if(y+1 <= selection_tbl.max.y) { @@ -1201,12 +1208,33 @@ df_watch_view_build(DF_Window *ws, DF_Panel *panel, DF_View *view, DF_WatchViewS os_set_clipboard_text(string); } + ////////////////////////// + //- rjf: [table] do cell-granularity expansions + // + if(!ewv->text_editing && evt->slot == UI_EventActionSlot_Accept && selection_tbl.min.x <= 0) + { + taken = 1; + DF_EvalVizWindowedRowList rows = df_eval_viz_windowed_row_list_from_viz_block_list(scratch.arena, scope, &ctrl_ctx, &parse_ctx, ¯o_map, eval_view, default_radix, code_font, ui_top_font_size(), + r1s64(ui_scroll_list_row_from_item(&row_blocks, selection_tbl.min.y-1), + ui_scroll_list_row_from_item(&row_blocks, selection_tbl.max.y-1)+1), &blocks); + DF_EvalVizRow *row = rows.first; + for(S64 y = selection_tbl.min.y; y <= selection_tbl.max.y && row != 0; y += 1, row = row->next) + { + if(row->flags & DF_EvalVizRowFlag_CanExpand) + { + B32 is_expanded = df_expand_key_is_set(&eval_view->expand_tree_table, row->key); + df_expand_set_expansion(eval_view->arena, &eval_view->expand_tree_table, row->parent_key, row->key, !is_expanded); + } + } + } + ////////////////////////// //- rjf: [table] do cell-granularity deletions // if(!ewv->text_editing && evt->flags & UI_EventFlag_Delete) { taken = 1; + state_dirty = 1; for(S64 y = selection_tbl.min.y; y <= selection_tbl.max.y; y += 1) { DF_WatchViewPoint pt = df_watch_view_point_from_tbl(&blocks, v2s64(0, y)); @@ -2405,7 +2433,7 @@ DF_VIEW_UI_FUNCTION_DEF(Commands) df_cmd_lister_item_array_sort_by_strength__in_place(cmd_array); //- rjf: submit best match when hitting enter w/ no selection - if(cv->selected_cmd_spec == &df_g_nil_cmd_spec && ui_key_press(0, OS_Key_Return)) + if(cv->selected_cmd_spec == &df_g_nil_cmd_spec && ui_slot_press(UI_EventActionSlot_Accept)) { DF_CmdParams params = df_cmd_params_from_view(ws, panel, view); if(cmd_array.count > 0) @@ -2750,7 +2778,7 @@ DF_VIEW_UI_FUNCTION_DEF(FileSystem) } //- rjf: submit best match when hitting enter w/ no selection - if(ps->cursor.y == 0 && ui_key_press(0, OS_Key_Return)) + if(ps->cursor.y == 0 && ui_slot_press(UI_EventActionSlot_Accept)) { FileProperties query_normalized_with_opt_slash_props = os_properties_from_file_path(query_normalized_with_opt_slash); FileProperties path_query_path_props = os_properties_from_file_path(path_query.path); @@ -3095,7 +3123,7 @@ DF_VIEW_UI_FUNCTION_DEF(SystemProcesses) } //- rjf: submit best match when hitting enter w/ no selection - if(sp->selected_pid == 0 && process_info_array.count > 0 && ui_key_press(0, OS_Key_Return)) + if(sp->selected_pid == 0 && process_info_array.count > 0 && ui_slot_press(UI_EventActionSlot_Accept)) { DF_ProcessInfo *info = &process_info_array.v[0]; DF_CmdParams params = df_cmd_params_from_view(ws, panel, view); @@ -3257,7 +3285,7 @@ DF_VIEW_UI_FUNCTION_DEF(EntityLister) df_entity_lister_item_array_sort_by_strength__in_place(ent_arr); //- rjf: submit best match when hitting enter w/ no selection - if(df_entity_is_nil(df_entity_from_handle(fev->selected_entity_handle)) && ent_arr.count != 0 && ui_key_press(0, OS_Key_Return)) + if(df_entity_is_nil(df_entity_from_handle(fev->selected_entity_handle)) && ent_arr.count != 0 && ui_slot_press(UI_EventActionSlot_Accept)) { DF_Entity *ent = ent_arr.v[0].entity; DF_CmdParams params = df_cmd_params_from_view(ws, panel, view); @@ -3415,7 +3443,7 @@ DF_VIEW_UI_FUNCTION_DEF(SymbolLister) } //- rjf: submit best match when hitting enter w/ no selection - if(slv->cursor.y == 0 && items.count != 0 && ui_key_press(0, OS_Key_Return)) + if(slv->cursor.y == 0 && items.count != 0 && ui_slot_press(UI_EventActionSlot_Accept)) { RDI_Procedure *procedure = rdi_element_from_idx(rdi, procedures, items.v[0].idx); U64 name_size = 0; @@ -3629,23 +3657,23 @@ DF_VIEW_UI_FUNCTION_DEF(Target) break; } } - if(ui_key_press(0, OS_Key_F2)) + if(ui_slot_press(UI_EventActionSlot_Edit)) { edit_begin = 1; } - if(ui_key_press(0, OS_Key_Return)) + if(ui_slot_press(UI_EventActionSlot_Accept)) { edit_begin = 1; } } if(tv->input_editing) { - if(ui_key_press(0, OS_Key_Esc)) + if(ui_slot_press(UI_EventActionSlot_Cancel)) { edit_end = 1; edit_commit = 0; } - if(ui_key_press(0, OS_Key_Return)) + if(ui_slot_press(UI_EventActionSlot_Accept)) { edit_end = 1; edit_commit = 1; @@ -4114,19 +4142,19 @@ DF_VIEW_UI_FUNCTION_DEF(FilePathMap) break; } } - if(ui_key_press(0, OS_Key_F2)) + if(ui_slot_press(UI_EventActionSlot_Edit)) { edit_begin = 1; } } if(fpms->input_editing) { - if(ui_key_press(0, OS_Key_Esc)) + if(ui_slot_press(UI_EventActionSlot_Cancel)) { edit_end = 1; edit_commit = 0; } - if(ui_key_press(0, OS_Key_Return)) + if(ui_slot_press(UI_EventActionSlot_Accept)) { edit_end = 1; edit_commit = 1; @@ -4437,19 +4465,19 @@ DF_VIEW_UI_FUNCTION_DEF(AutoViewRules) break; } } - if(ui_key_press(0, OS_Key_F2)) + if(ui_slot_press(UI_EventActionSlot_Edit)) { edit_begin = 1; } } if(avrs->input_editing) { - if(ui_key_press(0, OS_Key_Esc)) + if(ui_slot_press(UI_EventActionSlot_Cancel)) { edit_end = 1; edit_commit = 0; } - if(ui_key_press(0, OS_Key_Return)) + if(ui_slot_press(UI_EventActionSlot_Accept)) { edit_end = 1; edit_commit = 1; @@ -5269,20 +5297,19 @@ DF_VIEW_UI_FUNCTION_DEF(Modules) break; } } - if(ui_key_press(0, OS_Key_F2) || - ui_key_press(0, OS_Key_Return)) + if(ui_slot_press(UI_EventActionSlot_Edit)) { edit_begin = 1; } } if(mv->txt_editing && ui_is_focus_active()) { - if(ui_key_press(0, OS_Key_Esc)) + if(ui_slot_press(UI_EventActionSlot_Cancel)) { edit_end = 1; edit_commit = 0; } - if(ui_key_press(0, OS_Key_Return)) + if(ui_slot_press(UI_EventActionSlot_Accept)) { edit_end = 1; edit_commit = 1; diff --git a/src/df/gfx/generated/df_gfx.meta.c b/src/df/gfx/generated/df_gfx.meta.c index fd95865b..1edde9d8 100644 --- a/src/df/gfx/generated/df_gfx.meta.c +++ b/src/df/gfx/generated/df_gfx.meta.c @@ -598,7 +598,7 @@ str8_lit_comp("goto_name"), str8_lit_comp("function_breakpoint"), }; -DF_StringBindingPair df_g_default_binding_table[99] = +DF_StringBindingPair df_g_default_binding_table[102] = { {str8_lit_comp("kill_all"), {OS_Key_F5, 0 |OS_EventFlag_Shift }}, {str8_lit_comp("step_into_inst"), {OS_Key_F11, 0 |OS_EventFlag_Alt}}, @@ -644,6 +644,9 @@ DF_StringBindingPair df_g_default_binding_table[99] = {str8_lit_comp("switch_to_partner_file"), {OS_Key_O, 0 |OS_EventFlag_Alt}}, {str8_lit_comp("load_user"), {OS_Key_O, 0 |OS_EventFlag_Ctrl |OS_EventFlag_Shift |OS_EventFlag_Alt}}, {str8_lit_comp("load_profile"), {OS_Key_O, 0 |OS_EventFlag_Ctrl |OS_EventFlag_Alt}}, +{str8_lit_comp("edit"), {OS_Key_F2, 0 }}, +{str8_lit_comp("accept"), {OS_Key_Return, 0 }}, +{str8_lit_comp("cancel"), {OS_Key_Esc, 0 }}, {str8_lit_comp("move_left"), {OS_Key_Left, 0 }}, {str8_lit_comp("move_right"), {OS_Key_Right, 0 }}, {str8_lit_comp("move_up"), {OS_Key_Up, 0 }}, diff --git a/src/df/gfx/generated/df_gfx.meta.h b/src/df/gfx/generated/df_gfx.meta.h index adb55bec..118e62c1 100644 --- a/src/df/gfx/generated/df_gfx.meta.h +++ b/src/df/gfx/generated/df_gfx.meta.h @@ -290,7 +290,7 @@ extern Vec4F32* df_g_theme_preset_colors_table[9]; extern DF_CmdParamSlot df_g_cmd_param_slot_2_view_spec_src_map[7]; extern String8 df_g_cmd_param_slot_2_view_spec_dst_map[7]; extern String8 df_g_cmd_param_slot_2_view_spec_cmd_map[7]; -extern DF_StringBindingPair df_g_default_binding_table[99]; +extern DF_StringBindingPair df_g_default_binding_table[102]; extern String8 df_g_binding_version_remap_old_name_table[3]; extern String8 df_g_binding_version_remap_new_name_table[3]; extern DF_ViewSpecInfo df_g_gfx_view_kind_spec_info_table[31]; diff --git a/src/raddbg/raddbg.c b/src/raddbg/raddbg.c index e68ef468..c0af86cc 100644 --- a/src/raddbg/raddbg.c +++ b/src/raddbg/raddbg.c @@ -131,6 +131,7 @@ update_and_render(OS_Handle repaint_window_handle, void *user_data) event->key != OS_Key_Delete && event->key != OS_Key_LeftMouseButton && event->key != OS_Key_RightMouseButton && + event->key != OS_Key_MiddleMouseButton && event->key != OS_Key_Ctrl && event->key != OS_Key_Alt && event->key != OS_Key_Shift) diff --git a/src/ui/ui_core.c b/src/ui/ui_core.c index 905591ec..cd68bcae 100644 --- a/src/ui/ui_core.c +++ b/src/ui/ui_core.c @@ -582,6 +582,23 @@ ui_text(U32 character) return result; } +internal B32 +ui_slot_press(UI_EventActionSlot slot) +{ + UI_EventList *list = ui_events(); + B32 result = 0; + for(UI_EventNode *n = list->first; n != 0; n = n->next) + { + if(n->v.kind == UI_EventKind_Press && n->v.slot == slot) + { + result = 1; + ui_eat_event(list, n); + break; + } + } + return result; +} + //- rjf: drag data internal Vec2F32 @@ -926,7 +943,7 @@ ui_begin_build(OS_Handle window, UI_EventList *events, UI_IconInfo *icon_info, F //- rjf: some child has the active focus -> accept escape keys to pop from the active key stack if(!ui_key_match(ui_key_zero(), nav_root->default_nav_focus_active_key)) { - for(;ui_key_press(0, OS_Key_Esc);) + for(;ui_slot_press(UI_EventActionSlot_Cancel);) { UI_Box *prev_focus_root = nav_root; for(UI_Box *focus_root = ui_box_from_key(nav_root->default_nav_focus_active_key); @@ -1074,7 +1091,7 @@ ui_end_build(void) ProfBeginFunction(); //- rjf: escape -> close context menu - if(ui_state->ctx_menu_open != 0 && ui_key_press(0, OS_Key_Esc)) + if(ui_state->ctx_menu_open != 0 && ui_slot_press(UI_EventActionSlot_Cancel)) { ui_ctx_menu_close(); } @@ -2561,7 +2578,7 @@ ui_signal_from_box(UI_Box *box) if(box->flags & UI_BoxFlag_KeyboardClickable && is_focus_hot && evt->kind == UI_EventKind_Press && - evt->key == OS_Key_Return) + evt->slot == UI_EventActionSlot_Accept) { sig.f |= UI_SignalFlag_KeyboardPressed; taken = 1; diff --git a/src/ui/ui_core.h b/src/ui/ui_core.h index 3553eaa4..390315c0 100644 --- a/src/ui/ui_core.h +++ b/src/ui/ui_core.h @@ -59,6 +59,8 @@ UI_FocusKind; //////////////////////////////// //~ rjf: Events +// TODO(rjf): clean all this up + typedef enum UI_EventKind { UI_EventKind_Null, @@ -74,6 +76,16 @@ typedef enum UI_EventKind } UI_EventKind; +typedef enum UI_EventActionSlot +{ + UI_EventActionSlot_Null, + UI_EventActionSlot_Accept, + UI_EventActionSlot_Cancel, + UI_EventActionSlot_Edit, + UI_EventActionSlot_COUNT +} +UI_EventActionSlot; + typedef U32 UI_EventFlags; enum { @@ -103,6 +115,7 @@ typedef struct UI_Event UI_Event; struct UI_Event { UI_EventKind kind; + UI_EventActionSlot slot; UI_EventFlags flags; UI_EventDeltaUnit delta_unit; OS_Key key; @@ -641,6 +654,7 @@ internal F32 ui_dt(void); internal B32 ui_key_press(OS_EventFlags mods, OS_Key key); internal B32 ui_key_release(OS_EventFlags mods, OS_Key key); internal B32 ui_text(U32 character); +internal B32 ui_slot_press(UI_EventActionSlot slot); //- rjf: drag data internal Vec2F32 ui_drag_start_mouse(void); From 6e039430a5cf5d6a60beef08ed885d4783e81c52 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Wed, 15 May 2024 11:22:05 -0700 Subject: [PATCH 26/30] mouse controls for new watch window editing mechanism --- src/df/gfx/df_views.c | 364 +++++++++--------------------------------- src/df/gfx/df_views.h | 3 + 2 files changed, 78 insertions(+), 289 deletions(-) diff --git a/src/df/gfx/df_views.c b/src/df/gfx/df_views.c index abf2dd66..ba2b20c4 100644 --- a/src/df/gfx/df_views.c +++ b/src/df/gfx/df_views.c @@ -474,6 +474,14 @@ df_expand_key_from_eval_root(DF_EvalRoot *root) //- rjf: watch view points <-> table coordinates +internal B32 +df_watch_view_point_match(DF_WatchViewPoint a, DF_WatchViewPoint b) +{ + return (a.column_kind == b.column_kind && + df_expand_key_match(a.parent_key, b.parent_key) && + df_expand_key_match(a.key, b.key)); +} + internal DF_WatchViewPoint df_watch_view_point_from_tbl(DF_EvalVizBlockList *blocks, Vec2S64 tbl) { @@ -522,9 +530,7 @@ df_watch_view_text_edit_state_from_pt(DF_WatchViewState *wv, DF_WatchViewPoint p U64 slot_idx = hash%wv->text_edit_state_slots_count; for(DF_WatchViewTextEditState *s = wv->text_edit_state_slots[slot_idx]; s != 0; s = s->pt_hash_next) { - if(pt.column_kind == s->pt.column_kind && - df_expand_key_match(pt.parent_key, s->pt.parent_key) && - df_expand_key_match(pt.key, s->pt.key)) + if(df_watch_view_point_match(pt, s->pt)) { result = s; break; @@ -993,6 +999,8 @@ df_watch_view_build(DF_Window *ws, DF_Panel *panel, DF_View *view, DF_WatchViewS ewv->text_editing = 0; } } + ewv->next_cursor = ewv->cursor; + ewv->next_mark = ewv->mark; } ////////////////////////// @@ -1005,16 +1013,32 @@ df_watch_view_build(DF_Window *ws, DF_Panel *panel, DF_View *view, DF_WatchViewS Max(cursor_tbl.x, mark_tbl.x), Max(cursor_tbl.y, mark_tbl.y)); } + ////////////////////////////// + //- rjf: apply cursor/mark rugpull change + // + B32 cursor_rugpull = 0; + if(!df_watch_view_point_match(ewv->cursor, ewv->next_cursor)) + { + cursor_rugpull = 1; + ewv->cursor = ewv->next_cursor; + ewv->mark = ewv->next_mark; + } + ////////////////////////// //- rjf: grab next event, if any - otherwise exit the loop, as we now have // the most up-to-date state // - if(event_n == 0 || !ui_is_focus_active()) + if(!cursor_rugpull && (event_n == 0 || !ui_is_focus_active())) { break; } - next = event_n->next; - UI_Event *evt = &event_n->v; + UI_Event dummy_evt = {0}; + UI_Event *evt = &dummy_evt; + if(event_n != 0) + { + evt = &event_n->v; + next = event_n->next; + } B32 taken = 0; ////////////////////////// @@ -1023,8 +1047,9 @@ df_watch_view_build(DF_Window *ws, DF_Panel *panel, DF_View *view, DF_WatchViewS if(!ewv->text_editing && (evt->kind == UI_EventKind_Text || evt->flags & UI_EventFlag_Paste || - (evt->kind == UI_EventKind_Press && (evt->slot == UI_EventActionSlot_Accept || evt->slot == UI_EventActionSlot_Edit))) && - selection_tbl.min.x == selection_tbl.max.x) + (evt->kind == UI_EventKind_Press && evt->slot == UI_EventActionSlot_Edit)) && + selection_tbl.min.x == selection_tbl.max.x && + (selection_tbl.min.x != 0 || modifiable)) { Vec2S64 selection_dim = dim_2s64(selection_tbl); ewv->text_editing = 1; @@ -1058,13 +1083,34 @@ df_watch_view_build(DF_Window *ws, DF_Panel *panel, DF_View *view, DF_WatchViewS } } + ////////////////////////// + //- rjf: [table] do cell-granularity expansions + // + if(!ewv->text_editing && evt->slot == UI_EventActionSlot_Accept && selection_tbl.min.x <= 0) + { + taken = 1; + DF_EvalVizWindowedRowList rows = df_eval_viz_windowed_row_list_from_viz_block_list(scratch.arena, scope, &ctrl_ctx, &parse_ctx, ¯o_map, eval_view, default_radix, code_font, ui_top_font_size(), + r1s64(ui_scroll_list_row_from_item(&row_blocks, selection_tbl.min.y-1), + ui_scroll_list_row_from_item(&row_blocks, selection_tbl.max.y-1)+1), &blocks); + DF_EvalVizRow *row = rows.first; + for(S64 y = selection_tbl.min.y; y <= selection_tbl.max.y && row != 0; y += 1, row = row->next) + { + if(row->flags & DF_EvalVizRowFlag_CanExpand) + { + B32 is_expanded = df_expand_key_is_set(&eval_view->expand_tree_table, row->key); + df_expand_set_expansion(eval_view->arena, &eval_view->expand_tree_table, row->parent_key, row->key, !is_expanded); + } + } + } + ////////////////////////// //- rjf: [text] apply textual edits // if(ewv->text_editing) { B32 editing_complete = ((evt->kind == UI_EventKind_Press && (evt->slot == UI_EventActionSlot_Cancel || evt->slot == UI_EventActionSlot_Accept)) || - (evt->kind == UI_EventKind_Navigate && evt->delta_2s32.y != 0)); + (evt->kind == UI_EventKind_Navigate && evt->delta_2s32.y != 0) || + cursor_rugpull); if(editing_complete || ((evt->kind == UI_EventKind_Edit || evt->kind == UI_EventKind_Navigate || @@ -1134,6 +1180,8 @@ df_watch_view_build(DF_Window *ws, DF_Panel *panel, DF_View *view, DF_WatchViewS { root = df_eval_root_alloc(view, ewv); df_eval_root_equip_string(root, new_string); + DF_ExpandKey key = df_expand_key_from_eval_root(root); + df_eval_view_set_key_rule(eval_view, key, str8_zero()); state_dirty = 1; } }break; @@ -1208,26 +1256,6 @@ df_watch_view_build(DF_Window *ws, DF_Panel *panel, DF_View *view, DF_WatchViewS os_set_clipboard_text(string); } - ////////////////////////// - //- rjf: [table] do cell-granularity expansions - // - if(!ewv->text_editing && evt->slot == UI_EventActionSlot_Accept && selection_tbl.min.x <= 0) - { - taken = 1; - DF_EvalVizWindowedRowList rows = df_eval_viz_windowed_row_list_from_viz_block_list(scratch.arena, scope, &ctrl_ctx, &parse_ctx, ¯o_map, eval_view, default_radix, code_font, ui_top_font_size(), - r1s64(ui_scroll_list_row_from_item(&row_blocks, selection_tbl.min.y-1), - ui_scroll_list_row_from_item(&row_blocks, selection_tbl.max.y-1)+1), &blocks); - DF_EvalVizRow *row = rows.first; - for(S64 y = selection_tbl.min.y; y <= selection_tbl.max.y && row != 0; y += 1, row = row->next) - { - if(row->flags & DF_EvalVizRowFlag_CanExpand) - { - B32 is_expanded = df_expand_key_is_set(&eval_view->expand_tree_table, row->key); - df_expand_set_expansion(eval_view->arena, &eval_view->expand_tree_table, row->parent_key, row->key, !is_expanded); - } - } - } - ////////////////////////// //- rjf: [table] do cell-granularity deletions // @@ -1259,7 +1287,7 @@ df_watch_view_build(DF_Window *ws, DF_Panel *panel, DF_View *view, DF_WatchViewS } DF_WatchViewPoint new_cursor_pt = {DF_WatchViewColumnKind_Expr, new_cursor_parent_key, new_cursor_key}; df_eval_root_release(ewv, root); - ewv->cursor = ewv->mark = new_cursor_pt; + ewv->cursor = ewv->mark = ewv->next_cursor = ewv->next_mark = new_cursor_pt; } } @@ -1392,7 +1420,7 @@ df_watch_view_build(DF_Window *ws, DF_Panel *panel, DF_View *view, DF_WatchViewS ////////////////////////// //- rjf: consume event, if taken // - if(taken) + if(taken && evt != &dummy_evt) { ui_eat_event(events, event_n); } @@ -1421,7 +1449,6 @@ df_watch_view_build(DF_Window *ws, DF_Panel *panel, DF_View *view, DF_WatchViewS &ewv->view_rule_column_pct, }; B32 pressed = 0; - Vec2S64 next_cursor_tbl = cursor_tbl; Rng1S64 visible_row_rng = {0}; UI_ScrollListParams scroll_list_params = {0}; { @@ -1457,8 +1484,6 @@ df_watch_view_build(DF_Window *ws, DF_Panel *panel, DF_View *view, DF_WatchViewS UI_Focus(UI_FocusKind_Null) UI_TableF(ArrayCount(col_pcts), col_pcts, "table_header") { - next_cursor_tbl = cursor_tbl; - //- rjf: build table header if(visible_row_rng.min == 0) UI_TableVector UI_TextColor(df_rgba_from_theme_color(DF_ThemeColor_WeakText)) { @@ -1549,6 +1574,8 @@ df_watch_view_build(DF_Window *ws, DF_Panel *panel, DF_View *view, DF_WatchViewS //- rjf: build canvas row if(row->flags & DF_EvalVizRowFlag_Canvas) UI_FocusHot(row_selected ? UI_FocusKind_On : UI_FocusKind_Off) ProfScope("canvas row") { + DF_WatchViewPoint pt = {DF_WatchViewColumnKind_Expr, row->parent_key, row->key}; + //- rjf: build ui_set_next_flags(disabled_flags); ui_set_next_pref_width(ui_pct(1, 0)); @@ -1577,13 +1604,12 @@ df_watch_view_build(DF_Window *ws, DF_Panel *panel, DF_View *view, DF_WatchViewS //- rjf: press -> focus if(ui_pressed(sig)) { - // TODO(rjf): edit_commit = edit_commit || (!row_selected && ewv->text_editing); - next_cursor_tbl = v2s64(DF_WatchViewColumnKind_Expr, (semantic_idx+1)); + ewv->next_cursor = ewv->next_mark = pt; pressed = 1; } - //- rjf: double clicked or keyboard clicked -> open dedicated tab - if(ui_double_clicked(sig) || sig.f & UI_SignalFlag_KeyboardPressed) + //- rjf: double clicked -> open dedicated tab + if(ui_double_clicked(sig)) { DF_CfgNode *cfg = df_cfg_tree_copy(scratch.arena, row->expand_ui_rule_node); DF_CfgNode *cfg_root = push_array(scratch.arena, DF_CfgNode, 1); @@ -1659,18 +1685,6 @@ df_watch_view_build(DF_Window *ws, DF_Panel *panel, DF_View *view, DF_WatchViewS B32 cell_selected = (row_selected && selection_tbl.min.x <= pt.column_kind && pt.column_kind <= selection_tbl.max.x); B32 can_edit_expr = !(row->depth > 0 || modifiable == 0); - // rjf: begin editing -#if 0 - if(cell_selected && (edit_begin || (edit_begin_or_expand && !(row->flags & DF_EvalVizRowFlag_CanExpand))) && can_edit_expr) - { - ewv->text_editing = 1; - ewv->input_size = Min(sizeof(ewv->input_buffer), row->display_expr.size); - MemoryCopy(ewv->input_buffer, row->display_expr.str, ewv->input_size); - ewv->input_cursor = txt_pt(1, 1+ewv->input_size); - ewv->input_mark = txt_pt(1, 1); - } -#endif - // rjf: build UI_Signal sig = {0}; B32 next_expanded = row_expanded; @@ -1712,7 +1726,6 @@ df_watch_view_build(DF_Window *ws, DF_Panel *panel, DF_View *view, DF_WatchViewS row->display_expr, "###row_%I64x", row_hash); } - // TODO(rjf): edit_commit = edit_commit || ui_committed(sig); if(is_inherited && ui_hovering(sig)) UI_Tooltip { String8List inheritance_chain_type_names = {0}; @@ -1790,48 +1803,22 @@ df_watch_view_build(DF_Window *ws, DF_Panel *panel, DF_View *view, DF_WatchViewS DF_AutoCompListerParams params = {DF_AutoCompListerFlag_Locals}; df_set_autocomp_lister_query(ws, sig.box->key, ctrl_ctx, ¶ms, input, edit_state->cursor.column-1); } - -#if 0 // TODO(rjf): - if(expr_editing_active && !edit_end && txt_pt_match(ewv->input_cursor, ewv->input_mark)) - { - String8 input = str8(ewv->input_buffer, ewv->input_size); - DF_AutoCompListerParams params = {DF_AutoCompListerFlag_Locals}; - df_set_autocomp_lister_query(ws, sig.box->key, ctrl_ctx, ¶ms, input, ewv->input_cursor.column-1); - } -#endif } // rjf: press -> commit if editing & select -#if 0 // TODO(rjf): if(ui_pressed(sig)) { - edit_commit = edit_commit || (!cell_selected && ewv->text_editing); - next_cursor_tbl = v2s64(DF_WatchViewColumnKind_Expr, (semantic_idx+1)); + ewv->next_cursor = ewv->next_mark = pt; pressed = 1; } -#endif - - // rjf: keyboard-click & expandable -> expand -#if 0// TODO(rjf): - if(cell_selected && edit_begin_or_expand && row->flags & DF_EvalVizRowFlag_CanExpand) - { - next_expanded ^= 1; - } -#endif // rjf: double-click -> start editing - // TODO(rjf): -#if 0 - if(ui_double_clicked(sig) && !ewv->text_editing && can_edit_expr) + if(ui_double_clicked(sig) && can_edit_expr) { ui_kill_action(); - ewv->text_editing = 1; - ewv->input_size = Min(sizeof(ewv->input_buffer), row->display_expr.size); - MemoryCopy(ewv->input_buffer, row->display_expr.str, ewv->input_size); - ewv->input_cursor = txt_pt(1, 1+ewv->input_size); - ewv->input_mark = txt_pt(1, 1); + DF_CmdParams p = df_cmd_params_from_view(ws, panel, view); + df_push_cmd__root(&p, df_cmd_spec_from_core_cmd_kind(DF_CoreCmdKind_Edit)); } -#endif // rjf: commit expansion state if(next_expanded != row_expanded) @@ -1851,18 +1838,6 @@ df_watch_view_build(DF_Window *ws, DF_Panel *panel, DF_View *view, DF_WatchViewS B32 value_is_complex = (!value_is_error && !value_is_hook && !(row->flags & DF_EvalVizRowFlag_CanEditValue)); B32 value_is_simple = (!value_is_error && !value_is_hook && (row->flags & DF_EvalVizRowFlag_CanEditValue)); - // rjf: begin editing -#if 0 // TODO(rjf): - if(cell_selected && (edit_begin || edit_begin_or_expand) && value_is_simple) - { - ewv->text_editing = 1; - ewv->input_size = Min(sizeof(ewv->input_buffer), row->edit_value.size); - MemoryCopy(ewv->input_buffer, row->edit_value.str, ewv->input_size); - ewv->input_cursor = txt_pt(1, 1+ewv->input_size); - ewv->input_mark = txt_pt(1, 1); - } -#endif - // rjf: build UI_Signal sig = {0}; if(row_is_bad) @@ -1913,7 +1888,6 @@ df_watch_view_build(DF_Window *ws, DF_Panel *panel, DF_View *view, DF_WatchViewS if(value_is_simple) { sig = df_line_editf(DF_LineEditFlag_CodeContents|DF_LineEditFlag_NoBackground, 0, 0, &edit_state->cursor, &edit_state->mark, edit_state->input_buffer, sizeof(edit_state->input_buffer), &edit_state->input_size, 0, row->display_value, "%S###val_%I64x", row->display_value, row_hash); - // TODO(rjf): edit_commit = (edit_commit || ui_committed(sig)); } } @@ -1926,23 +1900,17 @@ df_watch_view_build(DF_Window *ws, DF_Panel *panel, DF_View *view, DF_WatchViewS // rjf: press -> focus & commit if editing & not selected if(ui_pressed(sig)) { + ewv->next_cursor = ewv->next_mark = pt; pressed = 1; - // TODO(rjf): edit_commit = edit_commit || (ewv->text_editing && !cell_selected); - next_cursor_tbl = v2s64(DF_WatchViewColumnKind_Value, (semantic_idx+1)); } // rjf: double-click -> start editing -#if 0 if(ui_double_clicked(sig) && value_is_simple) { ui_kill_action(); - ewv->text_editing = 1; - ewv->input_size = Min(sizeof(ewv->input_buffer), row->edit_value.size); - MemoryCopy(ewv->input_buffer, row->edit_value.str, ewv->input_size); - ewv->input_cursor = txt_pt(1, 1+ewv->input_size); - ewv->input_mark = txt_pt(1, 1); + DF_CmdParams p = df_cmd_params_from_view(ws, panel, view); + df_push_cmd__root(&p, df_cmd_spec_from_core_cmd_kind(DF_CoreCmdKind_Edit)); } -#endif } //- rjf: type @@ -1966,9 +1934,8 @@ df_watch_view_build(DF_Window *ws, DF_Panel *panel, DF_View *view, DF_WatchViewS UI_Signal sig = ui_signal_from_box(box); if(ui_pressed(sig)) { + ewv->next_cursor = ewv->next_mark = pt; pressed = 1; - // TODO(rjf): edit_commit = edit_commit || (ewv->text_editing && !cell_selected); - next_cursor_tbl = v2s64(DF_WatchViewColumnKind_Type, (semantic_idx+1)); } } } @@ -1981,18 +1948,6 @@ df_watch_view_build(DF_Window *ws, DF_Panel *panel, DF_View *view, DF_WatchViewS B32 cell_selected = (row_selected && selection_tbl.min.x <= pt.column_kind && pt.column_kind <= selection_tbl.max.x); String8 view_rule = df_eval_view_rule_from_key(eval_view, row->key); - // rjf: begin editing -#if 0 // TODO(rjf): - if(cell_selected && (edit_begin || edit_begin_or_expand)) - { - ewv->text_editing = 1; - ewv->input_size = Min(sizeof(ewv->input_buffer), view_rule.size); - MemoryCopy(ewv->input_buffer, view_rule.str, ewv->input_size); - ewv->input_cursor = txt_pt(1, 1+ewv->input_size); - ewv->input_mark = txt_pt(1, 1); - } -#endif - // rjf: build UI_Signal sig = {0}; B32 rule_editing_active = 0; @@ -2002,15 +1957,13 @@ df_watch_view_build(DF_Window *ws, DF_Panel *panel, DF_View *view, DF_WatchViewS { rule_editing_active = ui_is_focus_active(); sig = df_line_editf(DF_LineEditFlag_CodeContents|DF_LineEditFlag_NoBackground, 0, 0, &edit_state->cursor, &edit_state->mark, edit_state->input_buffer, sizeof(edit_state->input_buffer), &edit_state->input_size, 0, view_rule, "###view_rule_%I64x", row_hash); - // TODO(rjf): edit_commit = edit_commit || ui_committed(sig); } // rjf: press -> commit if not selected, select this cell if(ui_pressed(sig)) { + ewv->next_cursor = ewv->next_mark = pt; pressed = 1; - // TODO(rjf): edit_commit = edit_commit || (ewv->text_editing && !cell_selected); - next_cursor_tbl = v2s64(DF_WatchViewColumnKind_ViewRule, (semantic_idx+1)); } // rjf: autocomplete lister @@ -2028,33 +1981,12 @@ df_watch_view_build(DF_Window *ws, DF_Panel *panel, DF_View *view, DF_WatchViewS } // rjf: double-click -> begin editing - // TODO(rjf): -#if 0 if(ui_double_clicked(sig) && !ewv->text_editing) { ui_kill_action(); - ewv->text_editing = 1; - ewv->input_size = Min(sizeof(ewv->input_buffer), view_rule.size); - MemoryCopy(ewv->input_buffer, view_rule.str, ewv->input_size); - ewv->input_cursor = txt_pt(1, 1+ewv->input_size); - ewv->input_mark = txt_pt(1, 1); + DF_CmdParams p = df_cmd_params_from_view(ws, panel, view); + df_push_cmd__root(&p, df_cmd_spec_from_core_cmd_kind(DF_CoreCmdKind_Edit)); } -#endif - - // rjf: autocomplete lister - // TODO(rjf): -#if 0 - if(rule_editing_active && !edit_end && txt_pt_match(ewv->input_cursor, ewv->input_mark)) - { - String8 input = str8(ewv->input_buffer, ewv->input_size); - DF_AutoCompListerParams params = df_view_rule_autocomp_lister_params_from_input_cursor(scratch.arena, input, ewv->input_cursor.column-1); - if(params.flags == 0) - { - params.flags = DF_AutoCompListerFlag_ViewRules; - } - df_set_autocomp_lister_query(ws, sig.box->key, ctrl_ctx, ¶ms, input, ewv->input_cursor.column-1); - } -#endif } } } @@ -2071,152 +2003,6 @@ df_watch_view_build(DF_Window *ws, DF_Panel *panel, DF_View *view, DF_WatchViewS df_push_cmd__root(&p, df_cmd_spec_from_core_cmd_kind(DF_CoreCmdKind_FocusPanel)); } - ////////////////////////////// - //- rjf: commit edits - // -#if 0 - { - DF_WatchViewColumnKind commit_column = (DF_WatchViewColumnKind)cursor_tbl.x; - if(!MemoryMatchStruct(&cursor_tbl, &next_cursor_tbl)) - { - mark_tbl = next_cursor_tbl; - } - cursor_tbl = next_cursor_tbl; - if(commit_row != 0 && edit_commit) - { - ewv->text_editing = 0; - String8 commit_string = str8(ewv->input_buffer, ewv->input_size); - switch(commit_column) - { - default:break; - - //- rjf: expression commits - case DF_WatchViewColumnKind_Expr: if(modifiable) - { - if(commit_string.size == 0) - { - DF_EvalRoot *root = df_eval_root_from_expand_key(ewv, eval_view, commit_row->key); - if(root != 0) - { - df_eval_root_release(ewv, root); - } - } - else - { - DF_EvalRoot *root = df_eval_root_from_expand_key(ewv, eval_view, commit_row->key); - if(!root && df_expand_key_match(commit_row->key, empty_row_key)) - { - root = df_eval_root_alloc(view, ewv); - DF_ExpandKey parent_key = df_parent_expand_key_from_eval_root(root); - DF_ExpandKey key = df_expand_key_from_eval_root(root); - df_expand_set_expansion(eval_view->arena, &eval_view->expand_tree_table, parent_key, key, 0); - df_eval_view_set_key_rule(eval_view, key, str8_lit("")); - } - if(root != 0) - { - df_eval_root_equip_string(root, commit_string); - } - } - }break; - - //- rjf: value commits - case DF_WatchViewColumnKind_Value: - { - Temp scratch = scratch_begin(0, 0); - DF_Eval write_eval = df_eval_from_string(scratch.arena, scope, &ctrl_ctx, &parse_ctx, ¯o_map, commit_string); - B32 success = df_commit_eval_value(parse_ctx.type_graph, parse_ctx.rdi, &ctrl_ctx, commit_row->eval, write_eval); - if(success == 0) - { - DF_CmdParams params = df_cmd_params_from_view(ws, panel, view); - params.string = str8_lit("Could not commit value successfully."); - df_cmd_params_mark_slot(¶ms, DF_CmdParamSlot_String); - df_push_cmd__root(¶ms, df_cmd_spec_from_core_cmd_kind(DF_CoreCmdKind_Error)); - } - scratch_end(scratch); - }break; - - //- rjf: type commits - case DF_WatchViewColumnKind_Type: - { - }break; - - //- rjf: view rule commits - case DF_WatchViewColumnKind_ViewRule: - { - df_eval_view_set_key_rule(eval_view, commit_row->key, commit_string); - }break; - } - if(edit_submit && commit_string.size != 0) - { - cursor_tbl.y += 1; - } - } - } - - ////////////////////////////// - //- rjf: end edits - // - if(edit_end) - { - ewv->text_editing = 0; - } - - ////////////////////////////// - //- rjf: commits occurred -> re-compute blocks to adjust to new state - // - if(edit_commit) - { - blocks = df_eval_viz_block_list_from_watch_view_state(scratch.arena, scope, &ctrl_ctx, &parse_ctx, ¯o_map, view, ewv); - if(modifiable) - { - DF_EvalVizBlock *b = df_eval_viz_block_begin(scratch.arena, DF_EvalVizBlockKind_Null, empty_row_parent_key, empty_row_key, 0); - b->visual_idx_range = b->semantic_idx_range = r1u64(0, 1); - df_eval_viz_block_end(&blocks, b); - } - } - - ////////////////////////////// - //- rjf: convert new table coordinates back to selection state - // - struct - { - DF_WatchViewPoint *pt_state; - Vec2S64 pt_tbl; - } - points[] = - { - {&ewv->cursor, cursor_tbl}, - {&ewv->mark, mark_tbl}, - }; - for(U64 point_idx = 0; point_idx < ArrayCount(points); point_idx += 1) - { - DF_ExpandKey last_key = points[point_idx].pt_state->key; - DF_ExpandKey last_parent_key = points[point_idx].pt_state->parent_key; - points[point_idx].pt_state->column_kind= (DF_WatchViewColumnKind)points[point_idx].pt_tbl.x; - points[point_idx].pt_state->key = df_key_from_viz_block_list_row_num(&blocks, points[point_idx].pt_tbl.y); - points[point_idx].pt_state->parent_key = df_parent_key_from_viz_block_list_row_num(&blocks, points[point_idx].pt_tbl.y); - if(df_expand_key_match(df_expand_key_zero(), points[point_idx].pt_state->key)) - { - points[point_idx].pt_state->key = last_parent_key; - DF_ExpandNode *node = df_expand_node_from_key(&eval_view->expand_tree_table, last_parent_key); - for(DF_ExpandNode *n = node; n != 0; n = n->parent) - { - points[point_idx].pt_state->key = n->key; - if(n->expanded == 0) - { - break; - } - } - } - if(point_idx == 0 && - (!df_expand_key_match(ewv->cursor.key, last_key) || - !df_expand_key_match(ewv->cursor.parent_key, last_parent_key))) - { - ewv->text_editing = 0; - } - } -#endif - scratch_end(scratch); dbgi_scope_close(scope); ProfEnd(); diff --git a/src/df/gfx/df_views.h b/src/df/gfx/df_views.h index e10ebf1e..7f450c41 100644 --- a/src/df/gfx/df_views.h +++ b/src/df/gfx/df_views.h @@ -336,6 +336,8 @@ struct DF_WatchViewState // rjf; table cursor state DF_WatchViewPoint cursor; DF_WatchViewPoint mark; + DF_WatchViewPoint next_cursor; + DF_WatchViewPoint next_mark; // rjf: text input state Arena *text_edit_arena; @@ -483,6 +485,7 @@ internal DF_ExpandKey df_parent_expand_key_from_eval_root(DF_EvalRoot *root); internal DF_ExpandKey df_expand_key_from_eval_root(DF_EvalRoot *root); //- rjf: watch view points <-> table coordinates +internal B32 df_watch_view_point_match(DF_WatchViewPoint a, DF_WatchViewPoint b); internal DF_WatchViewPoint df_watch_view_point_from_tbl(DF_EvalVizBlockList *blocks, Vec2S64 tbl); internal Vec2S64 df_tbl_from_watch_view_point(DF_EvalVizBlockList *blocks, DF_WatchViewPoint pt); From 56afe8ca603680eb22b4ca81ebb80b9f629879f5 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Wed, 15 May 2024 11:57:46 -0700 Subject: [PATCH 27/30] watch window reordering --- src/df/core/df_core.mdesk | 2 ++ src/df/core/generated/df_core.meta.c | 4 ++- src/df/core/generated/df_core.meta.h | 2 ++ src/df/gfx/df_gfx.c | 18 ++++++++++++ src/df/gfx/df_gfx.mdesk | 2 ++ src/df/gfx/df_views.c | 42 ++++++++++++++++++++++++++-- src/df/gfx/generated/df_gfx.meta.c | 4 ++- src/df/gfx/generated/df_gfx.meta.h | 2 +- src/raddbg/raddbg.h | 4 +-- src/ui/ui_core.h | 1 + 10 files changed, 74 insertions(+), 7 deletions(-) diff --git a/src/df/core/df_core.mdesk b/src/df/core/df_core.mdesk index 355a3a15..cf37ac1e 100644 --- a/src/df/core/df_core.mdesk +++ b/src/df/core/df_core.mdesk @@ -281,6 +281,8 @@ DF_CoreCmdTable:// | | | {MoveDownPageSelect 0 Null Nil 0 0 0 0 0 0 Null "move_down_page_select" "Move Down Page Select" "Moves the cursor or selection down one page, while selecting." "" } {MoveUpWholeSelect 0 Null Nil 0 0 0 0 0 0 Null "move_up_whole_select" "Move Up Whole Select" "Moves the cursor or selection to the beginning of the relevant content, while selecting." "" } {MoveDownWholeSelect 0 Null Nil 0 0 0 0 0 0 Null "move_down_whole_select" "Move Down Whole Select" "Moves the cursor or selection to the end of the relevant content, while selecting." "" } + {MoveUpReorder 0 Null Nil 0 0 0 0 0 0 Null "move_up_reorder" "Move Up Reorder" "Moves the cursor or selection up, while swapping the currently selected element with that upward." "" } + {MoveDownReorder 0 Null Nil 0 0 0 0 0 0 Null "move_down_reorder" "Move Down Reorder" "Moves the cursor or selection down, while swapping the currently selected element with that downward." "" } {MoveHome 0 Null Nil 0 0 0 0 0 0 Null "move_home" "Move Home" "Moves the cursor to the beginning of the line." "" } {MoveEnd 0 Null Nil 0 0 0 0 0 0 Null "move_end" "Move End" "Moves the cursor to the end of the line." "" } {MoveHomeSelect 0 Null Nil 0 0 0 0 0 0 Null "move_home_select" "Move Home Select" "Moves the cursor to the beginning of the line, while selecting." "" } diff --git a/src/df/core/generated/df_core.meta.c b/src/df/core/generated/df_core.meta.c index 9638f520..03e9c0f9 100644 --- a/src/df/core/generated/df_core.meta.c +++ b/src/df/core/generated/df_core.meta.c @@ -217,7 +217,7 @@ DF_CoreCmdKind_Null, DF_CoreCmdKind_Null, }; -DF_CmdSpecInfo df_g_core_cmd_kind_spec_info_table[218] = +DF_CmdSpecInfo df_g_core_cmd_kind_spec_info_table[220] = { { str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp(""), (DF_CmdSpecFlag_OmitFromLists*1), {DF_CmdParamSlot_Null, DF_EntityKind_Nil, (DF_CmdQueryFlag_AllowFiles*0)|(DF_CmdQueryFlag_AllowFolders*0)|(DF_CmdQueryFlag_CodeInput*0)|(DF_CmdQueryFlag_KeepOldInput*0)|(DF_CmdQueryFlag_SelectOldInput*0)|(DF_CmdQueryFlag_Required*0)}, DF_IconKind_Null}, { str8_lit_comp("exit"), str8_lit_comp("Exits the debugger."), str8_lit_comp("quit,close,abort"), str8_lit_comp("Exit"), (DF_CmdSpecFlag_OmitFromLists*0), {DF_CmdParamSlot_Null, DF_EntityKind_Nil, (DF_CmdQueryFlag_AllowFiles*0)|(DF_CmdQueryFlag_AllowFolders*0)|(DF_CmdQueryFlag_CodeInput*0)|(DF_CmdQueryFlag_KeepOldInput*0)|(DF_CmdQueryFlag_SelectOldInput*0)|(DF_CmdQueryFlag_Required*0)}, DF_IconKind_X}, @@ -344,6 +344,8 @@ DF_CmdSpecInfo df_g_core_cmd_kind_spec_info_table[218] = { str8_lit_comp("move_down_page_select"), str8_lit_comp("Moves the cursor or selection down one page, while selecting."), str8_lit_comp(""), str8_lit_comp("Move Down Page Select"), (DF_CmdSpecFlag_OmitFromLists*0), {DF_CmdParamSlot_Null, DF_EntityKind_Nil, (DF_CmdQueryFlag_AllowFiles*0)|(DF_CmdQueryFlag_AllowFolders*0)|(DF_CmdQueryFlag_CodeInput*0)|(DF_CmdQueryFlag_KeepOldInput*0)|(DF_CmdQueryFlag_SelectOldInput*0)|(DF_CmdQueryFlag_Required*0)}, DF_IconKind_Null}, { str8_lit_comp("move_up_whole_select"), str8_lit_comp("Moves the cursor or selection to the beginning of the relevant content, while selecting."), str8_lit_comp(""), str8_lit_comp("Move Up Whole Select"), (DF_CmdSpecFlag_OmitFromLists*0), {DF_CmdParamSlot_Null, DF_EntityKind_Nil, (DF_CmdQueryFlag_AllowFiles*0)|(DF_CmdQueryFlag_AllowFolders*0)|(DF_CmdQueryFlag_CodeInput*0)|(DF_CmdQueryFlag_KeepOldInput*0)|(DF_CmdQueryFlag_SelectOldInput*0)|(DF_CmdQueryFlag_Required*0)}, DF_IconKind_Null}, { str8_lit_comp("move_down_whole_select"), str8_lit_comp("Moves the cursor or selection to the end of the relevant content, while selecting."), str8_lit_comp(""), str8_lit_comp("Move Down Whole Select"), (DF_CmdSpecFlag_OmitFromLists*0), {DF_CmdParamSlot_Null, DF_EntityKind_Nil, (DF_CmdQueryFlag_AllowFiles*0)|(DF_CmdQueryFlag_AllowFolders*0)|(DF_CmdQueryFlag_CodeInput*0)|(DF_CmdQueryFlag_KeepOldInput*0)|(DF_CmdQueryFlag_SelectOldInput*0)|(DF_CmdQueryFlag_Required*0)}, DF_IconKind_Null}, +{ str8_lit_comp("move_up_reorder"), str8_lit_comp("Moves the cursor or selection up, while swapping the currently selected element with that upward."), str8_lit_comp(""), str8_lit_comp("Move Up Reorder"), (DF_CmdSpecFlag_OmitFromLists*0), {DF_CmdParamSlot_Null, DF_EntityKind_Nil, (DF_CmdQueryFlag_AllowFiles*0)|(DF_CmdQueryFlag_AllowFolders*0)|(DF_CmdQueryFlag_CodeInput*0)|(DF_CmdQueryFlag_KeepOldInput*0)|(DF_CmdQueryFlag_SelectOldInput*0)|(DF_CmdQueryFlag_Required*0)}, DF_IconKind_Null}, +{ str8_lit_comp("move_down_reorder"), str8_lit_comp("Moves the cursor or selection down, while swapping the currently selected element with that downward."), str8_lit_comp(""), str8_lit_comp("Move Down Reorder"), (DF_CmdSpecFlag_OmitFromLists*0), {DF_CmdParamSlot_Null, DF_EntityKind_Nil, (DF_CmdQueryFlag_AllowFiles*0)|(DF_CmdQueryFlag_AllowFolders*0)|(DF_CmdQueryFlag_CodeInput*0)|(DF_CmdQueryFlag_KeepOldInput*0)|(DF_CmdQueryFlag_SelectOldInput*0)|(DF_CmdQueryFlag_Required*0)}, DF_IconKind_Null}, { str8_lit_comp("move_home"), str8_lit_comp("Moves the cursor to the beginning of the line."), str8_lit_comp(""), str8_lit_comp("Move Home"), (DF_CmdSpecFlag_OmitFromLists*0), {DF_CmdParamSlot_Null, DF_EntityKind_Nil, (DF_CmdQueryFlag_AllowFiles*0)|(DF_CmdQueryFlag_AllowFolders*0)|(DF_CmdQueryFlag_CodeInput*0)|(DF_CmdQueryFlag_KeepOldInput*0)|(DF_CmdQueryFlag_SelectOldInput*0)|(DF_CmdQueryFlag_Required*0)}, DF_IconKind_Null}, { str8_lit_comp("move_end"), str8_lit_comp("Moves the cursor to the end of the line."), str8_lit_comp(""), str8_lit_comp("Move End"), (DF_CmdSpecFlag_OmitFromLists*0), {DF_CmdParamSlot_Null, DF_EntityKind_Nil, (DF_CmdQueryFlag_AllowFiles*0)|(DF_CmdQueryFlag_AllowFolders*0)|(DF_CmdQueryFlag_CodeInput*0)|(DF_CmdQueryFlag_KeepOldInput*0)|(DF_CmdQueryFlag_SelectOldInput*0)|(DF_CmdQueryFlag_Required*0)}, DF_IconKind_Null}, { str8_lit_comp("move_home_select"), str8_lit_comp("Moves the cursor to the beginning of the line, while selecting."), str8_lit_comp(""), str8_lit_comp("Move Home Select"), (DF_CmdSpecFlag_OmitFromLists*0), {DF_CmdParamSlot_Null, DF_EntityKind_Nil, (DF_CmdQueryFlag_AllowFiles*0)|(DF_CmdQueryFlag_AllowFolders*0)|(DF_CmdQueryFlag_CodeInput*0)|(DF_CmdQueryFlag_KeepOldInput*0)|(DF_CmdQueryFlag_SelectOldInput*0)|(DF_CmdQueryFlag_Required*0)}, DF_IconKind_Null}, diff --git a/src/df/core/generated/df_core.meta.h b/src/df/core/generated/df_core.meta.h index ebdb155f..9e7faeef 100644 --- a/src/df/core/generated/df_core.meta.h +++ b/src/df/core/generated/df_core.meta.h @@ -174,6 +174,8 @@ DF_CoreCmdKind_MoveUpPageSelect, DF_CoreCmdKind_MoveDownPageSelect, DF_CoreCmdKind_MoveUpWholeSelect, DF_CoreCmdKind_MoveDownWholeSelect, +DF_CoreCmdKind_MoveUpReorder, +DF_CoreCmdKind_MoveDownReorder, DF_CoreCmdKind_MoveHome, DF_CoreCmdKind_MoveEnd, DF_CoreCmdKind_MoveHomeSelect, diff --git a/src/df/gfx/df_gfx.c b/src/df/gfx/df_gfx.c index 36968c75..686c2c53 100644 --- a/src/df/gfx/df_gfx.c +++ b/src/df/gfx/df_gfx.c @@ -2348,6 +2348,24 @@ df_window_update_and_render(Arena *arena, DF_Window *ws, DF_CmdList *cmds) evt.delta_2s32 = v2s32(+0, +1); ui_event_list_push(ui_build_arena(), &events, &evt); }break; + case DF_CoreCmdKind_MoveUpReorder: + { + UI_Event evt = zero_struct; + evt.kind = UI_EventKind_Navigate; + evt.flags = UI_EventFlag_Reorder; + evt.delta_unit = UI_EventDeltaUnit_Char; + evt.delta_2s32 = v2s32(+0, -1); + ui_event_list_push(ui_build_arena(), &events, &evt); + }break; + case DF_CoreCmdKind_MoveDownReorder: + { + UI_Event evt = zero_struct; + evt.kind = UI_EventKind_Navigate; + evt.flags = UI_EventFlag_Reorder; + evt.delta_unit = UI_EventDeltaUnit_Char; + evt.delta_2s32 = v2s32(+0, +1); + ui_event_list_push(ui_build_arena(), &events, &evt); + }break; case DF_CoreCmdKind_MoveHome: { UI_Event evt = zero_struct; diff --git a/src/df/gfx/df_gfx.mdesk b/src/df/gfx/df_gfx.mdesk index 38470bad..3620c593 100644 --- a/src/df/gfx/df_gfx.mdesk +++ b/src/df/gfx/df_gfx.mdesk @@ -120,6 +120,8 @@ DF_DefaultBindingTable: { "move_down_page_select" PageDown 0 shift 0 } { "move_up_whole_select" Home ctrl shift 0 } { "move_down_whole_select" End ctrl shift 0 } + { "move_up_reorder" Up 0 0 alt } + { "move_down_reorder" Down 0 0 alt } { "move_home" Home 0 0 0 } { "move_end" End 0 0 0 } { "move_home_select" Home 0 shift 0 } diff --git a/src/df/gfx/df_views.c b/src/df/gfx/df_views.c index ba2b20c4..f35d43fc 100644 --- a/src/df/gfx/df_views.c +++ b/src/df/gfx/df_views.c @@ -1302,7 +1302,7 @@ df_watch_view_build(DF_Window *ws, DF_Panel *panel, DF_View *view, DF_WatchViewS ////////////////////////// //- rjf: [table] apply deltas to cursor & mark // - if(!ewv->text_editing && !(evt->flags & UI_EventFlag_Delete)) + if(!ewv->text_editing && !(evt->flags & UI_EventFlag_Delete) && !(evt->flags & UI_EventFlag_Reorder)) { B32 cursor_tbl_min_is_empty_selection[Axis2_COUNT] = {0, 1}; Rng2S64 cursor_tbl_range = r2s64(v2s64(0, 0), v2s64(3, blocks.total_semantic_row_count)); @@ -1417,6 +1417,44 @@ df_watch_view_build(DF_Window *ws, DF_Panel *panel, DF_View *view, DF_WatchViewS } } + ////////////////////////// + //- rjf: [table] do cell-granularity reorders + // + if(!ewv->text_editing && evt->flags & UI_EventFlag_Reorder) + { + taken = 1; + DF_ExpandKey first_root_key = df_key_from_viz_block_list_row_num(&blocks, selection_tbl.min.y); + DF_EvalRoot *first_root = df_eval_root_from_expand_key(ewv, eval_view, first_root_key); + DF_EvalRoot *last_root = first_root; + if(first_root != 0) + { + for(S64 y = selection_tbl.min.y+1; y <= selection_tbl.max.y; y += 1) + { + DF_ExpandKey key = df_key_from_viz_block_list_row_num(&blocks, y); + DF_EvalRoot *new_root = df_eval_root_from_expand_key(ewv, eval_view, key); + if(new_root != 0) + { + last_root = new_root; + } + } + } + if(evt->delta_2s32.y < 0 && first_root != 0 && first_root->prev != 0) + { + state_dirty = 1; + DF_EvalRoot *reordered = first_root->prev; + DLLRemove(ewv->first_root, ewv->last_root, reordered); + DLLInsert(ewv->first_root, ewv->last_root, last_root, reordered); + } + if(evt->delta_2s32.y > 0 && last_root != 0 && last_root->next != 0) + { + state_dirty = 1; + DF_EvalRoot *prev_child = first_root->prev; + DF_EvalRoot *reordered = last_root->next; + DLLRemove(ewv->first_root, ewv->last_root, reordered); + DLLInsert(ewv->first_root, ewv->last_root, prev_child, reordered); + } + } + ////////////////////////// //- rjf: consume event, if taken // @@ -1493,7 +1531,7 @@ df_watch_view_build(DF_Window *ws, DF_Panel *panel, DF_View *view, DF_WatchViewS UI_TableCell if(df_help_label(str8_lit("View Rule"))) UI_Tooltip { F32 max_width = ui_top_font_size()*35; - ui_label_multiline(max_width, str8_lit("View rules are used to tweak the way evaluated expressions are visualized. Multiple rules can be specified on each row. They are specified in a key:(value) form.")); + ui_label_multiline(max_width, str8_lit("View rules are used to tweak the way evaluated expressions are visualized. Multiple rules can be specified on each row. They are specified in a key:(value) form. Some examples follow:")); ui_spacer(ui_em(1.5f, 1)); UI_Font(df_font_from_slot(DF_FontSlot_Code)) UI_TextColor(df_rgba_from_theme_color(DF_ThemeColor_PlainText)) ui_labelf("array:(N)"); ui_label_multiline(max_width, str8_lit("Specifies that a pointer points to N elements, rather than only 1.")); diff --git a/src/df/gfx/generated/df_gfx.meta.c b/src/df/gfx/generated/df_gfx.meta.c index 1edde9d8..ca6f9d3d 100644 --- a/src/df/gfx/generated/df_gfx.meta.c +++ b/src/df/gfx/generated/df_gfx.meta.c @@ -598,7 +598,7 @@ str8_lit_comp("goto_name"), str8_lit_comp("function_breakpoint"), }; -DF_StringBindingPair df_g_default_binding_table[102] = +DF_StringBindingPair df_g_default_binding_table[104] = { {str8_lit_comp("kill_all"), {OS_Key_F5, 0 |OS_EventFlag_Shift }}, {str8_lit_comp("step_into_inst"), {OS_Key_F11, 0 |OS_EventFlag_Alt}}, @@ -671,6 +671,8 @@ DF_StringBindingPair df_g_default_binding_table[102] = {str8_lit_comp("move_down_page_select"), {OS_Key_PageDown, 0 |OS_EventFlag_Shift }}, {str8_lit_comp("move_up_whole_select"), {OS_Key_Home, 0 |OS_EventFlag_Ctrl |OS_EventFlag_Shift }}, {str8_lit_comp("move_down_whole_select"), {OS_Key_End, 0 |OS_EventFlag_Ctrl |OS_EventFlag_Shift }}, +{str8_lit_comp("move_up_reorder"), {OS_Key_Up, 0 |OS_EventFlag_Alt}}, +{str8_lit_comp("move_down_reorder"), {OS_Key_Down, 0 |OS_EventFlag_Alt}}, {str8_lit_comp("move_home"), {OS_Key_Home, 0 }}, {str8_lit_comp("move_end"), {OS_Key_End, 0 }}, {str8_lit_comp("move_home_select"), {OS_Key_Home, 0 |OS_EventFlag_Shift }}, diff --git a/src/df/gfx/generated/df_gfx.meta.h b/src/df/gfx/generated/df_gfx.meta.h index 118e62c1..e8921033 100644 --- a/src/df/gfx/generated/df_gfx.meta.h +++ b/src/df/gfx/generated/df_gfx.meta.h @@ -290,7 +290,7 @@ extern Vec4F32* df_g_theme_preset_colors_table[9]; extern DF_CmdParamSlot df_g_cmd_param_slot_2_view_spec_src_map[7]; extern String8 df_g_cmd_param_slot_2_view_spec_dst_map[7]; extern String8 df_g_cmd_param_slot_2_view_spec_cmd_map[7]; -extern DF_StringBindingPair df_g_default_binding_table[102]; +extern DF_StringBindingPair df_g_default_binding_table[104]; extern String8 df_g_binding_version_remap_old_name_table[3]; extern String8 df_g_binding_version_remap_new_name_table[3]; extern DF_ViewSpecInfo df_g_gfx_view_kind_spec_info_table[31]; diff --git a/src/raddbg/raddbg.h b/src/raddbg/raddbg.h index ecc89863..7d62c32d 100644 --- a/src/raddbg/raddbg.h +++ b/src/raddbg/raddbg.h @@ -10,14 +10,14 @@ // ctrl+C // [x] UI_NavActions, OS_Event -> UI_Event (single event stream) // -// [ ] better discoverability for view rules - have better help hover tooltip, +// [x] better discoverability for view rules - have better help hover tooltip, // info on arguments, and better autocomplete lister // // [x] source view -> floating margin/line-nums // [ ] theme colors -> more explicit about e.g. opaque backgrounds vs. floating // & scrollbars etc. // [ ] target/breakpoint/watch-pin reordering -// [ ] watch window reordering +// [x] watch window reordering // [x] standard way to filter // [ ] visualize remapped files (via path map) // [ ] theme lister -> fonts & font sizes diff --git a/src/ui/ui_core.h b/src/ui/ui_core.h index 390315c0..6b24be53 100644 --- a/src/ui/ui_core.h +++ b/src/ui/ui_core.h @@ -97,6 +97,7 @@ enum UI_EventFlag_PickSelectSide = (1<<5), UI_EventFlag_CapAtLine = (1<<6), UI_EventFlag_ExplicitDirectional = (1<<7), + UI_EventFlag_Reorder = (1<<8), }; typedef enum UI_EventDeltaUnit From 364a2160af8140364893ccbd67972b6bb95efafb Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Wed, 15 May 2024 13:25:20 -0700 Subject: [PATCH 28/30] correctly register jit debugger exe; collect jit_debug_info into dmn win32; notes --- src/demon/win32/demon_core_win32.c | 17 +++++++++++++++++ src/df/core/df_core.c | 6 ++++-- src/raddbg/raddbg.h | 23 +++++++++-------------- 3 files changed, 30 insertions(+), 16 deletions(-) diff --git a/src/demon/win32/demon_core_win32.c b/src/demon/win32/demon_core_win32.c index 5e765be6..da0984ae 100644 --- a/src/demon/win32/demon_core_win32.c +++ b/src/demon/win32/demon_core_win32.c @@ -1242,6 +1242,23 @@ dmn_ctrl_attach(DMN_CtrlCtx *ctx, U32 pid) { result = 1; dmn_w32_shared->new_process_pending = 1; + +#if 0 + // TODO(rjf): JIT debugging info + { + typedef struct JIT_DEBUG_INFO JIT_DEBUG_INFO; + struct JIT_DEBUG_INFO + { + DWORD dwSize; + DWORD dwProcessorArchitecture; + DWORD dwThreadID; + DWORD dwReserved0; + ULONG64 lpExceptionAddress; + ULONG64 lpExceptionRecord; + ULONG64 lpContextRecord; + }; + } +#endif } return result; } diff --git a/src/df/core/df_core.c b/src/df/core/df_core.c index 165b3fc8..26f5bbfd 100644 --- a/src/df/core/df_core.c +++ b/src/df/core/df_core.c @@ -8720,9 +8720,11 @@ df_core_begin_frame(Arena *arena, DF_CmdList *cmds, F32 dt) case DF_CoreCmdKind_RegisterAsJITDebugger: { #if OS_WINDOWS - String8 path_to_debugger_binary = os_string_from_system_path(scratch.arena, OS_SystemPath_Binary); + char filename_cstr[MAX_PATH] = {0}; + GetModuleFileName(0, filename_cstr, sizeof(filename_cstr)); + String8 debugger_binary_path = str8_cstring(filename_cstr); String8 name8 = str8_lit("Debugger"); - String8 data8 = push_str8f(scratch.arena, "%S --jit_pid:%%ld --jit_code:%%ld --jit_addr:0x%%p", path_to_debugger_binary); + String8 data8 = push_str8f(scratch.arena, "%S --jit_pid:%%ld --jit_code:%%ld --jit_addr:0x%%p", debugger_binary_path); String16 name16 = str16_from_8(scratch.arena, name8); String16 data16 = str16_from_8(scratch.arena, data8); B32 likely_not_in_admin_mode = 0; diff --git a/src/raddbg/raddbg.h b/src/raddbg/raddbg.h index 7d62c32d..69d76177 100644 --- a/src/raddbg/raddbg.h +++ b/src/raddbg/raddbg.h @@ -5,20 +5,12 @@ //~ rjf: Frontend/UI Pass Tasks // // [ ] editing multiple bindings for commands -// // [ ] n-row table selection, in watch window & other UIs, multi-selection // ctrl+C -// [x] UI_NavActions, OS_Event -> UI_Event (single event stream) // -// [x] better discoverability for view rules - have better help hover tooltip, -// info on arguments, and better autocomplete lister -// -// [x] source view -> floating margin/line-nums // [ ] theme colors -> more explicit about e.g. opaque backgrounds vs. floating // & scrollbars etc. // [ ] target/breakpoint/watch-pin reordering -// [x] watch window reordering -// [x] standard way to filter // [ ] visualize remapped files (via path map) // [ ] theme lister -> fonts & font sizes // [ ] font lister @@ -34,9 +26,6 @@ // that you use to tag them. Just some way that would make it easier to // focus on your own threads. // -// [x] autocomplete lister should respect position in edited expression, -// tabbing through should autocomplete but not exit, etc. -// // [ ] it would be nice to have "show in explorer" for right click on source // file tab (opens explorer & selects the file) // @@ -44,8 +33,6 @@ // different color? can I turn it off? And why sometimes digits in number // start with brighter color, but sometimes with darker - shouldn't it // always have the same color ordering? -// -// [ ] pipe failure-to-launch errors back to frontend //////////////////////////////// //~ rjf: Hot, High Priority Tasks (Complete Unusability, Crashes, Fire-Worthy) @@ -391,7 +378,15 @@ //////////////////////////////// //~ rjf: Recently Completed Task Log // -// +// [x] UI_NavActions, OS_Event -> UI_Event (single event stream) +// [x] better discoverability for view rules - have better help hover tooltip, +// info on arguments, and better autocomplete lister +// [x] source view -> floating margin/line-nums +// [x] watch window reordering +// [x] standard way to filter +// [x] autocomplete lister should respect position in edited expression, +// tabbing through should autocomplete but not exit, etc. +// [x] pipe failure-to-launch errors back to frontend #ifndef RADDBG_H #define RADDBG_H From 55c1674ec6131bc8620e017bd0e88f0affd55e71 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Wed, 15 May 2024 13:38:38 -0700 Subject: [PATCH 29/30] notes --- src/df/gfx/df_gfx.c | 2 +- src/raddbg/raddbg.h | 60 ++++++++++++++++++++------------------------- 2 files changed, 27 insertions(+), 35 deletions(-) diff --git a/src/df/gfx/df_gfx.c b/src/df/gfx/df_gfx.c index 686c2c53..eb993471 100644 --- a/src/df/gfx/df_gfx.c +++ b/src/df/gfx/df_gfx.c @@ -7101,7 +7101,7 @@ df_window_update_and_render(Arena *arena, DF_Window *ws, DF_CmdList *cmds) // rjf: space for next tab { - ui_spacer(ui_em(0.15f, 1.f)); + ui_spacer(ui_em(0.3f, 1.f)); } // rjf: store off drop-site diff --git a/src/raddbg/raddbg.h b/src/raddbg/raddbg.h index 69d76177..1e7a1ce1 100644 --- a/src/raddbg/raddbg.h +++ b/src/raddbg/raddbg.h @@ -66,7 +66,6 @@ // [ ] highlighted text & ctrl+f -> auto-fill search query // [ ] double-click any part of frame in callstack view -> snap to function // [ ] sort locals by appearance in source code (or maybe just debug info) -// [ ] bit more padding on the tabs // [ ] sum view rule // [ ] plot view rule // [ ] histogram view rule @@ -130,24 +129,11 @@ // have alternating bright/dim letters to show sections of a number. Is // this in the theme colors somewhere? // -// [ ] ** I couldn't figure out how to really view threads in the debugger. -// The only place I found a thread list was in "The Scheduler", but it -// only lists threads by ID, which is hard to use. I can hover over them -// to get the stack, which helps, but it would be much nicer if the top -// function was displayed in the window by default next to the thread. -// [ ] ** It would be nice if thread listings displayed the name of the -// thread, instead of just the ID. -// // [ ] ** Scrollbars are barely visible for me, for some reason. I could not // find anything in the theme that would fill them with a solid, bright // color. Instead they are just a thin outline and the same color as the // scroll bar background. // -// [ ] Dragging a window tab (like Locals or Registers or whatnot) and -// canceling with ESC should revert the window tab to where it was. -// Currently, it leaves the window tab reordered if you dragged over its -// window and shuffled its position. -// // [ ] Many of the UI elements, like the menus, would like better if they had // a little bit of margin. Having the text right next to the edges, and // with no line spacing, makes it harder to read things quickly. @@ -206,11 +192,6 @@ // be fine with them, but they would have to be much more light (like // alpha 0.1 or something) // -// [ ] It's confusing that ENTER is the way you expand and collapse things in -// the watch window, but then also how you edit them if they are not -// expandable? It seems like this should be consistent (one way to edit, -// one way to expand/collapse, that are distinct) -// // [ ] The hex format for color values in the config file was a real // mindbender. It's prefixed with "0x", so I was assuming it was either // Windows Big Endian (0xAARRGGBB) or Mac Little Endian (0xAABBGGRR). To @@ -235,16 +216,10 @@ // [ ] can it ignore stepping into _RTC_CheckStackVars generated functions? // [ ] mouse back button should make view to go back after I double clicked // on function to open it -// [ ] pressing random keyboard keys in source code advances text cursor like -// you were inputting text, very strange. // [ ] Alt+8 to switch to disassembly would be nice (regardless on which // panel was previous, don't want to use ctrl+, multiple times) // Alt+8 for disasm and Alt+6 for memory view are shortcuts I often use // in VS -// [ ] in watch window when I enter some new expression and then click mouse -// away from cell, then it should behave the same as if I pressed enter. -// Currently it does the same as if I have pressed esc and I have lost my -// expression // [ ] default font size is too small for me - not only source code, but // menus/tab/watch names (which don't resize). Maybe you could query // Windows for initial font size? @@ -320,7 +295,6 @@ // variables? // // [ ] @feature disasm view improvement features -// [ ] interleaved src/dasm view // [ ] visualize jump destinations in disasm // // [ ] @feature eval ui improvement features @@ -356,14 +330,6 @@ // [ ] fancy string runs can include "weakness" information for text truncation // ... can prioritize certain parts of strings to be truncated before // others. would be good for e.g. the middle of a path -// [ ] ui code maintenance, simplification, design, & robustness pass -// [ ] page-up & page-down correct handling in keyboard nav -// [ ] collapse context menus & command lister into same codepaths. filter by -// context. parameterize by context. -// [ ] collapse text cells & command lister & etc. into same codepath (?) -// [ ] nested context menus -// [ ] unified top-level cursor/typing/lister helper -// [ ] font selection lister // [ ] font cache eviction (both for font tags, closing fp handles, and // rasterizations) // [ ] frontend speedup opportunities @@ -387,6 +353,32 @@ // [x] autocomplete lister should respect position in edited expression, // tabbing through should autocomplete but not exit, etc. // [x] pipe failure-to-launch errors back to frontend +// [x] bit more padding on the tabs +// [x] unified top-level cursor/typing/lister helper +// [x] collapse text cells & command lister & etc. into same codepath (?) +// [x] page-up & page-down correct handling in keyboard nav +// [x] interleaved src/dasm view +// [x] in watch window when I enter some new expression and then click mouse +// away from cell, then it should behave the same as if I pressed enter. +// Currently it does the same as if I have pressed esc and I have lost my +// expression +// [x] pressing random keyboard keys in source code advances text cursor like +// you were inputting text, very strange. +// [x] It's confusing that ENTER is the way you expand and collapse things in +// the watch window, but then also how you edit them if they are not +// expandable? It seems like this should be consistent (one way to edit, +// one way to expand/collapse, that are distinct) +// [x] Dragging a window tab (like Locals or Registers or whatnot) and +// canceling with ESC should revert the window tab to where it was. +// Currently, it leaves the window tab reordered if you dragged over its +// window and shuffled its position. +// [x] ** I couldn't figure out how to really view threads in the debugger. +// The only place I found a thread list was in "The Scheduler", but it +// only lists threads by ID, which is hard to use. I can hover over them +// to get the stack, which helps, but it would be much nicer if the top +// function was displayed in the window by default next to the thread. +// [x] ** It would be nice if thread listings displayed the name of the +// thread, instead of just the ID. #ifndef RADDBG_H #define RADDBG_H From e1a5d131c8ccf6498b00607027231cdceb20ab96 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Wed, 15 May 2024 15:41:03 -0700 Subject: [PATCH 30/30] fix clang... sigh --- src/df/gfx/df_views.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/df/gfx/df_views.c b/src/df/gfx/df_views.c index f35d43fc..59fee683 100644 --- a/src/df/gfx/df_views.c +++ b/src/df/gfx/df_views.c @@ -1032,7 +1032,7 @@ df_watch_view_build(DF_Window *ws, DF_Panel *panel, DF_View *view, DF_WatchViewS { break; } - UI_Event dummy_evt = {0}; + UI_Event dummy_evt = zero_struct; UI_Event *evt = &dummy_evt; if(event_n != 0) {