panel interaction testing

This commit is contained in:
jacob 2025-12-19 17:10:35 -06:00
parent 87d54b2ea6
commit 4410f63c71
5 changed files with 66 additions and 61 deletions

View File

@ -138,7 +138,7 @@ void V_EndCommandsWidget(V_CommandsWidget *widget)
Vec4 divider_color = theme.divider_color; Vec4 divider_color = theme.divider_color;
{ {
UI_Report rep = UI_ReportFromKey(titlebar_key); UI_Report rep = UI_ReportFromKey(titlebar_key);
if (rep.m1_held) if (rep.is_m1_held)
{ {
widget->pos = SubVec2(cursor_pos, rep.last_m1_offset); widget->pos = SubVec2(cursor_pos, rep.last_m1_offset);
} }
@ -583,16 +583,18 @@ void V_TickForever(WaveLaneCtx *lane)
V_CmdNode *first_cmd_node = 0; V_CmdNode *first_cmd_node = 0;
V_CmdNode *last_cmd_node = 0; V_CmdNode *last_cmd_node = 0;
if (!window_frame.has_focus) b32 has_focus = window_frame.has_focus && UI_MatchKey(ui_frame->hovered_box, UI_NilKey);
if (!has_focus)
{ {
ZeroStructs(frame->held_buttons, countof(frame->held_buttons)); ZeroStructs(frame->held_buttons, countof(frame->held_buttons));
} }
for (u64 i = 0; i < window_frame.controller_events.count; ++i) for (u64 i = 0; i < window_frame.controller_events.count; ++i)
{ {
ControllerEvent cev = window_frame.controller_events.events[i]; ControllerEvent cev = window_frame.controller_events.events[i];
b32 down = cev.kind == ControllerEventKind_ButtonDown; b32 down = cev.kind == ControllerEventKind_ButtonDown;
b32 up = cev.kind == ControllerEventKind_ButtonUp; b32 up = cev.kind == ControllerEventKind_ButtonUp;
if (down || up) if (up || (down && has_focus))
{ {
V_Hotkey hotkey = Zi; V_Hotkey hotkey = Zi;
hotkey.button = cev.button; hotkey.button = cev.button;
@ -793,10 +795,10 @@ void V_TickForever(WaveLaneCtx *lane)
{ {
{ {
V_Panel *panel = PushStruct(perm, V_Panel); V_Panel *panel = PushStruct(perm, V_Panel);
panel->key = UI_TransKey(); /* TODO: Don't use transient keys for panels */
panel->axis = Axis_X; panel->axis = Axis_X;
// panel->pref_size[Axis_X] = UI_PIX(frame->ui_dims.x, 0); // panel->pref_size[Axis_X] = UI_PIX(frame->ui_dims.x, 0);
// panel->pref_size[Axis_Y] = UI_PIX(frame->ui_dims.y, 0); // panel->pref_size[Axis_Y] = UI_PIX(frame->ui_dims.y, 0);
panel->key = UI_TransKey(); /* TODO: Don't use transient keys for panels */
panel->pref_size[Axis_X] = UI_GROW(1, 0); panel->pref_size[Axis_X] = UI_GROW(1, 0);
panel->pref_size[Axis_Y] = UI_GROW(1, 0); panel->pref_size[Axis_Y] = UI_GROW(1, 0);
panel->is_organizing_panel = 1; panel->is_organizing_panel = 1;
@ -806,8 +808,8 @@ void V_TickForever(WaveLaneCtx *lane)
{ {
V_Panel *panel = PushStruct(perm, V_Panel); V_Panel *panel = PushStruct(perm, V_Panel);
panel->parent = V.root_panel; panel->parent = V.root_panel;
panel->key = UI_TransKey(); /* TODO: Don't use transient keys */
panel->axis = !panel->parent->axis; panel->axis = !panel->parent->axis;
panel->key = UI_TransKey(); /* TODO: Don't use transient keys for panels */
panel->pref_size[Axis_X] = UI_GROW(1, 0); panel->pref_size[Axis_X] = UI_GROW(1, 0);
panel->pref_size[Axis_Y] = UI_GROW(1, 0); panel->pref_size[Axis_Y] = UI_GROW(1, 0);
DllQueuePush(panel->parent->first, panel->parent->last, panel); DllQueuePush(panel->parent->first, panel->parent->last, panel);
@ -816,6 +818,7 @@ void V_TickForever(WaveLaneCtx *lane)
{ {
V_Window *window = PushStruct(perm, V_Window); V_Window *window = PushStruct(perm, V_Window);
window->panel = panel; window->panel = panel;
window->key = UI_TransKey(); /* TODO: Don't use transient keys */
// window->is_tile_window = 1; // window->is_tile_window = 1;
DllQueuePushNP(panel->first_window, panel->last_window, window, next_in_panel, prev_in_panel); DllQueuePushNP(panel->first_window, panel->last_window, window, next_in_panel, prev_in_panel);
++panel->windows_count; ++panel->windows_count;
@ -823,6 +826,7 @@ void V_TickForever(WaveLaneCtx *lane)
{ {
V_Window *window = PushStruct(perm, V_Window); V_Window *window = PushStruct(perm, V_Window);
window->panel = panel; window->panel = panel;
window->key = UI_TransKey(); /* TODO: Don't use transient keys */
window->is_tile_window = 1; window->is_tile_window = 1;
DllQueuePushNP(panel->first_window, panel->last_window, window, next_in_panel, prev_in_panel); DllQueuePushNP(panel->first_window, panel->last_window, window, next_in_panel, prev_in_panel);
++panel->windows_count; ++panel->windows_count;
@ -833,8 +837,8 @@ void V_TickForever(WaveLaneCtx *lane)
{ {
V_Panel *panel = PushStruct(perm, V_Panel); V_Panel *panel = PushStruct(perm, V_Panel);
panel->parent = V.root_panel; panel->parent = V.root_panel;
panel->key = UI_TransKey(); /* TODO: Don't use transient keys */
panel->axis = !panel->parent->axis; panel->axis = !panel->parent->axis;
panel->key = UI_TransKey(); /* TODO: Don't use transient keys for panels */
panel->pref_size[Axis_X] = UI_GROW(1, 0); panel->pref_size[Axis_X] = UI_GROW(1, 0);
panel->pref_size[Axis_Y] = UI_GROW(1, 0); panel->pref_size[Axis_Y] = UI_GROW(1, 0);
DllQueuePush(panel->parent->first, panel->parent->last, panel); DllQueuePush(panel->parent->first, panel->parent->last, panel);
@ -843,49 +847,12 @@ void V_TickForever(WaveLaneCtx *lane)
{ {
V_Window *window = PushStruct(perm, V_Window); V_Window *window = PushStruct(perm, V_Window);
window->panel = panel; window->panel = panel;
window->key = UI_TransKey(); /* TODO: Don't use transient keys */
window->is_viewport_window = 1; window->is_viewport_window = 1;
DllQueuePushNP(panel->first_window, panel->last_window, window, next_in_panel, prev_in_panel); DllQueuePushNP(panel->first_window, panel->last_window, window, next_in_panel, prev_in_panel);
++panel->windows_count; ++panel->windows_count;
} }
} }
// {
// V_Space *space = PushStruct(perm, V_Space);
// space->parent = V.root_space;
// space->axis = !space->parent->axis;
// space->pref_size[Axis_X] = UI_GROW(1, 0);
// space->pref_size[Axis_Y] = UI_GROW(1, 0);
// DllQueuePush(space->parent->first, space->parent->last, space);
// ++space->parent->count;
// V_Panel *panel = PushStruct(perm, V_Panel);
// panel->space = space;
// DllQueuePushNP(space->first_panel, space->last_panel, panel, next_in_space, prev_in_space);
// ++space->panels_count;
// {
// V_Window *window = PushStruct(perm, V_Window);
// window->panel = panel;
// window->is_viewport_window = 1;
// DllQueuePushNP(panel->first_window, panel->last_window, window, next_in_panel, prev_in_panel);
// ++panel->windows_count;
// }
// }
// {
// V_Panel *panel = PushStruct(perm, V_Panel);
// panel->space = space;
// DllQueuePushNP(space->first_panel, space->last_panel, panel, next_in_space, prev_in_space);
// ++space->panels_count;
// {
// V_Window *window = PushStruct(perm, V_Window);
// window->panel = panel;
// // window->is_tile_window = 1;
// DllQueuePushNP(panel->first_window, panel->last_window, window, next_in_panel, prev_in_panel);
// ++panel->windows_count;
// }
// }
} }
if (frame->is_editing) if (frame->is_editing)
@ -919,10 +886,12 @@ void V_TickForever(WaveLaneCtx *lane)
{ {
UI_BuildColumnEx(panel->key); UI_BuildColumnEx(panel->key);
} }
UI_Push(Tag, panel->key.hash);
panel_dfs->cp = UI_PushCP(panel->key); panel_dfs->cp = UI_PushCP(panel->key);
if (!panel->is_organizing_panel) if (!panel->is_organizing_panel)
{ {
i64 new_active_window_idx = panel->active_window_idx;
// UI_SetNext(Width, UI_SHRINK(0, 1)); // UI_SetNext(Width, UI_SHRINK(0, 1));
// UI_SetNext(Width, UI_GROW(1, 0)); // UI_SetNext(Width, UI_GROW(1, 0));
// UI_SetNext(Height, UI_GROW(1, 0)); // UI_SetNext(Height, UI_GROW(1, 0));
@ -941,22 +910,39 @@ void V_TickForever(WaveLaneCtx *lane)
{ {
if (!window->is_viewport_window) if (!window->is_viewport_window)
{ {
UI_Report rep = UI_ReportFromKey(window->key);
if (rep.m1_downs > 0)
{
new_active_window_idx = window_idx;
}
Vec4 border_color = VEC4(0.5, 0.5, 0.5, 1);
UI_BuildSpacer(UI_PIX(tab_spacing, 0), Axis_X); UI_BuildSpacer(UI_PIX(tab_spacing, 0), Axis_X);
if (window_idx == active_window_idx) if (window_idx == active_window_idx)
{ {
active_window = window; active_window = window;
UI_SetNext(BorderColor, VEC4(0.9, 0.5, 0.5, 1)); border_color = VEC4(0.9, 0.5, 0.5, 1);
} }
else
{ Vec4 hovered_color = VEC4(0.5, 0.5, 0.5, 1);
UI_SetNext(BorderColor, VEC4(0.5, 0.5, 0.5, 1)); Vec4 pressed_color = hovered_color;
} pressed_color.w = 0.2;
UI_SetNext(BackgroundColor, VEC4(0.2, 0.2, 0.2, 1));
Vec4 bg_color = theme.window_background_color;
bg_color.x = 0.4;
bg_color = BlendSrgb(bg_color, hovered_color, rep.hot);
bg_color = BlendSrgb(bg_color, pressed_color, rep.active * rep.hovered);
UI_SetNext(BackgroundColor, bg_color);
UI_SetNext(BorderColor, border_color);
UI_SetNext(Border, 1); UI_SetNext(Border, 1);
UI_SetNext(Width, UI_SHRINK(theme.text_padding_x, 1)); UI_SetNext(Width, UI_SHRINK(theme.text_padding_x, 1));
UI_SetNext(Height, UI_SHRINK(theme.text_padding_y, 1)); UI_SetNext(Height, UI_SHRINK(theme.text_padding_y, 1));
UI_SetNext(ChildAlignment, UI_Alignment_Center); UI_SetNext(ChildAlignment, UI_Alignment_Center);
UI_PushCP(UI_BuildRow()); UI_SetNext(Flags, UI_BoxFlag_Interactable);
UI_PushCP(UI_BuildRowEx(window->key));
{ {
if (window->is_tile_window) if (window->is_tile_window)
{ {
@ -1001,6 +987,7 @@ void V_TickForever(WaveLaneCtx *lane)
} }
} }
UI_PopCP(UI_TopCP()); UI_PopCP(UI_TopCP());
panel->active_window_idx = new_active_window_idx;
} }
} }
else else
@ -1011,14 +998,29 @@ void V_TickForever(WaveLaneCtx *lane)
//- Build divider //- Build divider
if (panel->next != 0) if (panel->next != 0)
{ {
UI_Key divider_key = UI_TransKey(); UI_Key divider_key = UI_KeyF("Divider");
UI_SetNext(BackgroundColor, Color_Cyan); UI_Report rep = UI_ReportFromKey(divider_key);
// Vec4 hovered_color = Rgb32(0x103c4c);
Vec4 hovered_color = VEC4(0.5, 0.5, 0.5, 1);
Vec4 pressed_color = hovered_color;
pressed_color.w = 0.2;
Vec4 bg_color = theme.window_background_color;
bg_color.x = 0.4;
bg_color = BlendSrgb(bg_color, hovered_color, rep.hot);
bg_color = BlendSrgb(bg_color, pressed_color, rep.active * rep.hovered);
UI_SetNext(Flags, UI_BoxFlag_Interactable);
UI_SetNext(BackgroundColor, bg_color);
// UI_SetNext(Border, 2); // UI_SetNext(Border, 2);
UI_SetNext(AxisSize, UI_GROW(1, 1), .axis = panel->axis); UI_SetNext(AxisSize, UI_GROW(1, 1), .axis = panel->axis);
UI_SetNext(AxisSize, UI_PIX(5, 1), .axis = !panel->axis); UI_SetNext(AxisSize, UI_PIX(3, 1), .axis = !panel->axis);
/* FIXME: Non-transient key */ /* FIXME: Non-transient key */
UI_BuildBoxEx(divider_key); UI_BuildBoxEx(divider_key);
} }
UI_Pop(Tag);
} }
} }
} }
@ -1176,7 +1178,7 @@ void V_TickForever(WaveLaneCtx *lane)
} }
else else
{ {
UI_SetNext(BackgroundColor, Rgba(1, 1, 1, 0.02)); UI_SetNext(BackgroundColor, Rgba(0, 0, 0, 1));
UI_SetNext(Width, UI_GROW(1, 0)); UI_SetNext(Width, UI_GROW(1, 0));
UI_SetNext(Height, UI_SHRINK(0, 1)); UI_SetNext(Height, UI_SHRINK(0, 1));
} }

View File

@ -177,6 +177,8 @@ Struct(V_Window)
V_Window *next_in_panel; V_Window *next_in_panel;
V_Window *prev_in_panel; V_Window *prev_in_panel;
UI_Key key;
b32 is_tile_window; b32 is_tile_window;
b32 is_viewport_window; b32 is_viewport_window;
}; };

View File

@ -14,7 +14,7 @@ ComputeShader2D(V_BackdropCS, 8, 8)
const Vec4 y_axis_color = LinearFromSrgb(Vec4(0, 0.75, 0, 1)); const Vec4 y_axis_color = LinearFromSrgb(Vec4(0, 0.75, 0, 1));
const Vec4 bounds_color = LinearFromSrgb(Vec4(0.75, 0.75, 0, 1)); const Vec4 bounds_color = LinearFromSrgb(Vec4(0.75, 0.75, 0, 1));
Vec2 screen_pos = Vec2(SV_DispatchThreadID) + Vec2(0.5, 0.5); Vec2 screen_pos = SV_DispatchThreadID + Vec2(0.5, 0.5);
if (screen_pos.x < params.target_size.x && screen_pos.y < params.target_size.y) if (screen_pos.x < params.target_size.x && screen_pos.y < params.target_size.y)
{ {
Vec4 result = Vec4(0.025, 0.025, 0.025, 1); Vec4 result = Vec4(0.025, 0.025, 0.025, 1);
@ -118,8 +118,7 @@ ComputeShader2D(V_BackdropCS, 8, 8)
} }
} }
target[SV_DispatchThreadID] = result;
target[trunc(screen_pos)] = result;
} }
} }

View File

@ -695,7 +695,7 @@ UI_Frame *UI_BeginFrame(UI_FrameFlag frame_flags, Vec4 swapchain_color)
if (hovered_box) if (hovered_box)
{ {
++hovered_box->report.m1_downs; ++hovered_box->report.m1_downs;
hovered_box->report.m1_held = 1; hovered_box->report.is_m1_held = 1;
hovered_box->report.last_m1_offset = SubVec2(frame->cursor_pos, hovered_box->rect.p0); hovered_box->report.last_m1_offset = SubVec2(frame->cursor_pos, hovered_box->rect.p0);
active_box = hovered_box; active_box = hovered_box;
} }
@ -713,7 +713,7 @@ UI_Frame *UI_BeginFrame(UI_FrameFlag frame_flags, Vec4 swapchain_color)
++active_box->report.m1_presses; ++active_box->report.m1_presses;
} }
++active_box->report.m1_ups; ++active_box->report.m1_ups;
active_box->report.m1_held = 0; active_box->report.is_m1_held = 0;
active_box = 0; active_box = 0;
} }
} }
@ -731,6 +731,7 @@ UI_Frame *UI_BeginFrame(UI_FrameFlag frame_flags, Vec4 swapchain_color)
{ {
UI_Box *box = last_frame->boxes_pre[pre_index]; UI_Box *box = last_frame->boxes_pre[pre_index];
UI_Report *report = &box->report; UI_Report *report = &box->report;
report->is_hovered = box == hovered_box;
f32 target_hot = box == active_box || (box == hovered_box && (box == active_box || active_box == 0)); f32 target_hot = box == active_box || (box == hovered_box && (box == active_box || active_box == 0));
f32 target_active = box == active_box; f32 target_active = box == active_box;
f32 target_hovered = box == hovered_box; f32 target_hovered = box == hovered_box;

View File

@ -174,7 +174,8 @@ Struct(UI_Stack)
Struct(UI_Report) Struct(UI_Report)
{ {
b32 m1_held; b32 is_m1_held;
b32 is_hovered;
f32 hovered; f32 hovered;
f32 hot; f32 hot;