functional panel separation

This commit is contained in:
jacob 2026-04-03 06:35:32 -05:00
parent c95168b24a
commit 346b6ebaac
4 changed files with 125 additions and 84 deletions

View File

@ -616,7 +616,7 @@ V_WidgetTheme V_GetWidgetTheme(void)
theme.h6 = 0.75;
theme.micro = 0.50;
theme.rounding = TweakFloat("Rounding", 1, 0, 1);
theme.rounding = TweakFloat("UI rounded corners", 1, 0, 1);
theme.text_padding_x = 5;
theme.text_padding_y = 5;
@ -629,7 +629,9 @@ V_WidgetTheme V_GetWidgetTheme(void)
theme.col.panel_bg = theme.col.window_bg;
theme.col.panel_bd = theme.col.window_bd;
theme.col.panel_opacity = TweakFloat("Panel opacity", 1, 0, 1);
theme.col.panel_opacity = TweakFloat("Panel opacity", 0.75, 0, 1);
theme.col.panel_border_opacity = TweakFloat("Panel border opacity", 1, 0, 1);
theme.col.panel_resizer_opacity = TweakFloat("Panel resizer opacity", 1, 0, 1);
theme.col.divider = LerpSrgb(Color_Black, theme.col.window_bd, 0.6);
@ -1058,6 +1060,7 @@ void V_TickForever(WaveLaneCtx *lane)
WND_Frame window_frame = ui_frame->window_frame;
WND_SetCursor(window_frame, WND_CursorKind_Default);
WND_PushCmd(window_frame, .kind = WND_CmdKind_SetLockedCursor, .v = 0);
frame->ui_cursor = UI_CursorPos();
// Restore window
{
@ -1074,28 +1077,30 @@ void V_TickForever(WaveLaneCtx *lane)
UI_Push(ChildLayoutAxis, Axis_Y);
UI_Push(Width, UI_Grow(1, 0));
UI_Push(Height, UI_Grow(1, 0));
UI_Key vis_game_box = UI_KeyF("vis game box");
UI_Key vis_game_overlay_box = UI_KeyF("vis game overlay box");
UI_Key vis_root_box = UI_KeyF("vis root box");
UI_Key vis_screen_panel_box = UI_KeyF("vis screen panel box");
UI_Key vis_screen_box = UI_KeyF("vis screen box");
UI_Key vis_screen_overlay_box = UI_KeyF("vis screen overlay box");
UI_Key vis_screen_ui_box = UI_KeyF("vis screen ui box");
UI_Key vis_panels_box = UI_KeyF("vis panels box");
UI_Key vis_ui_box = UI_KeyF("vis ui box");
{
UI_SetNext(Flags, UI_BoxFlag_CaptureMouse);
UI_BuildColumnEx(vis_game_box);
UI_BuildColumnEx(vis_root_box);
UI_SetNext(Flags, UI_BoxFlag_Floating);
UI_SetNext(Parent, vis_game_box);
UI_BuildColumnEx(vis_game_overlay_box);
UI_SetNext(Parent, vis_screen_box);
UI_BuildColumnEx(vis_screen_overlay_box);
UI_SetNext(Flags, UI_BoxFlag_Floating);
UI_SetNext(Parent, vis_game_box);
UI_BuildBoxEx(vis_panels_box);
UI_SetNext(Parent, vis_screen_panel_box);
UI_BuildColumnEx(vis_screen_ui_box);
// NOTE: Vis ui box is built by panel tree
UI_Push(Parent, vis_ui_box);
UI_Push(Parent, vis_screen_ui_box);
}
// TODO: Don't rely on ui report for draw size since it introduces one frame of delay when resizing
frame->screen_dims = RoundVec2(DimsFromRng2(UI_Rect(vis_game_box)));
// frame->screen_dims = RoundVec2(DimsFromRng2(UI_Rect(vis_root_box)));
frame->screen_dims = RoundVec2(DimsFromRng2(UI_Rect(vis_screen_box)));
frame->screen_dims.x = MaxF32(frame->screen_dims.x, 64);
frame->screen_dims.y = MaxF32(frame->screen_dims.y, 64);
@ -1153,7 +1158,7 @@ void V_TickForever(WaveLaneCtx *lane)
V_TextboxDeltaList text_input_deltas = Zi;
frame->has_mouse_focus = UI_IsKeyNil(ui_frame->top_hot_box) || UI_MatchKey(ui_frame->top_hot_box, vis_game_box);
frame->has_mouse_focus = UI_IsKeyNil(ui_frame->top_hot_box) || UI_MatchKey(ui_frame->top_hot_box, vis_root_box);
frame->has_keyboard_focus = 1;
Vec2 mouse_delta = Zi;
{
@ -1442,7 +1447,7 @@ void V_TickForever(WaveLaneCtx *lane)
edit_to_screen_af = TranslateAffine(edit_to_screen_af, NegVec2(frame->edit_camera_pos));
}
Vec2 prev_target_cursor = MulAffineVec2(InvertAffine(prev_frame_edit_to_screen_af), prev_frame->screen_cursor);
Vec2 target_cursor = MulAffineVec2(InvertAffine(edit_to_screen_af), ui_frame->cursor_pos);
Vec2 target_cursor = MulAffineVec2(InvertAffine(edit_to_screen_af), SubVec2(UI_CursorPos(), UI_Rect(vis_screen_box).p0));
Vec2 diff = SubVec2(prev_target_cursor, target_cursor);
frame->edit_camera_pos = AddVec2(frame->edit_camera_pos, diff);
}
@ -2606,7 +2611,7 @@ void V_TickForever(WaveLaneCtx *lane)
}
else
{
frame->screen_cursor = ui_frame->cursor_pos;
frame->screen_cursor = SubVec2(UI_CursorPos(), UI_Rect(vis_screen_box).p0);
}
frame->shade_cursor = MulAffineVec2(frame->af.screen_to_shade, frame->screen_cursor);
frame->world_cursor = MulAffineVec2(frame->af.screen_to_world, frame->screen_cursor);
@ -3639,19 +3644,6 @@ void V_TickForever(WaveLaneCtx *lane)
}
}
//- Vis ui panel
{
V_Panel *parent = subroot_row_panel;
V_Panel *panel = PushStruct(perm, V_Panel);
panel->parent = parent;
panel->axis = Axis_X;
DllQueuePush(parent->first, parent->last, panel);
panel->box = UI_KeyF("test vis ui panel");
panel->contents_box = vis_ui_box;
panel->resizer_box = UI_KeyF("panel resizer box %F", FmtUint(panel->box.v));
panel->pct = 0.5;
}
//- Test panel
{
V_Panel *parent = subroot_row_panel;
@ -3662,7 +3654,20 @@ void V_TickForever(WaveLaneCtx *lane)
panel->box = UI_KeyF("test raah panel");
panel->contents_box = UI_KeyF("panel contents box %F", FmtUint(panel->box.v));
panel->resizer_box = UI_KeyF("panel resizer box %F", FmtUint(panel->box.v));
panel->pct = 0.5;
panel->pct = 0.25;
}
//- Vis screen panel
{
V_Panel *parent = subroot_row_panel;
V_Panel *panel = PushStruct(perm, V_Panel);
panel->parent = parent;
panel->axis = Axis_X;
DllQueuePush(parent->first, parent->last, panel);
panel->box = UI_KeyF("test vis ui panel");
panel->contents_box = vis_screen_panel_box;
panel->resizer_box = UI_KeyF("panel resizer box %F", FmtUint(panel->box.v));
panel->pct = 1;
}
}
@ -3670,7 +3675,7 @@ void V_TickForever(WaveLaneCtx *lane)
// // FIXME: Remove this (build it as a panel)
// BuildBoxEx(vis_ui_box);
// BuildBoxEx(vis_screen_box);
@ -3679,8 +3684,34 @@ void V_TickForever(WaveLaneCtx *lane)
// UI_PushDF(Parent, vis_game_box)
// UI_PushDF(Parent, vis_root_box)
b32 show_panels = frame->is_editing && !hide_editor_ui;
if (!show_panels)
{
UI_SetNext(Flags, UI_BoxFlag_Floating);
UI_SetNext(Parent, vis_root_box);
UI_BuildColumnEx(vis_screen_panel_box);
}
{
b32 lock_screen_to_panel = TweakBool("Lock screen to panel", 0);
if (lock_screen_to_panel)
{
UI_SetNext(Parent, vis_screen_panel_box);
}
else
{
UI_SetNext(Parent, vis_root_box);
}
UI_BuildBoxEx(vis_screen_box);
}
if (show_panels)
{
UI_SetNext(Flags, UI_BoxFlag_Floating);
UI_SetNext(Parent, vis_root_box);
UI_BuildBoxEx(vis_panels_box);
Struct(PanelBfs) { PanelBfs *next; V_Panel *panel; };
PanelBfs *first_panel_bfs = 0;
PanelBfs *last_panel_bfs = 0;
@ -3700,29 +3731,28 @@ void V_TickForever(WaveLaneCtx *lane)
Axis parent_axis = parent_panel->axis;
Rng2 parent_rect = UI_Rect(parent_contents_box);
Vec2 parent_dims = DimsFromRng2(parent_rect);
f32 parent_contents_size_px = DimsFromRng2(UI_Rect(parent_contents_box)).v[parent_axis];
f32 parent_contents_size_px = MaxF32(DimsFromRng2(UI_Rect(parent_contents_box)).v[parent_axis], 1);
UI_PushDF(Parent, parent_contents_box)
{
//- Solve panel size percentages
// {
// // f32 unconstrained_pct_accum = 0;
// // f32 flex_accum = 0;
// // f32 violation_accum = 0
// // for (V_Panel *panel = parent_panel->first; panel; panel = panel->next)
// // {
// // unconstrained_pct_accum += total_pct += panel->pct;
// // }
f32 minimum_panel_pct = 0.05;
// f32 unconstrained_pct_accum = 0;
// f32 flex_accum = 0;
// f32 violation_accum = 0
// for (V_Panel *panel = parent_panel->first; panel; panel = panel->next)
// {
// unconstrained_pct_accum += total_pct += panel->pct;
// }
// }
//- Adjust panel pcts to add to 1
{
f32 pct_accum = 0;
f32 children_count = 0;
for (V_Panel *panel = parent_panel->first; panel; panel = panel->next)
{
children_count += 1;
pct_accum += panel->pct;
}
f32 violation = 1.0 - pct_accum;
for (V_Panel *panel = parent_panel->first; panel; panel = panel->next)
{
panel->pct += violation / children_count;
panel->pct = MaxF32(panel->pct, minimum_panel_pct);
}
}
//- Build panel boxes
for (V_Panel *panel = parent_panel->first; panel; panel = panel->next)
@ -3735,11 +3765,15 @@ void V_TickForever(WaveLaneCtx *lane)
UI_Key contents_box = panel->contents_box;
UI_Key resizer_box = panel->resizer_box;
UI_Size resizer_size = UI_Px(10, 1);
Vec4 resizer_color = theme.col.divider;
UI_Size resizer_size = UI_Px(3, 1);
f32 minimum_panel_px = 100;
f32 minimum_panel_pct = minimum_panel_px / parent_contents_size_px;
Vec4 panel_bg = theme.col.panel_bg;
Vec4 panel_bd = theme.col.panel_bd;
panel_bg.a *= theme.col.panel_opacity;
Vec4 resizer_color = theme.col.divider;
resizer_color.a *= theme.col.panel_resizer_opacity;
panel_bd.a *= theme.col.panel_border_opacity;
if (UI_Downs(resizer_box, Button_M1))
{
@ -3783,21 +3817,22 @@ void V_TickForever(WaveLaneCtx *lane)
f32 panel_pct = panel->pct;
UI_SetNext(AxisSize, UI_Grow(panel_pct, 1), .axis = parent_axis);
// UI_SetNext(AxisSize, UI_Grow(panel_pct, 1), .axis = parent_axis);
UI_SetNext(AxisSize, UI_Grow(panel_pct, 0), .axis = parent_axis);
UI_SetNext(AxisSize, UI_Grow(1, 0), .axis = !parent_axis);
UI_SetNext(ChildLayoutAxis, parent_axis);
UI_PushDF(Tag, panel_box.v)
UI_PushDF(Parent, UI_BuildBoxEx(panel_box))
{
Vec4 panel_bg = theme.col.panel_bg;
Vec4 panel_bd = theme.col.panel_bd;
panel_bg.a *= theme.col.panel_opacity;
// panel_bd.a = 0;
// resizer_color.a = 0;
if (UI_MatchKey(contents_box, vis_ui_box))
b32 is_screen_panel_box = UI_MatchKey(contents_box, vis_screen_panel_box);
if (is_screen_panel_box || panel->is_organizational)
{
panel_bg.a = 0;
// panel_bd.a = 0;
// resizer_color.a = 0;
panel_bd.a = 0;
resizer_color.a = 0;
}
if (panel->is_organizational)
{
@ -3805,12 +3840,12 @@ void V_TickForever(WaveLaneCtx *lane)
}
//- Left null-resizer box
if (!panel->prev)
{
UI_SetNext(AxisSize, resizer_size, .axis = parent_axis);
UI_SetNext(BackgroundColor, resizer_color);
UI_BuildBox();
}
// if (!panel->prev)
// {
// UI_SetNext(AxisSize, resizer_size, .axis = parent_axis);
// UI_SetNext(BackgroundColor, resizer_color);
// UI_BuildBox();
// }
//- Panel contents box
{
@ -3823,6 +3858,7 @@ void V_TickForever(WaveLaneCtx *lane)
UI_SetNext(BorderColor, panel_bd);
UI_SetNext(BorderSize, 2);
// UI_SetNext(Rounding, UI_Rpx(10 * theme.rounding));
UI_SetNext(Flags, UI_BoxFlag_Scissor | (UI_BoxFlag_CaptureMouse * (!is_screen_panel_box && !panel->is_organizational)));
UI_PushDF(Parent, UI_BuildBoxEx(contents_box))
{
}
@ -3832,6 +3868,7 @@ void V_TickForever(WaveLaneCtx *lane)
//- Resizer box
b32 can_resize = panel->next != 0;
if (can_resize)
{
UI_SetNext(AxisSize, resizer_size, .axis = parent_axis);
UI_SetNext(BackgroundColor, resizer_color);
@ -3953,7 +3990,7 @@ void V_TickForever(WaveLaneCtx *lane)
// {
// V_Panel *panel = PushStruct(perm, V_Panel);
// panel->parent = V.root_panel;
// panel->key = vis_ui_box;
// panel->key = vis_screen_box;
// panel->axis = !panel->parent->axis;
// DllQueuePush(panel->parent->first, panel->parent->last, panel);
// ++panel->parent->count;
@ -4014,7 +4051,7 @@ void V_TickForever(WaveLaneCtx *lane)
// //////////////////////////////
// //- Build panels
// UI_PushDF(Parent, vis_game_box)
// UI_PushDF(Parent, vis_root_box)
// // if (show_editor_ui && frame->is_editing)
// {
// Struct(PanelDfsNode) { PanelDfsNode *next; b32 visited; V_Panel *panel; UI_Checkpoint cp; };
@ -4814,7 +4851,7 @@ void V_TickForever(WaveLaneCtx *lane)
// {
// V_Panel *panel = PushStruct(perm, V_Panel);
// panel->parent = V.root_panel;
// panel->key = vis_ui_box;
// panel->key = vis_screen_box;
// panel->axis = !panel->parent->axis;
// DllQueuePush(panel->parent->first, panel->parent->last, panel);
// ++panel->parent->count;
@ -4868,7 +4905,7 @@ void V_TickForever(WaveLaneCtx *lane)
// //////////////////////////////
// //- Build panels
// UI_PushDF(Parent, vis_game_box)
// UI_PushDF(Parent, vis_root_box)
// // if (show_editor_ui && frame->is_editing)
// {
// Struct(PanelDfsNode) { PanelDfsNode *next; b32 visited; V_Panel *panel; UI_Checkpoint cp; };
@ -5614,7 +5651,7 @@ void V_TickForever(WaveLaneCtx *lane)
palette->drag_scissor = UI_Rect(scissor_key);
palette->drag_track = UI_Rect(track_key);
palette->drag_thumb = UI_Rect(thumb_key);
palette->drag_cursor = frame->screen_cursor;
palette->drag_cursor = UI_CursorPos();
palette->drag_scroll = palette->scroll;
}
@ -5623,7 +5660,7 @@ void V_TickForever(WaveLaneCtx *lane)
f32 drag_track_height = palette->drag_track.p1.y - palette->drag_track.p0.y;
f32 drag_thumb_height = palette->drag_thumb.p1.y - palette->drag_thumb.p0.y;
f32 drag_scroll_height = (palette->drag_lister.p1.y - palette->drag_lister.p0.y) - (palette->drag_scissor.p1.y - palette->drag_scissor.p0.y);
f32 delta_ratio = (frame->screen_cursor.y - palette->drag_cursor.y) / (drag_track_height - drag_thumb_height);
f32 delta_ratio = (UI_CursorPos().y - palette->drag_cursor.y) / (drag_track_height - drag_thumb_height);
palette->scroll = palette->drag_scroll + delta_ratio * drag_scroll_height;
palette->target_scroll = palette->scroll;
}
@ -5667,7 +5704,7 @@ void V_TickForever(WaveLaneCtx *lane)
if (UI_Held(titlebar_key, Button_M1))
{
Vec2 drag_offset = SubVec2(ui_frame->drag_cursor_pos, UI_DragAnchor(palette->key));
palette->pos = SubVec2(frame->screen_cursor, drag_offset);
palette->pos = SubVec2(UI_CursorPos(), drag_offset);
}
window_border_color = LerpSrgb(window_border_color, theme.col.button_active, UI_Hot(titlebar_key));
@ -6342,11 +6379,11 @@ void V_TickForever(WaveLaneCtx *lane)
f64 virtual_slider_start = initial_cursor - (initial_slider_width * initial_ratio);
f64 virtual_slider_end = virtual_slider_start + initial_slider_width;
f64 virtual_cursor_ratio = (frame->screen_cursor.x - virtual_slider_start) / (virtual_slider_end - virtual_slider_start);
f64 virtual_cursor_ratio = (frame->ui_cursor.x - virtual_slider_start) / (virtual_slider_end - virtual_slider_start);
tweak_float = LerpF64(range_min, range_max, virtual_cursor_ratio);
tweak_float = ClampF64(tweak_float, range_min, range_max);
if (frame->screen_cursor.x != prev_frame->screen_cursor.x)
if (frame->ui_cursor.x != prev_frame->ui_cursor.x)
{
new_tweak_str = StringFromFloat(frame->arena, tweak_float, tweak_var.precision);
}
@ -7258,7 +7295,7 @@ void V_TickForever(WaveLaneCtx *lane)
// main_color_sampled.g += 0.05;
UI_SetNext(Parent, vis_ui_box);
UI_SetNext(Parent, vis_screen_box);
UI_SetNext(BorderColor, theme.col.window_bd);
UI_SetNext(BorderSize, 2);
UI_SetNext(BackgroundColor, profiler_color);
@ -8402,7 +8439,7 @@ void V_TickForever(WaveLaneCtx *lane)
UI_PushDF(FontSize, UI_Top(FontSize) * 1.5)
// UI_PushDF(TextColor, SrgbFromHsv(32, 1, 1))
UI_PushDF(TextColor, SrgbFromHsv(32, 0.75, 1))
UI_PushDF(Parent, vis_game_overlay_box)
UI_PushDF(Parent, vis_screen_overlay_box)
UI_PushDF(Anchor, UI_Region_Bottom)
UI_PushDF(Flags, UI_BoxFlag_Floating | UI_BoxFlag_DrawText | UI_BoxFlag_DontClampFloatingX | UI_BoxFlag_DontClampFloatingY)
{
@ -8902,7 +8939,7 @@ void V_TickForever(WaveLaneCtx *lane)
cl, gpu_frame_arena,
G_TextureLayout_Family,
G_Format_R16G16B16A16_Float,
G_DimsFromMip2D(G_Count2D(frame->screen), 1),
G_DimsFromMip2D(Vec2I32FromVec(frame->screen_dims), 1),
.flags = G_MemoryFlag_AllowTextureRW,
.name = StringF(frame->arena, "Backdrop target [%F]", FmtSint(frame->tick)),
.max_mips = 4
@ -8914,7 +8951,7 @@ void V_TickForever(WaveLaneCtx *lane)
cl, gpu_frame_arena,
G_TextureLayout_Family,
G_Format_R16G16B16A16_Float,
G_DimsFromMip2D(G_Count2D(frame->screen), 1),
G_DimsFromMip2D(Vec2I32FromVec(frame->screen_dims), 1),
.flags = G_MemoryFlag_AllowTextureRW,
.name = StringF(frame->arena, "Bloom target [%F]", FmtSint(frame->tick)),
.max_mips = G_MaxMips
@ -9172,8 +9209,9 @@ void V_TickForever(WaveLaneCtx *lane)
Rng2 uv = Zi;
uv.p0 = Vec2FromVec(screen_viewport.p0);
uv.p1 = Vec2FromVec(screen_viewport.p1);
uv = DivRng2Vec2(uv, Vec2FromVec(frame->screen_dims));
UI_SetRawTexture(vis_game_box, frame->screen, uv);
uv = DivRng2Vec2(uv, Vec2FromVec(G_Count2D(frame->screen)));
UI_SetRawTexture(vis_screen_box, frame->screen, uv);
}
}

View File

@ -65,6 +65,8 @@ Struct(V_WidgetTheme)
Vec4 panel_bg;
Vec4 panel_bd;
f32 panel_opacity;
f32 panel_border_opacity;
f32 panel_resizer_opacity;
Vec4 button;
Vec4 button_hot;

View File

@ -1011,7 +1011,7 @@ ComputeShader(V_CompositeCS)
Vec4 grid_color = 0;
if (is_in_world)
{
b32 draw_grid = frame.show_console || frame.is_editing;
b32 draw_grid = frame.show_console;
// Grid outline
if (draw_grid)

View File

@ -357,6 +357,7 @@ Struct(V_SharedFrame)
//- Cursor
Vec2 ui_cursor;
Vec2 screen_cursor;
Vec2 shade_cursor;
Vec2 world_cursor;