Refactor main menu action shell

This commit is contained in:
2026-03-27 00:15:38 +08:00
parent 3ebad63874
commit 6ec5f05601
7 changed files with 148 additions and 76 deletions

View File

@@ -0,0 +1,50 @@
#pragma once
#include "EditActionRouter.h"
#include "EditorActions.h"
#include "Commands/SceneCommands.h"
#include "Core/EditorEvents.h"
#include "Core/EventBus.h"
#include "Core/IEditorContext.h"
#include "UI/PopupState.h"
namespace XCEngine {
namespace Editor {
namespace Actions {
inline void HandleMainMenuShortcuts(IEditorContext& context, const ShortcutContext& shortcutContext) {
HandleShortcut(MakeNewSceneAction(), shortcutContext, [&]() { Commands::NewScene(context); });
HandleShortcut(MakeOpenSceneAction(), shortcutContext, [&]() { Commands::OpenSceneWithDialog(context); });
HandleShortcut(MakeSaveSceneAction(), shortcutContext, [&]() { Commands::SaveCurrentScene(context); });
HandleShortcut(MakeSaveSceneAsAction(), shortcutContext, [&]() { Commands::SaveSceneAsWithDialog(context); });
HandleShortcut(MakeUndoAction(context), shortcutContext, [&]() { context.GetUndoManager().Undo(); });
HandleShortcut(MakeRedoAction(context), shortcutContext, [&]() { context.GetUndoManager().Redo(); });
HandleEditShortcuts(context, shortcutContext);
}
inline void DrawFileMenuActions(IEditorContext& context) {
DrawMenuAction(MakeNewSceneAction(), [&]() { Commands::NewScene(context); });
DrawMenuAction(MakeOpenSceneAction(), [&]() { Commands::OpenSceneWithDialog(context); });
DrawMenuAction(MakeSaveSceneAction(), [&]() { Commands::SaveCurrentScene(context); });
DrawMenuAction(MakeSaveSceneAsAction(), [&]() { Commands::SaveSceneAsWithDialog(context); });
DrawMenuSeparator();
DrawMenuAction(MakeExitAction(), [&]() {
context.GetEventBus().Publish(EditorExitRequestedEvent{});
});
}
inline void DrawViewMenuActions(IEditorContext& context) {
DrawMenuAction(MakeResetLayoutAction(), [&]() {
context.GetEventBus().Publish(DockLayoutResetRequestedEvent{});
});
}
inline void DrawHelpMenuActions(UI::DeferredPopupState& aboutPopup) {
DrawMenuAction(MakeAboutAction(), [&]() {
aboutPopup.RequestOpen();
});
}
} // namespace Actions
} // namespace Editor
} // namespace XCEngine

View File

@@ -0,0 +1,39 @@
#pragma once
#include "PopupState.h"
#include "Widgets.h"
#include "Core/IEditorContext.h"
namespace XCEngine {
namespace Editor {
namespace UI {
inline void DrawEditorAboutDialog(const IEditorContext* context, DeferredPopupState& popupState) {
popupState.ConsumeOpenRequest("About XCEngine Editor");
if (!BeginModalPopup("About XCEngine Editor")) {
return;
}
ImGui::TextUnformatted("XCEngine Editor");
ImGui::Separator();
DrawHintText("Unity-like editor shell built on Dear ImGui.");
ImGui::Spacing();
ImGui::Text("Date: 2026-03-27");
ImGui::Text("UI Refactor: Actions / Commands / Layout in progress");
if (context) {
ImGui::Text("Project: %s", context->GetProjectPath().c_str());
}
ImGui::Spacing();
if (ImGui::Button("Close", DialogActionButtonSize())) {
ImGui::CloseCurrentPopup();
}
EndPopup();
}
} // namespace UI
} // namespace Editor
} // namespace XCEngine

View File

@@ -0,0 +1,46 @@
#pragma once
#include "Widgets.h"
#include "Core/IEditorContext.h"
#include "Core/ISceneManager.h"
#include <filesystem>
#include <string>
namespace XCEngine {
namespace Editor {
namespace UI {
inline void DrawSceneStatusWidget(IEditorContext& context) {
auto& sceneManager = context.GetSceneManager();
std::string sceneLabel = sceneManager.HasActiveScene() ? sceneManager.GetCurrentSceneName() : "No Scene";
if (sceneLabel.empty()) {
sceneLabel = "Untitled Scene";
}
const std::string fileLabel = sceneManager.GetCurrentScenePath().empty()
? "Unsaved.xc"
: std::filesystem::path(sceneManager.GetCurrentScenePath()).filename().string();
const bool dirty = sceneManager.IsSceneDirty();
const std::string statusText = dirty ? (std::string("* ") + fileLabel) : fileLabel;
DrawRightAlignedText(
statusText.c_str(),
dirty ? MenuBarStatusDirtyColor() : MenuBarStatusIdleColor());
if (ImGui::IsItemHovered()) {
BeginTitledTooltip("Scene");
ImGui::Text("Name: %s", sceneLabel.c_str());
ImGui::Text("File: %s", fileLabel.c_str());
ImGui::Text("State: %s", dirty ? "Modified" : "Saved");
ImGui::Text(
"Path: %s",
sceneManager.GetCurrentScenePath().empty() ? "(not saved yet)" : sceneManager.GetCurrentScenePath().c_str());
EndTitledTooltip();
}
}
} // namespace UI
} // namespace Editor
} // namespace XCEngine

View File

@@ -1,5 +1,6 @@
#pragma once
#include "AboutEditorDialog.h"
#include "BaseTheme.h"
#include "ConsoleFilterState.h"
#include "ConsoleLogFormatter.h"
@@ -9,6 +10,7 @@
#include "PopupState.h"
#include "PropertyGrid.h"
#include "ScalarControls.h"
#include "SceneStatusWidget.h"
#include "StyleTokens.h"
#include "VectorControls.h"
#include "Widgets.h"

View File

@@ -1,5 +1,6 @@
#pragma once
#include "Core.h"
#include "StyleTokens.h"
#include <imgui.h>

View File

@@ -1,14 +1,9 @@
#include "Actions/ActionRouting.h"
#include "Actions/EditActionRouter.h"
#include "Actions/EditorActions.h"
#include "Commands/SceneCommands.h"
#include "Actions/MainMenuActionRouter.h"
#include "MenuBar.h"
#include "Core/EditorEvents.h"
#include "Core/EventBus.h"
#include "Core/IEditorContext.h"
#include "Core/ISceneManager.h"
#include "UI/UI.h"
#include <filesystem>
#include <imgui.h>
namespace XCEngine {
@@ -36,27 +31,12 @@ void MenuBar::HandleShortcuts() {
return;
}
const Actions::ShortcutContext shortcutContext = Actions::GlobalShortcutContext();
Actions::HandleShortcut(Actions::MakeNewSceneAction(), shortcutContext, [&]() { Commands::NewScene(*m_context); });
Actions::HandleShortcut(Actions::MakeOpenSceneAction(), shortcutContext, [&]() { Commands::OpenSceneWithDialog(*m_context); });
Actions::HandleShortcut(Actions::MakeSaveSceneAction(), shortcutContext, [&]() { Commands::SaveCurrentScene(*m_context); });
Actions::HandleShortcut(Actions::MakeSaveSceneAsAction(), shortcutContext, [&]() { Commands::SaveSceneAsWithDialog(*m_context); });
Actions::HandleShortcut(Actions::MakeUndoAction(*m_context), shortcutContext, [&]() { m_context->GetUndoManager().Undo(); });
Actions::HandleShortcut(Actions::MakeRedoAction(*m_context), shortcutContext, [&]() { m_context->GetUndoManager().Redo(); });
Actions::HandleEditShortcuts(*m_context, shortcutContext);
Actions::HandleMainMenuShortcuts(*m_context, Actions::GlobalShortcutContext());
}
void MenuBar::ShowFileMenu() {
UI::DrawMenuScope("File", [&]() {
Actions::DrawMenuAction(Actions::MakeNewSceneAction(), [&]() { Commands::NewScene(*m_context); });
Actions::DrawMenuAction(Actions::MakeOpenSceneAction(), [&]() { Commands::OpenSceneWithDialog(*m_context); });
Actions::DrawMenuAction(Actions::MakeSaveSceneAction(), [&]() { Commands::SaveCurrentScene(*m_context); });
Actions::DrawMenuAction(Actions::MakeSaveSceneAsAction(), [&]() { Commands::SaveSceneAsWithDialog(*m_context); });
Actions::DrawMenuSeparator();
Actions::DrawMenuAction(Actions::MakeExitAction(), [&]() {
m_context->GetEventBus().Publish(EditorExitRequestedEvent{});
});
Actions::DrawFileMenuActions(*m_context);
});
}
@@ -68,74 +48,25 @@ void MenuBar::ShowEditMenu() {
void MenuBar::ShowViewMenu() {
UI::DrawMenuScope("View", [&]() {
Actions::DrawMenuAction(Actions::MakeResetLayoutAction(), [&]() {
m_context->GetEventBus().Publish(DockLayoutResetRequestedEvent{});
});
Actions::DrawViewMenuActions(*m_context);
});
}
void MenuBar::ShowHelpMenu() {
UI::DrawMenuScope("Help", [&]() {
Actions::DrawMenuAction(Actions::MakeAboutAction(), [&]() {
m_aboutPopup.RequestOpen();
});
Actions::DrawHelpMenuActions(m_aboutPopup);
});
}
void MenuBar::RenderAboutPopup() {
m_aboutPopup.ConsumeOpenRequest("About XCEngine Editor");
if (!UI::BeginModalPopup("About XCEngine Editor")) {
return;
}
ImGui::TextUnformatted("XCEngine Editor");
ImGui::Separator();
UI::DrawHintText("Unity-like editor shell built on Dear ImGui.");
ImGui::Spacing();
ImGui::Text("Date: 2026-03-26");
ImGui::Text("UI Refactor: Actions / Commands / Layout in progress");
if (m_context) {
ImGui::Text("Project: %s", m_context->GetProjectPath().c_str());
}
ImGui::Spacing();
if (Actions::DrawButtonAction(Actions::MakeAction("Close"), UI::DialogActionButtonSize())) {
ImGui::CloseCurrentPopup();
}
UI::EndPopup();
UI::DrawEditorAboutDialog(m_context, m_aboutPopup);
}
void MenuBar::RenderSceneStatus() {
if (!m_context) {
return;
}
auto& sceneManager = m_context->GetSceneManager();
std::string sceneLabel = sceneManager.HasActiveScene() ? sceneManager.GetCurrentSceneName() : "No Scene";
if (sceneLabel.empty()) {
sceneLabel = "Untitled Scene";
}
std::string fileLabel = sceneManager.GetCurrentScenePath().empty()
? "Unsaved.xc"
: std::filesystem::path(sceneManager.GetCurrentScenePath()).filename().string();
const bool dirty = sceneManager.IsSceneDirty();
const std::string statusText = dirty ? (std::string("* ") + fileLabel) : fileLabel;
UI::DrawRightAlignedText(
statusText.c_str(),
dirty ? UI::MenuBarStatusDirtyColor() : UI::MenuBarStatusIdleColor());
if (ImGui::IsItemHovered()) {
UI::BeginTitledTooltip("Scene");
ImGui::Text("Name: %s", sceneLabel.c_str());
ImGui::Text("File: %s", fileLabel.c_str());
ImGui::Text("State: %s", dirty ? "Modified" : "Saved");
ImGui::Text("Path: %s", sceneManager.GetCurrentScenePath().empty() ? "(not saved yet)" : sceneManager.GetCurrentScenePath().c_str());
UI::EndTitledTooltip();
}
UI::DrawSceneStatusWidget(*m_context);
}
}