Files
XCEngine/new_editor/src/Workspace/UIEditorWorkspaceController.cpp

244 lines
8.1 KiB
C++
Raw Normal View History

#include "Workspace/UIEditorWorkspaceControllerInternal.h"
#include <utility>
namespace XCEngine::UI::Editor::Detail {
bool IsPanelOpenAndVisible(
const UIEditorWorkspaceSession& session,
std::string_view panelId) {
const UIEditorPanelSessionState* panelState =
FindUIEditorPanelSessionState(session, panelId);
return panelState != nullptr && panelState->open && panelState->visible;
}
std::vector<std::string> CollectVisiblePanelIds(
const UIEditorWorkspaceModel& workspace,
const UIEditorWorkspaceSession& session) {
const std::vector<UIEditorWorkspaceVisiblePanel> panels =
CollectUIEditorWorkspaceVisiblePanels(workspace, session);
std::vector<std::string> ids = {};
ids.reserve(panels.size());
for (const UIEditorWorkspaceVisiblePanel& panel : panels) {
ids.push_back(panel.panelId);
}
return ids;
}
VisibleTabStackInfo ResolveVisibleTabStackInfo(
const UIEditorWorkspaceNode& node,
const UIEditorWorkspaceSession& session,
std::string_view panelId) {
VisibleTabStackInfo info = {};
for (const UIEditorWorkspaceNode& child : node.children) {
if (child.kind != UIEditorWorkspaceNodeKind::Panel) {
continue;
}
const bool visible = IsPanelOpenAndVisible(session, child.panel.panelId);
if (child.panel.panelId == panelId) {
info.panelExists = true;
info.panelVisible = visible;
if (visible) {
info.currentVisibleIndex = info.visibleTabCount;
}
}
if (visible) {
++info.visibleTabCount;
}
}
return info;
}
std::size_t CountVisibleTabs(
const UIEditorWorkspaceNode& node,
const UIEditorWorkspaceSession& session) {
if (node.kind != UIEditorWorkspaceNodeKind::TabStack) {
return 0u;
}
std::size_t visibleCount = 0u;
for (const UIEditorWorkspaceNode& child : node.children) {
if (child.kind == UIEditorWorkspaceNodeKind::Panel &&
IsPanelOpenAndVisible(session, child.panel.panelId)) {
++visibleCount;
}
}
return visibleCount;
}
} // namespace XCEngine::UI::Editor::Detail
namespace XCEngine::UI::Editor {
std::string_view GetUIEditorWorkspaceCommandKindName(UIEditorWorkspaceCommandKind kind) {
switch (kind) {
case UIEditorWorkspaceCommandKind::OpenPanel:
return "OpenPanel";
case UIEditorWorkspaceCommandKind::ClosePanel:
return "ClosePanel";
case UIEditorWorkspaceCommandKind::ShowPanel:
return "ShowPanel";
case UIEditorWorkspaceCommandKind::HidePanel:
return "HidePanel";
case UIEditorWorkspaceCommandKind::ActivatePanel:
return "ActivatePanel";
case UIEditorWorkspaceCommandKind::ResetWorkspace:
return "ResetWorkspace";
}
return "Unknown";
}
std::string_view GetUIEditorWorkspaceCommandStatusName(
UIEditorWorkspaceCommandStatus status) {
switch (status) {
case UIEditorWorkspaceCommandStatus::Changed:
return "Changed";
case UIEditorWorkspaceCommandStatus::NoOp:
return "NoOp";
case UIEditorWorkspaceCommandStatus::Rejected:
return "Rejected";
}
return "Unknown";
}
std::string_view GetUIEditorWorkspaceLayoutOperationStatusName(
UIEditorWorkspaceLayoutOperationStatus status) {
switch (status) {
case UIEditorWorkspaceLayoutOperationStatus::Changed:
return "Changed";
case UIEditorWorkspaceLayoutOperationStatus::NoOp:
return "NoOp";
case UIEditorWorkspaceLayoutOperationStatus::Rejected:
return "Rejected";
}
return "Unknown";
}
UIEditorWorkspaceController::UIEditorWorkspaceController(
UIEditorPanelRegistry panelRegistry,
UIEditorWorkspaceModel workspace,
UIEditorWorkspaceSession session)
: m_panelRegistry(std::move(panelRegistry))
, m_baselineWorkspace(CanonicalizeUIEditorWorkspaceModel(workspace))
, m_baselineSession(session)
, m_workspace(m_baselineWorkspace)
, m_session(std::move(session)) {
}
UIEditorWorkspaceControllerValidationResult UIEditorWorkspaceController::ValidateState() const {
const UIEditorPanelRegistryValidationResult registryValidation =
ValidateUIEditorPanelRegistry(m_panelRegistry);
if (!registryValidation.IsValid()) {
UIEditorWorkspaceControllerValidationResult result = {};
result.code = UIEditorWorkspaceControllerValidationCode::InvalidPanelRegistry;
result.message = registryValidation.message;
return result;
}
const UIEditorWorkspaceValidationResult workspaceValidation =
ValidateUIEditorWorkspace(m_workspace);
if (!workspaceValidation.IsValid()) {
UIEditorWorkspaceControllerValidationResult result = {};
result.code = UIEditorWorkspaceControllerValidationCode::InvalidWorkspace;
result.message = workspaceValidation.message;
return result;
}
const UIEditorWorkspaceSessionValidationResult sessionValidation =
ValidateUIEditorWorkspaceSession(m_panelRegistry, m_workspace, m_session);
if (!sessionValidation.IsValid()) {
UIEditorWorkspaceControllerValidationResult result = {};
result.code = UIEditorWorkspaceControllerValidationCode::InvalidWorkspaceSession;
result.message = sessionValidation.message;
return result;
}
return {};
}
UIEditorWorkspaceLayoutSnapshot UIEditorWorkspaceController::CaptureLayoutSnapshot() const {
return BuildUIEditorWorkspaceLayoutSnapshot(m_workspace, m_session);
}
UIEditorWorkspaceCommandResult UIEditorWorkspaceController::BuildResult(
const UIEditorWorkspaceCommand& command,
UIEditorWorkspaceCommandStatus status,
std::string message) const {
UIEditorWorkspaceCommandResult result = {};
result.kind = command.kind;
result.status = status;
result.panelId = command.panelId;
result.message = std::move(message);
result.activePanelId = m_workspace.activePanelId;
result.visiblePanelIds = Detail::CollectVisiblePanelIds(m_workspace, m_session);
return result;
}
UIEditorWorkspaceLayoutOperationResult UIEditorWorkspaceController::BuildLayoutOperationResult(
UIEditorWorkspaceLayoutOperationStatus status,
std::string message) const {
UIEditorWorkspaceLayoutOperationResult result = {};
result.status = status;
result.message = std::move(message);
result.activePanelId = m_workspace.activePanelId;
result.visiblePanelIds = Detail::CollectVisiblePanelIds(m_workspace, m_session);
return result;
}
UIEditorWorkspaceCommandResult UIEditorWorkspaceController::FinalizeMutation(
const UIEditorWorkspaceCommand& command,
bool changed,
std::string changedMessage,
std::string unexpectedFailureMessage,
const UIEditorWorkspaceModel& previousWorkspace,
const UIEditorWorkspaceSession& previousSession) {
if (!changed) {
return BuildResult(
command,
UIEditorWorkspaceCommandStatus::Rejected,
std::move(unexpectedFailureMessage));
}
const UIEditorWorkspaceControllerValidationResult validation = ValidateState();
if (!validation.IsValid()) {
m_workspace = previousWorkspace;
m_session = previousSession;
return BuildResult(
command,
UIEditorWorkspaceCommandStatus::Rejected,
"Command produced invalid workspace state: " + validation.message);
}
return BuildResult(
command,
UIEditorWorkspaceCommandStatus::Changed,
std::move(changedMessage));
}
const UIEditorPanelDescriptor* UIEditorWorkspaceController::FindPanelDescriptor(
std::string_view panelId) const {
return FindUIEditorPanelDescriptor(m_panelRegistry, panelId);
}
UIEditorWorkspaceController BuildDefaultUIEditorWorkspaceController(
const UIEditorPanelRegistry& panelRegistry,
const UIEditorWorkspaceModel& workspace) {
const UIEditorWorkspaceModel canonicalWorkspace =
CanonicalizeUIEditorWorkspaceModel(workspace);
return UIEditorWorkspaceController(
panelRegistry,
canonicalWorkspace,
BuildDefaultUIEditorWorkspaceSession(panelRegistry, canonicalWorkspace));
}
} // namespace XCEngine::UI::Editor