refactor(new_editor): finish shell runtime stage split
This commit is contained in:
@@ -4,36 +4,9 @@
|
||||
#include "Composition/EditorContext.h"
|
||||
#include "Composition/EditorPanelIds.h"
|
||||
#include <XCEngine/Rendering/RenderContext.h>
|
||||
#include <XCEditor/Foundation/UIEditorTheme.h>
|
||||
#include <algorithm>
|
||||
#include "Features/PanelInputContext.h"
|
||||
|
||||
namespace XCEngine::UI::Editor::App {
|
||||
|
||||
void ApplyViewportFramesToShellFrame(
|
||||
UIEditorShellInteractionFrame& shellFrame,
|
||||
ViewportHostService& viewportHostService);
|
||||
|
||||
std::vector<::XCEngine::UI::UIInputEvent> FilterShellInputEventsForHostedContentCapture(
|
||||
const std::vector<::XCEngine::UI::UIInputEvent>& inputEvents);
|
||||
|
||||
bool ShouldHostedContentYieldPointerStream(
|
||||
const UIEditorShellInteractionFrame& shellFrame,
|
||||
bool shellInteractiveCaptureActive);
|
||||
|
||||
std::vector<::XCEngine::UI::UIInputEvent> FilterHostedContentInputEventsForShellOwnership(
|
||||
const std::vector<::XCEngine::UI::UIInputEvent>& inputEvents,
|
||||
bool shellOwnsPointerStream);
|
||||
|
||||
UIEditorShellComposeModel BuildShellComposeModelFromFrame(
|
||||
const UIEditorShellInteractionFrame& frame);
|
||||
|
||||
void AppendShellPopups(
|
||||
::XCEngine::UI::UIDrawList& drawList,
|
||||
const UIEditorShellInteractionFrame& frame,
|
||||
const UIEditorShellInteractionPalette& palette,
|
||||
const UIEditorShellInteractionMetrics& metrics);
|
||||
|
||||
void EditorShellRuntime::Initialize(
|
||||
const std::filesystem::path& repoRoot,
|
||||
Ports::TexturePort& textureHost,
|
||||
@@ -155,35 +128,10 @@ UIEditorDockHostTabDropTarget EditorShellRuntime::ResolveDockTabDropTarget(
|
||||
}
|
||||
|
||||
EditorShellPointerOwner EditorShellRuntime::GetPointerOwner() const {
|
||||
const auto& dockHostInteractionState =
|
||||
m_shellInteractionState.workspaceInteractionState.dockHostInteractionState;
|
||||
if (dockHostInteractionState.splitterDragState.active ||
|
||||
!dockHostInteractionState.activeTabDragNodeId.empty()) {
|
||||
return EditorShellPointerOwner::DockHost;
|
||||
}
|
||||
|
||||
for (const auto& panelState :
|
||||
m_shellInteractionState.workspaceInteractionState.composeState.panelStates) {
|
||||
if (!panelState.viewportShellState.inputBridgeState.captured) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (panelState.panelId == kGamePanelId) {
|
||||
return EditorShellPointerOwner::GameViewport;
|
||||
}
|
||||
|
||||
return EditorShellPointerOwner::SceneViewport;
|
||||
}
|
||||
|
||||
if (m_hierarchyPanel.HasActivePointerCapture()) {
|
||||
return EditorShellPointerOwner::HierarchyPanel;
|
||||
}
|
||||
|
||||
if (m_projectPanel.HasActivePointerCapture()) {
|
||||
return EditorShellPointerOwner::ProjectPanel;
|
||||
}
|
||||
|
||||
return EditorShellPointerOwner::None;
|
||||
return m_hostedPanelCoordinator.ResolvePointerOwner(
|
||||
m_shellInteractionState,
|
||||
m_hierarchyPanel,
|
||||
m_projectPanel);
|
||||
}
|
||||
|
||||
bool EditorShellRuntime::WantsHostPointerCapture() const {
|
||||
@@ -235,93 +183,6 @@ void EditorShellRuntime::Append(::XCEngine::UI::UIDrawData& drawData) const {
|
||||
|
||||
namespace XCEngine::UI::Editor::App {
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
const UIEditorPanelDescriptor* ResolveSingleVisibleToolWindowPanelDescriptor(
|
||||
const UIEditorWorkspaceController& workspaceController) {
|
||||
const UIEditorWorkspaceNode& root = workspaceController.GetWorkspace().root;
|
||||
if (root.kind != UIEditorWorkspaceNodeKind::TabStack) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
const UIEditorWorkspaceSession& session = workspaceController.GetSession();
|
||||
const UIEditorPanelRegistry& panelRegistry = workspaceController.GetPanelRegistry();
|
||||
const UIEditorPanelDescriptor* visibleDescriptor = nullptr;
|
||||
std::size_t visibleCount = 0u;
|
||||
for (const UIEditorWorkspaceNode& child : root.children) {
|
||||
if (child.kind != UIEditorWorkspaceNodeKind::Panel) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const UIEditorPanelSessionState* panelState =
|
||||
FindUIEditorPanelSessionState(session, child.panel.panelId);
|
||||
if (panelState == nullptr || !panelState->open || !panelState->visible) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const UIEditorPanelDescriptor* descriptor =
|
||||
FindUIEditorPanelDescriptor(panelRegistry, child.panel.panelId);
|
||||
if (descriptor == nullptr) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
++visibleCount;
|
||||
visibleDescriptor = descriptor;
|
||||
if (visibleCount > 1u) {
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
return visibleDescriptor != nullptr && visibleDescriptor->toolWindow
|
||||
? visibleDescriptor
|
||||
: nullptr;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
std::vector<UIInputEvent> FilterShellInputEventsForHostedContentCapture(
|
||||
const std::vector<UIInputEvent>& inputEvents) {
|
||||
std::vector<UIInputEvent> 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;
|
||||
}
|
||||
|
||||
} // namespace XCEngine::UI::Editor::App
|
||||
|
||||
namespace XCEngine::UI::Editor::App {
|
||||
|
||||
void EditorShellRuntime::Update(
|
||||
EditorContext& context,
|
||||
UIEditorWorkspaceController& workspaceController,
|
||||
@@ -332,37 +193,8 @@ void EditorShellRuntime::Update(
|
||||
bool useDetachedTitleBarTabStrip,
|
||||
float detachedTitleBarTabHeight,
|
||||
float detachedWindowChromeHeight) {
|
||||
UIEditorShellInteractionMetrics metrics = ResolveUIEditorShellInteractionMetrics();
|
||||
if (const UIEditorPanelDescriptor* toolWindowDescriptor =
|
||||
ResolveSingleVisibleToolWindowPanelDescriptor(workspaceController);
|
||||
toolWindowDescriptor != nullptr) {
|
||||
metrics.shellMetrics.dockHostMetrics.tabStripMetrics.layoutMetrics.headerHeight = 0.0f;
|
||||
const float minimumContentWidth =
|
||||
toolWindowDescriptor->minimumDetachedWindowSize.width > 0.0f
|
||||
? toolWindowDescriptor->minimumDetachedWindowSize.width
|
||||
: metrics.shellMetrics.dockHostMetrics.minimumStandalonePanelBodySize.width;
|
||||
const float minimumContentHeight =
|
||||
toolWindowDescriptor->minimumDetachedWindowSize.height > detachedWindowChromeHeight
|
||||
? toolWindowDescriptor->minimumDetachedWindowSize.height -
|
||||
detachedWindowChromeHeight
|
||||
: metrics.shellMetrics.dockHostMetrics.minimumStandalonePanelBodySize.height;
|
||||
metrics.shellMetrics.dockHostMetrics.minimumStandalonePanelBodySize =
|
||||
::XCEngine::UI::UISize(minimumContentWidth, minimumContentHeight);
|
||||
metrics.shellMetrics.dockHostMetrics.minimumTabContentBodySize =
|
||||
metrics.shellMetrics.dockHostMetrics.minimumStandalonePanelBodySize;
|
||||
}
|
||||
if (useDetachedTitleBarTabStrip && detachedTitleBarTabHeight > 0.0f) {
|
||||
metrics.shellMetrics.dockHostMetrics.tabStripMetrics.layoutMetrics.headerHeight =
|
||||
detachedTitleBarTabHeight;
|
||||
}
|
||||
|
||||
const UIEditorWorkspaceLayoutSnapshot preUpdateSnapshot =
|
||||
workspaceController.CaptureLayoutSnapshot();
|
||||
const Widgets::UIEditorDockHostLayout preUpdateDockLayout =
|
||||
m_shellFrame.workspaceInteractionFrame.dockHostFrame.layout;
|
||||
|
||||
UIEditorShellInteractionDefinition definition =
|
||||
m_sessionCoordinator.PrepareShellDefinition(
|
||||
const auto buildDefinition = [&]() {
|
||||
return m_sessionCoordinator.PrepareShellDefinition(
|
||||
EditorShellSessionCoordinatorContext{
|
||||
.context = context,
|
||||
.workspaceController = workspaceController,
|
||||
@@ -374,52 +206,23 @@ void EditorShellRuntime::Update(
|
||||
.sceneEditCommandRoute = m_sceneEditCommandRoute,
|
||||
.sceneViewportFeature = m_sceneViewportFeature,
|
||||
});
|
||||
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);
|
||||
|
||||
if (TryApplyUIEditorWorkspaceSplitterDragCorrection(
|
||||
m_splitterDragCorrectionState,
|
||||
m_shellInteractionState.workspaceInteractionState.dockHostInteractionState,
|
||||
preUpdateSnapshot,
|
||||
preUpdateDockLayout,
|
||||
workspaceController,
|
||||
metrics.shellMetrics.dockHostMetrics)) {
|
||||
definition =
|
||||
m_sessionCoordinator.PrepareShellDefinition(
|
||||
EditorShellSessionCoordinatorContext{
|
||||
.context = context,
|
||||
.workspaceController = workspaceController,
|
||||
.captureText = captureText,
|
||||
.shellVariant = shellVariant,
|
||||
.hierarchyPanel = m_hierarchyPanel,
|
||||
.inspectorPanel = m_inspectorPanel,
|
||||
.projectPanel = m_projectPanel,
|
||||
.sceneEditCommandRoute = m_sceneEditCommandRoute,
|
||||
.sceneViewportFeature = m_sceneViewportFeature,
|
||||
});
|
||||
m_shellFrame = UpdateUIEditorShellInteraction(
|
||||
m_shellInteractionState,
|
||||
workspaceController,
|
||||
bounds,
|
||||
definition,
|
||||
{},
|
||||
context.GetShellServices(),
|
||||
metrics);
|
||||
}
|
||||
|
||||
ApplyViewportFramesToShellFrame(m_shellFrame, m_viewportHostService);
|
||||
};
|
||||
m_interactionEngine.Update(
|
||||
EditorShellInteractionEngineContext{
|
||||
.shellInteractionState = m_shellInteractionState,
|
||||
.shellFrame = m_shellFrame,
|
||||
.splitterDragCorrectionState = m_splitterDragCorrectionState,
|
||||
.workspaceController = workspaceController,
|
||||
.bounds = bounds,
|
||||
.inputEvents = inputEvents,
|
||||
.shellServices = context.GetShellServices(),
|
||||
.buildDefinition = buildDefinition,
|
||||
.hostedContentCaptureActive = HasHostedContentCapture(),
|
||||
.useDetachedTitleBarTabStrip = useDetachedTitleBarTabStrip,
|
||||
.detachedTitleBarTabHeight = detachedTitleBarTabHeight,
|
||||
.detachedWindowChromeHeight = detachedWindowChromeHeight,
|
||||
.viewportHostService = m_viewportHostService,
|
||||
});
|
||||
m_sessionCoordinator.FinalizeFrame(context, workspaceController, m_shellFrame.result);
|
||||
|
||||
m_hostedPanelCoordinator.Update(
|
||||
@@ -441,78 +244,4 @@ void EditorShellRuntime::Update(
|
||||
|
||||
} // namespace XCEngine::UI::Editor::App
|
||||
|
||||
namespace XCEngine::UI::Editor::App {
|
||||
|
||||
namespace {
|
||||
|
||||
bool IsViewportPanel(std::string_view panelId) {
|
||||
return IsEditorViewportPanelId(panelId);
|
||||
}
|
||||
|
||||
void ApplyViewportFrameToPresentation(
|
||||
const ViewportFrame& viewportFrame,
|
||||
UIEditorWorkspacePanelPresentationModel& presentation) {
|
||||
presentation.viewportShellModel.frame.texture = viewportFrame.texture;
|
||||
presentation.viewportShellModel.frame.requestedSize = viewportFrame.requestedSize;
|
||||
presentation.viewportShellModel.frame.presentedSize = viewportFrame.renderSize;
|
||||
presentation.viewportShellModel.frame.hasTexture = viewportFrame.hasTexture;
|
||||
presentation.viewportShellModel.frame.statusText = viewportFrame.statusText;
|
||||
}
|
||||
|
||||
void ApplyViewportFrameToShellModel(
|
||||
const ViewportFrame& viewportFrame,
|
||||
UIEditorViewportShellModel& shellModel) {
|
||||
shellModel.frame.texture = viewportFrame.texture;
|
||||
shellModel.frame.requestedSize = viewportFrame.requestedSize;
|
||||
shellModel.frame.presentedSize = viewportFrame.renderSize;
|
||||
shellModel.frame.hasTexture = viewportFrame.hasTexture;
|
||||
shellModel.frame.statusText = viewportFrame.statusText;
|
||||
}
|
||||
|
||||
UIEditorWorkspacePanelPresentationModel* FindMutableWorkspacePresentation(
|
||||
std::vector<UIEditorWorkspacePanelPresentationModel>& presentations,
|
||||
std::string_view panelId) {
|
||||
for (UIEditorWorkspacePanelPresentationModel& presentation : presentations) {
|
||||
if (presentation.panelId == panelId) {
|
||||
return &presentation;
|
||||
}
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
void ApplyViewportFramesToShellFrame(
|
||||
UIEditorShellInteractionFrame& shellFrame,
|
||||
ViewportHostService& viewportHostService) {
|
||||
auto applyToViewportFrames =
|
||||
[&](std::vector<UIEditorWorkspaceViewportComposeFrame>& viewportFrames) {
|
||||
for (UIEditorWorkspaceViewportComposeFrame& viewportComposeFrame : viewportFrames) {
|
||||
if (!IsViewportPanel(viewportComposeFrame.panelId)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const ViewportFrame viewportFrame =
|
||||
viewportHostService.RequestViewport(
|
||||
viewportComposeFrame.panelId,
|
||||
viewportComposeFrame.viewportShellFrame.requestedViewportSize);
|
||||
ApplyViewportFrameToShellModel(
|
||||
viewportFrame,
|
||||
viewportComposeFrame.viewportShellModel);
|
||||
if (UIEditorWorkspacePanelPresentationModel* presentation =
|
||||
FindMutableWorkspacePresentation(
|
||||
shellFrame.model.workspacePresentations,
|
||||
viewportComposeFrame.panelId);
|
||||
presentation != nullptr) {
|
||||
ApplyViewportFrameToPresentation(viewportFrame, *presentation);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
applyToViewportFrames(shellFrame.workspaceInteractionFrame.composeFrame.viewportFrames);
|
||||
}
|
||||
|
||||
} // namespace XCEngine::UI::Editor::App
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user