Refactor new editor boundaries and test ownership
This commit is contained in:
@@ -200,7 +200,8 @@ UIEditorWorkspaceComposeFrame UpdateUIEditorWorkspaceCompose(
|
||||
const std::vector<::XCEngine::UI::UIInputEvent>& inputEvents,
|
||||
const Widgets::UIEditorDockHostState& dockHostState,
|
||||
const Widgets::UIEditorDockHostMetrics& dockHostMetrics,
|
||||
const Widgets::UIEditorViewportSlotMetrics& viewportMetrics) {
|
||||
const Widgets::UIEditorViewportSlotMetrics& viewportMetrics,
|
||||
const UIEditorWorkspaceInputOwner* inputOwner) {
|
||||
UIEditorWorkspaceComposeFrame frame = {};
|
||||
frame.dockHostLayout = BuildUIEditorDockHostLayout(
|
||||
bounds,
|
||||
@@ -238,12 +239,19 @@ UIEditorWorkspaceComposeFrame UpdateUIEditorWorkspaceCompose(
|
||||
viewportFrame.panelId = presentation.panelId;
|
||||
viewportFrame.bounds = contentHostPanelState->bounds;
|
||||
viewportFrame.viewportShellModel = presentation.viewportShellModel;
|
||||
UIEditorViewportInputBridgeRequest inputRequest = {};
|
||||
if (inputOwner != nullptr) {
|
||||
inputRequest.focusMode = UIEditorViewportInputBridgeFocusMode::External;
|
||||
inputRequest.focused =
|
||||
IsUIEditorWorkspaceViewportInputOwner(*inputOwner, presentation.panelId);
|
||||
}
|
||||
viewportFrame.viewportShellFrame = UpdateUIEditorViewportShell(
|
||||
panelState.viewportShellState,
|
||||
contentHostPanelState->bounds,
|
||||
presentation.viewportShellModel,
|
||||
inputEvents,
|
||||
viewportMetrics);
|
||||
viewportMetrics,
|
||||
inputRequest);
|
||||
frame.viewportFrames.push_back(std::move(viewportFrame));
|
||||
}
|
||||
|
||||
|
||||
143
new_editor/src/Workspace/UIEditorWorkspaceInputOwner.cpp
Normal file
143
new_editor/src/Workspace/UIEditorWorkspaceInputOwner.cpp
Normal file
@@ -0,0 +1,143 @@
|
||||
#include <XCEditor/Workspace/UIEditorWorkspaceInputOwner.h>
|
||||
|
||||
namespace XCEngine::UI::Editor {
|
||||
|
||||
namespace {
|
||||
|
||||
using ::XCEngine::UI::UIPoint;
|
||||
using ::XCEngine::UI::UIRect;
|
||||
using Widgets::HitTestUIEditorDockHost;
|
||||
using Widgets::UIEditorDockHostHitTargetKind;
|
||||
|
||||
bool ContainsPoint(const UIRect& rect, const UIPoint& point) {
|
||||
return point.x >= rect.x &&
|
||||
point.x <= rect.x + rect.width &&
|
||||
point.y >= rect.y &&
|
||||
point.y <= rect.y + rect.height;
|
||||
}
|
||||
|
||||
bool HasUsableBounds(const UIRect& rect) {
|
||||
return rect.width > 0.0f && rect.height > 0.0f;
|
||||
}
|
||||
|
||||
bool IsMountedContentPanelValid(
|
||||
const UIEditorPanelContentHostPanelState& panelState) {
|
||||
return panelState.mounted && HasUsableBounds(panelState.bounds);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
std::string_view GetUIEditorWorkspaceInputOwnerKindName(
|
||||
UIEditorWorkspaceInputOwnerKind kind) {
|
||||
switch (kind) {
|
||||
case UIEditorWorkspaceInputOwnerKind::None:
|
||||
return "None";
|
||||
case UIEditorWorkspaceInputOwnerKind::DockHost:
|
||||
return "DockHost";
|
||||
case UIEditorWorkspaceInputOwnerKind::HostedPanel:
|
||||
return "HostedPanel";
|
||||
case UIEditorWorkspaceInputOwnerKind::Viewport:
|
||||
return "Viewport";
|
||||
}
|
||||
|
||||
return "Unknown";
|
||||
}
|
||||
|
||||
bool AreUIEditorWorkspaceInputOwnersEquivalent(
|
||||
const UIEditorWorkspaceInputOwner& lhs,
|
||||
const UIEditorWorkspaceInputOwner& rhs) {
|
||||
return lhs.kind == rhs.kind && lhs.panelId == rhs.panelId;
|
||||
}
|
||||
|
||||
bool IsUIEditorWorkspaceDockHostInputOwner(
|
||||
const UIEditorWorkspaceInputOwner& owner) {
|
||||
return owner.kind == UIEditorWorkspaceInputOwnerKind::DockHost;
|
||||
}
|
||||
|
||||
bool IsUIEditorWorkspaceHostedPanelInputOwner(
|
||||
const UIEditorWorkspaceInputOwner& owner,
|
||||
std::string_view panelId) {
|
||||
return owner.kind == UIEditorWorkspaceInputOwnerKind::HostedPanel &&
|
||||
(panelId.empty() || owner.panelId == panelId);
|
||||
}
|
||||
|
||||
bool IsUIEditorWorkspaceViewportInputOwner(
|
||||
const UIEditorWorkspaceInputOwner& owner,
|
||||
std::string_view panelId) {
|
||||
return owner.kind == UIEditorWorkspaceInputOwnerKind::Viewport &&
|
||||
(panelId.empty() || owner.panelId == panelId);
|
||||
}
|
||||
|
||||
UIEditorWorkspaceInputOwner ResolveUIEditorWorkspacePointerInputOwner(
|
||||
const Widgets::UIEditorDockHostLayout& dockHostLayout,
|
||||
const UIEditorPanelContentHostFrame& contentHostFrame,
|
||||
const UIPoint& pointerPosition) {
|
||||
for (const UIEditorPanelContentHostPanelState& panelState :
|
||||
contentHostFrame.panelStates) {
|
||||
if (!IsMountedContentPanelValid(panelState) ||
|
||||
!ContainsPoint(panelState.bounds, pointerPosition)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
UIEditorWorkspaceInputOwner owner = {};
|
||||
owner.panelId = panelState.panelId;
|
||||
owner.kind = panelState.kind == UIEditorPanelPresentationKind::ViewportShell
|
||||
? UIEditorWorkspaceInputOwnerKind::Viewport
|
||||
: UIEditorWorkspaceInputOwnerKind::HostedPanel;
|
||||
return owner;
|
||||
}
|
||||
|
||||
const Widgets::UIEditorDockHostHitTarget hitTarget =
|
||||
HitTestUIEditorDockHost(dockHostLayout, pointerPosition);
|
||||
switch (hitTarget.kind) {
|
||||
case UIEditorDockHostHitTargetKind::SplitterHandle:
|
||||
case UIEditorDockHostHitTargetKind::TabStripBackground:
|
||||
case UIEditorDockHostHitTargetKind::Tab:
|
||||
case UIEditorDockHostHitTargetKind::PanelHeader:
|
||||
case UIEditorDockHostHitTargetKind::PanelBody:
|
||||
case UIEditorDockHostHitTargetKind::PanelFooter:
|
||||
return { UIEditorWorkspaceInputOwnerKind::DockHost, {} };
|
||||
|
||||
case UIEditorDockHostHitTargetKind::None:
|
||||
default:
|
||||
return {};
|
||||
}
|
||||
}
|
||||
|
||||
UIEditorWorkspaceInputOwner NormalizeUIEditorWorkspaceInputOwner(
|
||||
UIEditorWorkspaceInputOwner owner,
|
||||
const Widgets::UIEditorDockHostLayout& dockHostLayout,
|
||||
const UIEditorPanelContentHostFrame& contentHostFrame) {
|
||||
switch (owner.kind) {
|
||||
case UIEditorWorkspaceInputOwnerKind::None:
|
||||
return {};
|
||||
|
||||
case UIEditorWorkspaceInputOwnerKind::DockHost:
|
||||
return HasUsableBounds(dockHostLayout.bounds)
|
||||
? owner
|
||||
: UIEditorWorkspaceInputOwner {};
|
||||
|
||||
case UIEditorWorkspaceInputOwnerKind::HostedPanel:
|
||||
case UIEditorWorkspaceInputOwnerKind::Viewport:
|
||||
for (const UIEditorPanelContentHostPanelState& panelState :
|
||||
contentHostFrame.panelStates) {
|
||||
if (!IsMountedContentPanelValid(panelState) ||
|
||||
panelState.panelId != owner.panelId) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const UIEditorWorkspaceInputOwnerKind expectedKind =
|
||||
panelState.kind == UIEditorPanelPresentationKind::ViewportShell
|
||||
? UIEditorWorkspaceInputOwnerKind::Viewport
|
||||
: UIEditorWorkspaceInputOwnerKind::HostedPanel;
|
||||
return owner.kind == expectedKind
|
||||
? owner
|
||||
: UIEditorWorkspaceInputOwner {};
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
} // namespace XCEngine::UI::Editor
|
||||
@@ -20,6 +20,41 @@ bool HasMeaningfulViewportInputFrame(const UIEditorViewportInputBridgeFrame& fra
|
||||
!frame.characters.empty();
|
||||
}
|
||||
|
||||
UIEditorWorkspaceInputOwner ResolveNextInputOwner(
|
||||
UIEditorWorkspaceInputOwner currentOwner,
|
||||
const Widgets::UIEditorDockHostLayout& dockHostLayout,
|
||||
const UIEditorPanelContentHostFrame& contentHostFrame,
|
||||
const std::vector<::XCEngine::UI::UIInputEvent>& inputEvents) {
|
||||
using ::XCEngine::UI::UIInputEventType;
|
||||
|
||||
currentOwner = NormalizeUIEditorWorkspaceInputOwner(
|
||||
std::move(currentOwner),
|
||||
dockHostLayout,
|
||||
contentHostFrame);
|
||||
for (const ::XCEngine::UI::UIInputEvent& event : inputEvents) {
|
||||
switch (event.type) {
|
||||
case UIInputEventType::FocusLost:
|
||||
currentOwner = {};
|
||||
break;
|
||||
|
||||
case UIInputEventType::PointerButtonDown:
|
||||
currentOwner = ResolveUIEditorWorkspacePointerInputOwner(
|
||||
dockHostLayout,
|
||||
contentHostFrame,
|
||||
event.position);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return NormalizeUIEditorWorkspaceInputOwner(
|
||||
std::move(currentOwner),
|
||||
dockHostLayout,
|
||||
contentHostFrame);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
UIEditorWorkspaceInteractionFrame UpdateUIEditorWorkspaceInteraction(
|
||||
@@ -31,12 +66,44 @@ UIEditorWorkspaceInteractionFrame UpdateUIEditorWorkspaceInteraction(
|
||||
const Widgets::UIEditorDockHostMetrics& dockHostMetrics,
|
||||
const Widgets::UIEditorViewportSlotMetrics& viewportMetrics) {
|
||||
UIEditorWorkspaceInteractionFrame frame = {};
|
||||
frame.previousInputOwner = state.inputOwner;
|
||||
frame.dockHostFrame = UpdateUIEditorDockHostInteraction(
|
||||
state.dockHostInteractionState,
|
||||
controller,
|
||||
bounds,
|
||||
inputEvents,
|
||||
dockHostMetrics);
|
||||
|
||||
const UIEditorWorkspaceComposeFrame previewComposeFrame = UpdateUIEditorWorkspaceCompose(
|
||||
state.composeState,
|
||||
bounds,
|
||||
controller.GetPanelRegistry(),
|
||||
controller.GetWorkspace(),
|
||||
controller.GetSession(),
|
||||
model.workspacePresentations,
|
||||
{},
|
||||
state.dockHostInteractionState.dockHostState,
|
||||
dockHostMetrics,
|
||||
viewportMetrics);
|
||||
state.inputOwner = ResolveNextInputOwner(
|
||||
state.inputOwner,
|
||||
previewComposeFrame.dockHostLayout,
|
||||
previewComposeFrame.contentHostFrame,
|
||||
inputEvents);
|
||||
frame.inputOwner = state.inputOwner;
|
||||
frame.inputOwnerChanged = !AreUIEditorWorkspaceInputOwnersEquivalent(
|
||||
frame.previousInputOwner,
|
||||
frame.inputOwner);
|
||||
state.dockHostInteractionState.dockHostState.focused =
|
||||
IsUIEditorWorkspaceDockHostInputOwner(frame.inputOwner);
|
||||
frame.dockHostFrame.layout = Widgets::BuildUIEditorDockHostLayout(
|
||||
bounds,
|
||||
controller.GetPanelRegistry(),
|
||||
controller.GetWorkspace(),
|
||||
controller.GetSession(),
|
||||
state.dockHostInteractionState.dockHostState,
|
||||
dockHostMetrics);
|
||||
frame.dockHostFrame.focused = state.dockHostInteractionState.dockHostState.focused;
|
||||
frame.composeFrame = UpdateUIEditorWorkspaceCompose(
|
||||
state.composeState,
|
||||
bounds,
|
||||
@@ -47,7 +114,8 @@ UIEditorWorkspaceInteractionFrame UpdateUIEditorWorkspaceInteraction(
|
||||
inputEvents,
|
||||
state.dockHostInteractionState.dockHostState,
|
||||
dockHostMetrics,
|
||||
viewportMetrics);
|
||||
viewportMetrics,
|
||||
&frame.inputOwner);
|
||||
|
||||
frame.result.dockHostResult = frame.dockHostFrame.result;
|
||||
frame.result.consumed = frame.dockHostFrame.result.consumed;
|
||||
|
||||
Reference in New Issue
Block a user