#include "EditorShellRuntime.h" #include "UiTextureHost.h" #include "ViewportRenderHost.h" #include #include #include #include namespace XCEngine::UI::Editor::App { EditorShellRuntime::EditorShellRuntime( EditorWorkspacePanelRuntimeSet workspacePanels, std::unique_ptr iconService, std::unique_ptr viewportRuntimeServices) : m_iconService(std::move(iconService)) , m_viewportRuntimeServices(std::move(viewportRuntimeServices)) , m_workspacePanels(std::move(workspacePanels)) {} void EditorShellRuntime::Initialize( const EditorRuntimePaths& runtimePaths, Rendering::Host::UiTextureHost& textureHost, Host::EditorHostResourceService& resourceService, UIEditorTextMeasurer& textMeasurer) { assert(m_iconService != nullptr); assert(m_viewportRuntimeServices != nullptr); if (m_iconService == nullptr || m_viewportRuntimeServices == nullptr) { return; } m_iconService->Initialize(textureHost, resourceService); m_viewportRuntimeServices->Initialize(runtimePaths); m_workspacePanels.Initialize( EditorWorkspacePanelInitializationContext{ .runtimePaths = runtimePaths, .textMeasurer = textMeasurer, .iconService = *m_iconService, .sceneViewportRuntime = &m_viewportRuntimeServices->GetSceneViewportRuntime(), }); } void EditorShellRuntime::AttachViewportWindowRenderer(Rendering::Host::ViewportRenderHost& renderer) { if (m_viewportRuntimeServices != nullptr) { m_viewportRuntimeServices->AttachWindowRenderer(renderer); } } void EditorShellRuntime::DetachViewportWindowRenderer() { if (m_viewportRuntimeServices != nullptr) { m_viewportRuntimeServices->DetachWindowRenderer(); } } void EditorShellRuntime::SetViewportSurfacePresentationEnabled(bool enabled) { if (m_viewportRuntimeServices != nullptr) { m_viewportRuntimeServices->SetSurfacePresentationEnabled(enabled); } } void EditorShellRuntime::Shutdown() { m_shellFrame = {}; m_shellInteractionState = {}; m_splitterDragCorrectionState = {}; m_traceEntries.clear(); m_workspacePanels.Shutdown(EditorWorkspacePanelShutdownContext{}); m_workspacePanels = {}; if (m_iconService != nullptr) { m_iconService->Shutdown(); } if (m_viewportRuntimeServices != nullptr) { m_viewportRuntimeServices->Shutdown(); } } void EditorShellRuntime::ResetInteractionState() { m_shellFrame = {}; m_shellInteractionState = {}; m_splitterDragCorrectionState = {}; m_traceEntries.clear(); m_workspacePanels.ResetInteractionState(); } const UIEditorShellInteractionFrame& EditorShellRuntime::GetShellFrame() const { return m_shellFrame; } const UIEditorShellInteractionState& EditorShellRuntime::GetShellInteractionState() const { return m_shellInteractionState; } const std::vector& EditorShellRuntime::GetTraceEntries() const { return m_traceEntries; } const std::string& EditorShellRuntime::GetBuiltInIconError() const { static const std::string kEmptyError = {}; return m_iconService != nullptr ? m_iconService->GetLastError() : kEmptyError; } void EditorShellRuntime::SetExternalDockHostDropPreview( const Widgets::UIEditorDockHostDropPreviewState& preview) { m_shellInteractionState.workspaceInteractionState.dockHostInteractionState .dockHostState.dropPreview = preview; } void EditorShellRuntime::ClearExternalDockHostDropPreview() { m_shellInteractionState.workspaceInteractionState.dockHostInteractionState .dockHostState.dropPreview = {}; } EditorWorkspaceShellCursorKind EditorShellRuntime::GetHostedContentCursorKind() const { switch (m_workspacePanels.GetHostedContentCursorKind()) { case EditorWorkspacePanelCursorKind::ResizeEW: return EditorWorkspaceShellCursorKind::ResizeEW; case EditorWorkspacePanelCursorKind::Arrow: default: return EditorWorkspaceShellCursorKind::Arrow; } } Widgets::UIEditorDockHostCursorKind EditorShellRuntime::GetDockCursorKind() const { return Widgets::ResolveUIEditorDockHostCursorKind( m_shellFrame.workspaceInteractionFrame.dockHostFrame.layout); } bool EditorShellRuntime::TryResolveDockTabDragHotspot( std::string_view nodeId, std::string_view panelId, const ::XCEngine::UI::UIPoint& point, ::XCEngine::UI::UIPoint& outHotspot) const { return TryResolveUIEditorDockHostTabDragHotspot( m_shellFrame.workspaceInteractionFrame.dockHostFrame.layout, nodeId, panelId, point, outHotspot); } UIEditorDockHostTabDropTarget EditorShellRuntime::ResolveDockTabDropTarget( const ::XCEngine::UI::UIPoint& point) const { return ResolveUIEditorDockHostTabDropTarget( m_shellFrame.workspaceInteractionFrame.dockHostFrame.layout, point); } bool EditorShellRuntime::HasHostedContentCapture() const { return m_workspacePanels.HasActivePointerCapture(); } bool EditorShellRuntime::HasShellInteractiveCapture() const { return HasActiveUIEditorShellInteractiveCapture(m_shellInteractionState); } bool EditorShellRuntime::HasInteractiveCapture() const { return HasHostedContentCapture() || HasShellInteractiveCapture(); } std::unique_ptr CreateEditorWorkspaceShellRuntime( EditorWorkspacePanelRuntimeSet workspacePanels, std::unique_ptr iconService, std::unique_ptr viewportRuntimeServices) { return std::make_unique( std::move(workspacePanels), std::move(iconService), std::move(viewportRuntimeServices)); } } // namespace XCEngine::UI::Editor::App namespace XCEngine::UI::Editor::App { void EditorShellRuntime::RenderRequestedViewports( const ::XCEngine::Rendering::RenderContext& renderContext) { if (m_viewportRuntimeServices != nullptr) { m_viewportRuntimeServices->RenderRequestedViewports(renderContext); } } void EditorShellRuntime::Append(::XCEngine::UI::UIDrawData& drawData) const { if (m_iconService == nullptr) { return; } m_drawComposer.Append( EditorShellDrawComposerContext{ .shellFrame = m_shellFrame, .shellInteractionState = m_shellInteractionState, .iconService = *m_iconService, .workspacePanels = m_workspacePanels, }, drawData); } } // namespace XCEngine::UI::Editor::App namespace XCEngine::UI::Editor::App { void EditorShellRuntime::Update( EditorFrameServices& frameServices, UIEditorWorkspaceController& workspaceController, const ::XCEngine::UI::UIRect& bounds, const std::vector<::XCEngine::UI::UIInputEvent>& inputEvents, std::string_view captureText, EditorShellVariant shellVariant, bool useDetachedTitleBarTabStrip, float detachedTitleBarTabHeight, float detachedWindowChromeHeight) { if (m_viewportRuntimeServices == nullptr) { return; } const auto buildDefinition = [&]() { return m_sessionCoordinator.PrepareShellDefinition( EditorShellSessionCoordinatorContext{ .frameServices = frameServices, .workspaceController = workspaceController, .captureText = captureText, .shellVariant = shellVariant, .workspacePanels = m_workspacePanels, }); }; m_interactionEngine.Update( EditorShellInteractionEngineContext{ .shellInteractionState = m_shellInteractionState, .shellFrame = m_shellFrame, .splitterDragCorrectionState = m_splitterDragCorrectionState, .workspaceController = workspaceController, .bounds = bounds, .inputEvents = inputEvents, .shellServices = frameServices.GetShellServices(), .buildDefinition = buildDefinition, .hostedContentCaptureActive = HasHostedContentCapture(), .useDetachedTitleBarTabStrip = useDetachedTitleBarTabStrip, .detachedTitleBarTabHeight = detachedTitleBarTabHeight, .detachedWindowChromeHeight = detachedWindowChromeHeight, .viewportRuntimeServices = *m_viewportRuntimeServices, }); m_sessionCoordinator.FinalizeFrame(frameServices, workspaceController, m_shellFrame.result); m_hostedPanelCoordinator.Update( EditorShellHostedPanelCoordinatorContext{ .frameServices = frameServices, .shellFrame = m_shellFrame, .shellInteractionState = m_shellInteractionState, .inputEvents = inputEvents, .shellInteractiveCaptureActive = HasShellInteractiveCapture(), .workspacePanels = m_workspacePanels, }); m_traceEntries = frameServices.SyncWorkspacePanelFrameEvents( m_workspacePanels.CollectFrameEvents()); } } // namespace XCEngine::UI::Editor::App