diff --git a/src/base/base_prof.h b/src/base/base_prof.h index 3b709498..f39bae49 100644 --- a/src/base/base_prof.h +++ b/src/base/base_prof.h @@ -54,7 +54,7 @@ void BeginProfZone(char *name_cstr_lit); void EndProfZone(void); #if PROFILING_ENABLED - #define ProfZoneDF(name_cstr_lit) DeferFor(BeginProfZone(name_cstr_lit"\0"), EndProfZone()) + #define ProfZoneDF(name_cstr_lit) DeferFor(BeginProfZone(name_cstr_lit"\0"), EndProfZone()) #else #define ProfZoneDF(...) #endif diff --git a/src/gpu/gpu_dx12/gpu_dx12_core.h b/src/gpu/gpu_dx12/gpu_dx12_core.h index c75374b3..60402346 100644 --- a/src/gpu/gpu_dx12/gpu_dx12_core.h +++ b/src/gpu/gpu_dx12/gpu_dx12_core.h @@ -660,7 +660,7 @@ extern G_D12_Ctx G_D12; extern ThreadLocal G_D12_ThreadLocalCtx G_D12_tl; //////////////////////////////////////////////////////////// -//~ Pix debug marker API +//~ Pix debug events API #define G_D12_PixApiXList(X) \ X(PIXBeginEventOnCommandList, void, (ID3D12GraphicsCommandList* commandList, UINT64 color, _In_ PCSTR formatString)) \ @@ -671,7 +671,7 @@ extern ThreadLocal G_D12_ThreadLocalCtx G_D12_tl; DeclApiFromXList(G_D12_PixApi, G_D12_PixApiXList, "WinPixEventRuntime.dll"); //////////////////////////////////////////////////////////// -//~ AMD GPU Service debug marker API +//~ AMD GPU Service debug events API #define G_D12_AgsApiXList(X) \ X(agsGetVersionNumber, i32, (void)) \ diff --git a/src/gpu/gpu_shared.cgh b/src/gpu/gpu_shared.cgh index b3cf1b57..ec5992d5 100644 --- a/src/gpu/gpu_shared.cgh +++ b/src/gpu/gpu_shared.cgh @@ -96,8 +96,8 @@ Struct(G_IndexBufferDesc) #if IsGpu // TODO: Add explicit uniform-dereference variations, since on AMD hardware - // non-uniform is slower and there are some shader-compilation issues in older - // driver versions + // non-uniform is slower and there are some related shader-compilation bugs + // in older driver versions template struct G_DerefImpl; template<> struct G_DerefImpl< SamplerState > { static SamplerState Deref(G_SamplerRef r) { return ResourceDescriptorHeap[NonUniformResourceIndex(r.v)]; } }; @@ -112,7 +112,6 @@ Struct(G_IndexBufferDesc) template struct G_DerefImpl< RWTexture2D > { static RWTexture2D Deref(G_TextureRef r, u32 mip=0) { return ResourceDescriptorHeap[NonUniformResourceIndex(r.v + (mip * 2) + 1)]; } }; template struct G_DerefImpl< RWTexture3D > { static RWTexture3D Deref(G_TextureRef r, u32 mip=0) { return ResourceDescriptorHeap[NonUniformResourceIndex(r.v + (mip * 2) + 1)]; } }; - // Wrap since HLSL can't handle template double angle bracket '>>' #define G_Deref(ref, type, ...) (G_DerefImpl< type >::Deref((ref), ##__VA_ARGS__)) #endif @@ -275,7 +274,8 @@ Struct(G_FmtArg) } } - #define G_PrintF_(fmt, ...) do { \ + #define G_PrintF_(fmt, ...) \ + do { \ G_TempPrintBuffer __tmp; \ __tmp.bytes_count = 0; \ __tmp.overflowed = 0; \ diff --git a/src/meta/meta.c b/src/meta/meta.c index f5a5945e..f0bc9626 100644 --- a/src/meta/meta.c +++ b/src/meta/meta.c @@ -547,8 +547,8 @@ void M_BuildEntryPoint(WaveLaneCtx *lane) PushStringToList(perm, &cp.warnings_msvc, Lit("-wd4200")); // nonstandard extension used: zero-sized array in struct/union PushStringToList(perm, &cp.warnings_msvc, Lit("-wd4702")); // unreachable code PushStringToList(perm, &cp.warnings_msvc, Lit("-wd4305")); // 'initializing': truncation from 'double' to 'f32' - PushStringToList(perm, &cp.warnings_msvc, Lit("-wd4152")); // nonstandard extension, function/data pointer conversion in expression + PushStringToList(perm, &cp.warnings_msvc, Lit("-wd4223")); // nonstandard extension, function/data pointer conversion in expression // PushStringToList(perm, &cp.warnings_msvc, Lit("-wd4127")); // conditional expression is constant // PushStringToList(perm, &cp.warnings_msvc, Lit("-wd4820")); // bytes padding added after data member diff --git a/src/pp/pp_vis/pp_vis_core.c b/src/pp/pp_vis/pp_vis_core.c index 6d3e69a8..45cc0b8a 100644 --- a/src/pp/pp_vis/pp_vis_core.c +++ b/src/pp/pp_vis/pp_vis_core.c @@ -627,6 +627,10 @@ V_WidgetTheme V_GetWidgetTheme(void) theme.col.window_bg = Rgb32(0xff1a1d1e); theme.col.window_bd = Rgb32(0xff343a3b); + 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.divider = LerpSrgb(Color_Black, theme.col.window_bd, 0.6); theme.col.button = theme.col.window_bg; @@ -1071,11 +1075,21 @@ void V_TickForever(WaveLaneCtx *lane) 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_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_SetNext(Flags, UI_BoxFlag_Floating); + UI_SetNext(Parent, vis_game_box); + UI_BuildColumnEx(vis_game_overlay_box); + + UI_SetNext(Flags, UI_BoxFlag_Floating); + UI_SetNext(Parent, vis_game_box); + UI_BuildBoxEx(vis_panels_box); + // NOTE: Vis ui box is built by panel tree UI_Push(Parent, vis_ui_box); } @@ -2597,7 +2611,7 @@ void V_TickForever(WaveLaneCtx *lane) frame->shade_cursor = MulAffineVec2(frame->af.screen_to_shade, frame->screen_cursor); frame->world_cursor = MulAffineVec2(frame->af.screen_to_world, frame->screen_cursor); - b32 hide_editor_ui = TweakBool("Hide editor UI", 1); + b32 hide_editor_ui = TweakBool("Hide editor UI", 0); frame->world_selection_start = frame->world_cursor; if (frame->is_editing) @@ -3539,779 +3553,329 @@ void V_TickForever(WaveLaneCtx *lane) P_tl.debug_draw_nodes_count = 0; } - ////////////////////////////// - //- Init test layout - // TODO: Remove this - if (!V.root_panel) - { - { - V_Panel *panel = PushStruct(perm, V_Panel); - panel->key = UI_RandKey(); // TODO: Don't use random keys for panels - panel->axis = Axis_X; - panel->pref_ratio = 1; - panel->is_organizing_panel = 1; - V.root_panel = panel; - ++V.panels_count; - } - { - V_Panel *panel = PushStruct(perm, V_Panel); - panel->parent = V.root_panel; - panel->key = UI_RandKey(); // TODO: Don't use random keys - panel->axis = !panel->parent->axis; - panel->pref_ratio = 0.15; - panel->is_editor_panel = 1; - DllQueuePush(panel->parent->first, panel->parent->last, panel); - ++panel->parent->count; - ++V.panels_count; - { - V_Window *window = PushStruct(perm, V_Window); - window->panel = panel; - window->key = UI_RandKey(); // TODO: Don't use random keys - // 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); - window->panel = panel; - window->key = UI_RandKey(); // TODO: Don't use random keys - 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); - window->panel = panel; - window->key = UI_RandKey(); // TODO: Don't use random keys - window->is_prefab_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 = 2; - } - { - V_Panel *panel = PushStruct(perm, V_Panel); - panel->parent = V.root_panel; - panel->key = vis_ui_box; - panel->axis = !panel->parent->axis; - DllQueuePush(panel->parent->first, panel->parent->last, panel); - ++panel->parent->count; - ++V.panels_count; - panel->pref_ratio = 0.85; - panel->is_vis_ui_panel = 1; - // { - // V_Window *window = PushStruct(perm, V_Window); - // window->panel = panel; - // window->key = UI_RandKey(); // TODO: Don't use random keys - // 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; - // } - } - // { - // V_Panel *panel = PushStruct(perm, V_Panel); - // panel->parent = V.root_panel; - // panel->key = UI_RandKey(); // TODO: Don't use random keys - // 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); - // window->panel = panel; - // window->key = UI_RandKey(); // TODO: Don't use random keys - // // 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); - // window->panel = panel; - // window->key = UI_RandKey(); // TODO: Don't use random keys - // 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; - // } - } + + ////////////////////////////// //- Build panels - UI_PushDF(Parent, vis_game_box) - // if (show_editor_ui && frame->is_editing) - { - Struct(PanelDfsNode) { PanelDfsNode *next; b32 visited; V_Panel *panel; UI_Checkpoint cp; }; - PanelDfsNode *first_panel_dfs = PushStruct(frame->arena, PanelDfsNode); - first_panel_dfs->panel = V.root_panel; - f32 divider_size = 10; - i64 prune_windows_count = 0; - V_Window **prune_windows = PushStructsNoZero(frame->arena, V_Window *, V.windows_count); + + // FIXME: Remove this + + + UI_PushDF(Tag, HashF("vis panels")) + { + Struct(V_Panel) + { + V_Panel *parent; + V_Panel *next; + V_Panel *prev; + V_Panel *first; + V_Panel *last; + + Axis axis; + + UI_Key box; + UI_Key contents_box; + UI_Key resizer_box; + + f32 pct; + + f32 drag_resize_pct; + f32 drag_resize_pct_per_px; + + b32 is_organizational; + }; + + + + PERSIST V_Panel *root_panel = 0; ////////////////////////////// - //- Walk panel tree - - - - - - - - + //- Init test panels // FIXME: Remove this - #define V_ShouldSkipPanel(panel) (panel->is_editor_panel && (hide_editor_ui || !frame->is_editing)) - - - - - - - while (first_panel_dfs) + if (!root_panel) { - PanelDfsNode *panel_dfs = first_panel_dfs; - V_Panel *panel = panel_dfs->panel; - if (!panel_dfs->visited) + V_Panel *subroot_row_panel = 0; + + //- Root panel column { - panel_dfs->visited = 1; - - f32 panel_size = 0; - if (panel->axis == Axis_X) { - panel_size = DimsFromRng2(UI_Rect(panel->key)).x; - } - else - { - panel_size = DimsFromRng2(UI_Rect(panel->key)).y; + V_Panel *panel = PushStruct(perm, V_Panel); + panel->box = UI_KeyF("test root panel"); + panel->contents_box = vis_panels_box; + panel->resizer_box = UI_KeyF("panel resizer box %F", FmtUint(panel->box.v)); + panel->pct = 1; + panel->axis = Axis_Y; + root_panel = panel; } - // Push children to dfs stack - V_Panel *resize_panel = 0; - for (V_Panel *child = panel->last; child; child = child->prev) + //- Sub-root panel row { - if (!V_ShouldSkipPanel(child)) - { - PanelDfsNode *n = PushStruct(frame->arena, PanelDfsNode); - n->panel = child; - SllStackPush(first_panel_dfs, n); - if (child->resizing) - { - resize_panel = child; - } - } - } - - // Apply resize - if (resize_panel) - { - Vec2 drag_pos = UI_DragCursorPos(); - Vec2 drag_anchor = UI_DragAnchor(resize_panel->divider_key); - f32 drag_offset = drag_pos.v[panel->axis] - drag_anchor.v[panel->axis]; - - f32 child_pref_size = 0; - child_pref_size += frame->screen_cursor.v[panel->axis]; - child_pref_size -= drag_anchor.v[panel->axis]; - // child_pref_size -= divider_rep.last_cursor_down_anchor_offset.v[panel->axis]; - child_pref_size -= drag_offset; - - f32 ratio_diff = (child_pref_size / panel_size) - resize_panel->pref_ratio; - f32 min_ratio = 0.05; - { - ratio_diff += MaxF32(min_ratio - (resize_panel->pref_ratio + ratio_diff), 0); - ratio_diff -= MaxF32(min_ratio - (resize_panel->next->pref_ratio - ratio_diff), 0); - } - - resize_panel->next->pref_ratio -= ratio_diff; - resize_panel->pref_ratio += ratio_diff; - resize_panel->resizing = 0; - } - - // Constrain child raitos - f32 ratio_accum = 0; - if (panel_size != 0) - { - ratio_accum += (MaxF32(panel->count - 1, 0) * divider_size) / panel_size; - } - for (V_Panel *child = panel->last; child; child = child->prev) - { - if (!V_ShouldSkipPanel(child)) - { - child->pref_ratio = MaxF32(child->pref_ratio, 0.01); - ratio_accum += child->pref_ratio; - } - } - for (V_Panel *child = panel->last; child; child = child->prev) - { - if (!V_ShouldSkipPanel(child)) - { - child->pref_ratio += (1.0 - ratio_accum) / panel->count; - } - } - - UI_SetNext(AxisSize, UI_Grow(panel->pref_ratio, 0), .axis = !panel->axis); - UI_SetNext(AxisSize, UI_Grow(1, 0), .axis = panel->axis); - if (panel->axis == Axis_X) - { - UI_BuildRowEx(panel->key); - } - else - { - UI_BuildColumnEx(panel->key); - } - UI_Push(Tag, panel->key.v); - panel_dfs->cp = UI_PushCp(panel->key); - - if (!panel->is_organizing_panel && !panel->is_vis_ui_panel) - { - i64 new_active_window_idx = panel->active_window_idx; - UI_PushCp(UI_BuildColumn()); - { - UI_Push(Tint, VEC4(1, 1, 1, 0.90 * UI_Exists(panel->key))); - - i64 active_window_idx = ClampI64(panel->active_window_idx, 0, MaxI64(panel->windows_count - 1, 0)); - - ////////////////////////////// - //- Build tab row - - f32 tab_spacing = UI_Fnt(0.25, 0).v; - V_Window *active_window = 0; - V_Window *close_window = 0; - { - UI_Key tab_row_key = UI_KeyF("tab row"); - - UI_SetNext(Width, UI_Grow(1, 0)); - UI_SetNext(Height, UI_Shrink(0, 1)); - UI_SetNext(Flags, UI_BoxFlag_CaptureMouse); - 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) - { - 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; - } - - // Insert ghost tab - if (V.dragging_window && UI_HotAbsolute(panel->key)) - { - DrawableTab *left = 0; - DrawableTab *right = first_drawable_tab; - for (DrawableTab *sibling = first_drawable_tab; sibling; sibling = sibling->next) - { - f32 zone = CenterFromRng2(UI_Rect(sibling->key)).x; - if (frame->screen_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.v); - if (tab == first_drawable_tab) - { - UI_BuildSpacer(UI_Px(tab_spacing, 0), Axis_X); - } - - switch (tab->kind) - { - ////////////////////////////// - //- Build window tab - - case DrawableTabKind_Window: - { - V_Window *window = tab->window; - { - if (UI_Downs(tab->key, Button_M1) > 0) - { - new_active_window_idx = tab->window_idx; - } - - if (V.dragging_window == 0) - { - f32 drag_threshold = 20; - if (UI_Held(tab->key, Button_M1)) - { - Vec2 drag_start = ui_frame->drag_cursor_pos; - if (Vec2Len(SubVec2(frame->screen_cursor, drag_start)) > drag_threshold) - { - V.dragging_window = window; - } - } - } - - b32 is_dragging = window == V.dragging_window; - if (is_dragging && UI_Ups(tab->key, Button_M1) > 0) - { - V.dragging_window = 0; - } - - Vec4 bg_color = theme.col.window_bg; - Vec4 border_color = theme.col.window_bd; - if (tab->window_idx == active_window_idx) - { - active_window = window; - border_color = theme.col.button_active; - } - - bg_color = LerpSrgb(bg_color, theme.col.button_hot, UI_Hot(tab->key)); - bg_color = LerpSrgb(bg_color, theme.col.button_active, UI_Active(tab->key) * is_dragging); - border_color = LerpSrgb(border_color, theme.col.button_active, UI_Misc(tab->key)); - - String tab_name = Zi; - if (window->is_tile_window) - { - tab_name = Lit("Tiles"); - } - else if (window->is_prefab_window) - { - tab_name = Lit("Prefabs"); - } - else - { - tab_name = Lit("Unknown"); - } - - UI_SetNext(BackgroundColor, bg_color); - UI_SetNext(BorderColor, border_color); - UI_SetNext(BorderSize, 1); - UI_SetNext(Width, UI_Shrink(0, 1)); - UI_SetNext(Height, UI_Shrink(0, 0)); - UI_SetNext(ChildAlignment, UI_Region_Left); - UI_SetNext(Misc, window == active_window); - UI_SetNext(Flags, UI_BoxFlag_CaptureMouse); - UI_PushCp(UI_BuildRowEx(tab->key)); - { - UI_BuildSpacer(UI_Px(tab_spacing, 0), Axis_X); - - // Build tab title - { - UI_SetNext(ChildAlignment, UI_Region_Center); - UI_SetNext(Flags, UI_BoxFlag_DrawText); - UI_SetNext(Text, tab_name); - UI_SetNext(Width, UI_Shrink(0, 0)); - UI_SetNext(Height, UI_Shrink(2, 0)); - UI_BuildRow(); - } - - UI_BuildSpacer(UI_Px(tab_spacing, 0), Axis_X); - - // Build tab close button - { - UI_Key close_key = UI_KeyF("close"); - - Vec4 close_color = Zi; - close_color = LerpSrgb(close_color, theme.col.button_hot, UI_Hot(close_key)); - close_color = LerpSrgb(close_color, theme.col.button_active, UI_Active(close_key)); - Vec4 close_border_color = LerpSrgb(VEC4(0, 0, 0, 0), theme.col.button_active, UI_Hot(close_key)); - - UI_SetNext(BackgroundColor, close_color); - UI_SetNext(BorderColor, close_border_color); - UI_SetNext(BorderSize, 2); - UI_SetNext(ChildAlignment, UI_Region_Center); - UI_SetNext(Flags, UI_BoxFlag_CaptureMouse); - UI_SetNext(Width, UI_Shrink(0, 0)); - UI_SetNext(Height, UI_Grow(1, 0)); - UI_PushCp(UI_BuildRowEx(close_key)); - { - UI_BuildSpacer(UI_Px(tab_spacing * 2, 0), Axis_X); - - UI_SetNext(Width, UI_Shrink(0, 1)); - UI_SetNext(Height, UI_Shrink(0, 1)); - UI_SetNext(FontSize, UI_Top(FontSize) * theme.micro); - UI_BuildIcon(theme.icon_font, UI_Icon_Cross); - - UI_BuildSpacer(UI_Px(tab_spacing * 2, 0), Axis_X); - } - UI_PopCp(UI_TopCp()); - - if (UI_Presses(close_key, Button_M1)) - { - prune_windows[prune_windows_count] = window; - prune_windows_count += 1; - } - } - } - UI_PopCp(UI_TopCp()); - } - UI_Pop(Tag); - } break; - - ////////////////////////////// - //- Build ghost tab - - case DrawableTabKind_Ghost: - { - Vec4 bg_color = Zi; - bg_color = LerpSrgb(bg_color, theme.col.button_hot, UI_Exists(tab->key)); - bg_color.w *= 0.5; - Vec4 border_color = LerpSrgb(VEC4(0, 0, 0, 0), theme.col.button_active, UI_Exists(tab->key)); - - // UI_SetNext(Anchor, UI_Region_Center); - UI_SetNext(Anchor, UI_Region_TopRight); - - UI_SetNext(Scale, VEC2(UI_Exists(tab->key), 1)); - UI_SetNext(BackgroundColor, bg_color); - UI_SetNext(BorderColor, border_color); - UI_SetNext(BorderSize, 2); - // UI_SetNext(Width, UI_Px(30, 0)); - UI_SetNext(Width, UI_Px(100, 0)); - UI_SetNext(Height, UI_Grow(1, 0)); - UI_SetNext(ChildAlignment, UI_Region_Center); - // UI_SetNext(FontSize, theme.font_size * 1.5); - UI_PushCp(UI_BuildRowEx(tab->key)); - { - } - UI_PopCp(UI_TopCp()); - } break; - - ////////////////////////////// - //- Build new tab button - - case DrawableTabKind_NewTab: - { - UI_Key key = UI_KeyF("new tab"); - - Vec4 bg_color = Zi; - bg_color = LerpSrgb(bg_color, theme.col.button_hot, UI_Hot(key)); - bg_color = LerpSrgb(bg_color, theme.col.button_active, UI_Active(key)); - bg_color.w *= 0.5; - Vec4 border_color = LerpSrgb(VEC4(0, 0, 0, 0), theme.col.button_active, UI_Hot(key)); - - UI_SetNext(BackgroundColor, bg_color); - UI_SetNext(BorderColor, border_color); - UI_SetNext(BorderSize, 2); - UI_SetNext(Width, UI_Shrink(10, 0)); - UI_SetNext(Height, UI_Grow(1, 0)); - UI_SetNext(ChildAlignment, UI_Region_Center); - // UI_SetNext(FontSize, theme.font_size * 1.5); - UI_SetNext(Flags, UI_BoxFlag_CaptureMouse); - UI_PushCp(UI_BuildRowEx(key)); - { - UI_SetNext(Width, UI_Shrink(0, 1)); - UI_SetNext(Height, UI_Shrink(0, 1)); - UI_SetNext(FontSize, UI_Top(FontSize) * theme.micro); - UI_BuildIcon(theme.icon_font, UI_Icon_Plus); - } - UI_PopCp(UI_TopCp()); - } - } - UI_BuildSpacer(UI_Px(tab_spacing, 0), Axis_X); - } - UI_PopCp(UI_TopCp()); - } - - ////////////////////////////// - //- Build active window - - if (active_window) - { - Vec4 window_bg_color = theme.col.window_bg; - Vec4 window_border_color = theme.col.window_bd; - - V_Window *window = active_window; - UI_SetNext(BackgroundColor, window_bg_color); - UI_SetNext(BorderColor, window_border_color); - UI_SetNext(BorderSize, 1); - UI_SetNext(Width, UI_Grow(1, 0)); - UI_SetNext(Height, UI_Grow(1, 0)); - UI_SetNext(Flags, UI_BoxFlag_CaptureMouse); - UI_PushCp(UI_BuildColumn()); - { - UI_Push(Tag, window->key.v); - - ////////////////////////////// - //- Build tile window - - if (window->is_tile_window) - { - for (P_TileKind tile_kind = 0; tile_kind < P_TileKind_COUNT; ++tile_kind) - { - String tile_name = P_NameFromTileKind(tile_kind); - UI_Key key = UI_KeyF("Tile %F", FmtString(tile_name)); - - if (UI_Downs(key, Button_M1)) - { - frame->edit_mode = V_EditMode_Tile; - frame->equipped_tile = tile_kind; - } - - Vec4 bg_color = Zi; - bg_color = LerpSrgb(bg_color, theme.col.button_hot, UI_Hot(key)); - bg_color = LerpSrgb(bg_color, theme.col.button_active, UI_Active(key)); - - b32 is_selected = ( - frame->edit_mode == V_EditMode_Tile && - tile_kind == frame->equipped_tile - ); - - Vec4 border_color = Zi; - border_color = LerpSrgb(border_color, theme.col.button_selected, UI_Misc(key)); - border_color = LerpSrgb(border_color, theme.col.button_active, UI_Hot(key)); - - UI_SetNext(BackgroundColor, bg_color); - UI_SetNext(BorderColor, border_color); - UI_SetNext(BorderSize, 1); - UI_SetNext(Width, UI_Grow(1, 0)); - UI_SetNext(Height, UI_Shrink(UI_Fnt(0.25, 0).v, 0)); - UI_SetNext(Misc, is_selected); - UI_SetNext(Flags, UI_BoxFlag_CaptureMouse); - UI_SetNext(ChildAlignment, UI_Region_Left); - UI_PushCp(UI_BuildRowEx(key)); - { - UI_BuildSpacer(UI_Fnt(0.25, 0), Axis_X); - - // Tile sprite - { - String sheet_name = StringF(frame->arena, "tile/%F.ase", FmtString(tile_name)); - ResourceKey sheet_resource = ResourceKeyFromStore(&P_Resources, sheet_name); - SPR_SheetKey sheet = SPR_SheetKeyFromResource(sheet_resource); - - UI_SetNext(ChildAlignment, UI_Region_Center); - UI_SetNext(Width, UI_Fnt(2.5, 0)); - UI_SetNext(Height, UI_Fnt(2.5, 0)); - UI_SetNext(SpriteSheet, sheet); - UI_BuildRow(); - } - - UI_BuildSpacer(UI_Fnt(0.5, 0), Axis_X); - - // Tile name - { - UI_SetNext(ChildAlignment, UI_Region_Center); - UI_SetNext(Text, tile_name); - UI_SetNext(Flags, UI_BoxFlag_DrawText); - UI_SetNext(Width, UI_Shrink(4, 0)); - UI_SetNext(Height, UI_Shrink(2, 0)); - UI_BuildRow(); - } - } - UI_PopCp(UI_TopCp()); - } - } - - ////////////////////////////// - //- Build prefab window - - if (window->is_prefab_window) - { - for (P_PrefabKind prefab_kind = 0; prefab_kind < P_PrefabKind_COUNT; ++prefab_kind) - { - String prefab_name = P_NameFromPrefabKind(prefab_kind); - P_PrefabFlag prefab_flags = P_FlagsFromPrefabKind(prefab_kind); - if (!AnyBit(prefab_flags, P_PrefabFlag_HideFromEditor)) - { - UI_Key key = UI_KeyF("Prefab %F", FmtString(prefab_name)); - - if (UI_Downs(key, Button_M1)) - { - frame->edit_mode = V_EditMode_Prefab; - frame->equipped_prefab = prefab_kind; - } - - Vec4 bg_color = Zi; - bg_color = LerpSrgb(bg_color, theme.col.button_hot, UI_Hot(key)); - bg_color = LerpSrgb(bg_color, theme.col.button_active, UI_Active(key)); - - b32 is_selected = ( - frame->edit_mode == V_EditMode_Prefab && - prefab_kind == frame->equipped_prefab - ); - - Vec4 border_color = Zi; - border_color = LerpSrgb(border_color, theme.col.button_selected, UI_Misc(key)); - border_color = LerpSrgb(border_color, theme.col.button_active, UI_Hot(key)); - - UI_SetNext(BackgroundColor, bg_color); - UI_SetNext(BorderColor, border_color); - UI_SetNext(BorderSize, 1); - UI_SetNext(Width, UI_Grow(1, 0)); - UI_SetNext(Height, UI_Shrink(UI_Fnt(0.25, 0).v, 0)); - UI_SetNext(Misc, is_selected); - UI_SetNext(Flags, UI_BoxFlag_CaptureMouse); - UI_SetNext(ChildAlignment, UI_Region_Left); - UI_PushCp(UI_BuildRowEx(key)); - { - UI_BuildSpacer(UI_Fnt(0.25, 0), Axis_X); - - // Prefab sprite - { - String sheet_name = StringF(frame->arena, "prefab/%F.ase", FmtString(prefab_name)); - ResourceKey sheet_resource = ResourceKeyFromStore(&P_Resources, sheet_name); - SPR_SheetKey sheet = SPR_SheetKeyFromResource(sheet_resource); - - UI_SetNext(ChildAlignment, UI_Region_Center); - UI_SetNext(Width, UI_Fnt(2.5, 0)); - UI_SetNext(Height, UI_Fnt(2.5, 0)); - UI_SetNext(SpriteSheet, sheet); - UI_BuildRow(); - } - - UI_BuildSpacer(UI_Fnt(0.5, 0), Axis_X); - - // Prefab name - { - UI_SetNext(ChildAlignment, UI_Region_Center); - UI_SetNext(Text, prefab_name); - UI_SetNext(Flags, UI_BoxFlag_DrawText); - UI_SetNext(Width, UI_Shrink(4, 0)); - UI_SetNext(Height, UI_Shrink(2, 0)); - UI_BuildRow(); - } - } - UI_PopCp(UI_TopCp()); - } - } - } - } - UI_PopCp(UI_TopCp()); - } - } - UI_PopCp(UI_TopCp()); - panel->active_window_idx = new_active_window_idx; + V_Panel *parent = root_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 raah subroot row 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 = 1; + panel->is_organizational = 1; + subroot_row_panel = panel; } } - else + + //- Vis ui panel { - UI_PopCp(panel_dfs->cp); - SllStackPop(first_panel_dfs); + 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; + } - ////////////////////////////// - //- Build panel divider - - if (panel->next != 0) - { - panel->divider_key = UI_KeyF("Divider"); - - Vec4 active_color = theme.col.button_active; - Vec4 hot_color = LerpSrgb(theme.col.button_hot, theme.col.button_active, 0.25); - - Vec4 bg_color = Zi; - bg_color = LerpSrgb(bg_color, hot_color, UI_Hot(panel->divider_key)); - bg_color = LerpSrgb(bg_color, active_color, UI_Active(panel->divider_key)); - - Vec4 border_color = Zi; - f32 visible_size = 2.0; - - UI_SetNext(BackgroundColor, bg_color); - UI_SetNext(BorderColor, border_color); - UI_SetNext(BorderSize, MaxF32((divider_size / 2.0) - (visible_size / 2.0), 0)); - UI_SetNext(Flags, UI_BoxFlag_CaptureMouse); - UI_SetNext(AxisSize, UI_Grow(1, 1), .axis = panel->axis); - UI_SetNext(AxisSize, UI_Px(divider_size, 1), .axis = !panel->axis); - UI_BuildBoxEx(panel->divider_key); - - if (UI_HotAbsolute(panel->divider_key) || UI_Held(panel->divider_key, Button_M1)) - { - if (panel->axis == Axis_X) - { - WND_SetCursor(window_frame, WND_CursorKind_VerticalResize); - } - else - { - WND_SetCursor(window_frame, WND_CursorKind_HorizontalResize); - } - } - - if (UI_Held(panel->divider_key, Button_M1)) - { - panel->resizing = 1; - } - } - - UI_Pop(Tag); + //- Test 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 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; } } - ////////////////////////////// - //- Prune windows - for (i64 prune_window_idx = 0; prune_window_idx < prune_windows_count; ++prune_window_idx) + + + // // FIXME: Remove this (build it as a panel) + // BuildBoxEx(vis_ui_box); + + + + + + + + + // UI_PushDF(Parent, vis_game_box) { - V_Window *window = prune_windows[prune_window_idx]; - V_Panel *panel = window->panel; + Struct(PanelBfs) { PanelBfs *next; V_Panel *panel; }; + PanelBfs *first_panel_bfs = 0; + PanelBfs *last_panel_bfs = 0; - if (window == V.dragging_window) { - V.dragging_window = 0; + PanelBfs *root_bfs = PushStruct(frame->arena, PanelBfs); + root_bfs->panel = root_panel; + SllQueuePush(first_panel_bfs, last_panel_bfs, root_bfs); } - // TODO: Add window to freelist - // TODO: Remove panel if windowless - DllQueueRemoveNP(panel->first_window, panel->last_window, window, next_in_panel, prev_in_panel); - panel->windows_count -= 1; + for (PanelBfs *bfs_parent = first_panel_bfs; bfs_parent; bfs_parent = first_panel_bfs) + { + SllQueuePop(first_panel_bfs, last_panel_bfs); + V_Panel *parent_panel = bfs_parent->panel; + UI_Key parent_contents_box = parent_panel->contents_box; + + 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]; + + 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 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; + // } + + // } + + //- Build panel boxes + for (V_Panel *panel = parent_panel->first; panel; panel = panel->next) + { + PanelBfs *bfs_panel = PushStruct(frame->arena, PanelBfs); + bfs_panel->panel = panel; + SllQueuePush(first_panel_bfs, last_panel_bfs, bfs_panel); + + UI_Key panel_box = panel->box; + 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; + + f32 minimum_panel_px = 100; + f32 minimum_panel_pct = minimum_panel_px / parent_contents_size_px; + + if (UI_Downs(resizer_box, Button_M1)) + { + // FIXME: Don't need to store this state per-panel + panel->drag_resize_pct = panel->pct; + panel->drag_resize_pct_per_px = 1.0 / parent_contents_size_px; + } + if (UI_Held(resizer_box, Button_M1)) + { + f32 drag_delta_px = UI_CursorPos().v[parent_axis] - UI_DragCursorPos().v[parent_axis]; + f32 drag_delta_pct = drag_delta_px * panel->drag_resize_pct_per_px; + + f32 old_pct = panel->pct; + f32 new_pct = MaxF32(panel->drag_resize_pct + drag_delta_pct, minimum_panel_pct); + f32 new_sibling_pct = 0; + if (panel->next) + { + f32 old_sibling_pct = panel->next->pct; + f32 desired_new_sibling_pct = panel->next->pct - (new_pct - old_pct); + new_sibling_pct = MaxF32(desired_new_sibling_pct, minimum_panel_pct); + new_pct -= (new_sibling_pct - desired_new_sibling_pct); + } + + if (panel->next) + { + panel->next->pct = new_sibling_pct; + } + panel->pct = new_pct; + } + if (UI_HotAbsolute(resizer_box)) + { + if (parent_axis == Axis_X) + { + WND_SetCursor(window_frame, WND_CursorKind_HorizontalResize); + } + else + { + WND_SetCursor(window_frame, WND_CursorKind_VerticalResize); + } + } + + f32 panel_pct = panel->pct; + + UI_SetNext(AxisSize, UI_Grow(panel_pct, 1), .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; + + if (UI_MatchKey(contents_box, vis_ui_box)) + { + panel_bg.a = 0; + // panel_bd.a = 0; + // resizer_color.a = 0; + } + if (panel->is_organizational) + { + panel_bg.a = 0; + } + + //- Left null-resizer box + if (!panel->prev) + { + UI_SetNext(AxisSize, resizer_size, .axis = parent_axis); + UI_SetNext(BackgroundColor, resizer_color); + UI_BuildBox(); + } + + //- Panel contents box + { + // UI_SetNext(AxisSize, UI_Grow(panel_pct, 1), .axis = parent_axis); + // UI_SetNext(AxisSize, UI_Grow(1, 0), .axis = !parent_axis); + UI_SetNext(ChildLayoutAxis, panel->axis); + // UI_SetNext(Width, UI_Px(500, 1)); + // UI_SetNext(Height, UI_Px(200, 1)); + UI_SetNext(BackgroundColor, panel_bg); + UI_SetNext(BorderColor, panel_bd); + UI_SetNext(BorderSize, 2); + // UI_SetNext(Rounding, UI_Rpx(10 * theme.rounding)); + UI_PushDF(Parent, UI_BuildBoxEx(contents_box)) + { + } + } + + + + //- Resizer box + b32 can_resize = panel->next != 0; + { + UI_SetNext(AxisSize, resizer_size, .axis = parent_axis); + UI_SetNext(BackgroundColor, resizer_color); + UI_SetNext(Flags, UI_BoxFlag_CaptureMouse * !!can_resize); + UI_BuildBoxEx(resizer_box); + } + + + // //- Overlay box + // { + // // UI_SetNext(AxisSize, resizer_size, .axis = parent_axis); + // // UI_SetNext(AxisSize, UI_Px(100, 1), .axis = parent_axis); + // // UI_SetNext(AxisSize, UI_Px(100, 1), .axis = !parent_axis); + // // UI_SetNext(AxisSize, UI_Grow(1, 1), .axis = !parent_axis); + // // UI_SetNext(AxisSize, UI_Grow(1, 1), .axis = !parent_axis); + // // UI_SetNext(BackgroundColor, Color_Cyan); + // // UI_SetNext(Anchor, UI_Region_Center); + // UI_SetNext(ChildLayoutAxis, parent_axis); + // UI_SetNext(Flags, UI_BoxFlag_Floating); + // UI_SetNext(Parent, contents_box); + // // FIXME: Don't use contents box + // UI_PushDF(Parent, UI_BuildBoxEx(UI_KeyF("overlay box"))) + // { + // UI_SetNext(AxisSize, UI_Grow(1, 0), .axis = parent_axis); + // UI_BuildBox(); + + // //- Resizer box + // if (panel->next) + // { + // UI_SetNext(AxisSize, resizer_size, .axis = parent_axis); + // // UI_SetNext(AxisSize, UI_Px(100, 1), .axis = parent_axis); + // // UI_SetNext(AxisSize, UI_Px(100, 1), .axis = !parent_axis); + // // UI_SetNext(AxisSize, UI_Grow(1, 1), .axis = !parent_axis); + // // UI_SetNext(BackgroundColor, theme.col.divider); + // UI_SetNext(Anchor, UI_Region_Center); + // UI_SetNext(Flags, UI_BoxFlag_CaptureMouse); + // UI_BuildBoxEx(resizer_box); + // } + // } + // } + } + } + } + } } } @@ -4328,6 +3892,1656 @@ void V_TickForever(WaveLaneCtx *lane) + // ////////////////////////////// + // //- Init test layout + + // // TODO: Remove this + + // if (!V.root_panel) + // { + // { + // V_Panel *panel = PushStruct(perm, V_Panel); + // panel->key = UI_RandKey(); // TODO: Don't use random keys for panels + // panel->axis = Axis_X; + // panel->pref_ratio = 1; + // panel->is_organizing_panel = 1; + // V.root_panel = panel; + // ++V.panels_count; + // } + + // { + // V_Panel *panel = PushStruct(perm, V_Panel); + // panel->parent = V.root_panel; + // panel->key = UI_RandKey(); // TODO: Don't use random keys + // panel->axis = !panel->parent->axis; + // panel->pref_ratio = 0.15; + // panel->is_editor_panel = 1; + // DllQueuePush(panel->parent->first, panel->parent->last, panel); + // ++panel->parent->count; + // ++V.panels_count; + + // { + // V_Window *window = PushStruct(perm, V_Window); + // window->panel = panel; + // window->key = UI_RandKey(); // TODO: Don't use random keys + // // 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); + // window->panel = panel; + // window->key = UI_RandKey(); // TODO: Don't use random keys + // 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); + // window->panel = panel; + // window->key = UI_RandKey(); // TODO: Don't use random keys + // window->is_prefab_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 = 2; + // } + + // { + // V_Panel *panel = PushStruct(perm, V_Panel); + // panel->parent = V.root_panel; + // panel->key = vis_ui_box; + // panel->axis = !panel->parent->axis; + // DllQueuePush(panel->parent->first, panel->parent->last, panel); + // ++panel->parent->count; + // ++V.panels_count; + + // panel->pref_ratio = 0.85; + // panel->is_vis_ui_panel = 1; + + // // { + // // V_Window *window = PushStruct(perm, V_Window); + // // window->panel = panel; + // // window->key = UI_RandKey(); // TODO: Don't use random keys + // // 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; + // // } + // } + + // // { + // // V_Panel *panel = PushStruct(perm, V_Panel); + // // panel->parent = V.root_panel; + // // panel->key = UI_RandKey(); // TODO: Don't use random keys + // // 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); + // // window->panel = panel; + // // window->key = UI_RandKey(); // TODO: Don't use random keys + // // // 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); + // // window->panel = panel; + // // window->key = UI_RandKey(); // TODO: Don't use random keys + // // 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; + // // } + // } + + + + + + + + + // ////////////////////////////// + // //- Build panels + + // UI_PushDF(Parent, vis_game_box) + // // if (show_editor_ui && frame->is_editing) + // { + // Struct(PanelDfsNode) { PanelDfsNode *next; b32 visited; V_Panel *panel; UI_Checkpoint cp; }; + // PanelDfsNode *first_panel_dfs = PushStruct(frame->arena, PanelDfsNode); + // first_panel_dfs->panel = V.root_panel; + // f32 divider_size = 10; + + // 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; + // V_Panel *panel = panel_dfs->panel; + // if (!panel_dfs->visited) + // { + // panel_dfs->visited = 1; + + // f32 panel_size = 0; + // if (panel->axis == Axis_X) + // { + // panel_size = DimsFromRng2(UI_Rect(panel->key)).x; + // } + // else + // { + // panel_size = DimsFromRng2(UI_Rect(panel->key)).y; + // } + + // // Push children to dfs stack + // V_Panel *resize_panel = 0; + // for (V_Panel *child = panel->last; child; child = child->prev) + // { + // if (!V_ShouldSkipPanel(child)) + // { + // PanelDfsNode *n = PushStruct(frame->arena, PanelDfsNode); + // n->panel = child; + // SllStackPush(first_panel_dfs, n); + // if (child->resizing) + // { + // resize_panel = child; + // } + // } + // } + + // // Apply resize + // if (resize_panel) + // { + // Vec2 drag_pos = UI_DragCursorPos(); + // Vec2 drag_anchor = UI_DragAnchor(resize_panel->divider_key); + // f32 drag_offset = drag_pos.v[panel->axis] - drag_anchor.v[panel->axis]; + + // f32 child_pref_size = 0; + // child_pref_size += frame->screen_cursor.v[panel->axis]; + // child_pref_size -= drag_anchor.v[panel->axis]; + // // child_pref_size -= divider_rep.last_cursor_down_anchor_offset.v[panel->axis]; + // child_pref_size -= drag_offset; + + // f32 ratio_diff = (child_pref_size / panel_size) - resize_panel->pref_ratio; + // f32 min_ratio = 0.05; + // { + // ratio_diff += MaxF32(min_ratio - (resize_panel->pref_ratio + ratio_diff), 0); + // ratio_diff -= MaxF32(min_ratio - (resize_panel->next->pref_ratio - ratio_diff), 0); + // } + + // resize_panel->next->pref_ratio -= ratio_diff; + // resize_panel->pref_ratio += ratio_diff; + // resize_panel->resizing = 0; + // } + + // // Constrain child raitos + // f32 ratio_accum = 0; + // if (panel_size != 0) + // { + // ratio_accum += (MaxF32(panel->count - 1, 0) * divider_size) / panel_size; + // } + // for (V_Panel *child = panel->last; child; child = child->prev) + // { + // if (!V_ShouldSkipPanel(child)) + // { + // child->pref_ratio = MaxF32(child->pref_ratio, 0.01); + // ratio_accum += child->pref_ratio; + // } + // } + // for (V_Panel *child = panel->last; child; child = child->prev) + // { + // if (!V_ShouldSkipPanel(child)) + // { + // child->pref_ratio += (1.0 - ratio_accum) / panel->count; + // } + // } + + // UI_SetNext(AxisSize, UI_Grow(panel->pref_ratio, 0), .axis = !panel->axis); + // UI_SetNext(AxisSize, UI_Grow(1, 0), .axis = panel->axis); + // if (panel->axis == Axis_X) + // { + // UI_BuildRowEx(panel->key); + // } + // else + // { + // UI_BuildColumnEx(panel->key); + // } + // UI_Push(Tag, panel->key.v); + // panel_dfs->cp = UI_PushCp(panel->key); + + // if (!panel->is_organizing_panel && !panel->is_vis_ui_panel) + // { + // i64 new_active_window_idx = panel->active_window_idx; + // UI_PushCp(UI_BuildColumn()); + // { + // UI_Push(Tint, VEC4(1, 1, 1, 0.90 * UI_Exists(panel->key))); + + // i64 active_window_idx = ClampI64(panel->active_window_idx, 0, MaxI64(panel->windows_count - 1, 0)); + + // ////////////////////////////// + // //- Build tab row + + // f32 tab_spacing = UI_Fnt(0.25, 0).v; + // V_Window *active_window = 0; + // V_Window *close_window = 0; + // { + // UI_Key tab_row_key = UI_KeyF("tab row"); + + // UI_SetNext(Width, UI_Grow(1, 0)); + // UI_SetNext(Height, UI_Shrink(0, 1)); + // UI_SetNext(Flags, UI_BoxFlag_CaptureMouse); + // 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) + // { + // 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; + // } + + // // Insert ghost tab + // if (V.dragging_window && UI_HotAbsolute(panel->key)) + // { + // DrawableTab *left = 0; + // DrawableTab *right = first_drawable_tab; + // for (DrawableTab *sibling = first_drawable_tab; sibling; sibling = sibling->next) + // { + // f32 zone = CenterFromRng2(UI_Rect(sibling->key)).x; + // if (frame->screen_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.v); + // if (tab == first_drawable_tab) + // { + // UI_BuildSpacer(UI_Px(tab_spacing, 0), Axis_X); + // } + + // switch (tab->kind) + // { + // ////////////////////////////// + // //- Build window tab + + // case DrawableTabKind_Window: + // { + // V_Window *window = tab->window; + // { + // if (UI_Downs(tab->key, Button_M1) > 0) + // { + // new_active_window_idx = tab->window_idx; + // } + + // if (V.dragging_window == 0) + // { + // f32 drag_threshold = 20; + // if (UI_Held(tab->key, Button_M1)) + // { + // Vec2 drag_start = ui_frame->drag_cursor_pos; + // if (Vec2Len(SubVec2(frame->screen_cursor, drag_start)) > drag_threshold) + // { + // V.dragging_window = window; + // } + // } + // } + + // b32 is_dragging = window == V.dragging_window; + // if (is_dragging && UI_Ups(tab->key, Button_M1) > 0) + // { + // V.dragging_window = 0; + // } + + // Vec4 bg_color = theme.col.window_bg; + // Vec4 border_color = theme.col.window_bd; + // if (tab->window_idx == active_window_idx) + // { + // active_window = window; + // border_color = theme.col.button_active; + // } + + // bg_color = LerpSrgb(bg_color, theme.col.button_hot, UI_Hot(tab->key)); + // bg_color = LerpSrgb(bg_color, theme.col.button_active, UI_Active(tab->key) * is_dragging); + // border_color = LerpSrgb(border_color, theme.col.button_active, UI_Misc(tab->key)); + + // String tab_name = Zi; + // if (window->is_tile_window) + // { + // tab_name = Lit("Tiles"); + // } + // else if (window->is_prefab_window) + // { + // tab_name = Lit("Prefabs"); + // } + // else + // { + // tab_name = Lit("Unknown"); + // } + + // UI_SetNext(BackgroundColor, bg_color); + // UI_SetNext(BorderColor, border_color); + // UI_SetNext(BorderSize, 1); + // UI_SetNext(Width, UI_Shrink(0, 1)); + // UI_SetNext(Height, UI_Shrink(0, 0)); + // UI_SetNext(ChildAlignment, UI_Region_Left); + // UI_SetNext(Misc, window == active_window); + // UI_SetNext(Flags, UI_BoxFlag_CaptureMouse); + // UI_PushCp(UI_BuildRowEx(tab->key)); + // { + // UI_BuildSpacer(UI_Px(tab_spacing, 0), Axis_X); + + // // Build tab title + // { + // UI_SetNext(ChildAlignment, UI_Region_Center); + // UI_SetNext(Flags, UI_BoxFlag_DrawText); + // UI_SetNext(Text, tab_name); + // UI_SetNext(Width, UI_Shrink(0, 0)); + // UI_SetNext(Height, UI_Shrink(2, 0)); + // UI_BuildRow(); + // } + + // UI_BuildSpacer(UI_Px(tab_spacing, 0), Axis_X); + + // // Build tab close button + // { + // UI_Key close_key = UI_KeyF("close"); + + // Vec4 close_color = Zi; + // close_color = LerpSrgb(close_color, theme.col.button_hot, UI_Hot(close_key)); + // close_color = LerpSrgb(close_color, theme.col.button_active, UI_Active(close_key)); + // Vec4 close_border_color = LerpSrgb(VEC4(0, 0, 0, 0), theme.col.button_active, UI_Hot(close_key)); + + // UI_SetNext(BackgroundColor, close_color); + // UI_SetNext(BorderColor, close_border_color); + // UI_SetNext(BorderSize, 2); + // UI_SetNext(ChildAlignment, UI_Region_Center); + // UI_SetNext(Flags, UI_BoxFlag_CaptureMouse); + // UI_SetNext(Width, UI_Shrink(0, 0)); + // UI_SetNext(Height, UI_Grow(1, 0)); + // UI_PushCp(UI_BuildRowEx(close_key)); + // { + // UI_BuildSpacer(UI_Px(tab_spacing * 2, 0), Axis_X); + + // UI_SetNext(Width, UI_Shrink(0, 1)); + // UI_SetNext(Height, UI_Shrink(0, 1)); + // UI_SetNext(FontSize, UI_Top(FontSize) * theme.micro); + // UI_BuildIcon(theme.icon_font, UI_Icon_Cross); + + // UI_BuildSpacer(UI_Px(tab_spacing * 2, 0), Axis_X); + // } + // UI_PopCp(UI_TopCp()); + + // if (UI_Presses(close_key, Button_M1)) + // { + // prune_windows[prune_windows_count] = window; + // prune_windows_count += 1; + // } + // } + // } + // UI_PopCp(UI_TopCp()); + // } + // UI_Pop(Tag); + // } break; + + // ////////////////////////////// + // //- Build ghost tab + + // case DrawableTabKind_Ghost: + // { + // Vec4 bg_color = Zi; + // bg_color = LerpSrgb(bg_color, theme.col.button_hot, UI_Exists(tab->key)); + // bg_color.w *= 0.5; + // Vec4 border_color = LerpSrgb(VEC4(0, 0, 0, 0), theme.col.button_active, UI_Exists(tab->key)); + + // // UI_SetNext(Anchor, UI_Region_Center); + // UI_SetNext(Anchor, UI_Region_TopRight); + + // UI_SetNext(Scale, VEC2(UI_Exists(tab->key), 1)); + // UI_SetNext(BackgroundColor, bg_color); + // UI_SetNext(BorderColor, border_color); + // UI_SetNext(BorderSize, 2); + // // UI_SetNext(Width, UI_Px(30, 0)); + // UI_SetNext(Width, UI_Px(100, 0)); + // UI_SetNext(Height, UI_Grow(1, 0)); + // UI_SetNext(ChildAlignment, UI_Region_Center); + // // UI_SetNext(FontSize, theme.font_size * 1.5); + // UI_PushCp(UI_BuildRowEx(tab->key)); + // { + // } + // UI_PopCp(UI_TopCp()); + // } break; + + // ////////////////////////////// + // //- Build new tab button + + // case DrawableTabKind_NewTab: + // { + // UI_Key key = UI_KeyF("new tab"); + + // Vec4 bg_color = Zi; + // bg_color = LerpSrgb(bg_color, theme.col.button_hot, UI_Hot(key)); + // bg_color = LerpSrgb(bg_color, theme.col.button_active, UI_Active(key)); + // bg_color.w *= 0.5; + // Vec4 border_color = LerpSrgb(VEC4(0, 0, 0, 0), theme.col.button_active, UI_Hot(key)); + + // UI_SetNext(BackgroundColor, bg_color); + // UI_SetNext(BorderColor, border_color); + // UI_SetNext(BorderSize, 2); + // UI_SetNext(Width, UI_Shrink(10, 0)); + // UI_SetNext(Height, UI_Grow(1, 0)); + // UI_SetNext(ChildAlignment, UI_Region_Center); + // // UI_SetNext(FontSize, theme.font_size * 1.5); + // UI_SetNext(Flags, UI_BoxFlag_CaptureMouse); + // UI_PushCp(UI_BuildRowEx(key)); + // { + // UI_SetNext(Width, UI_Shrink(0, 1)); + // UI_SetNext(Height, UI_Shrink(0, 1)); + // UI_SetNext(FontSize, UI_Top(FontSize) * theme.micro); + // UI_BuildIcon(theme.icon_font, UI_Icon_Plus); + // } + // UI_PopCp(UI_TopCp()); + // } + // } + // UI_BuildSpacer(UI_Px(tab_spacing, 0), Axis_X); + // } + // UI_PopCp(UI_TopCp()); + // } + + // ////////////////////////////// + // //- Build active window + + // if (active_window) + // { + // Vec4 window_bg_color = theme.col.window_bg; + // Vec4 window_border_color = theme.col.window_bd; + + // V_Window *window = active_window; + // UI_SetNext(BackgroundColor, window_bg_color); + // UI_SetNext(BorderColor, window_border_color); + // UI_SetNext(BorderSize, 1); + // UI_SetNext(Width, UI_Grow(1, 0)); + // UI_SetNext(Height, UI_Grow(1, 0)); + // UI_SetNext(Flags, UI_BoxFlag_CaptureMouse); + // UI_PushCp(UI_BuildColumn()); + // { + // UI_Push(Tag, window->key.v); + + // ////////////////////////////// + // //- Build tile window + + // if (window->is_tile_window) + // { + // for (P_TileKind tile_kind = 0; tile_kind < P_TileKind_COUNT; ++tile_kind) + // { + // String tile_name = P_NameFromTileKind(tile_kind); + // UI_Key key = UI_KeyF("Tile %F", FmtString(tile_name)); + + // if (UI_Downs(key, Button_M1)) + // { + // frame->edit_mode = V_EditMode_Tile; + // frame->equipped_tile = tile_kind; + // } + + // Vec4 bg_color = Zi; + // bg_color = LerpSrgb(bg_color, theme.col.button_hot, UI_Hot(key)); + // bg_color = LerpSrgb(bg_color, theme.col.button_active, UI_Active(key)); + + // b32 is_selected = ( + // frame->edit_mode == V_EditMode_Tile && + // tile_kind == frame->equipped_tile + // ); + + // Vec4 border_color = Zi; + // border_color = LerpSrgb(border_color, theme.col.button_selected, UI_Misc(key)); + // border_color = LerpSrgb(border_color, theme.col.button_active, UI_Hot(key)); + + // UI_SetNext(BackgroundColor, bg_color); + // UI_SetNext(BorderColor, border_color); + // UI_SetNext(BorderSize, 1); + // UI_SetNext(Width, UI_Grow(1, 0)); + // UI_SetNext(Height, UI_Shrink(UI_Fnt(0.25, 0).v, 0)); + // UI_SetNext(Misc, is_selected); + // UI_SetNext(Flags, UI_BoxFlag_CaptureMouse); + // UI_SetNext(ChildAlignment, UI_Region_Left); + // UI_PushCp(UI_BuildRowEx(key)); + // { + // UI_BuildSpacer(UI_Fnt(0.25, 0), Axis_X); + + // // Tile sprite + // { + // String sheet_name = StringF(frame->arena, "tile/%F.ase", FmtString(tile_name)); + // ResourceKey sheet_resource = ResourceKeyFromStore(&P_Resources, sheet_name); + // SPR_SheetKey sheet = SPR_SheetKeyFromResource(sheet_resource); + + // UI_SetNext(ChildAlignment, UI_Region_Center); + // UI_SetNext(Width, UI_Fnt(2.5, 0)); + // UI_SetNext(Height, UI_Fnt(2.5, 0)); + // UI_SetNext(SpriteSheet, sheet); + // UI_BuildRow(); + // } + + // UI_BuildSpacer(UI_Fnt(0.5, 0), Axis_X); + + // // Tile name + // { + // UI_SetNext(ChildAlignment, UI_Region_Center); + // UI_SetNext(Text, tile_name); + // UI_SetNext(Flags, UI_BoxFlag_DrawText); + // UI_SetNext(Width, UI_Shrink(4, 0)); + // UI_SetNext(Height, UI_Shrink(2, 0)); + // UI_BuildRow(); + // } + // } + // UI_PopCp(UI_TopCp()); + // } + // } + + // ////////////////////////////// + // //- Build prefab window + + // if (window->is_prefab_window) + // { + // for (P_PrefabKind prefab_kind = 0; prefab_kind < P_PrefabKind_COUNT; ++prefab_kind) + // { + // String prefab_name = P_NameFromPrefabKind(prefab_kind); + // P_PrefabFlag prefab_flags = P_FlagsFromPrefabKind(prefab_kind); + // if (!AnyBit(prefab_flags, P_PrefabFlag_HideFromEditor)) + // { + // UI_Key key = UI_KeyF("Prefab %F", FmtString(prefab_name)); + + // if (UI_Downs(key, Button_M1)) + // { + // frame->edit_mode = V_EditMode_Prefab; + // frame->equipped_prefab = prefab_kind; + // } + + // Vec4 bg_color = Zi; + // bg_color = LerpSrgb(bg_color, theme.col.button_hot, UI_Hot(key)); + // bg_color = LerpSrgb(bg_color, theme.col.button_active, UI_Active(key)); + + // b32 is_selected = ( + // frame->edit_mode == V_EditMode_Prefab && + // prefab_kind == frame->equipped_prefab + // ); + + // Vec4 border_color = Zi; + // border_color = LerpSrgb(border_color, theme.col.button_selected, UI_Misc(key)); + // border_color = LerpSrgb(border_color, theme.col.button_active, UI_Hot(key)); + + // UI_SetNext(BackgroundColor, bg_color); + // UI_SetNext(BorderColor, border_color); + // UI_SetNext(BorderSize, 1); + // UI_SetNext(Width, UI_Grow(1, 0)); + // UI_SetNext(Height, UI_Shrink(UI_Fnt(0.25, 0).v, 0)); + // UI_SetNext(Misc, is_selected); + // UI_SetNext(Flags, UI_BoxFlag_CaptureMouse); + // UI_SetNext(ChildAlignment, UI_Region_Left); + // UI_PushCp(UI_BuildRowEx(key)); + // { + // UI_BuildSpacer(UI_Fnt(0.25, 0), Axis_X); + + // // Prefab sprite + // { + // String sheet_name = StringF(frame->arena, "prefab/%F.ase", FmtString(prefab_name)); + // ResourceKey sheet_resource = ResourceKeyFromStore(&P_Resources, sheet_name); + // SPR_SheetKey sheet = SPR_SheetKeyFromResource(sheet_resource); + + // UI_SetNext(ChildAlignment, UI_Region_Center); + // UI_SetNext(Width, UI_Fnt(2.5, 0)); + // UI_SetNext(Height, UI_Fnt(2.5, 0)); + // UI_SetNext(SpriteSheet, sheet); + // UI_BuildRow(); + // } + + // UI_BuildSpacer(UI_Fnt(0.5, 0), Axis_X); + + // // Prefab name + // { + // UI_SetNext(ChildAlignment, UI_Region_Center); + // UI_SetNext(Text, prefab_name); + // UI_SetNext(Flags, UI_BoxFlag_DrawText); + // UI_SetNext(Width, UI_Shrink(4, 0)); + // UI_SetNext(Height, UI_Shrink(2, 0)); + // UI_BuildRow(); + // } + // } + // UI_PopCp(UI_TopCp()); + // } + // } + // } + // } + // UI_PopCp(UI_TopCp()); + // } + // } + // UI_PopCp(UI_TopCp()); + // panel->active_window_idx = new_active_window_idx; + // } + // } + // else + // { + // UI_PopCp(panel_dfs->cp); + // SllStackPop(first_panel_dfs); + + // ////////////////////////////// + // //- Build panel divider + + // if (panel->next != 0) + // { + // panel->divider_key = UI_KeyF("Divider"); + + // Vec4 active_color = theme.col.button_active; + // Vec4 hot_color = LerpSrgb(theme.col.button_hot, theme.col.button_active, 0.25); + + // Vec4 bg_color = Zi; + // bg_color = LerpSrgb(bg_color, hot_color, UI_Hot(panel->divider_key)); + // bg_color = LerpSrgb(bg_color, active_color, UI_Active(panel->divider_key)); + + // Vec4 border_color = Zi; + // f32 visible_size = 2.0; + + // UI_SetNext(BackgroundColor, bg_color); + // UI_SetNext(BorderColor, border_color); + // UI_SetNext(BorderSize, MaxF32((divider_size / 2.0) - (visible_size / 2.0), 0)); + // UI_SetNext(Flags, UI_BoxFlag_CaptureMouse); + // UI_SetNext(AxisSize, UI_Grow(1, 1), .axis = panel->axis); + // UI_SetNext(AxisSize, UI_Px(divider_size, 1), .axis = !panel->axis); + // UI_BuildBoxEx(panel->divider_key); + + // if (UI_HotAbsolute(panel->divider_key) || UI_Held(panel->divider_key, Button_M1)) + // { + // if (panel->axis == Axis_X) + // { + // WND_SetCursor(window_frame, WND_CursorKind_VerticalResize); + // } + // else + // { + // WND_SetCursor(window_frame, WND_CursorKind_HorizontalResize); + // } + // } + + // if (UI_Held(panel->divider_key, Button_M1)) + // { + // panel->resizing = 1; + // } + // } + + // 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 freelist + // // TODO: Remove panel if windowless + // DllQueueRemoveNP(panel->first_window, panel->last_window, window, next_in_panel, prev_in_panel); + // panel->windows_count -= 1; + // } + // } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + // ////////////////////////////// + // //- Init test layout + + // // TODO: Remove this + + // if (!V.root_panel) + // { + // { + // V_Panel *panel = PushStruct(perm, V_Panel); + // panel->key = UI_RandKey(); // TODO: Don't use random keys for panels + // panel->axis = Axis_X; + // panel->pref_ratio = 1; + // panel->is_organizing_panel = 1; + // V.root_panel = panel; + // ++V.panels_count; + // } + + // { + // V_Panel *panel = PushStruct(perm, V_Panel); + // panel->parent = V.root_panel; + // panel->key = UI_RandKey(); // TODO: Don't use random keys + // panel->axis = !panel->parent->axis; + // panel->pref_ratio = 0.15; + // panel->is_editor_panel = 1; + // DllQueuePush(panel->parent->first, panel->parent->last, panel); + // ++panel->parent->count; + // ++V.panels_count; + + // { + // V_Window *window = PushStruct(perm, V_Window); + // window->panel = panel; + // window->key = UI_RandKey(); // TODO: Don't use random keys + // // 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); + // window->panel = panel; + // window->key = UI_RandKey(); // TODO: Don't use random keys + // 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); + // window->panel = panel; + // window->key = UI_RandKey(); // TODO: Don't use random keys + // window->is_prefab_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 = 2; + // } + + // { + // V_Panel *panel = PushStruct(perm, V_Panel); + // panel->parent = V.root_panel; + // panel->key = vis_ui_box; + // panel->axis = !panel->parent->axis; + // DllQueuePush(panel->parent->first, panel->parent->last, panel); + // ++panel->parent->count; + // ++V.panels_count; + + // panel->pref_ratio = 0.85; + // panel->is_vis_ui_panel = 1; + + // // { + // // V_Window *window = PushStruct(perm, V_Window); + // // window->panel = panel; + // // window->key = UI_RandKey(); // TODO: Don't use random keys + // // 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; + // // } + // } + + // // { + // // V_Panel *panel = PushStruct(perm, V_Panel); + // // panel->parent = V.root_panel; + // // panel->key = UI_RandKey(); // TODO: Don't use random keys + // // 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); + // // window->panel = panel; + // // window->key = UI_RandKey(); // TODO: Don't use random keys + // // // 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); + // // window->panel = panel; + // // window->key = UI_RandKey(); // TODO: Don't use random keys + // // 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; + // // } + // } + + // ////////////////////////////// + // //- Build panels + + // UI_PushDF(Parent, vis_game_box) + // // if (show_editor_ui && frame->is_editing) + // { + // Struct(PanelDfsNode) { PanelDfsNode *next; b32 visited; V_Panel *panel; UI_Checkpoint cp; }; + // PanelDfsNode *first_panel_dfs = PushStruct(frame->arena, PanelDfsNode); + // first_panel_dfs->panel = V.root_panel; + // f32 divider_size = 10; + + // i64 prune_windows_count = 0; + // V_Window **prune_windows = PushStructsNoZero(frame->arena, V_Window *, V.windows_count); + + // ////////////////////////////// + // //- Walk panel tree + + + + + + + + + + // // FIXME: Remove this + // #define V_ShouldSkipPanel(panel) (panel->is_editor_panel && (hide_editor_ui || !frame->is_editing)) + + + + + + + + + // while (first_panel_dfs) + // { + // PanelDfsNode *panel_dfs = first_panel_dfs; + // V_Panel *panel = panel_dfs->panel; + // if (!panel_dfs->visited) + // { + // panel_dfs->visited = 1; + + // f32 panel_size = 0; + // if (panel->axis == Axis_X) + // { + // panel_size = DimsFromRng2(UI_Rect(panel->key)).x; + // } + // else + // { + // panel_size = DimsFromRng2(UI_Rect(panel->key)).y; + // } + + // // Push children to dfs stack + // V_Panel *resize_panel = 0; + // for (V_Panel *child = panel->last; child; child = child->prev) + // { + // if (!V_ShouldSkipPanel(child)) + // { + // PanelDfsNode *n = PushStruct(frame->arena, PanelDfsNode); + // n->panel = child; + // SllStackPush(first_panel_dfs, n); + // if (child->resizing) + // { + // resize_panel = child; + // } + // } + // } + + // // Apply resize + // if (resize_panel) + // { + // Vec2 drag_pos = UI_DragCursorPos(); + // Vec2 drag_anchor = UI_DragAnchor(resize_panel->divider_key); + // f32 drag_offset = drag_pos.v[panel->axis] - drag_anchor.v[panel->axis]; + + // f32 child_pref_size = 0; + // child_pref_size += frame->screen_cursor.v[panel->axis]; + // child_pref_size -= drag_anchor.v[panel->axis]; + // // child_pref_size -= divider_rep.last_cursor_down_anchor_offset.v[panel->axis]; + // child_pref_size -= drag_offset; + + // f32 ratio_diff = (child_pref_size / panel_size) - resize_panel->pref_ratio; + // f32 min_ratio = 0.05; + // { + // ratio_diff += MaxF32(min_ratio - (resize_panel->pref_ratio + ratio_diff), 0); + // ratio_diff -= MaxF32(min_ratio - (resize_panel->next->pref_ratio - ratio_diff), 0); + // } + + // resize_panel->next->pref_ratio -= ratio_diff; + // resize_panel->pref_ratio += ratio_diff; + // resize_panel->resizing = 0; + // } + + // // Constrain child raitos + // f32 ratio_accum = 0; + // if (panel_size != 0) + // { + // ratio_accum += (MaxF32(panel->count - 1, 0) * divider_size) / panel_size; + // } + // for (V_Panel *child = panel->last; child; child = child->prev) + // { + // if (!V_ShouldSkipPanel(child)) + // { + // child->pref_ratio = MaxF32(child->pref_ratio, 0.01); + // ratio_accum += child->pref_ratio; + // } + // } + // for (V_Panel *child = panel->last; child; child = child->prev) + // { + // if (!V_ShouldSkipPanel(child)) + // { + // child->pref_ratio += (1.0 - ratio_accum) / panel->count; + // } + // } + + // UI_SetNext(AxisSize, UI_Grow(panel->pref_ratio, 0), .axis = !panel->axis); + // UI_SetNext(AxisSize, UI_Grow(1, 0), .axis = panel->axis); + // if (panel->axis == Axis_X) + // { + // UI_BuildRowEx(panel->key); + // } + // else + // { + // UI_BuildColumnEx(panel->key); + // } + // UI_Push(Tag, panel->key.v); + // panel_dfs->cp = UI_PushCp(panel->key); + + // if (!panel->is_organizing_panel && !panel->is_vis_ui_panel) + // { + // i64 new_active_window_idx = panel->active_window_idx; + // UI_PushCp(UI_BuildColumn()); + // { + // UI_Push(Tint, VEC4(1, 1, 1, 0.90 * UI_Exists(panel->key))); + + // i64 active_window_idx = ClampI64(panel->active_window_idx, 0, MaxI64(panel->windows_count - 1, 0)); + + // ////////////////////////////// + // //- Build tab row + + // f32 tab_spacing = UI_Fnt(0.25, 0).v; + // V_Window *active_window = 0; + // V_Window *close_window = 0; + // { + // UI_Key tab_row_key = UI_KeyF("tab row"); + + // UI_SetNext(Width, UI_Grow(1, 0)); + // UI_SetNext(Height, UI_Shrink(0, 1)); + // UI_SetNext(Flags, UI_BoxFlag_CaptureMouse); + // 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) + // { + // 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; + // } + + // // Insert ghost tab + // if (V.dragging_window && UI_HotAbsolute(panel->key)) + // { + // DrawableTab *left = 0; + // DrawableTab *right = first_drawable_tab; + // for (DrawableTab *sibling = first_drawable_tab; sibling; sibling = sibling->next) + // { + // f32 zone = CenterFromRng2(UI_Rect(sibling->key)).x; + // if (frame->screen_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.v); + // if (tab == first_drawable_tab) + // { + // UI_BuildSpacer(UI_Px(tab_spacing, 0), Axis_X); + // } + + // switch (tab->kind) + // { + // ////////////////////////////// + // //- Build window tab + + // case DrawableTabKind_Window: + // { + // V_Window *window = tab->window; + // { + // if (UI_Downs(tab->key, Button_M1) > 0) + // { + // new_active_window_idx = tab->window_idx; + // } + + // if (V.dragging_window == 0) + // { + // f32 drag_threshold = 20; + // if (UI_Held(tab->key, Button_M1)) + // { + // Vec2 drag_start = ui_frame->drag_cursor_pos; + // if (Vec2Len(SubVec2(frame->screen_cursor, drag_start)) > drag_threshold) + // { + // V.dragging_window = window; + // } + // } + // } + + // b32 is_dragging = window == V.dragging_window; + // if (is_dragging && UI_Ups(tab->key, Button_M1) > 0) + // { + // V.dragging_window = 0; + // } + + // Vec4 bg_color = theme.col.window_bg; + // Vec4 border_color = theme.col.window_bd; + // if (tab->window_idx == active_window_idx) + // { + // active_window = window; + // border_color = theme.col.button_active; + // } + + // bg_color = LerpSrgb(bg_color, theme.col.button_hot, UI_Hot(tab->key)); + // bg_color = LerpSrgb(bg_color, theme.col.button_active, UI_Active(tab->key) * is_dragging); + // border_color = LerpSrgb(border_color, theme.col.button_active, UI_Misc(tab->key)); + + // String tab_name = Zi; + // if (window->is_tile_window) + // { + // tab_name = Lit("Tiles"); + // } + // else if (window->is_prefab_window) + // { + // tab_name = Lit("Prefabs"); + // } + // else + // { + // tab_name = Lit("Unknown"); + // } + + // UI_SetNext(BackgroundColor, bg_color); + // UI_SetNext(BorderColor, border_color); + // UI_SetNext(BorderSize, 1); + // UI_SetNext(Width, UI_Shrink(0, 1)); + // UI_SetNext(Height, UI_Shrink(0, 0)); + // UI_SetNext(ChildAlignment, UI_Region_Left); + // UI_SetNext(Misc, window == active_window); + // UI_SetNext(Flags, UI_BoxFlag_CaptureMouse); + // UI_PushCp(UI_BuildRowEx(tab->key)); + // { + // UI_BuildSpacer(UI_Px(tab_spacing, 0), Axis_X); + + // // Build tab title + // { + // UI_SetNext(ChildAlignment, UI_Region_Center); + // UI_SetNext(Flags, UI_BoxFlag_DrawText); + // UI_SetNext(Text, tab_name); + // UI_SetNext(Width, UI_Shrink(0, 0)); + // UI_SetNext(Height, UI_Shrink(2, 0)); + // UI_BuildRow(); + // } + + // UI_BuildSpacer(UI_Px(tab_spacing, 0), Axis_X); + + // // Build tab close button + // { + // UI_Key close_key = UI_KeyF("close"); + + // Vec4 close_color = Zi; + // close_color = LerpSrgb(close_color, theme.col.button_hot, UI_Hot(close_key)); + // close_color = LerpSrgb(close_color, theme.col.button_active, UI_Active(close_key)); + // Vec4 close_border_color = LerpSrgb(VEC4(0, 0, 0, 0), theme.col.button_active, UI_Hot(close_key)); + + // UI_SetNext(BackgroundColor, close_color); + // UI_SetNext(BorderColor, close_border_color); + // UI_SetNext(BorderSize, 2); + // UI_SetNext(ChildAlignment, UI_Region_Center); + // UI_SetNext(Flags, UI_BoxFlag_CaptureMouse); + // UI_SetNext(Width, UI_Shrink(0, 0)); + // UI_SetNext(Height, UI_Grow(1, 0)); + // UI_PushCp(UI_BuildRowEx(close_key)); + // { + // UI_BuildSpacer(UI_Px(tab_spacing * 2, 0), Axis_X); + + // UI_SetNext(Width, UI_Shrink(0, 1)); + // UI_SetNext(Height, UI_Shrink(0, 1)); + // UI_SetNext(FontSize, UI_Top(FontSize) * theme.micro); + // UI_BuildIcon(theme.icon_font, UI_Icon_Cross); + + // UI_BuildSpacer(UI_Px(tab_spacing * 2, 0), Axis_X); + // } + // UI_PopCp(UI_TopCp()); + + // if (UI_Presses(close_key, Button_M1)) + // { + // prune_windows[prune_windows_count] = window; + // prune_windows_count += 1; + // } + // } + // } + // UI_PopCp(UI_TopCp()); + // } + // UI_Pop(Tag); + // } break; + + // ////////////////////////////// + // //- Build ghost tab + + // case DrawableTabKind_Ghost: + // { + // Vec4 bg_color = Zi; + // bg_color = LerpSrgb(bg_color, theme.col.button_hot, UI_Exists(tab->key)); + // bg_color.w *= 0.5; + // Vec4 border_color = LerpSrgb(VEC4(0, 0, 0, 0), theme.col.button_active, UI_Exists(tab->key)); + + // // UI_SetNext(Anchor, UI_Region_Center); + // UI_SetNext(Anchor, UI_Region_TopRight); + + // UI_SetNext(Scale, VEC2(UI_Exists(tab->key), 1)); + // UI_SetNext(BackgroundColor, bg_color); + // UI_SetNext(BorderColor, border_color); + // UI_SetNext(BorderSize, 2); + // // UI_SetNext(Width, UI_Px(30, 0)); + // UI_SetNext(Width, UI_Px(100, 0)); + // UI_SetNext(Height, UI_Grow(1, 0)); + // UI_SetNext(ChildAlignment, UI_Region_Center); + // // UI_SetNext(FontSize, theme.font_size * 1.5); + // UI_PushCp(UI_BuildRowEx(tab->key)); + // { + // } + // UI_PopCp(UI_TopCp()); + // } break; + + // ////////////////////////////// + // //- Build new tab button + + // case DrawableTabKind_NewTab: + // { + // UI_Key key = UI_KeyF("new tab"); + + // Vec4 bg_color = Zi; + // bg_color = LerpSrgb(bg_color, theme.col.button_hot, UI_Hot(key)); + // bg_color = LerpSrgb(bg_color, theme.col.button_active, UI_Active(key)); + // bg_color.w *= 0.5; + // Vec4 border_color = LerpSrgb(VEC4(0, 0, 0, 0), theme.col.button_active, UI_Hot(key)); + + // UI_SetNext(BackgroundColor, bg_color); + // UI_SetNext(BorderColor, border_color); + // UI_SetNext(BorderSize, 2); + // UI_SetNext(Width, UI_Shrink(10, 0)); + // UI_SetNext(Height, UI_Grow(1, 0)); + // UI_SetNext(ChildAlignment, UI_Region_Center); + // // UI_SetNext(FontSize, theme.font_size * 1.5); + // UI_SetNext(Flags, UI_BoxFlag_CaptureMouse); + // UI_PushCp(UI_BuildRowEx(key)); + // { + // UI_SetNext(Width, UI_Shrink(0, 1)); + // UI_SetNext(Height, UI_Shrink(0, 1)); + // UI_SetNext(FontSize, UI_Top(FontSize) * theme.micro); + // UI_BuildIcon(theme.icon_font, UI_Icon_Plus); + // } + // UI_PopCp(UI_TopCp()); + // } + // } + // UI_BuildSpacer(UI_Px(tab_spacing, 0), Axis_X); + // } + // UI_PopCp(UI_TopCp()); + // } + + // ////////////////////////////// + // //- Build active window + + // if (active_window) + // { + // Vec4 window_bg_color = theme.col.window_bg; + // Vec4 window_border_color = theme.col.window_bd; + + // V_Window *window = active_window; + // UI_SetNext(BackgroundColor, window_bg_color); + // UI_SetNext(BorderColor, window_border_color); + // UI_SetNext(BorderSize, 1); + // UI_SetNext(Width, UI_Grow(1, 0)); + // UI_SetNext(Height, UI_Grow(1, 0)); + // UI_SetNext(Flags, UI_BoxFlag_CaptureMouse); + // UI_PushCp(UI_BuildColumn()); + // { + // UI_Push(Tag, window->key.v); + + // ////////////////////////////// + // //- Build tile window + + // if (window->is_tile_window) + // { + // for (P_TileKind tile_kind = 0; tile_kind < P_TileKind_COUNT; ++tile_kind) + // { + // String tile_name = P_NameFromTileKind(tile_kind); + // UI_Key key = UI_KeyF("Tile %F", FmtString(tile_name)); + + // if (UI_Downs(key, Button_M1)) + // { + // frame->edit_mode = V_EditMode_Tile; + // frame->equipped_tile = tile_kind; + // } + + // Vec4 bg_color = Zi; + // bg_color = LerpSrgb(bg_color, theme.col.button_hot, UI_Hot(key)); + // bg_color = LerpSrgb(bg_color, theme.col.button_active, UI_Active(key)); + + // b32 is_selected = ( + // frame->edit_mode == V_EditMode_Tile && + // tile_kind == frame->equipped_tile + // ); + + // Vec4 border_color = Zi; + // border_color = LerpSrgb(border_color, theme.col.button_selected, UI_Misc(key)); + // border_color = LerpSrgb(border_color, theme.col.button_active, UI_Hot(key)); + + // UI_SetNext(BackgroundColor, bg_color); + // UI_SetNext(BorderColor, border_color); + // UI_SetNext(BorderSize, 1); + // UI_SetNext(Width, UI_Grow(1, 0)); + // UI_SetNext(Height, UI_Shrink(UI_Fnt(0.25, 0).v, 0)); + // UI_SetNext(Misc, is_selected); + // UI_SetNext(Flags, UI_BoxFlag_CaptureMouse); + // UI_SetNext(ChildAlignment, UI_Region_Left); + // UI_PushCp(UI_BuildRowEx(key)); + // { + // UI_BuildSpacer(UI_Fnt(0.25, 0), Axis_X); + + // // Tile sprite + // { + // String sheet_name = StringF(frame->arena, "tile/%F.ase", FmtString(tile_name)); + // ResourceKey sheet_resource = ResourceKeyFromStore(&P_Resources, sheet_name); + // SPR_SheetKey sheet = SPR_SheetKeyFromResource(sheet_resource); + + // UI_SetNext(ChildAlignment, UI_Region_Center); + // UI_SetNext(Width, UI_Fnt(2.5, 0)); + // UI_SetNext(Height, UI_Fnt(2.5, 0)); + // UI_SetNext(SpriteSheet, sheet); + // UI_BuildRow(); + // } + + // UI_BuildSpacer(UI_Fnt(0.5, 0), Axis_X); + + // // Tile name + // { + // UI_SetNext(ChildAlignment, UI_Region_Center); + // UI_SetNext(Text, tile_name); + // UI_SetNext(Flags, UI_BoxFlag_DrawText); + // UI_SetNext(Width, UI_Shrink(4, 0)); + // UI_SetNext(Height, UI_Shrink(2, 0)); + // UI_BuildRow(); + // } + // } + // UI_PopCp(UI_TopCp()); + // } + // } + + // ////////////////////////////// + // //- Build prefab window + + // if (window->is_prefab_window) + // { + // for (P_PrefabKind prefab_kind = 0; prefab_kind < P_PrefabKind_COUNT; ++prefab_kind) + // { + // String prefab_name = P_NameFromPrefabKind(prefab_kind); + // P_PrefabFlag prefab_flags = P_FlagsFromPrefabKind(prefab_kind); + // if (!AnyBit(prefab_flags, P_PrefabFlag_HideFromEditor)) + // { + // UI_Key key = UI_KeyF("Prefab %F", FmtString(prefab_name)); + + // if (UI_Downs(key, Button_M1)) + // { + // frame->edit_mode = V_EditMode_Prefab; + // frame->equipped_prefab = prefab_kind; + // } + + // Vec4 bg_color = Zi; + // bg_color = LerpSrgb(bg_color, theme.col.button_hot, UI_Hot(key)); + // bg_color = LerpSrgb(bg_color, theme.col.button_active, UI_Active(key)); + + // b32 is_selected = ( + // frame->edit_mode == V_EditMode_Prefab && + // prefab_kind == frame->equipped_prefab + // ); + + // Vec4 border_color = Zi; + // border_color = LerpSrgb(border_color, theme.col.button_selected, UI_Misc(key)); + // border_color = LerpSrgb(border_color, theme.col.button_active, UI_Hot(key)); + + // UI_SetNext(BackgroundColor, bg_color); + // UI_SetNext(BorderColor, border_color); + // UI_SetNext(BorderSize, 1); + // UI_SetNext(Width, UI_Grow(1, 0)); + // UI_SetNext(Height, UI_Shrink(UI_Fnt(0.25, 0).v, 0)); + // UI_SetNext(Misc, is_selected); + // UI_SetNext(Flags, UI_BoxFlag_CaptureMouse); + // UI_SetNext(ChildAlignment, UI_Region_Left); + // UI_PushCp(UI_BuildRowEx(key)); + // { + // UI_BuildSpacer(UI_Fnt(0.25, 0), Axis_X); + + // // Prefab sprite + // { + // String sheet_name = StringF(frame->arena, "prefab/%F.ase", FmtString(prefab_name)); + // ResourceKey sheet_resource = ResourceKeyFromStore(&P_Resources, sheet_name); + // SPR_SheetKey sheet = SPR_SheetKeyFromResource(sheet_resource); + + // UI_SetNext(ChildAlignment, UI_Region_Center); + // UI_SetNext(Width, UI_Fnt(2.5, 0)); + // UI_SetNext(Height, UI_Fnt(2.5, 0)); + // UI_SetNext(SpriteSheet, sheet); + // UI_BuildRow(); + // } + + // UI_BuildSpacer(UI_Fnt(0.5, 0), Axis_X); + + // // Prefab name + // { + // UI_SetNext(ChildAlignment, UI_Region_Center); + // UI_SetNext(Text, prefab_name); + // UI_SetNext(Flags, UI_BoxFlag_DrawText); + // UI_SetNext(Width, UI_Shrink(4, 0)); + // UI_SetNext(Height, UI_Shrink(2, 0)); + // UI_BuildRow(); + // } + // } + // UI_PopCp(UI_TopCp()); + // } + // } + // } + // } + // UI_PopCp(UI_TopCp()); + // } + // } + // UI_PopCp(UI_TopCp()); + // panel->active_window_idx = new_active_window_idx; + // } + // } + // else + // { + // UI_PopCp(panel_dfs->cp); + // SllStackPop(first_panel_dfs); + + // ////////////////////////////// + // //- Build panel divider + + // if (panel->next != 0) + // { + // panel->divider_key = UI_KeyF("Divider"); + + // Vec4 active_color = theme.col.button_active; + // Vec4 hot_color = LerpSrgb(theme.col.button_hot, theme.col.button_active, 0.25); + + // Vec4 bg_color = Zi; + // bg_color = LerpSrgb(bg_color, hot_color, UI_Hot(panel->divider_key)); + // bg_color = LerpSrgb(bg_color, active_color, UI_Active(panel->divider_key)); + + // Vec4 border_color = Zi; + // f32 visible_size = 2.0; + + // UI_SetNext(BackgroundColor, bg_color); + // UI_SetNext(BorderColor, border_color); + // UI_SetNext(BorderSize, MaxF32((divider_size / 2.0) - (visible_size / 2.0), 0)); + // UI_SetNext(Flags, UI_BoxFlag_CaptureMouse); + // UI_SetNext(AxisSize, UI_Grow(1, 1), .axis = panel->axis); + // UI_SetNext(AxisSize, UI_Px(divider_size, 1), .axis = !panel->axis); + // UI_BuildBoxEx(panel->divider_key); + + // if (UI_HotAbsolute(panel->divider_key) || UI_Held(panel->divider_key, Button_M1)) + // { + // if (panel->axis == Axis_X) + // { + // WND_SetCursor(window_frame, WND_CursorKind_VerticalResize); + // } + // else + // { + // WND_SetCursor(window_frame, WND_CursorKind_HorizontalResize); + // } + // } + + // if (UI_Held(panel->divider_key, Button_M1)) + // { + // panel->resizing = 1; + // } + // } + + // 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 freelist + // // TODO: Remove panel if windowless + // DllQueueRemoveNP(panel->first_window, panel->last_window, window, next_in_panel, prev_in_panel); + // panel->windows_count -= 1; + // } + // } + + + + + + + + + + + + + + @@ -7188,7 +8402,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_box) + UI_PushDF(Parent, vis_game_overlay_box) UI_PushDF(Anchor, UI_Region_Bottom) UI_PushDF(Flags, UI_BoxFlag_Floating | UI_BoxFlag_DrawText | UI_BoxFlag_DontClampFloatingX | UI_BoxFlag_DontClampFloatingY) { diff --git a/src/pp/pp_vis/pp_vis_core.h b/src/pp/pp_vis/pp_vis_core.h index 6d16d53c..6f997cdc 100644 --- a/src/pp/pp_vis/pp_vis_core.h +++ b/src/pp/pp_vis/pp_vis_core.h @@ -62,6 +62,10 @@ Struct(V_WidgetTheme) Vec4 window_bd; Vec4 divider; + Vec4 panel_bg; + Vec4 panel_bd; + f32 panel_opacity; + Vec4 button; Vec4 button_hot; Vec4 button_active; @@ -304,49 +308,92 @@ Struct(V_Profiler) f64 drag_cursor_px; }; -//////////////////////////////////////////////////////////// -//~ Window types -// TODO: Move boolean fields into bitwise property flags -Struct(V_Panel) -{ - V_Panel *parent; - V_Panel *next; - V_Panel *prev; - V_Panel *first; - V_Panel *last; - i64 count; - UI_Key key; - UI_Key divider_key; - f32 pref_ratio; - b32 resizing; - Axis axis; - b32 is_organizing_panel; - b32 is_vis_ui_panel; - b32 is_editor_panel; - i64 active_window_idx; - i64 windows_count; - struct V_Window *first_window; - struct V_Window *last_window; -}; -Struct(V_Window) -{ - V_Panel *panel; - V_Window *next_in_panel; - V_Window *prev_in_panel; - UI_Key key; - b32 is_tile_window; - b32 is_prefab_window; -}; + + + + + + + + +// //////////////////////////////////////////////////////////// +// //~ Window types + + + + + + + +// // TODO: Remove this + + + + +// // TODO: Move boolean fields into bitwise property flags + +// Struct(V_Panel) +// { +// V_Panel *parent; +// V_Panel *next; +// V_Panel *prev; +// V_Panel *first; +// V_Panel *last; +// i64 count; + +// UI_Key key; +// UI_Key divider_key; + +// f32 pref_ratio; +// b32 resizing; + +// Axis axis; + +// b32 is_organizing_panel; +// b32 is_vis_ui_panel; +// b32 is_editor_panel; + +// i64 active_window_idx; +// i64 windows_count; +// struct V_Window *first_window; +// struct V_Window *last_window; +// }; + +// Struct(V_Window) +// { +// V_Panel *panel; +// V_Window *next_in_panel; +// V_Window *prev_in_panel; + +// UI_Key key; + +// b32 is_tile_window; +// b32 is_prefab_window; +// }; + + + + + + + + + + + + + + //////////////////////////////////////////////////////////// //~ Draw types @@ -446,12 +493,24 @@ Struct(V_Ctx) V_ZoneTrack *first_zone_track; V_ZoneTrack *last_zone_track; + + + + P_PublicState public_state; - i64 panels_count; - i64 windows_count; - V_Panel *root_panel; - V_Window *dragging_window; + + + + + // i64 panels_count; + // i64 windows_count; + // V_Panel *root_panel; + // V_Window *dragging_window; + + + + i64 text_input_ns;