fix: respect dock layout for top run toolbar

This commit is contained in:
2026-04-02 22:19:03 +08:00
parent 00ce503762
commit ec2891b16b
6 changed files with 45 additions and 27 deletions

View File

@@ -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 面板标题区
## 本轮验证

View File

@@ -27,7 +27,7 @@ public:
void Attach(IEditorContext& context) {
m_panels.Clear();
m_panels.SetContext(&context);
m_panels.Emplace<MenuBar>();
m_menuBar = &m_panels.Emplace<MenuBar>();
m_panels.Emplace<HierarchyPanel>();
m_panels.Emplace<SceneViewPanel>();
m_panels.Emplace<GameViewPanel>();
@@ -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<DockLayoutController> m_dockLayoutController;
PlaySessionController m_playSessionController;

View File

@@ -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;

View File

@@ -33,11 +33,10 @@ std::string BuildRunToolbarIconPath(const char* fileName) {
}
const std::string& GetRunToolbarIconPath(size_t index) {
static const std::array<const char*, 4> kFileNames = {
static const std::array<const char*, 3> kFileNames = {
"play_button.png",
"pause_button.png",
"step_button.png",
"stop_button.png"
"step_button.png"
};
static std::array<std::string, kFileNames.size()> 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();
}

View File

@@ -10,6 +10,8 @@ class MenuBar : public Panel {
public:
MenuBar();
void Render() override;
void RenderChrome();
void RenderOverlays();
private:
void RenderRunToolbar();

View File

@@ -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();
}
}