Fix editor scene persistence and XC scene workflow

This commit is contained in:
2026-03-26 01:26:26 +08:00
parent 39edb0b497
commit 0651666d8c
35 changed files with 1958 additions and 256 deletions

View File

@@ -1,4 +1,8 @@
#include "MenuBar.h"
#include "Core/IEditorContext.h"
#include "Core/ISceneManager.h"
#include "Utils/SceneEditorUtils.h"
#include <filesystem>
#include <imgui.h>
namespace XCEngine {
@@ -7,20 +11,103 @@ namespace Editor {
MenuBar::MenuBar() : Panel("MenuBar") {}
void MenuBar::Render() {
HandleShortcuts();
if (ImGui::BeginMainMenuBar()) {
ShowFileMenu();
ShowEditMenu();
ShowViewMenu();
ShowHelpMenu();
RenderSceneStatus();
ImGui::EndMainMenuBar();
}
}
void MenuBar::NewScene() {
if (!m_context || !SceneEditorUtils::ConfirmSceneSwitch(*m_context)) {
return;
}
m_context->GetSceneManager().NewScene();
}
void MenuBar::OpenScene() {
if (!m_context || !SceneEditorUtils::ConfirmSceneSwitch(*m_context)) {
return;
}
const std::string filePath = SceneEditorUtils::OpenSceneFileDialog(
m_context->GetProjectPath(),
m_context->GetSceneManager().GetCurrentScenePath());
if (!filePath.empty()) {
m_context->GetSceneManager().LoadScene(filePath);
}
}
void MenuBar::SaveScene() {
if (!m_context) {
return;
}
if (!SceneEditorUtils::SaveCurrentScene(*m_context)) {
return;
}
}
void MenuBar::SaveSceneAs() {
if (!m_context) {
return;
}
const std::string filePath = SceneEditorUtils::SaveSceneFileDialog(
m_context->GetProjectPath(),
m_context->GetSceneManager().GetCurrentScenePath(),
m_context->GetSceneManager().GetCurrentSceneName());
if (!filePath.empty() && m_context->GetSceneManager().SaveSceneAs(filePath)) {
m_context->GetProjectManager().RefreshCurrentFolder();
}
}
void MenuBar::HandleShortcuts() {
if (!m_context) {
return;
}
ImGuiIO& io = ImGui::GetIO();
if (!io.KeyCtrl) {
return;
}
auto& sceneManager = m_context->GetSceneManager();
if (ImGui::IsKeyPressed(ImGuiKey_N, false)) {
NewScene();
}
if (ImGui::IsKeyPressed(ImGuiKey_O, false)) {
OpenScene();
}
if (ImGui::IsKeyPressed(ImGuiKey_S, false)) {
if (io.KeyShift) {
SaveSceneAs();
} else {
SaveScene();
}
}
}
void MenuBar::ShowFileMenu() {
if (ImGui::BeginMenu("File")) {
if (ImGui::MenuItem("New Scene", "Ctrl+N")) {}
if (ImGui::MenuItem("Open Scene", "Ctrl+O")) {}
if (ImGui::MenuItem("Save Scene", "Ctrl+S")) {}
if (ImGui::MenuItem("New Scene", "Ctrl+N")) {
NewScene();
}
if (ImGui::MenuItem("Open Scene", "Ctrl+O")) {
OpenScene();
}
if (ImGui::MenuItem("Save Scene", "Ctrl+S")) {
SaveScene();
}
if (ImGui::MenuItem("Save Scene As...", "Ctrl+Shift+S")) {
SaveSceneAs();
}
ImGui::Separator();
if (ImGui::MenuItem("Exit", "Alt+F4")) {}
ImGui::EndMenu();
@@ -53,5 +140,45 @@ void MenuBar::ShowHelpMenu() {
}
}
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 = std::string("Scene: ") + fileLabel + (dirty ? " Modified" : " Saved");
const ImVec2 textSize = ImGui::CalcTextSize(statusText.c_str());
const float targetX = ImGui::GetWindowWidth() - textSize.x - 20.0f;
if (targetX > ImGui::GetCursorPosX()) {
ImGui::SetCursorPosX(targetX);
}
const ImVec4 accentColor = dirty
? ImVec4(0.94f, 0.68f, 0.20f, 1.0f)
: ImVec4(0.48f, 0.78f, 0.49f, 1.0f);
ImGui::TextColored(accentColor, "%s", statusText.c_str());
if (ImGui::IsItemHovered()) {
ImGui::BeginTooltip();
ImGui::Text("Scene");
ImGui::Separator();
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());
ImGui::EndTooltip();
}
}
}
}
}