feat: add editor project switching workflow
This commit is contained in:
@@ -3,15 +3,10 @@
|
||||
#include "Core/IEditorContext.h"
|
||||
#include "Core/IProjectManager.h"
|
||||
#include "Core/ISceneManager.h"
|
||||
|
||||
#ifndef NOMINMAX
|
||||
#define NOMINMAX
|
||||
#endif
|
||||
#include "Utils/FileDialogUtils.h"
|
||||
|
||||
#include <windows.h>
|
||||
#include <commdlg.h>
|
||||
|
||||
#include <array>
|
||||
#include <filesystem>
|
||||
#include <string>
|
||||
|
||||
@@ -19,36 +14,6 @@ namespace XCEngine {
|
||||
namespace Editor {
|
||||
namespace SceneEditorUtils {
|
||||
|
||||
inline std::wstring Utf8ToWide(const std::string& value) {
|
||||
if (value.empty()) {
|
||||
return {};
|
||||
}
|
||||
|
||||
const int length = MultiByteToWideChar(CP_UTF8, 0, value.c_str(), -1, nullptr, 0);
|
||||
if (length <= 0) {
|
||||
return {};
|
||||
}
|
||||
|
||||
std::wstring result(length - 1, L'\0');
|
||||
MultiByteToWideChar(CP_UTF8, 0, value.c_str(), -1, &result[0], length);
|
||||
return result;
|
||||
}
|
||||
|
||||
inline std::string WideToUtf8(const std::wstring& value) {
|
||||
if (value.empty()) {
|
||||
return {};
|
||||
}
|
||||
|
||||
const int length = WideCharToMultiByte(CP_UTF8, 0, value.c_str(), -1, nullptr, 0, nullptr, nullptr);
|
||||
if (length <= 0) {
|
||||
return {};
|
||||
}
|
||||
|
||||
std::string result(length - 1, '\0');
|
||||
WideCharToMultiByte(CP_UTF8, 0, value.c_str(), -1, &result[0], length, nullptr, nullptr);
|
||||
return result;
|
||||
}
|
||||
|
||||
inline std::string SanitizeSceneFileName(const std::string& value) {
|
||||
std::string result = value.empty() ? "Untitled Scene" : value;
|
||||
for (char& ch : result) {
|
||||
@@ -74,14 +39,6 @@ inline std::string SanitizeSceneFileName(const std::string& value) {
|
||||
return result;
|
||||
}
|
||||
|
||||
inline HWND GetDialogOwnerWindow() {
|
||||
HWND owner = GetActiveWindow();
|
||||
if (!owner) {
|
||||
owner = GetForegroundWindow();
|
||||
}
|
||||
return owner;
|
||||
}
|
||||
|
||||
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";
|
||||
@@ -92,28 +49,10 @@ inline std::string OpenSceneFileDialog(const std::string& projectPath, const std
|
||||
namespace fs = std::filesystem;
|
||||
|
||||
const fs::path scenesDir = fs::path(projectPath) / "Assets" / "Scenes";
|
||||
const std::wstring initialDir = Utf8ToWide(scenesDir.string());
|
||||
|
||||
std::array<wchar_t, 1024> fileBuffer{};
|
||||
if (!initialPath.empty()) {
|
||||
const std::wstring initialFile = Utf8ToWide(initialPath);
|
||||
wcsncpy_s(fileBuffer.data(), fileBuffer.size(), initialFile.c_str(), _TRUNCATE);
|
||||
}
|
||||
|
||||
OPENFILENAMEW dialog{};
|
||||
dialog.lStructSize = sizeof(dialog);
|
||||
dialog.hwndOwner = GetDialogOwnerWindow();
|
||||
dialog.lpstrFilter = GetSceneFilter();
|
||||
dialog.lpstrFile = fileBuffer.data();
|
||||
dialog.nMaxFile = static_cast<DWORD>(fileBuffer.size());
|
||||
dialog.lpstrInitialDir = initialDir.empty() ? nullptr : initialDir.c_str();
|
||||
dialog.Flags = OFN_FILEMUSTEXIST | OFN_PATHMUSTEXIST | OFN_NOCHANGEDIR;
|
||||
|
||||
if (!GetOpenFileNameW(&dialog)) {
|
||||
return {};
|
||||
}
|
||||
|
||||
return WideToUtf8(fileBuffer.data());
|
||||
return FileDialogUtils::OpenFileDialog(
|
||||
GetSceneFilter(),
|
||||
scenesDir.string(),
|
||||
initialPath);
|
||||
}
|
||||
|
||||
inline std::string SaveSceneFileDialog(
|
||||
@@ -127,26 +66,11 @@ inline std::string SaveSceneFileDialog(
|
||||
? scenesDir / (SanitizeSceneFileName(currentSceneName) + ".xc")
|
||||
: fs::path(currentScenePath).replace_extension(".xc");
|
||||
|
||||
std::array<wchar_t, 1024> fileBuffer{};
|
||||
const std::wstring suggestedWide = Utf8ToWide(suggestedPath.string());
|
||||
wcsncpy_s(fileBuffer.data(), fileBuffer.size(), suggestedWide.c_str(), _TRUNCATE);
|
||||
|
||||
const std::wstring initialDir = Utf8ToWide(suggestedPath.parent_path().string());
|
||||
OPENFILENAMEW dialog{};
|
||||
dialog.lStructSize = sizeof(dialog);
|
||||
dialog.hwndOwner = GetDialogOwnerWindow();
|
||||
dialog.lpstrFilter = GetSceneFilter();
|
||||
dialog.lpstrFile = fileBuffer.data();
|
||||
dialog.nMaxFile = static_cast<DWORD>(fileBuffer.size());
|
||||
dialog.lpstrInitialDir = initialDir.empty() ? nullptr : initialDir.c_str();
|
||||
dialog.lpstrDefExt = L"xc";
|
||||
dialog.Flags = OFN_OVERWRITEPROMPT | OFN_PATHMUSTEXIST | OFN_NOCHANGEDIR;
|
||||
|
||||
if (!GetSaveFileNameW(&dialog)) {
|
||||
return {};
|
||||
}
|
||||
|
||||
return WideToUtf8(fileBuffer.data());
|
||||
return FileDialogUtils::SaveFileDialog(
|
||||
GetSceneFilter(),
|
||||
suggestedPath.parent_path().string(),
|
||||
suggestedPath.string(),
|
||||
L"xc");
|
||||
}
|
||||
|
||||
inline bool SaveCurrentScene(IEditorContext& context) {
|
||||
@@ -177,7 +101,7 @@ inline bool ConfirmSceneSwitch(IEditorContext& context) {
|
||||
}
|
||||
|
||||
const int result = MessageBoxW(
|
||||
GetDialogOwnerWindow(),
|
||||
FileDialogUtils::GetDialogOwnerWindow(),
|
||||
L"Save changes to the current scene before continuing?",
|
||||
L"Unsaved Scene Changes",
|
||||
MB_YESNOCANCEL | MB_ICONWARNING);
|
||||
|
||||
Reference in New Issue
Block a user