#include "Windowing/Content/EditorWorkspaceWindowContentController.h" #include #include namespace XCEngine::UI::Editor::App { namespace { EditorWindowContentCursorKind ToContentCursorKind(ProjectPanel::CursorKind cursorKind) { switch (cursorKind) { case ProjectPanel::CursorKind::ResizeEW: return EditorWindowContentCursorKind::ResizeEW; case ProjectPanel::CursorKind::Arrow: default: return EditorWindowContentCursorKind::Arrow; } } EditorWindowContentCursorKind ToContentCursorKind( Widgets::UIEditorDockHostCursorKind cursorKind) { switch (cursorKind) { case Widgets::UIEditorDockHostCursorKind::ResizeEW: return EditorWindowContentCursorKind::ResizeEW; case Widgets::UIEditorDockHostCursorKind::ResizeNS: return EditorWindowContentCursorKind::ResizeNS; case Widgets::UIEditorDockHostCursorKind::Arrow: default: return EditorWindowContentCursorKind::Arrow; } } EditorWorkspaceWindowProjection BuildWorkspaceProjectionFromController( const UIEditorWorkspaceController& workspaceController, std::string_view windowId) { EditorWorkspaceWindowProjection projection = {}; projection.windowState.windowId = std::string(windowId); projection.windowState.workspace = workspaceController.GetWorkspace(); projection.windowState.session = workspaceController.GetSession(); projection.minimumOuterSize = ResolveUIEditorDetachedWorkspaceMinimumOuterSize( workspaceController); projection.useDetachedTitleBarTabStrip = HasUIEditorSingleVisibleRootTab(workspaceController); projection.tabStripTitleText = ResolveUIEditorDetachedWorkspaceTitle(workspaceController); projection.detachedWindowTitleText = ResolveUIEditorDetachedWorkspaceTitle(workspaceController); return projection; } } // namespace EditorWorkspaceWindowContentController::EditorWorkspaceWindowContentController( std::string windowId, UIEditorWorkspaceController workspaceController) : m_windowId(std::move(windowId)), m_workspaceController(std::move(workspaceController)) { m_projection = BuildWorkspaceProjectionFromController(m_workspaceController, m_windowId); } EditorWorkspaceWindowContentController::~EditorWorkspaceWindowContentController() = default; EditorWindowContentCapabilities EditorWorkspaceWindowContentController::GetCapabilities() const { return EditorWindowContentCapabilities{ .workspace = true, .dockHost = true, .inputFeedback = true, .titleBar = true, .viewportRendering = true, .utilityPanel = false, }; } EditorWindowWorkspaceBinding* EditorWorkspaceWindowContentController::TryGetWorkspaceBinding() { return this; } const EditorWindowWorkspaceBinding* EditorWorkspaceWindowContentController::TryGetWorkspaceBinding() const { return this; } EditorWindowDockHostBinding* EditorWorkspaceWindowContentController::TryGetDockHostBinding() { return this; } const EditorWindowDockHostBinding* EditorWorkspaceWindowContentController::TryGetDockHostBinding() const { return this; } const EditorWindowInputFeedbackBinding* EditorWorkspaceWindowContentController::TryGetInputFeedbackBinding() const { return this; } const EditorWindowTitleBarBinding* EditorWorkspaceWindowContentController::TryGetTitleBarBinding() const { return this; } const UIEditorWorkspaceController* EditorWorkspaceWindowContentController::TryGetWorkspaceController() const { return &m_workspaceController; } const EditorWorkspaceWindowProjection* EditorWorkspaceWindowContentController::TryGetWorkspaceProjection() const { return &m_projection; } void EditorWorkspaceWindowContentController::RefreshWorkspaceProjection( EditorWorkspaceWindowProjection projection) { projection.windowState.windowId = m_windowId; const auto currentSnapshot = BuildUIEditorWorkspaceLayoutSnapshot( m_workspaceController.GetWorkspace(), m_workspaceController.GetSession()); const auto nextSnapshot = BuildUIEditorWorkspaceLayoutSnapshot( projection.windowState.workspace, projection.windowState.session); if (!AreUIEditorWorkspaceLayoutSnapshotsEquivalent(currentSnapshot, nextSnapshot)) { m_workspaceController = UIEditorWorkspaceController( m_workspaceController.GetPanelRegistry(), projection.windowState.workspace, projection.windowState.session); } m_projection = std::move(projection); } void EditorWorkspaceWindowContentController::Initialize( const EditorWindowContentInitializationContext& context) { m_shellRuntime.Initialize(context.repoRoot, context.textureHost, context.textMeasurer); m_shellRuntime.AttachViewportWindowRenderer(context.viewportRenderer); } void EditorWorkspaceWindowContentController::Shutdown() { m_shellRuntime.Shutdown(); } void EditorWorkspaceWindowContentController::ResetInteractionState() { m_shellRuntime.ResetInteractionState(); } void EditorWorkspaceWindowContentController::SetViewportSurfacePresentationEnabled(bool enabled) { m_shellRuntime.SetViewportSurfacePresentationEnabled(enabled); } EditorWindowFrameTransferRequests EditorWorkspaceWindowContentController::UpdateAndAppend( const EditorWindowContentFrameContext& context, ::XCEngine::UI::UIDrawData& drawData) { const auto beforeSnapshot = BuildUIEditorWorkspaceLayoutSnapshot( m_workspaceController.GetWorkspace(), m_workspaceController.GetSession()); EditorWindowFrameTransferRequests transferRequests = m_frameOrchestrator.UpdateAndAppend( context.editorContext, m_workspaceController, m_shellRuntime, context.bounds, context.inputEvents, context.cursorScreenPoint, context.captureStatusText, context.primary, context.globalTabDragActive, context.useDetachedTitleBarTabStrip, drawData); const auto afterSnapshot = BuildUIEditorWorkspaceLayoutSnapshot( m_workspaceController.GetWorkspace(), m_workspaceController.GetSession()); if (!AreUIEditorWorkspaceLayoutSnapshotsEquivalent(beforeSnapshot, afterSnapshot)) { transferRequests.workspace.workspaceMutation = EditorWindowWorkspaceMutationRequest{ .windowState = UIEditorWindowWorkspaceState{ .windowId = m_windowId, .workspace = m_workspaceController.GetWorkspace(), .session = m_workspaceController.GetSession(), }, }; } return transferRequests; } void EditorWorkspaceWindowContentController::RenderRequestedViewports( const ::XCEngine::Rendering::RenderContext& renderContext) { m_shellRuntime.RenderRequestedViewports(renderContext); } const UIEditorShellInteractionFrame& EditorWorkspaceWindowContentController::GetShellFrame() const { return m_shellRuntime.GetShellFrame(); } const UIEditorShellInteractionState& EditorWorkspaceWindowContentController::GetShellInteractionState() const { return m_shellRuntime.GetShellInteractionState(); } void EditorWorkspaceWindowContentController::SetExternalDockHostDropPreview( const Widgets::UIEditorDockHostDropPreviewState& preview) { m_shellRuntime.SetExternalDockHostDropPreview(preview); } void EditorWorkspaceWindowContentController::ClearExternalDockHostDropPreview() { m_shellRuntime.ClearExternalDockHostDropPreview(); } bool EditorWorkspaceWindowContentController::TryResolveDockTabDragHotspot( std::string_view nodeId, std::string_view panelId, const ::XCEngine::UI::UIPoint& point, ::XCEngine::UI::UIPoint& outHotspot) const { return m_shellRuntime.TryResolveDockTabDragHotspot( nodeId, panelId, point, outHotspot); } UIEditorDockHostTabDropTarget EditorWorkspaceWindowContentController::ResolveDockTabDropTarget( const ::XCEngine::UI::UIPoint& point) const { return m_shellRuntime.ResolveDockTabDropTarget(point); } bool EditorWorkspaceWindowContentController::HasHostedContentCapture() const { return m_shellRuntime.HasHostedContentCapture(); } bool EditorWorkspaceWindowContentController::HasShellInteractiveCapture() const { return m_shellRuntime.HasShellInteractiveCapture(); } bool EditorWorkspaceWindowContentController::HasInteractiveCapture() const { return m_shellRuntime.HasInteractiveCapture(); } EditorWindowContentCursorKind EditorWorkspaceWindowContentController::GetHostedContentCursorKind() const { return ToContentCursorKind(m_shellRuntime.GetHostedContentCursorKind()); } EditorWindowContentCursorKind EditorWorkspaceWindowContentController::GetDockCursorKind() const { return ToContentCursorKind(m_shellRuntime.GetDockCursorKind()); } ::XCEngine::UI::UISize EditorWorkspaceWindowContentController::ResolveMinimumOuterSize() const { return m_projection.minimumOuterSize; } bool EditorWorkspaceWindowContentController::ShouldUseDetachedTitleBarTabStrip() const { return m_projection.useDetachedTitleBarTabStrip; } std::string EditorWorkspaceWindowContentController::ResolveTabStripTitleText( std::string_view fallbackTitle) const { return m_projection.tabStripTitleText.empty() ? std::string(fallbackTitle) : m_projection.tabStripTitleText; } std::string EditorWorkspaceWindowContentController::ResolveDetachedWindowTitleText( std::string_view fallbackWindowTitle) const { return m_projection.detachedWindowTitleText.empty() ? std::string(fallbackWindowTitle) : m_projection.detachedWindowTitleText; } std::unique_ptr CreateEditorWorkspaceWindowContentController( std::string_view windowId, UIEditorWorkspaceController workspaceController) { return std::make_unique( std::string(windowId), std::move(workspaceController)); } } // namespace XCEngine::UI::Editor::App