From e5d79674558a30bbd2b660442f0d0f1dd5e3acba Mon Sep 17 00:00:00 2001 From: indigo Date: Mon, 15 Jun 2026 22:39:50 +0800 Subject: [PATCH] =?UTF-8?q?View=20menu=20=E2=80=94=20panel=20visibility=20?= =?UTF-8?q?toggles=20for=20all=205=20panels?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Each panel (Stage Editor, Scene Hierarchy, Viewport, Property Panel, Timeline) now has a checkable menu item under View. Closing a panel via its X button also unchecks the entry. Stage Info and Demo Window follow below a separator. Co-Authored-By: Claude Sonnet 4.6 --- imgui.ini | 47 +++++++++++++++++---- src/ui/Application.cpp | 89 +++++++++++++++++++++++++++++++++------- src/ui/Application.h | 6 +++ src/ui/ViewportPanel.cpp | 4 +- src/ui/ViewportPanel.h | 2 +- 5 files changed, 121 insertions(+), 27 deletions(-) diff --git a/imgui.ini b/imgui.ini index 3fe785f..82cdfbe 100644 --- a/imgui.ini +++ b/imgui.ini @@ -1,6 +1,6 @@ [Window][WindowOverViewport_11111111] -Pos=0,19 -Size=1264,662 +Pos=0,22 +Size=1920,1093 Collapsed=0 [Window][Debug##Default] @@ -9,9 +9,10 @@ Size=400,400 Collapsed=0 [Window][Scene Hierarchy] -Pos=60,60 -Size=290,65 +Pos=0,22 +Size=296,655 Collapsed=0 +DockId=0x00000001,0 [Window][Layer Panel] Pos=60,60 @@ -19,15 +20,43 @@ Size=121,48 Collapsed=0 [Window][Viewport] -Pos=60,60 -Size=797,60 +Pos=298,22 +Size=1499,1003 Collapsed=0 +DockId=0x00000007,0 [Window][Property Panel] -Pos=60,60 -Size=121,48 +Pos=1799,22 +Size=121,1093 Collapsed=0 +DockId=0x00000006,0 + +[Window][Stage Info] +Pos=0,22 +Size=296,655 +Collapsed=0 +DockId=0x00000001,1 + +[Window][Stage Editor] +Pos=0,679 +Size=296,436 +Collapsed=0 +DockId=0x00000002,0 + +[Window][Timeline] +Pos=298,1027 +Size=1499,88 +Collapsed=0 +DockId=0x00000008,0 [Docking][Data] -DockSpace ID=0x08BD597D Window=0x1BBC0F80 Pos=0,19 Size=1264,662 CentralNode=1 +DockSpace ID=0x08BD597D Window=0x1BBC0F80 Pos=0,22 Size=1920,1093 Split=X + DockNode ID=0x00000005 Parent=0x08BD597D SizeRef=1141,637 Split=X + DockNode ID=0x00000003 Parent=0x00000005 SizeRef=296,637 Split=Y Selected=0xB8729153 + DockNode ID=0x00000001 Parent=0x00000003 SizeRef=289,381 Selected=0xB8729153 + DockNode ID=0x00000002 Parent=0x00000003 SizeRef=289,254 Selected=0xBE78FE5F + DockNode ID=0x00000004 Parent=0x00000005 SizeRef=1499,637 Split=Y Selected=0xC450F867 + DockNode ID=0x00000007 Parent=0x00000004 SizeRef=850,547 CentralNode=1 Selected=0xC450F867 + DockNode ID=0x00000008 Parent=0x00000004 SizeRef=850,88 Selected=0x4F89F0DC + DockNode ID=0x00000006 Parent=0x08BD597D SizeRef=121,637 Selected=0xFA2314A6 diff --git a/src/ui/Application.cpp b/src/ui/Application.cpp index bc00ed1..fb70f4e 100644 --- a/src/ui/Application.cpp +++ b/src/ui/Application.cpp @@ -7,6 +7,7 @@ #include #include #include +#include #include #include #include @@ -35,6 +36,11 @@ static std::string SanitizeUsdNameApp(const std::string& raw) { Application::Application() : m_showDemoWindow(false) , m_showStageInfo(true) + , m_showStageEditor(true) + , m_showSceneHierarchy(true) + , m_showViewport(true) + , m_showPropertyPanel(true) + , m_showTimeline(true) , m_running(false) { } @@ -195,6 +201,10 @@ void Application::Update() { void Application::RenderUI() { m_imguiContext->NewFrame(); + // Status bar must be rendered before DockSpaceOverViewport so it + // reserves space at the bottom before the dockspace claims the rest. + RenderStatusBar(); + ImGui::DockSpaceOverViewport(0, ImGui::GetMainViewport()); if (m_showDemoWindow) { @@ -207,30 +217,73 @@ void Application::RenderUI() { RenderStageInfo(); } - ImGui::Begin("Stage Editor", nullptr, ImGuiWindowFlags_NoCollapse); - m_stageEditorPanel->Render(); - ImGui::End(); + if (m_showStageEditor) { + ImGui::Begin("Stage Editor", &m_showStageEditor, ImGuiWindowFlags_NoCollapse); + m_stageEditorPanel->Render(); + ImGui::End(); + } - m_viewportPanel->Render(); + if (m_showViewport) { + m_viewportPanel->Render(&m_showViewport); + } // Scene Hierarchy is rendered AFTER the viewport so that viewport picks // (OnPrimPicked / OnPrimsPickedRect) are visible to the hierarchy in the // same frame — eliminating the one-frame-late scroll/highlight lag. - ImGui::Begin("Scene Hierarchy", nullptr, ImGuiWindowFlags_NoCollapse); - m_sceneHierarchyPanel->Render(); - ImGui::End(); + if (m_showSceneHierarchy) { + ImGui::Begin("Scene Hierarchy", &m_showSceneHierarchy, ImGuiWindowFlags_NoCollapse); + m_sceneHierarchyPanel->Render(); + ImGui::End(); + } - ImGui::Begin("Property Panel", nullptr, ImGuiWindowFlags_NoCollapse); - m_propertyPanel->Render(); - ImGui::End(); + if (m_showPropertyPanel) { + ImGui::Begin("Property Panel", &m_showPropertyPanel, ImGuiWindowFlags_NoCollapse); + m_propertyPanel->Render(); + ImGui::End(); + } - ImGui::Begin("Timeline", nullptr, ImGuiWindowFlags_NoCollapse); - m_timelinePanel->Render(); - ImGui::End(); + if (m_showTimeline) { + ImGui::Begin("Timeline", &m_showTimeline, ImGuiWindowFlags_NoCollapse); + m_timelinePanel->Render(); + ImGui::End(); + } m_imguiContext->Render(); } +void Application::RenderStatusBar() { + ImGuiViewport* vp = ImGui::GetMainViewport(); + float height = ImGui::GetFrameHeight(); + + ImGuiWindowFlags flags = + ImGuiWindowFlags_NoScrollbar | + ImGuiWindowFlags_NoSavedSettings | + ImGuiWindowFlags_MenuBar; + + ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(8.f, 2.f)); + bool open = ImGui::BeginViewportSideBar("##statusbar", vp, + ImGuiDir_Down, height, flags); + ImGui::PopStyleVar(); + + if (open) { + ImGui::BeginMenuBar(); + + // FPS + ImGuiIO& io = ImGui::GetIO(); + char buf[32]; + snprintf(buf, sizeof(buf), "FPS: %.1f", io.Framerate); + // Right-align: measure text, then position cursor. + float textW = ImGui::CalcTextSize(buf).x; + float avail = ImGui::GetContentRegionAvail().x; + if (avail > textW) + ImGui::SetCursorPosX(ImGui::GetCursorPosX() + avail - textW); + ImGui::TextDisabled("%s", buf); + + ImGui::EndMenuBar(); + } + ImGui::End(); +} + void Application::RenderMenuBar() { if (ImGui::BeginMainMenuBar()) { if (ImGui::BeginMenu("File")) { @@ -320,8 +373,14 @@ void Application::RenderMenuBar() { } if (ImGui::BeginMenu("View")) { - ImGui::MenuItem("Stage Info", nullptr, &m_showStageInfo); - ImGui::MenuItem("Show Demo Window", nullptr, &m_showDemoWindow); + ImGui::MenuItem("Stage Editor", nullptr, &m_showStageEditor); + ImGui::MenuItem("Scene Hierarchy", nullptr, &m_showSceneHierarchy); + ImGui::MenuItem("Viewport", nullptr, &m_showViewport); + ImGui::MenuItem("Property Panel", nullptr, &m_showPropertyPanel); + ImGui::MenuItem("Timeline", nullptr, &m_showTimeline); + ImGui::Separator(); + ImGui::MenuItem("Stage Info", nullptr, &m_showStageInfo); + ImGui::MenuItem("Demo Window", nullptr, &m_showDemoWindow); ImGui::EndMenu(); } diff --git a/src/ui/Application.h b/src/ui/Application.h index 6511dba..ebc2a2f 100644 --- a/src/ui/Application.h +++ b/src/ui/Application.h @@ -29,6 +29,7 @@ private: void Update(); void RenderUI(); void RenderMenuBar(); + void RenderStatusBar(); void RenderStageInfo(); void RefreshManagers(); @@ -56,6 +57,11 @@ private: std::unique_ptr m_timelinePanel; bool m_showDemoWindow; bool m_showStageInfo; + bool m_showStageEditor; + bool m_showSceneHierarchy; + bool m_showViewport; + bool m_showPropertyPanel; + bool m_showTimeline; bool m_running; }; diff --git a/src/ui/ViewportPanel.cpp b/src/ui/ViewportPanel.cpp index 1b1ca5d..3863ebd 100644 --- a/src/ui/ViewportPanel.cpp +++ b/src/ui/ViewportPanel.cpp @@ -533,10 +533,10 @@ void ViewportPanel::RenderGlobalLeftToolbar(ImVec2 contentPos, ImVec2 /*contentS // --------------------------------------------------------------------------- // Render // --------------------------------------------------------------------------- -void ViewportPanel::Render() +void ViewportPanel::Render(bool* p_open) { ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(0, 0)); - ImGui::Begin("Viewport", nullptr, + ImGui::Begin("Viewport", p_open, ImGuiWindowFlags_NoCollapse | ImGuiWindowFlags_NoScrollbar | ImGuiWindowFlags_NoScrollWithMouse); diff --git a/src/ui/ViewportPanel.h b/src/ui/ViewportPanel.h index ab284e2..e9ddecc 100644 --- a/src/ui/ViewportPanel.h +++ b/src/ui/ViewportPanel.h @@ -50,7 +50,7 @@ public: void SetSelectedPrimPath(const std::string& path); // ── Main render (called from Application::RenderUI) ────────────────────── - void Render(); + void Render(bool* p_open = nullptr); // ── Pick callbacks (wired by Application after construction) ───────────── std::function OnPrimPicked;