#pragma once #include "Core/IEditorContext.h" #include "Core/IProjectManager.h" #include "Core/ISceneManager.h" #include "Utils/FileDialogUtils.h" #include #include #include namespace XCEngine { namespace Editor { namespace SceneEditorUtils { inline std::string SanitizeSceneFileName(const std::string& value) { std::string result = value.empty() ? "Untitled Scene" : value; for (char& ch : result) { switch (ch) { case '\\': case '/': case ':': case '*': case '?': case '"': case '<': case '>': case '|': ch = '_'; break; default: if (static_cast(ch) < 32u) { ch = '_'; } break; } } return result; } inline const wchar_t* GetSceneFilter() { static const wchar_t filter[] = L"XCEngine Scene (*.xc)\0*.xc\0Legacy Scene (*.scene;*.unity)\0*.scene;*.unity\0All Files (*.*)\0*.*\0\0"; return filter; } inline std::string OpenSceneFileDialog(const std::string& projectPath, const std::string& initialPath = {}) { namespace fs = std::filesystem; const fs::path scenesDir = fs::path(projectPath) / "Assets" / "Scenes"; return FileDialogUtils::OpenFileDialog( GetSceneFilter(), scenesDir.string(), initialPath); } inline std::string SaveSceneFileDialog( const std::string& projectPath, const std::string& currentScenePath, const std::string& currentSceneName) { namespace fs = std::filesystem; const fs::path scenesDir = fs::path(projectPath) / "Assets" / "Scenes"; const fs::path suggestedPath = currentScenePath.empty() ? scenesDir / (SanitizeSceneFileName(currentSceneName) + ".xc") : fs::path(currentScenePath).replace_extension(".xc"); return FileDialogUtils::SaveFileDialog( GetSceneFilter(), suggestedPath.parent_path().string(), suggestedPath.string(), L"xc"); } inline bool SaveCurrentScene(IEditorContext& context) { auto& sceneManager = context.GetSceneManager(); if (sceneManager.SaveScene()) { return true; } const std::string filePath = SaveSceneFileDialog( context.GetProjectPath(), sceneManager.GetCurrentScenePath(), sceneManager.GetCurrentSceneName()); if (filePath.empty()) { return false; } const bool saved = sceneManager.SaveSceneAs(filePath); if (saved) { context.GetProjectManager().RefreshCurrentFolder(); } return saved; } inline bool ConfirmSceneSwitch(IEditorContext& context) { auto& sceneManager = context.GetSceneManager(); if (!sceneManager.HasActiveScene() || !sceneManager.IsSceneDirty()) { return true; } const int result = MessageBoxW( FileDialogUtils::GetDialogOwnerWindow(), L"Save changes to the current scene before continuing?", L"Unsaved Scene Changes", MB_YESNOCANCEL | MB_ICONWARNING); if (result == IDCANCEL) { return false; } if (result == IDYES) { return SaveCurrentScene(context); } return true; } } // namespace SceneEditorUtils } // namespace Editor } // namespace XCEngine