From ec2891b16b8028a44454c6692eedd4041461a0c6 Mon Sep 17 00:00:00 2001 From: ssdfasd <2156608475@qq.com> Date: Thu, 2 Apr 2026 22:19:03 +0800 Subject: [PATCH] fix: respect dock layout for top run toolbar --- ...式Tick系统与PlayMode运行时方案-阶段进展.md | 6 +-- editor/src/Core/EditorWorkspace.h | 14 ++++++- editor/src/Layout/DockLayoutController.h | 6 +-- editor/src/panels/MenuBar.cpp | 39 ++++++++++--------- editor/src/panels/MenuBar.h | 2 + editor/src/panels/PanelCollection.h | 5 ++- 6 files changed, 45 insertions(+), 27 deletions(-) diff --git a/docs/plan/Unity式Tick系统与PlayMode运行时方案-阶段进展.md b/docs/plan/Unity式Tick系统与PlayMode运行时方案-阶段进展.md index f539b971..29da2573 100644 --- a/docs/plan/Unity式Tick系统与PlayMode运行时方案-阶段进展.md +++ b/docs/plan/Unity式Tick系统与PlayMode运行时方案-阶段进展.md @@ -31,12 +31,12 @@ ### 阶段 D 当前收口 - 已在软件顶部增加独立运行栏 -- 运行栏已接入 `Play / Pause / Step / Stop` 四个图标按钮 +- 运行栏已接入 `Play / Pause / Step` 三个图标按钮 - 顶部按钮直接复用现有 PlayMode 请求通道,不额外分叉状态机 -- `Play` 仅在 `Edit` 且存在活动场景时可用 +- `Play` 按钮在运行中会保持高亮,再次点击即 `Stop` - `Pause` 在 `Play / Paused` 下可用,并沿用现有 `F6` -- `Stop` 在 `Play / Paused` 下可用 - `Step` 仍只在 `Paused` 下可用 +- 顶部栏已改为参与 dockspace 布局,不再覆盖 Scene / Hierarchy / Inspector 面板标题区 ## 本轮验证 diff --git a/editor/src/Core/EditorWorkspace.h b/editor/src/Core/EditorWorkspace.h index 31d75cc9..abc44d82 100644 --- a/editor/src/Core/EditorWorkspace.h +++ b/editor/src/Core/EditorWorkspace.h @@ -27,7 +27,7 @@ public: void Attach(IEditorContext& context) { m_panels.Clear(); m_panels.SetContext(&context); - m_panels.Emplace(); + m_menuBar = &m_panels.Emplace(); m_panels.Emplace(); m_panels.Emplace(); m_panels.Emplace(); @@ -54,6 +54,7 @@ public: m_panels.DetachAll(); m_panels.Clear(); + m_menuBar = nullptr; m_projectPanel = nullptr; } @@ -70,11 +71,19 @@ public: } void Render() { + if (m_menuBar) { + m_menuBar->RenderChrome(); + } + if (m_dockLayoutController) { m_dockLayoutController->RenderDockspace(); } - m_panels.RenderAll(); + m_panels.RenderAll(m_menuBar); + + if (m_menuBar) { + m_menuBar->RenderOverlays(); + } } private: @@ -83,6 +92,7 @@ private: } PanelCollection m_panels; + MenuBar* m_menuBar = nullptr; ProjectPanel* m_projectPanel = nullptr; std::unique_ptr m_dockLayoutController; PlaySessionController m_playSessionController; diff --git a/editor/src/Layout/DockLayoutController.h b/editor/src/Layout/DockLayoutController.h index 09cb2f9b..8e1c75c6 100644 --- a/editor/src/Layout/DockLayoutController.h +++ b/editor/src/Layout/DockLayoutController.h @@ -49,8 +49,8 @@ public: ImGuiWindowFlags windowFlags = ImGuiWindowFlags_MenuBar | ImGuiWindowFlags_NoDocking; ImGuiViewport* viewport = ImGui::GetMainViewport(); - ImGui::SetNextWindowPos(viewport->Pos); - ImGui::SetNextWindowSize(viewport->Size); + ImGui::SetNextWindowPos(viewport->WorkPos); + ImGui::SetNextWindowSize(viewport->WorkSize); ImGui::SetNextWindowViewport(viewport->ID); ImGui::PushStyleVar(ImGuiStyleVar_WindowRounding, 0.0f); ImGui::PushStyleVar(ImGuiStyleVar_WindowBorderSize, 0.0f); @@ -71,7 +71,7 @@ public: if (m_layoutDirty) { if (m_forceRebuild || !HasSavedDockLayout()) { - BuildDefaultLayout(dockspaceId, viewport->Size); + BuildDefaultLayout(dockspaceId, viewport->WorkSize); } m_layoutDirty = false; m_forceRebuild = false; diff --git a/editor/src/panels/MenuBar.cpp b/editor/src/panels/MenuBar.cpp index 2898d691..cf58cdd1 100644 --- a/editor/src/panels/MenuBar.cpp +++ b/editor/src/panels/MenuBar.cpp @@ -33,11 +33,10 @@ std::string BuildRunToolbarIconPath(const char* fileName) { } const std::string& GetRunToolbarIconPath(size_t index) { - static const std::array kFileNames = { + static const std::array kFileNames = { "play_button.png", "pause_button.png", - "step_button.png", - "stop_button.png" + "step_button.png" }; static std::array s_cachedPaths = {}; @@ -110,6 +109,11 @@ bool DrawRunToolbarIconButton( MenuBar::MenuBar() : Panel("MenuBar") {} void MenuBar::Render() { + RenderChrome(); + RenderOverlays(); +} + +void MenuBar::RenderChrome() { if (!m_context) { return; } @@ -117,6 +121,13 @@ void MenuBar::Render() { Actions::HandleMenuBarShortcuts(*m_context); Actions::DrawMainMenuBar(*m_context, m_aboutPopup); RenderRunToolbar(); +} + +void MenuBar::RenderOverlays() { + if (!m_context) { + return; + } + Actions::DrawMainMenuOverlays(m_context, m_aboutPopup); } @@ -147,7 +158,10 @@ void MenuBar::RenderRunToolbar() { if (open) { const Actions::ActionBinding playAction = - Actions::MakeStartPlayModeAction(m_context->GetRuntimeMode(), m_context->GetSceneManager().HasActiveScene()); + Actions::MakeTogglePlayModeAction( + m_context->GetRuntimeMode(), + m_context->GetRuntimeMode() != EditorRuntimeMode::Edit || + m_context->GetSceneManager().HasActiveScene()); const bool canPause = m_context->GetRuntimeMode() == EditorRuntimeMode::Play || m_context->GetRuntimeMode() == EditorRuntimeMode::Paused; @@ -155,10 +169,9 @@ void MenuBar::RenderRunToolbar() { Actions::MakeTogglePauseModeAction(m_context->GetRuntimeMode(), canPause); const Actions::ActionBinding stepAction = Actions::MakeStepPlayModeAction(m_context->GetRuntimeMode() == EditorRuntimeMode::Paused); - const Actions::ActionBinding stopAction = Actions::MakeStopPlayModeAction(m_context->GetRuntimeMode()); const float totalWidth = - kRunToolbarButtonExtent * 4.0f + kRunToolbarButtonSpacing * 3.0f; + kRunToolbarButtonExtent * 3.0f + kRunToolbarButtonSpacing * 2.0f; const float startX = ImGui::GetCursorPosX() + (std::max)(0.0f, (ImGui::GetContentRegionAvail().x - totalWidth) * 0.5f); const float startY = @@ -170,8 +183,8 @@ void MenuBar::RenderRunToolbar() { playAction, GetRunToolbarIconPath(0), "P", - "Available in Edit mode when an active scene exists.")) { - Actions::RequestStartPlayMode(*m_context); + "Play requires Edit mode with an active scene.")) { + Actions::RequestTogglePlayMode(*m_context); } ImGui::SameLine(0.0f, kRunToolbarButtonSpacing); @@ -194,16 +207,6 @@ void MenuBar::RenderRunToolbar() { Actions::RequestStepPlayMode(*m_context); } - ImGui::SameLine(0.0f, kRunToolbarButtonSpacing); - if (DrawRunToolbarIconButton( - "Stop", - stopAction, - GetRunToolbarIconPath(3), - "S", - "Available while runtime is active.")) { - Actions::RequestStopPlayMode(*m_context); - } - UI::DrawCurrentWindowBottomBorder(); } diff --git a/editor/src/panels/MenuBar.h b/editor/src/panels/MenuBar.h index a41e84f4..6b81310c 100644 --- a/editor/src/panels/MenuBar.h +++ b/editor/src/panels/MenuBar.h @@ -10,6 +10,8 @@ class MenuBar : public Panel { public: MenuBar(); void Render() override; + void RenderChrome(); + void RenderOverlays(); private: void RenderRunToolbar(); diff --git a/editor/src/panels/PanelCollection.h b/editor/src/panels/PanelCollection.h index b611eedd..cc4145d0 100644 --- a/editor/src/panels/PanelCollection.h +++ b/editor/src/panels/PanelCollection.h @@ -70,8 +70,11 @@ public: } } - void RenderAll() { + void RenderAll(const Panel* skipPanel = nullptr) { for (const auto& panel : m_panels) { + if (panel.get() == skipPanel) { + continue; + } panel->Render(); } }