From f7d7d08d998f09f3e32884fa2d355f52a78a13ad Mon Sep 17 00:00:00 2001 From: ssdfasd <2156608475@qq.com> Date: Thu, 2 Apr 2026 21:21:42 +0800 Subject: [PATCH] feat: add pause control to top run toolbar --- ...式Tick系统与PlayMode运行时方案-阶段进展.md | 5 +- editor/src/panels/MenuBar.cpp | 56 +++++++++++++++---- 2 files changed, 47 insertions(+), 14 deletions(-) diff --git a/docs/plan/Unity式Tick系统与PlayMode运行时方案-阶段进展.md b/docs/plan/Unity式Tick系统与PlayMode运行时方案-阶段进展.md index 6f42f794..f539b971 100644 --- a/docs/plan/Unity式Tick系统与PlayMode运行时方案-阶段进展.md +++ b/docs/plan/Unity式Tick系统与PlayMode运行时方案-阶段进展.md @@ -31,11 +31,12 @@ ### 阶段 D 当前收口 - 已在软件顶部增加独立运行栏 -- 运行栏已接入 `Play / Stop / Step` 三个图标按钮 +- 运行栏已接入 `Play / Pause / Step / Stop` 四个图标按钮 - 顶部按钮直接复用现有 PlayMode 请求通道,不额外分叉状态机 - `Play` 仅在 `Edit` 且存在活动场景时可用 +- `Pause` 在 `Play / Paused` 下可用,并沿用现有 `F6` - `Stop` 在 `Play / Paused` 下可用 -- `Step` 仍只在 `Paused` 下可用,`Pause / Resume` 继续走 `Run` 菜单与 `F6` +- `Step` 仍只在 `Paused` 下可用 ## 本轮验证 diff --git a/editor/src/panels/MenuBar.cpp b/editor/src/panels/MenuBar.cpp index 68efcb1d..2898d691 100644 --- a/editor/src/panels/MenuBar.cpp +++ b/editor/src/panels/MenuBar.cpp @@ -33,10 +33,11 @@ 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", - "stop_button.png", - "step_button.png" + "pause_button.png", + "step_button.png", + "stop_button.png" }; static std::array s_cachedPaths = {}; @@ -53,7 +54,8 @@ bool DrawRunToolbarIconButton( const char* id, const Actions::ActionBinding& action, const std::string& iconPath, - const char* fallbackGlyph) { + const char* fallbackGlyph, + const char* disabledHint = nullptr) { ImGui::BeginDisabled(!action.enabled); ImGui::PushID(id); @@ -92,8 +94,8 @@ bool DrawRunToolbarIconButton( if (!action.shortcutLabel.empty()) { ImGui::Text("Shortcut: %s", action.shortcutLabel.c_str()); } - if (!action.enabled && action.label == "Step") { - ImGui::TextUnformatted("Available while runtime is paused."); + if (!action.enabled && disabledHint && disabledHint[0] != '\0') { + ImGui::TextUnformatted(disabledHint); } UI::EndTitledTooltip(); } @@ -146,32 +148,62 @@ void MenuBar::RenderRunToolbar() { if (open) { const Actions::ActionBinding playAction = Actions::MakeStartPlayModeAction(m_context->GetRuntimeMode(), m_context->GetSceneManager().HasActiveScene()); - const Actions::ActionBinding stopAction = Actions::MakeStopPlayModeAction(m_context->GetRuntimeMode()); + const bool canPause = + m_context->GetRuntimeMode() == EditorRuntimeMode::Play || + m_context->GetRuntimeMode() == EditorRuntimeMode::Paused; + const Actions::ActionBinding pauseAction = + 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 * 3.0f + kRunToolbarButtonSpacing * 2.0f; + kRunToolbarButtonExtent * 4.0f + kRunToolbarButtonSpacing * 3.0f; const float startX = ImGui::GetCursorPosX() + (std::max)(0.0f, (ImGui::GetContentRegionAvail().x - totalWidth) * 0.5f); const float startY = (std::max)(ImGui::GetCursorPosY(), (ImGui::GetWindowHeight() - kRunToolbarButtonExtent) * 0.5f); ImGui::SetCursorPos(ImVec2(startX, startY)); - if (DrawRunToolbarIconButton("Play", playAction, GetRunToolbarIconPath(0), "P")) { + if (DrawRunToolbarIconButton( + "Play", + playAction, + GetRunToolbarIconPath(0), + "P", + "Available in Edit mode when an active scene exists.")) { Actions::RequestStartPlayMode(*m_context); } ImGui::SameLine(0.0f, kRunToolbarButtonSpacing); - if (DrawRunToolbarIconButton("Stop", stopAction, GetRunToolbarIconPath(1), "S")) { - Actions::RequestStopPlayMode(*m_context); + if (DrawRunToolbarIconButton( + "Pause", + pauseAction, + GetRunToolbarIconPath(1), + "||", + "Available while runtime is playing or paused.")) { + Actions::RequestTogglePauseMode(*m_context); } ImGui::SameLine(0.0f, kRunToolbarButtonSpacing); - if (DrawRunToolbarIconButton("Step", stepAction, GetRunToolbarIconPath(2), ">")) { + if (DrawRunToolbarIconButton( + "Step", + stepAction, + GetRunToolbarIconPath(2), + ">", + "Available while runtime is paused.")) { 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(); }