#include "EditorContext.h" #include "Composition/EditorShellAssetBuilder.h" #include "Scene/EditorSceneRuntime.h" #include "Composition/EditorPanelIds.h" #include #include namespace XCEngine::UI::Editor::App { namespace { using ::XCEngine::UI::Editor::BuildEditorShellShortcutManager; using ::XCEngine::UI::Editor::UIEditorWorkspacePanelPresentationModel; std::string ComposeStatusText( std::string_view status, std::string_view message) { if (status.empty()) { return std::string(message); } if (message.empty()) { return std::string(status); } return std::string(status) + ": " + std::string(message); } UIEditorWorkspacePanelPresentationModel* FindMutablePresentation( std::vector& presentations, std::string_view panelId) { for (UIEditorWorkspacePanelPresentationModel& presentation : presentations) { if (presentation.panelId == panelId) { return &presentation; } } return nullptr; } } // namespace bool EditorContext::Initialize(const std::filesystem::path& repoRoot) { m_shellAsset = BuildEditorApplicationShellAsset(repoRoot); m_shellValidation = ValidateEditorShellAsset(m_shellAsset); if (!m_shellValidation.IsValid()) { return false; } m_session = {}; m_session.repoRoot = repoRoot; m_session.projectRoot = (repoRoot / "project").lexically_normal(); m_commandFocusService = {}; m_selectionService = {}; m_projectRuntime = {}; m_projectRuntime.Initialize(repoRoot); m_projectRuntime.BindSelectionService(&m_selectionService); m_sceneRuntime = {}; m_sceneRuntime.Initialize(m_session.projectRoot); m_sceneRuntime.BindSelectionService(&m_selectionService); SyncSessionFromSelectionService(); m_hostCommandBridge.BindSession(m_session); m_hostCommandBridge.BindCommandFocusService(m_commandFocusService); SyncSessionFromCommandFocusService(); m_shortcutManager = BuildEditorShellShortcutManager(m_shellAsset); m_shortcutManager.SetHostCommandHandler(&m_hostCommandBridge); m_shellServices = {}; m_shellServices.commandDispatcher = &m_shortcutManager.GetCommandDispatcher(); m_shellServices.shortcutManager = &m_shortcutManager; SetReadyStatus(); return true; } void EditorContext::AttachTextMeasurer( const UIEditorTextMeasurer& textMeasurer) { m_shellServices.textMeasurer = &textMeasurer; } void EditorContext::SetSystemInteractionHost(Ports::SystemInteractionPort* systemInteractionHost) { m_systemInteractionHost = systemInteractionHost; } void EditorContext::BindEditCommandRoutes( EditorEditCommandRoute* hierarchyRoute, EditorEditCommandRoute* projectRoute, EditorEditCommandRoute* sceneRoute, EditorEditCommandRoute* inspectorRoute) { m_hostCommandBridge.BindEditCommandRoutes( hierarchyRoute, projectRoute, sceneRoute, inspectorRoute); } void EditorContext::SetExitRequestHandler(std::function handler) { m_hostCommandBridge.SetExitRequestHandler(std::move(handler)); } void EditorContext::SyncSessionFromWorkspace( const UIEditorWorkspaceController& workspaceController) { SyncEditorSessionFromWorkspace(m_session, workspaceController); SyncSessionFromCommandFocusService(); } bool EditorContext::IsValid() const { return m_shellValidation.IsValid(); } const std::string& EditorContext::GetValidationMessage() const { return m_shellValidation.message; } const EditorShellAsset& EditorContext::GetShellAsset() const { return m_shellAsset; } const EditorSession& EditorContext::GetSession() const { return m_session; } EditorCommandFocusService& EditorContext::GetCommandFocusService() { return m_commandFocusService; } const EditorCommandFocusService& EditorContext::GetCommandFocusService() const { return m_commandFocusService; } EditorProjectRuntime& EditorContext::GetProjectRuntime() { return m_projectRuntime; } const EditorProjectRuntime& EditorContext::GetProjectRuntime() const { return m_projectRuntime; } EditorSceneRuntime& EditorContext::GetSceneRuntime() { return m_sceneRuntime; } const EditorSceneRuntime& EditorContext::GetSceneRuntime() const { return m_sceneRuntime; } void EditorContext::SetSelection(EditorSelectionState selection) { m_selectionService.SetSelection(std::move(selection)); SyncSessionFromSelectionService(); } void EditorContext::ClearSelection() { m_selectionService.ClearSelection(); SyncSessionFromSelectionService(); } void EditorContext::SyncSessionFromSelectionService() { m_session.selection = m_selectionService.GetSelection(); } void EditorContext::SyncSessionFromCommandFocusService() { m_session.activeRoute = m_commandFocusService.ResolveRoute( ResolveEditorActionRoute(m_session.activePanelId)); } Ports::SystemInteractionPort* EditorContext::GetSystemInteractionHost() { return m_systemInteractionHost; } const Ports::SystemInteractionPort* EditorContext::GetSystemInteractionHost() const { return m_systemInteractionHost; } UIEditorWorkspaceController EditorContext::BuildWorkspaceController() const { return UIEditorWorkspaceController( m_shellAsset.panelRegistry, m_shellAsset.workspace, m_shellAsset.workspaceSession); } const UIEditorShellInteractionServices& EditorContext::GetShellServices() const { return m_shellServices; } UIEditorShellInteractionDefinition EditorContext::BuildShellDefinition( const UIEditorWorkspaceController& workspaceController, std::string_view captureText, EditorShellVariant variant) const { UIEditorShellInteractionDefinition definition = BuildEditorApplicationShellInteractionDefinition( m_shellAsset, workspaceController, ComposeStatusText(m_lastStatus, m_lastMessage), captureText, variant); if (UIEditorWorkspacePanelPresentationModel* scenePresentation = FindMutablePresentation(definition.workspacePresentations, kScenePanelId); scenePresentation != nullptr) { scenePresentation->viewportShellModel.spec.chrome.showTopBar = false; scenePresentation->viewportShellModel.spec.chrome.title = {}; scenePresentation->viewportShellModel.spec.chrome.subtitle = {}; scenePresentation->viewportShellModel.spec.toolItems.clear(); scenePresentation->viewportShellModel.spec.visualState.hoveredToolIndex = Widgets::UIEditorViewportSlotInvalidIndex; scenePresentation->viewportShellModel.spec.visualState.activeToolIndex = Widgets::UIEditorViewportSlotInvalidIndex; } return definition; } std::string EditorContext::DescribeWorkspaceState( const UIEditorWorkspaceController& workspaceController, const UIEditorShellInteractionState& interactionState) const { std::ostringstream stream = {}; stream << "active=" << workspaceController.GetWorkspace().activePanelId; const auto visiblePanels = CollectUIEditorWorkspaceVisiblePanels( workspaceController.GetWorkspace(), workspaceController.GetSession()); stream << " visible=["; for (std::size_t index = 0; index < visiblePanels.size(); ++index) { if (index > 0u) { stream << ','; } stream << visiblePanels[index].panelId; } stream << ']'; const auto& dockState = interactionState.workspaceInteractionState.dockHostInteractionState; stream << " dragNode=" << dockState.activeTabDragNodeId; stream << " dragPanel=" << dockState.activeTabDragPanelId; if (dockState.dockHostState.dropPreview.visible) { stream << " dropTarget=" << dockState.dockHostState.dropPreview.targetNodeId; } return stream.str(); } } // namespace XCEngine::UI::Editor::App