#include "Composition/EditorShellRuntimeSupport.h" #include namespace XCEngine::UI::Editor::App::RuntimeSupport { namespace { using ::XCEngine::UI::UIInputEvent; using ::XCEngine::UI::UIInputEventType; using Widgets::UIEditorDockHostHitTargetKind; bool IsPointerInputEventType(UIInputEventType type) { switch (type) { case UIInputEventType::PointerMove: case UIInputEventType::PointerEnter: case UIInputEventType::PointerLeave: case UIInputEventType::PointerButtonDown: case UIInputEventType::PointerButtonUp: case UIInputEventType::PointerWheel: return true; default: return false; } } } // namespace std::vector FilterShellInputEventsForHostedContentCapture( const std::vector& inputEvents) { std::vector filteredEvents = {}; filteredEvents.reserve(inputEvents.size()); for (const UIInputEvent& event : inputEvents) { switch (event.type) { case UIInputEventType::PointerMove: case UIInputEventType::PointerEnter: case UIInputEventType::PointerLeave: case UIInputEventType::PointerButtonDown: case UIInputEventType::PointerButtonUp: case UIInputEventType::PointerWheel: break; default: filteredEvents.push_back(event); break; } } return filteredEvents; } bool ShouldHostedContentYieldPointerStream( const UIEditorShellInteractionFrame& shellFrame, bool shellInteractiveCaptureActive) { if (shellInteractiveCaptureActive || shellFrame.result.requestPointerCapture || shellFrame.result.releasePointerCapture) { return true; } return shellFrame.result.workspaceResult.dockHostResult.hitTarget.kind == UIEditorDockHostHitTargetKind::SplitterHandle; } std::vector FilterHostedContentInputEventsForShellOwnership( const std::vector& inputEvents, bool shellOwnsPointerStream) { if (!shellOwnsPointerStream) { return inputEvents; } std::vector filteredEvents = {}; filteredEvents.reserve(inputEvents.size() + 1u); bool strippedPointerInput = false; UIInputEvent lastPointerEvent = {}; for (const UIInputEvent& event : inputEvents) { if (IsPointerInputEventType(event.type)) { strippedPointerInput = true; lastPointerEvent = event; continue; } filteredEvents.push_back(event); } if (strippedPointerInput) { UIInputEvent leaveEvent = {}; leaveEvent.type = UIInputEventType::PointerLeave; leaveEvent.position = lastPointerEvent.position; leaveEvent.modifiers = lastPointerEvent.modifiers; filteredEvents.push_back(leaveEvent); } return filteredEvents; } } // namespace XCEngine::UI::Editor::App::RuntimeSupport namespace XCEngine::UI::Editor::App { using namespace RuntimeSupport; void EditorShellRuntime::Update( EditorContext& context, UIEditorWorkspaceController& workspaceController, const ::XCEngine::UI::UIRect& bounds, const std::vector<::XCEngine::UI::UIInputEvent>& inputEvents, std::string_view captureText, EditorShellVariant shellVariant, bool useDetachedTitleBarTabStrip, float detachedTitleBarTabHeight) { UIEditorShellInteractionMetrics metrics = ResolveUIEditorShellInteractionMetrics(); if (useDetachedTitleBarTabStrip && detachedTitleBarTabHeight > 0.0f) { metrics.shellMetrics.dockHostMetrics.tabStripMetrics.layoutMetrics.headerHeight = detachedTitleBarTabHeight; } context.SyncSessionFromWorkspace(workspaceController); UIEditorShellInteractionDefinition definition = context.BuildShellDefinition(workspaceController, captureText, shellVariant); m_viewportHostService.BeginFrame(); const std::vector<::XCEngine::UI::UIInputEvent> shellEvents = HasHostedContentCapture() ? FilterShellInputEventsForHostedContentCapture(inputEvents) : inputEvents; m_shellFrame = UpdateUIEditorShellInteraction( m_shellInteractionState, workspaceController, bounds, definition, shellEvents, context.GetShellServices(), metrics); const bool shellOwnsHostedContentPointerStream = ShouldHostedContentYieldPointerStream(m_shellFrame, HasShellInteractiveCapture()); const std::vector<::XCEngine::UI::UIInputEvent> hostedContentEvents = FilterHostedContentInputEventsForShellOwnership( inputEvents, shellOwnsHostedContentPointerStream); ApplyViewportFramesToShellFrame(m_shellFrame, m_viewportHostService); context.SyncSessionFromWorkspace(workspaceController); context.UpdateStatusFromShellResult(workspaceController, m_shellFrame.result); const std::string& activePanelId = workspaceController.GetWorkspace().activePanelId; m_hierarchyPanel.Update( m_shellFrame.workspaceInteractionFrame.composeFrame.contentHostFrame, hostedContentEvents, !m_shellFrame.result.workspaceInputSuppressed, activePanelId == "hierarchy"); m_projectPanel.Update( m_shellFrame.workspaceInteractionFrame.composeFrame.contentHostFrame, hostedContentEvents, !m_shellFrame.result.workspaceInputSuppressed, activePanelId == "project"); m_traceEntries = SyncWorkspaceEvents(context, *this); m_inspectorPanel.Update( context.GetSession(), m_shellFrame.workspaceInteractionFrame.composeFrame.contentHostFrame); m_consolePanel.Update( context.GetSession(), m_shellFrame.workspaceInteractionFrame.composeFrame.contentHostFrame); } } // namespace XCEngine::UI::Editor::App