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);