Files
XCEngine/new_editor/app/Composition/EditorWindowWorkspaceStore.cpp

170 lines
5.6 KiB
C++

#include "Composition/EditorWindowWorkspaceStore.h"
#include <algorithm>
#include <utility>
namespace XCEngine::UI::Editor::App::Internal {
namespace {
UIEditorWindowWorkspaceState BuildWindowState(
std::string_view windowId,
const UIEditorWorkspaceController& workspaceController) {
UIEditorWindowWorkspaceState state = {};
state.windowId = std::string(windowId);
state.workspace = workspaceController.GetWorkspace();
state.session = workspaceController.GetSession();
return state;
}
std::string ResolveFallbackWindowId(const UIEditorWindowWorkspaceSet& windowSet) {
if (!windowSet.primaryWindowId.empty() &&
FindUIEditorWindowWorkspaceState(windowSet, windowSet.primaryWindowId) != nullptr) {
return windowSet.primaryWindowId;
}
return windowSet.windows.empty() ? std::string() : windowSet.windows.front().windowId;
}
void UpsertWindowState(
UIEditorWindowWorkspaceSet& windowSet,
UIEditorWindowWorkspaceState windowState) {
if (UIEditorWindowWorkspaceState* existing =
FindMutableUIEditorWindowWorkspaceState(windowSet, windowState.windowId);
existing != nullptr) {
*existing = std::move(windowState);
return;
}
windowSet.windows.push_back(std::move(windowState));
}
} // namespace
EditorWindowWorkspaceStore::EditorWindowWorkspaceStore(UIEditorPanelRegistry panelRegistry)
: m_panelRegistry(std::move(panelRegistry)) {}
UIEditorWindowWorkspaceController EditorWindowWorkspaceStore::BuildMutationController() const {
return UIEditorWindowWorkspaceController(m_panelRegistry, m_windowSet);
}
bool EditorWindowWorkspaceStore::RegisterWindowProjection(
std::string_view windowId,
bool primary,
const UIEditorWorkspaceController& workspaceController,
std::string& outError) {
UIEditorWindowWorkspaceSet nextWindowSet = m_windowSet;
UpsertWindowState(nextWindowSet, BuildWindowState(windowId, workspaceController));
if (primary) {
if (!nextWindowSet.primaryWindowId.empty() && nextWindowSet.primaryWindowId != windowId) {
outError =
"Cannot register a second primary window '" + std::string(windowId) +
"' while '" + nextWindowSet.primaryWindowId + "' is still primary.";
return false;
}
nextWindowSet.primaryWindowId = std::string(windowId);
} else if (nextWindowSet.primaryWindowId.empty()) {
outError =
"Cannot register detached window '" + std::string(windowId) +
"' before the primary window exists.";
return false;
}
if (nextWindowSet.activeWindowId.empty() ||
FindUIEditorWindowWorkspaceState(nextWindowSet, nextWindowSet.activeWindowId) == nullptr) {
nextWindowSet.activeWindowId = ResolveFallbackWindowId(nextWindowSet);
}
if (!ValidateWindowSet(nextWindowSet, outError)) {
return false;
}
ReplaceWindowSet(std::move(nextWindowSet));
outError.clear();
return true;
}
bool EditorWindowWorkspaceStore::CommitWindowProjection(
std::string_view windowId,
const UIEditorWorkspaceController& workspaceController,
std::string& outError) {
UIEditorWindowWorkspaceSet nextWindowSet = m_windowSet;
UIEditorWindowWorkspaceState* existingWindow =
FindMutableUIEditorWindowWorkspaceState(nextWindowSet, windowId);
if (existingWindow == nullptr) {
outError = "Window '" + std::string(windowId) + "' is not registered in the workspace store.";
return false;
}
existingWindow->workspace = workspaceController.GetWorkspace();
existingWindow->session = workspaceController.GetSession();
if (nextWindowSet.activeWindowId.empty() ||
FindUIEditorWindowWorkspaceState(nextWindowSet, nextWindowSet.activeWindowId) == nullptr) {
nextWindowSet.activeWindowId = ResolveFallbackWindowId(nextWindowSet);
}
if (!ValidateWindowSet(nextWindowSet, outError)) {
return false;
}
ReplaceWindowSet(std::move(nextWindowSet));
outError.clear();
return true;
}
bool EditorWindowWorkspaceStore::ValidateWindowSet(
const UIEditorWindowWorkspaceSet& windowSet,
std::string& outError) const {
const UIEditorWindowWorkspaceValidationResult validation =
ValidateUIEditorWindowWorkspaceSet(m_panelRegistry, windowSet);
if (!validation.IsValid()) {
outError = validation.message;
return false;
}
outError.clear();
return true;
}
void EditorWindowWorkspaceStore::ReplaceWindowSet(UIEditorWindowWorkspaceSet windowSet) {
m_windowSet = std::move(windowSet);
}
void EditorWindowWorkspaceStore::RemoveWindow(std::string_view windowId, bool primary) {
if (m_windowSet.windows.empty()) {
return;
}
if (primary || m_windowSet.primaryWindowId == windowId) {
m_windowSet = {};
return;
}
m_windowSet.windows.erase(
std::remove_if(
m_windowSet.windows.begin(),
m_windowSet.windows.end(),
[windowId](const UIEditorWindowWorkspaceState& state) {
return state.windowId == windowId;
}),
m_windowSet.windows.end());
if (m_windowSet.windows.empty()) {
m_windowSet = {};
return;
}
if (FindUIEditorWindowWorkspaceState(m_windowSet, m_windowSet.primaryWindowId) == nullptr) {
m_windowSet.primaryWindowId = ResolveFallbackWindowId(m_windowSet);
}
if (m_windowSet.activeWindowId == windowId ||
FindUIEditorWindowWorkspaceState(m_windowSet, m_windowSet.activeWindowId) == nullptr) {
m_windowSet.activeWindowId = ResolveFallbackWindowId(m_windowSet);
}
}
} // namespace XCEngine::UI::Editor::App::Internal