refactor(new_editor): snapshot hosted editor restructuring
This commit is contained in:
@@ -1,22 +1,50 @@
|
||||
#include "Composition/EditorShellRuntime.h"
|
||||
|
||||
#include "Composition/EditorShellRuntime.h"
|
||||
#include "Ports/TexturePort.h"
|
||||
#include "Ports/ViewportRenderPort.h"
|
||||
#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,
|
||||
UIEditorTextMeasurer& textMeasurer) {
|
||||
m_textureHost = &textureHost;
|
||||
m_builtInIcons.Initialize(textureHost);
|
||||
m_sceneViewportFeature.Initialize(repoRoot, textureHost, m_viewportHostService);
|
||||
m_sceneViewportFeature.Initialize(
|
||||
repoRoot,
|
||||
textureHost,
|
||||
&m_builtInIcons,
|
||||
m_viewportHostService);
|
||||
m_hierarchyPanel.SetBuiltInIcons(&m_builtInIcons);
|
||||
m_projectPanel.SetBuiltInIcons(&m_builtInIcons);
|
||||
m_projectPanel.SetTextMeasurer(&textMeasurer);
|
||||
@@ -59,6 +87,7 @@ void EditorShellRuntime::ResetInteractionState() {
|
||||
m_traceEntries.clear();
|
||||
m_sceneViewportFeature.ResetInteractionState();
|
||||
m_hierarchyPanel.ResetInteractionState();
|
||||
m_colorPickerPanel.ResetInteractionState();
|
||||
m_projectPanel.ResetInteractionState();
|
||||
}
|
||||
|
||||
@@ -106,6 +135,26 @@ Widgets::UIEditorDockHostCursorKind EditorShellRuntime::GetDockCursorKind() cons
|
||||
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);
|
||||
}
|
||||
|
||||
EditorShellPointerOwner EditorShellRuntime::GetPointerOwner() const {
|
||||
const auto& dockHostInteractionState =
|
||||
m_shellInteractionState.workspaceInteractionState.dockHostInteractionState;
|
||||
@@ -159,3 +208,465 @@ bool EditorShellRuntime::HasInteractiveCapture() const {
|
||||
}
|
||||
|
||||
} // namespace XCEngine::UI::Editor::App
|
||||
|
||||
namespace XCEngine::UI::Editor::App {
|
||||
|
||||
using ::XCEngine::UI::UIDrawList;
|
||||
|
||||
UIEditorShellComposeModel BuildShellComposeModelFromFrame(
|
||||
const UIEditorShellInteractionFrame& frame) {
|
||||
UIEditorShellComposeModel model = {};
|
||||
model.menuBarItems = frame.request.menuBarItems;
|
||||
model.toolbarButtons = frame.model.toolbarButtons;
|
||||
model.statusSegments = frame.model.statusSegments;
|
||||
model.workspacePresentations = frame.model.workspacePresentations;
|
||||
return model;
|
||||
}
|
||||
|
||||
void AppendShellPopups(
|
||||
UIDrawList& drawList,
|
||||
const UIEditorShellInteractionFrame& frame,
|
||||
const UIEditorShellInteractionPalette& palette,
|
||||
const UIEditorShellInteractionMetrics& metrics) {
|
||||
const std::size_t popupCount =
|
||||
(std::min)(frame.request.popupRequests.size(), frame.popupFrames.size());
|
||||
for (std::size_t index = 0; index < popupCount; ++index) {
|
||||
const UIEditorShellInteractionPopupRequest& popupRequest =
|
||||
frame.request.popupRequests[index];
|
||||
const UIEditorShellInteractionPopupFrame& popupFrame =
|
||||
frame.popupFrames[index];
|
||||
Widgets::AppendUIEditorMenuPopupBackground(
|
||||
drawList,
|
||||
popupRequest.layout,
|
||||
popupRequest.widgetItems,
|
||||
popupFrame.popupState,
|
||||
palette.popupPalette,
|
||||
metrics.popupMetrics);
|
||||
Widgets::AppendUIEditorMenuPopupForeground(
|
||||
drawList,
|
||||
popupRequest.layout,
|
||||
popupRequest.widgetItems,
|
||||
popupFrame.popupState,
|
||||
palette.popupPalette,
|
||||
metrics.popupMetrics);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace XCEngine::UI::Editor::App
|
||||
|
||||
namespace XCEngine::UI::Editor::App {
|
||||
|
||||
using ::XCEngine::UI::UIDrawList;
|
||||
void EditorShellRuntime::RenderRequestedViewports(
|
||||
const ::XCEngine::Rendering::RenderContext& renderContext) {
|
||||
m_viewportHostService.RenderRequestedViewports(renderContext);
|
||||
}
|
||||
|
||||
void EditorShellRuntime::Append(UIDrawList& drawList) const {
|
||||
const auto& metrics = ResolveUIEditorShellInteractionMetrics();
|
||||
const auto& palette = ResolveUIEditorShellInteractionPalette();
|
||||
const UIEditorShellComposeModel shellComposeModel =
|
||||
BuildShellComposeModelFromFrame(m_shellFrame);
|
||||
AppendUIEditorShellCompose(
|
||||
drawList,
|
||||
m_shellFrame.shellFrame,
|
||||
shellComposeModel,
|
||||
m_shellInteractionState.composeState,
|
||||
palette.shellPalette,
|
||||
metrics.shellMetrics,
|
||||
&m_builtInIcons);
|
||||
m_consolePanel.Append(drawList);
|
||||
m_colorPickerPanel.Append(drawList);
|
||||
m_hierarchyPanel.Append(drawList);
|
||||
m_inspectorPanel.Append(drawList);
|
||||
m_projectPanel.Append(drawList);
|
||||
m_sceneViewportFeature.Append(drawList);
|
||||
AppendUIEditorShellComposeOverlay(
|
||||
drawList,
|
||||
m_shellFrame.shellFrame,
|
||||
palette.shellPalette,
|
||||
metrics.shellMetrics);
|
||||
AppendShellPopups(drawList, m_shellFrame, palette, metrics);
|
||||
}
|
||||
|
||||
} // namespace XCEngine::UI::Editor::App
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
PanelInputContext BuildHostedPanelInputContext(
|
||||
const UIEditorWorkspaceInteractionFrame& workspaceFrame,
|
||||
bool allowInteraction,
|
||||
std::string_view panelId) {
|
||||
PanelInputContext inputContext = {};
|
||||
inputContext.allowInteraction = allowInteraction;
|
||||
inputContext.hasInputFocus =
|
||||
IsUIEditorWorkspaceHostedPanelInputOwner(workspaceFrame.inputOwner, panelId);
|
||||
inputContext.focusGained =
|
||||
!IsUIEditorWorkspaceHostedPanelInputOwner(workspaceFrame.previousInputOwner, panelId) &&
|
||||
inputContext.hasInputFocus;
|
||||
inputContext.focusLost =
|
||||
IsUIEditorWorkspaceHostedPanelInputOwner(workspaceFrame.previousInputOwner, panelId) &&
|
||||
!inputContext.hasInputFocus;
|
||||
return inputContext;
|
||||
}
|
||||
|
||||
} // 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;
|
||||
}
|
||||
|
||||
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<UIInputEvent> FilterHostedContentInputEventsForShellOwnership(
|
||||
const std::vector<UIInputEvent>& inputEvents,
|
||||
bool shellOwnsPointerStream) {
|
||||
if (!shellOwnsPointerStream) {
|
||||
return inputEvents;
|
||||
}
|
||||
|
||||
std::vector<UIInputEvent> 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
|
||||
|
||||
namespace XCEngine::UI::Editor::App {
|
||||
|
||||
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,
|
||||
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;
|
||||
|
||||
m_hierarchyPanel.SetSceneRuntime(&context.GetSceneRuntime());
|
||||
m_hierarchyPanel.SetCommandFocusService(&context.GetCommandFocusService());
|
||||
m_sceneEditCommandRoute.BindSceneRuntime(&context.GetSceneRuntime());
|
||||
m_sceneViewportFeature.SetCommandFocusService(&context.GetCommandFocusService());
|
||||
// Keep the previous render request available for readback-based picking during
|
||||
// this update, then refresh it again after camera/navigation state changes.
|
||||
m_sceneViewportFeature.SyncRenderRequest(context.GetSceneRuntime());
|
||||
context.BindEditCommandRoutes(
|
||||
&m_hierarchyPanel,
|
||||
&m_projectPanel,
|
||||
&m_sceneEditCommandRoute,
|
||||
&m_inspectorPanel);
|
||||
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);
|
||||
|
||||
if (TryApplyUIEditorWorkspaceSplitterDragCorrection(
|
||||
m_splitterDragCorrectionState,
|
||||
m_shellInteractionState.workspaceInteractionState.dockHostInteractionState,
|
||||
preUpdateSnapshot,
|
||||
preUpdateDockLayout,
|
||||
workspaceController,
|
||||
metrics.shellMetrics.dockHostMetrics)) {
|
||||
context.SyncSessionFromWorkspace(workspaceController);
|
||||
definition =
|
||||
context.BuildShellDefinition(workspaceController, captureText, shellVariant);
|
||||
m_shellFrame = UpdateUIEditorShellInteraction(
|
||||
m_shellInteractionState,
|
||||
workspaceController,
|
||||
bounds,
|
||||
definition,
|
||||
{},
|
||||
context.GetShellServices(),
|
||||
metrics);
|
||||
}
|
||||
|
||||
const bool shellOwnsHostedContentPointerStream =
|
||||
ShouldHostedContentYieldPointerStream(m_shellFrame, HasShellInteractiveCapture());
|
||||
const std::vector<::XCEngine::UI::UIInputEvent> hostedContentEvents =
|
||||
FilterHostedContentInputEventsForShellOwnership(
|
||||
inputEvents,
|
||||
shellOwnsHostedContentPointerStream);
|
||||
m_sceneViewportFeature.Update(
|
||||
context.GetSceneRuntime(),
|
||||
m_shellInteractionState.workspaceInteractionState.composeState,
|
||||
m_shellFrame.workspaceInteractionFrame.composeFrame);
|
||||
ApplyViewportFramesToShellFrame(m_shellFrame, m_viewportHostService);
|
||||
context.SyncSessionFromWorkspace(workspaceController);
|
||||
context.UpdateStatusFromShellResult(workspaceController, m_shellFrame.result);
|
||||
|
||||
const bool allowHostedInteraction = !m_shellFrame.result.workspaceInputSuppressed;
|
||||
const PanelInputContext hierarchyInputContext = BuildHostedPanelInputContext(
|
||||
m_shellFrame.workspaceInteractionFrame,
|
||||
allowHostedInteraction,
|
||||
kHierarchyPanelId);
|
||||
const PanelInputContext projectInputContext = BuildHostedPanelInputContext(
|
||||
m_shellFrame.workspaceInteractionFrame,
|
||||
allowHostedInteraction,
|
||||
kProjectPanelId);
|
||||
const PanelInputContext inspectorInputContext = BuildHostedPanelInputContext(
|
||||
m_shellFrame.workspaceInteractionFrame,
|
||||
allowHostedInteraction,
|
||||
kInspectorPanelId);
|
||||
const PanelInputContext colorPickerInputContext = BuildHostedPanelInputContext(
|
||||
m_shellFrame.workspaceInteractionFrame,
|
||||
allowHostedInteraction,
|
||||
kColorPickerPanelId);
|
||||
m_projectPanel.SetProjectRuntime(&context.GetProjectRuntime());
|
||||
m_projectPanel.SetCommandFocusService(&context.GetCommandFocusService());
|
||||
m_projectPanel.SetSystemInteractionHost(context.GetSystemInteractionHost());
|
||||
m_inspectorPanel.SetCommandFocusService(&context.GetCommandFocusService());
|
||||
m_hierarchyPanel.Update(
|
||||
m_shellFrame.workspaceInteractionFrame.composeFrame.contentHostFrame,
|
||||
hostedContentEvents,
|
||||
hierarchyInputContext);
|
||||
m_projectPanel.Update(
|
||||
m_shellFrame.workspaceInteractionFrame.composeFrame.contentHostFrame,
|
||||
hostedContentEvents,
|
||||
projectInputContext);
|
||||
m_traceEntries = SyncWorkspaceEvents(context, *this);
|
||||
m_colorPickerPanel.Update(
|
||||
context,
|
||||
m_shellFrame.workspaceInteractionFrame.composeFrame.contentHostFrame,
|
||||
hostedContentEvents,
|
||||
colorPickerInputContext);
|
||||
m_inspectorPanel.Update(
|
||||
context,
|
||||
m_shellFrame.workspaceInteractionFrame.composeFrame.contentHostFrame,
|
||||
hostedContentEvents,
|
||||
inspectorInputContext);
|
||||
context.SyncSessionFromCommandFocusService();
|
||||
m_consolePanel.Update(
|
||||
context.GetSession(),
|
||||
m_shellFrame.workspaceInteractionFrame.composeFrame.contentHostFrame);
|
||||
}
|
||||
|
||||
} // 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);
|
||||
applyToViewportFrames(shellFrame.shellFrame.workspaceFrame.viewportFrames);
|
||||
}
|
||||
|
||||
} // namespace XCEngine::UI::Editor::App
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user