panel-window relocation progress

This commit is contained in:
jacob 2025-12-29 17:27:40 -06:00
parent 4d25eadd40
commit e69aa09212
7 changed files with 368 additions and 187 deletions

View File

@ -863,7 +863,7 @@ u32 LinearU32FromSrgb(Vec4 srgb)
return result;
}
Vec4 BlendSrgb(Vec4 v0, Vec4 v1, f32 t)
Vec4 LerpSrgb(Vec4 v0, Vec4 v1, f32 t)
{
Vec4 v0_l = LinearFromSrgb(v0);
Vec4 v1_l = LinearFromSrgb(v1);

View File

@ -311,7 +311,7 @@ f32 LinearFromSrgbF32(f32 srgb);
Vec4 LinearFromSrgb(Vec4 srgb);
Vec4 SrgbFromLinear(Vec4 lin);
u32 LinearU32FromSrgb(Vec4 srgb);
Vec4 BlendSrgb(Vec4 v0, Vec4 v1, f32 t);
Vec4 LerpSrgb(Vec4 v0, Vec4 v1, f32 t);
////////////////////////////////////////////////////////////
//~ Vec2

View File

@ -211,6 +211,7 @@ GC_Run GC_RunFromString(Arena *arena, String str, GC_FontKey font, f32 font_size
if (ready_glyphs_count > 0)
{
// TOOD: Round these too?
GC_Glyph *glyph = ready_glyphs[0];
result.font_size = glyph->font_size * scale;
result.font_ascent = glyph->font_ascent * scale;

View File

@ -140,7 +140,6 @@ void V_EndCommandsWidget(V_CommandsWidget *widget)
UI_Key titlebar_key = UI_KeyF("title bar");
UI_Report titlebar_rep = UI_ReportFromKey(titlebar_key);
Vec2 titlebar_half_dims = MulVec2(DimsFromRng2(titlebar_rep.screen_rect), 0.5);
Vec4 window_background_color = theme.window_background_color;
// Vec4 window_background_color = VEC4(0, 0, 0, 0);
@ -150,18 +149,14 @@ void V_EndCommandsWidget(V_CommandsWidget *widget)
Vec4 divider_color = theme.divider_color;
if (titlebar_rep.m1.held)
{
widget->pos = AddVec2(SubVec2(cursor_pos, titlebar_rep.last_down_mouse_offset), titlebar_half_dims);
widget->pos = SubVec2(cursor_pos, titlebar_rep.last_mouse_down_cursor_offset);
}
// window_border_color = BlendSrgb(window_border_color, Rgb(0.5, 0.5, 0.5), titlebar_rep.hot);
window_border_color = BlendSrgb(window_border_color, Rgb32(0x0078a6), titlebar_rep.hot);
// window_border_color = LerpSrgb(window_border_color, Rgb(0.5, 0.5, 0.5), titlebar_rep.hot);
window_border_color = LerpSrgb(window_border_color, Rgb32(0x0078a6), titlebar_rep.hot);
UI_Push(Scale, titlebar_rep.exists);
UI_Push(Tint, VEC4(1, 1, 1, titlebar_rep.exists));
// Vec2 pos = LerpVec2(MulVec2(Vec2FromVec(frame->ui_dims), 0.5), widget->pos, titlebar_rep.exists);
Vec2 pos = SubVec2(widget->pos, titlebar_half_dims);
UI_Push(BackgroundColor, window_background_color);
UI_Push(BorderColor, window_border_color);
UI_Push(Border, theme.window_border);
@ -169,7 +164,7 @@ void V_EndCommandsWidget(V_CommandsWidget *widget)
UI_Push(Width, UI_PIX(theme.window_width, 0));
UI_Push(Height, UI_SHRINK(0, 0));
UI_Push(ChildLayoutAxis, Axis_Y);
UI_Push(FloatingPos, pos);
UI_Push(FloatingPos, widget->pos);
UI_SetNext(Flags, UI_BoxFlag_Floating);
UI_PushCP(UI_BuildBoxEx(widget->key));
{
@ -227,9 +222,9 @@ void V_EndCommandsWidget(V_CommandsWidget *widget)
UI_Report btn_rep = UI_ReportFromKey(btn_key);
Vec4 btn_color = theme.window_background_color;
btn_color = BlendSrgb(btn_color, theme.button_hot_color, btn_rep.hot);
btn_color = BlendSrgb(btn_color, theme.button_active_color, btn_rep.active);
Vec4 btn_border_color = BlendSrgb(VEC4(0, 0, 0, 0), theme.button_active_color, btn_rep.hot);
btn_color = LerpSrgb(btn_color, theme.button_hot_color, btn_rep.hot);
btn_color = LerpSrgb(btn_color, theme.button_active_color, btn_rep.active);
Vec4 btn_border_color = LerpSrgb(VEC4(0, 0, 0, 0), theme.button_active_color, btn_rep.hot);
UI_SetNext(Rounding, 0);
UI_SetNext(Tint, 0);
@ -272,9 +267,9 @@ void V_EndCommandsWidget(V_CommandsWidget *widget)
f32 hotkey_hot = hotkey_rep.hot;
f32 hotkey_active = hotkey_rep.active;
f32 hotkey_hovered = hotkey_rep.hovered;
hotkey_color = BlendSrgb(hotkey_color, hovered_color, hotkey_hot);
hotkey_color = BlendSrgb(hotkey_color, pressed_color, hotkey_active * hotkey_hovered);
hotkey_border_color = BlendSrgb(hotkey_border_color, Rgb32(0x0078a6), hotkey_hot);
hotkey_color = LerpSrgb(hotkey_color, hovered_color, hotkey_hot);
hotkey_color = LerpSrgb(hotkey_color, pressed_color, hotkey_active * hotkey_hovered);
hotkey_border_color = LerpSrgb(hotkey_border_color, Rgb32(0x0078a6), hotkey_hot);
}
V_Hotkey hotkey = item->desc.hotkeys[i];
@ -882,6 +877,7 @@ void V_TickForever(WaveLaneCtx *lane)
panel->pref_ratio = 1;
panel->is_organizing_panel = 1;
V.root_panel = panel;
++V.panels_count;
}
{
@ -892,6 +888,7 @@ void V_TickForever(WaveLaneCtx *lane)
panel->pref_ratio = 0.25;
DllQueuePush(panel->parent->first, panel->parent->last, panel);
++panel->parent->count;
++V.panels_count;
{
V_Window *window = PushStruct(perm, V_Window);
@ -900,6 +897,7 @@ void V_TickForever(WaveLaneCtx *lane)
// window->is_tile_window = 1;
DllQueuePushNP(panel->first_window, panel->last_window, window, next_in_panel, prev_in_panel);
++panel->windows_count;
++V.windows_count;
}
{
V_Window *window = PushStruct(perm, V_Window);
@ -908,6 +906,7 @@ void V_TickForever(WaveLaneCtx *lane)
window->is_tile_window = 1;
DllQueuePushNP(panel->first_window, panel->last_window, window, next_in_panel, prev_in_panel);
++panel->windows_count;
++V.windows_count;
}
panel->active_window_idx = 1;
}
@ -919,6 +918,7 @@ void V_TickForever(WaveLaneCtx *lane)
panel->axis = !panel->parent->axis;
DllQueuePush(panel->parent->first, panel->parent->last, panel);
++panel->parent->count;
++V.panels_count;
panel->pref_ratio = 0.75;
panel->is_viewport_panel = 1;
@ -930,6 +930,7 @@ void V_TickForever(WaveLaneCtx *lane)
// window->is_viewport_window = 1;
// DllQueuePushNP(panel->first_window, panel->last_window, window, next_in_panel, prev_in_panel);
// ++panel->windows_count;
// ++V.windows_count;
// }
}
@ -940,6 +941,7 @@ void V_TickForever(WaveLaneCtx *lane)
// panel->axis = !panel->parent->axis;
// DllQueuePush(panel->parent->first, panel->parent->last, panel);
// ++panel->parent->count;
// ++V.panels_count;
// {
// V_Window *window = PushStruct(perm, V_Window);
@ -948,6 +950,7 @@ void V_TickForever(WaveLaneCtx *lane)
// // window->is_tile_window = 1;
// DllQueuePushNP(panel->first_window, panel->last_window, window, next_in_panel, prev_in_panel);
// ++panel->windows_count;
// ++V.windows_count;
// }
// {
// V_Window *window = PushStruct(perm, V_Window);
@ -956,6 +959,7 @@ void V_TickForever(WaveLaneCtx *lane)
// window->is_tile_window = 1;
// DllQueuePushNP(panel->first_window, panel->last_window, window, next_in_panel, prev_in_panel);
// ++panel->windows_count;
// ++V.windows_count;
// }
// panel->active_window_idx = 1;
// }
@ -968,7 +972,12 @@ void V_TickForever(WaveLaneCtx *lane)
first_panel_dfs->panel = V.root_panel;
f32 divider_size = 10;
//- Iterate panels
i64 prune_windows_count = 0;
V_Window **prune_windows = PushStructsNoZero(frame->arena, V_Window *, V.windows_count);
//////////////////////////////
//- Walk panel tree
while (first_panel_dfs)
{
PanelDfsNode *panel_dfs = first_panel_dfs;
@ -1010,11 +1019,11 @@ void V_TickForever(WaveLaneCtx *lane)
f32 child_pref_size = 0;
if (panel->axis == Axis_X)
{
child_pref_size = frame->ui_cursor.x - child_rep.screen_rect.p0.x - divider_rep.last_down_mouse_offset.x;
child_pref_size = frame->ui_cursor.x - child_rep.screen_rect.p0.x - divider_rep.last_mouse_down_cursor_offset.x;
}
else
{
child_pref_size = frame->ui_cursor.y - child_rep.screen_rect.p0.y - divider_rep.last_down_mouse_offset.y;
child_pref_size = frame->ui_cursor.y - child_rep.screen_rect.p0.y - divider_rep.last_mouse_down_cursor_offset.y;
}
f32 ratio_diff = (child_pref_size / panel_size) - resize_panel->pref_ratio;
@ -1066,43 +1075,156 @@ void V_TickForever(WaveLaneCtx *lane)
UI_Push(Tint, VEC4(1, 1, 1, 0.90 * panel_rep.exists));
i64 active_window_idx = ClampI64(panel->active_window_idx, 0, MaxI64(panel->windows_count - 1, 0));
//////////////////////////////
//- Build tab row
f32 tab_spacing = 10;
V_Window *active_window = 0;
V_Window *close_window = 0;
{
i64 window_idx = 0;
UI_Key tab_row_key = UI_KeyF("tab row");
UI_Report tab_row_rep = UI_ReportFromKey(tab_row_key);
UI_SetNext(Width, UI_GROW(1, 0));
UI_SetNext(Height, UI_SHRINK(0, 1));
UI_PushCP(UI_BuildRow());
//- Build window tabs
UI_SetNext(Flags, UI_BoxFlag_Interactable);
UI_PushCP(UI_BuildRowEx(tab_row_key));
//////////////////////////////
//- Prep drawable tabs
Enum(DrawableTabKind)
{
DrawableTabKind_Window,
DrawableTabKind_NewTab,
DrawableTabKind_Ghost,
};
Struct(DrawableTab)
{
DrawableTab *next;
DrawableTab *prev;
DrawableTabKind kind;
UI_Key key;
V_Window *window;
i64 window_idx;
};
DrawableTab *first_drawable_tab = 0;
DrawableTab *last_drawable_tab = 0;
{
// Push window tabs
i64 window_idx = 0;
for (V_Window *window = panel->first_window; window; window = window->next_in_panel)
{
UI_Push(Tag, window->key.hash);
{
UI_Report tab_rep = UI_ReportFromKey(window->key);
if (tab_rep.m1.downs > 0)
{
new_active_window_idx = window_idx;
DrawableTab *tab = PushStruct(frame->arena, DrawableTab);
tab->key = window->key;
tab->kind = DrawableTabKind_Window;
tab->window = window;
tab->window_idx = window_idx;
DllQueuePush(first_drawable_tab, last_drawable_tab, tab);
window_idx += 1;
}
if (window == panel->first_window)
// Insert ghost tab
if (V.dragging_window && panel_rep.is_hovered)
{
DrawableTab *left = 0;
DrawableTab *right = 0;
for (DrawableTab *sibling = first_drawable_tab; sibling; sibling = sibling->next)
{
UI_Report sibling_rep = UI_ReportFromKey(sibling->key);
f32 zone = CenterFromRng2(sibling_rep.screen_rect).x;
if (frame->ui_cursor.x <= zone)
{
break;
}
left = sibling;
right = sibling->next;
}
b32 skip = (left && left->window == V.dragging_window) || (right && right->window == V.dragging_window);
if (!skip)
{
DrawableTab *tab = PushStruct(frame->arena, DrawableTab);
tab->key = UI_KeyF("ghost");
tab->kind = DrawableTabKind_Ghost;
DllQueueInsert(first_drawable_tab, last_drawable_tab, left, tab);
}
}
// Push new tab button
{
DrawableTab *tab = PushStruct(frame->arena, DrawableTab);
tab->key = UI_KeyF("new tab");
tab->kind = DrawableTabKind_NewTab;
DllQueuePush(first_drawable_tab, last_drawable_tab, tab);
}
}
//////////////////////////////
//- Build tabs
for (DrawableTab *tab = first_drawable_tab; tab; tab = tab->next)
{
UI_Push(Tag, tab->key.hash);
UI_Report tab_rep = UI_ReportFromKey(tab->key);
if (tab == first_drawable_tab)
{
UI_BuildSpacer(UI_PIX(tab_spacing, 0), Axis_X);
}
switch (tab->kind)
{
//////////////////////////////
//- Build window tab
case DrawableTabKind_Window:
{
V_Window *window = tab->window;
{
if (tab_rep.m1.downs > 0)
{
new_active_window_idx = tab->window_idx;
}
if (V.dragging_window == 0)
{
f32 drag_threshold = 20;
if (tab_rep.m1.held)
{
Vec2 drag_start = AddVec2(tab_rep.screen_rect.p0, tab_rep.last_mouse_down_cursor_offset);
if (Vec2Len(SubVec2(frame->ui_cursor, drag_start)) > drag_threshold)
{
V.dragging_window = window;
}
}
}
b32 is_dragging = window == V.dragging_window;
if (is_dragging && tab_rep.m1.ups > 0)
{
V.dragging_window = 0;
}
Vec4 bg_color = theme.window_background_color;
Vec4 border_color = theme.window_border_color;
if (window_idx == active_window_idx)
if (tab->window_idx == active_window_idx)
{
active_window = window;
border_color = theme.button_active_color;
}
bg_color = BlendSrgb(bg_color, theme.button_hot_color, tab_rep.hot);
bg_color = BlendSrgb(bg_color, theme.button_active_color, tab_rep.active);
border_color = BlendSrgb(border_color, theme.button_active_color, tab_rep.hot);
bg_color = LerpSrgb(bg_color, theme.button_hot_color, tab_rep.hot);
bg_color = LerpSrgb(bg_color, theme.button_active_color, tab_rep.active);
border_color = LerpSrgb(border_color, theme.button_active_color, tab_rep.hot);
if (is_dragging)
{
bg_color = Color_Blue;
}
String tab_name = Zi;
if (window->is_tile_window)
@ -1122,7 +1244,7 @@ void V_TickForever(WaveLaneCtx *lane)
UI_SetNext(ChildAlignment, UI_Alignment_Left);
UI_SetNext(Flags, UI_BoxFlag_Interactable);
UI_SetNext(Text, tab_name);
UI_PushCP(UI_BuildRowEx(window->key));
UI_PushCP(UI_BuildRowEx(tab->key));
{
// Build tab title
{
@ -1140,9 +1262,9 @@ void V_TickForever(WaveLaneCtx *lane)
UI_Report close_rep = UI_ReportFromKey(close_key);
Vec4 close_color = Zi;
close_color = BlendSrgb(close_color, theme.button_hot_color, close_rep.hot);
close_color = BlendSrgb(close_color, theme.button_active_color, close_rep.active);
Vec4 close_border_color = BlendSrgb(VEC4(0, 0, 0, 0), theme.button_active_color, close_rep.hot);
close_color = LerpSrgb(close_color, theme.button_hot_color, close_rep.hot);
close_color = LerpSrgb(close_color, theme.button_active_color, close_rep.active);
Vec4 close_border_color = LerpSrgb(VEC4(0, 0, 0, 0), theme.button_active_color, close_rep.hot);
UI_SetNext(BackgroundColor, close_color);
UI_SetNext(BorderColor, close_border_color);
@ -1156,27 +1278,55 @@ void V_TickForever(WaveLaneCtx *lane)
if (close_rep.m1.presses)
{
close_window = window;
prune_windows[prune_windows_count] = window;
prune_windows_count += 1;
}
}
}
UI_PopCP(UI_TopCP());
}
UI_Pop(Tag);
UI_BuildSpacer(UI_PIX(tab_spacing, 0), Axis_X);
window_idx += 1;
} break;
//////////////////////////////
//- Build ghost tab
case DrawableTabKind_Ghost:
{
UI_Report rep = UI_ReportFromKey(tab->key);
Vec4 bg_color = Zi;
bg_color = LerpSrgb(bg_color, theme.button_hot_color, rep.exists);
bg_color.w *= 0.5;
Vec4 border_color = LerpSrgb(VEC4(0, 0, 0, 0), theme.button_active_color, rep.exists);
UI_SetNext(Scale, rep.exists);
UI_SetNext(BackgroundColor, bg_color);
UI_SetNext(BorderColor, border_color);
UI_SetNext(Border, 2);
UI_SetNext(Width, UI_PIX(30, 0));
UI_SetNext(Height, UI_GROW(1, 0));
UI_SetNext(ChildAlignment, UI_Alignment_Center);
// UI_SetNext(FontSize, theme.font_size * 1.5);
UI_PushCP(UI_BuildRowEx(tab->key));
{
}
}
//- Build new-tab button
UI_PopCP(UI_TopCP());
} break;
//////////////////////////////
//- Build new tab button
case DrawableTabKind_NewTab:
{
UI_Key key = UI_KeyF("new tab");
UI_Report rep = UI_ReportFromKey(key);
Vec4 bg_color = Zi;
bg_color = BlendSrgb(bg_color, theme.button_hot_color, rep.hot);
bg_color = BlendSrgb(bg_color, theme.button_active_color, rep.active);
bg_color = LerpSrgb(bg_color, theme.button_hot_color, rep.hot);
bg_color = LerpSrgb(bg_color, theme.button_active_color, rep.active);
bg_color.w *= 0.5;
Vec4 border_color = BlendSrgb(VEC4(0, 0, 0, 0), theme.button_active_color, rep.hot);
Vec4 border_color = LerpSrgb(VEC4(0, 0, 0, 0), theme.button_active_color, rep.hot);
UI_SetNext(BackgroundColor, bg_color);
UI_SetNext(BorderColor, border_color);
@ -1192,9 +1342,15 @@ void V_TickForever(WaveLaneCtx *lane)
}
UI_PopCP(UI_TopCP());
}
}
UI_BuildSpacer(UI_PIX(tab_spacing, 0), Axis_X);
}
UI_PopCP(UI_TopCP());
}
//////////////////////////////
//- Build active window
if (active_window)
{
Vec4 window_bg_color = theme.window_background_color;
@ -1224,14 +1380,14 @@ void V_TickForever(WaveLaneCtx *lane)
}
Vec4 bg_color = Zi;
bg_color = BlendSrgb(bg_color, theme.button_hot_color, rep.hot);
bg_color = BlendSrgb(bg_color, theme.button_active_color, rep.active);
bg_color = LerpSrgb(bg_color, theme.button_hot_color, rep.hot);
bg_color = LerpSrgb(bg_color, theme.button_active_color, rep.active);
b32 is_selected = tile_kind == frame->equipped_tile;
Vec4 border_color = Zi;
border_color = BlendSrgb(border_color, theme.button_selected_color, rep.selected);
border_color = BlendSrgb(border_color, theme.button_active_color, rep.hot);
border_color = LerpSrgb(border_color, theme.button_selected_color, rep.selected);
border_color = LerpSrgb(border_color, theme.button_active_color, rep.hot);
UI_SetNext(BackgroundColor, bg_color);
UI_SetNext(BorderColor, border_color);
@ -1254,15 +1410,6 @@ void V_TickForever(WaveLaneCtx *lane)
}
UI_PopCP(UI_TopCP());
}
//- Close window
if (close_window != 0)
{
V_Window *window = close_window;
// TODO: Add window to free list
// TODO: Remove panel if windowless
DllQueueRemoveNP(panel->first_window, panel->last_window, window, next_in_panel, prev_in_panel);
panel->windows_count -= 1;
}
}
UI_PopCP(UI_TopCP());
panel->active_window_idx = new_active_window_idx;
@ -1273,18 +1420,20 @@ void V_TickForever(WaveLaneCtx *lane)
UI_PopCP(panel_dfs->cp);
SllStackPop(first_panel_dfs);
//- Build divider
//////////////////////////////
//- Build panel divider
if (panel->next != 0)
{
panel->divider_key = UI_KeyF("Divider");
UI_Report rep = UI_ReportFromKey(panel->divider_key);
Vec4 active_color = theme.button_active_color;
Vec4 hot_color = BlendSrgb(theme.button_hot_color, theme.button_active_color, 0.25);
Vec4 hot_color = LerpSrgb(theme.button_hot_color, theme.button_active_color, 0.25);
Vec4 bg_color = Zi;
bg_color = BlendSrgb(bg_color, hot_color, rep.hot);
bg_color = BlendSrgb(bg_color, active_color, rep.active);
bg_color = LerpSrgb(bg_color, hot_color, rep.hot);
bg_color = LerpSrgb(bg_color, active_color, rep.active);
Vec4 border_color = Zi;
f32 visible_size = 2.0;
@ -1318,6 +1467,25 @@ void V_TickForever(WaveLaneCtx *lane)
UI_Pop(Tag);
}
}
//////////////////////////////
//- Prune windows
for (i64 prune_window_idx = 0; prune_window_idx < prune_windows_count; ++prune_window_idx)
{
V_Window *window = prune_windows[prune_window_idx];
V_Panel *panel = window->panel;
if (window == V.dragging_window)
{
V.dragging_window = 0;
}
// TODO: Add window to free list
// TODO: Remove panel if windowless
DllQueueRemoveNP(panel->first_window, panel->last_window, window, next_in_panel, prev_in_panel);
panel->windows_count -= 1;
}
}
//////////////////////////////

View File

@ -281,7 +281,10 @@ Struct(V_Ctx)
S_Lookup lookup;
S_Key player_key;
i64 panels_count;
i64 windows_count;
V_Panel *root_panel;
V_Window *dragging_window;
Atomic32 shutdown;
Fence shutdown_complete;

View File

@ -640,7 +640,7 @@ UI_Frame *UI_BeginFrame(UI_FrameFlag frame_flags, Vec4 swapchain_color)
frame->cursor_pos = last_frame->cursor_pos;
// Locate boxes
UI_Box *hovered_box = 0;
UI_Box *top_hovered_box = 0;
UI_Box *active_box = UI_BoxFromKey(last_frame->active_box);
// Update cursor pos
@ -657,8 +657,6 @@ UI_Frame *UI_BeginFrame(UI_FrameFlag frame_flags, Vec4 swapchain_color)
for (u64 pre_index = UI.boxes_count; pre_index-- > 0;)
{
UI_Box *box = last_frame->boxes_pre[pre_index];
if (hovered_box == 0 && box->desc.flags & UI_BoxFlag_Interactable)
{
b32 is_cursor_in_box = 0;
{
// TODO: More efficient test. This logic is just copied from the renderer's SDF function for now.
@ -685,11 +683,10 @@ UI_Frame *UI_BeginFrame(UI_FrameFlag frame_flags, Vec4 swapchain_color)
}
is_cursor_in_box = non_corner_edge_dist >= 0 && corner_edge_dist >= 0;
}
if (is_cursor_in_box)
box->report.is_hovered = is_cursor_in_box;
if (top_hovered_box == 0 && box->desc.flags & UI_BoxFlag_Interactable && is_cursor_in_box)
{
hovered_box = box;
}
top_hovered_box = box;
}
box->report.m1.ups = 0;
box->report.m1.downs = 0;
@ -714,25 +711,25 @@ UI_Frame *UI_BeginFrame(UI_FrameFlag frame_flags, Vec4 swapchain_color)
{
if (cev.button == Button_M1 || cev.button == Button_M2 || cev.button == Button_M3)
{
if (hovered_box)
if (top_hovered_box && active_box == 0)
{
hovered_box->report.last_down_mouse_offset = SubVec2(frame->cursor_pos, hovered_box->rect.p0);
top_hovered_box->report.last_mouse_down_cursor_offset = SubVec2(frame->cursor_pos, top_hovered_box->rect.p0);
if (cev.button == Button_M1)
{
++hovered_box->report.m1.downs;
hovered_box->report.m1.held = 1;
++top_hovered_box->report.m1.downs;
top_hovered_box->report.m1.held = 1;
}
else if (cev.button == Button_M2)
{
++hovered_box->report.m2.downs;
hovered_box->report.m2.held = 1;
++top_hovered_box->report.m2.downs;
top_hovered_box->report.m2.held = 1;
}
else if (cev.button == Button_M3)
{
++hovered_box->report.m3.downs;
hovered_box->report.m3.held = 1;
++top_hovered_box->report.m3.downs;
top_hovered_box->report.m3.held = 1;
}
active_box = hovered_box;
active_box = top_hovered_box;
}
}
} break;
@ -743,34 +740,47 @@ UI_Frame *UI_BeginFrame(UI_FrameFlag frame_flags, Vec4 swapchain_color)
{
if (active_box)
{
++active_box->report.m1.ups;
if (cev.button == Button_M1)
{
if (active_box == hovered_box)
if (active_box == top_hovered_box)
{
++active_box->report.m1.presses;
}
++active_box->report.m1.ups;
if (active_box->report.m1.held)
{
active_box->report.m1.held = 0;
active_box = 0;
}
}
else if (cev.button == Button_M2)
{
if (active_box == hovered_box)
if (active_box == top_hovered_box)
{
++active_box->report.m2.presses;
}
++active_box->report.m2.ups;
if (active_box->report.m2.held)
{
active_box->report.m2.held = 0;
active_box = 0;
}
}
else if (cev.button == Button_M3)
{
if (active_box == hovered_box)
if (active_box == top_hovered_box)
{
++active_box->report.m3.presses;
}
++active_box->report.m3.ups;
if (active_box->report.m3.held)
{
active_box->report.m3.held = 0;
}
active_box = 0;
}
}
}
}
} break;
case ControllerEventKind_Quit:
@ -781,9 +791,9 @@ UI_Frame *UI_BeginFrame(UI_FrameFlag frame_flags, Vec4 swapchain_color)
}
UI_Box *hot_box = active_box;
if (hovered_box && !active_box)
if (top_hovered_box && !active_box)
{
hot_box = hovered_box;
hot_box = top_hovered_box;
}
// Update box reports
@ -791,7 +801,6 @@ UI_Frame *UI_BeginFrame(UI_FrameFlag frame_flags, Vec4 swapchain_color)
{
UI_Box *box = last_frame->boxes_pre[pre_index];
UI_Report *report = &box->report;
report->is_hovered = box == hovered_box;
report->is_hot = box == hot_box;
f32 target_exists = box->last_build_tick >= (frame->tick - 1);
@ -814,7 +823,7 @@ UI_Frame *UI_BeginFrame(UI_FrameFlag frame_flags, Vec4 swapchain_color)
report->screen_rect = box->rect;
}
frame->hovered_box = hovered_box ? hovered_box->key : UI_NilKey;
frame->top_hovered_box = top_hovered_box ? top_hovered_box->key : UI_NilKey;
frame->hot_box = hot_box ? hot_box->key : UI_NilKey;
frame->active_box = active_box ? active_box->key : UI_NilKey;
}

View File

@ -194,7 +194,7 @@ Struct(UI_Report)
f32 selected;
// Mouse button info
Vec2 last_down_mouse_offset;
Vec2 last_mouse_down_cursor_offset;
UI_MouseReport m1;
UI_MouseReport m2;
UI_MouseReport m3;
@ -363,7 +363,7 @@ Struct(UI_Frame)
// Control
Vec2 cursor_pos;
UI_Key hovered_box;
UI_Key top_hovered_box;
UI_Key hot_box;
UI_Key active_box;