View menu — panel visibility toggles for all 5 panels

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 <noreply@anthropic.com>
This commit is contained in:
2026-06-15 22:39:50 +08:00
parent 7f0fa6a944
commit e5d7967455
5 changed files with 121 additions and 27 deletions
+38 -9
View File
@@ -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
+74 -15
View File
@@ -7,6 +7,7 @@
#include <pxr/usd/sdf/path.h>
#include <pxr/base/tf/token.h>
#include <imgui.h>
#include <imgui_internal.h>
#include <vector>
#include <string>
#include <filesystem>
@@ -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();
}
+6
View File
@@ -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<TimelinePanel> 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;
};
+2 -2
View File
@@ -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);
+1 -1
View File
@@ -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<void(const std::string&)> OnPrimPicked;