fix(editor_ui): resolve splitter and tab drag gesture conflict

This commit is contained in:
2026-04-11 20:33:53 +08:00
parent 0a015b52ca
commit 3e55f8c204
4 changed files with 134 additions and 5 deletions

View File

@@ -53,6 +53,10 @@ struct UIEditorTabStripInteractionFrame {
bool focused = false;
};
// Clears transient pointer-driven state while preserving selection/navigation.
void ClearUIEditorTabStripTransientInteraction(
UIEditorTabStripInteractionState& state);
UIEditorTabStripInteractionFrame UpdateUIEditorTabStripInteraction(
UIEditorTabStripInteractionState& state,
std::string& selectedTabId,

View File

@@ -363,6 +363,14 @@ void CancelTabReorder(
} // namespace
void ClearUIEditorTabStripTransientInteraction(
UIEditorTabStripInteractionState& state) {
state.pressedTarget = {};
state.hasPointerPosition = false;
ClearHoverState(state);
ClearReorderState(state);
}
UIEditorTabStripInteractionFrame UpdateUIEditorTabStripInteraction(
UIEditorTabStripInteractionState& state,
std::string& selectedTabId,

View File

@@ -192,6 +192,14 @@ bool IsPointInsideRect(
point.y <= rect.y + rect.height;
}
void ClearAllTabStripTransientInteractions(
UIEditorDockHostInteractionState& state) {
for (UIEditorDockHostTabStripInteractionEntry& entry : state.tabStripInteractions) {
ClearUIEditorTabStripTransientInteraction(entry.state);
}
SyncDockHostTabStripVisualStates(state);
}
void ClearTabDockDragState(UIEditorDockHostInteractionState& state) {
state.activeTabDragNodeId.clear();
state.activeTabDragPanelId.clear();
@@ -510,9 +518,19 @@ UIEditorDockHostInteractionFrame UpdateUIEditorDockHostInteraction(
state.hasPointerPosition = false;
}
const UIEditorDockHostHitTarget pointerHitTarget =
state.hasPointerPosition
? HitTestUIEditorDockHost(layout, state.pointerPosition)
: UIEditorDockHostHitTarget {};
const bool splitterOwnsPointerDown =
event.type == UIInputEventType::PointerButtonDown &&
event.pointerButton == ::XCEngine::UI::UIPointerButton::Left &&
pointerHitTarget.kind == UIEditorDockHostHitTargetKind::SplitterHandle;
UIEditorDockHostInteractionResult eventResult = {};
const DockHostTabStripEventResult tabStripResult =
ShouldDispatchTabStripEvent(event, state.splitterDragState.active)
!splitterOwnsPointerDown &&
ShouldDispatchTabStripEvent(event, state.splitterDragState.active)
? ProcessTabStripEvent(state, layout, event, metrics)
: DockHostTabStripEventResult {};
eventResult.requestPointerCapture = tabStripResult.requestPointerCapture;
@@ -541,6 +559,7 @@ UIEditorDockHostInteractionFrame UpdateUIEditorDockHostInteraction(
if (state.splitterDragState.active) {
EndUISplitterDrag(state.splitterDragState);
state.dockHostState.activeSplitterNodeId.clear();
ClearAllTabStripTransientInteractions(state);
eventResult.consumed = true;
eventResult.releasePointerCapture = true;
}
@@ -609,11 +628,11 @@ UIEditorDockHostInteractionFrame UpdateUIEditorDockHostInteraction(
break;
}
if (state.dockHostState.hoveredTarget.kind ==
if (pointerHitTarget.kind ==
UIEditorDockHostHitTargetKind::SplitterHandle) {
const auto* splitter = FindUIEditorDockHostSplitterLayout(
layout,
state.dockHostState.hoveredTarget.nodeId);
pointerHitTarget.nodeId);
if (splitter != nullptr &&
BeginUISplitterDrag(
1u,
@@ -626,11 +645,12 @@ UIEditorDockHostInteractionFrame UpdateUIEditorDockHostInteraction(
splitter->metrics,
state.pointerPosition,
state.splitterDragState)) {
ClearAllTabStripTransientInteractions(state);
state.dockHostState.activeSplitterNodeId = splitter->nodeId;
state.dockHostState.focused = true;
eventResult.consumed = true;
eventResult.requestPointerCapture = true;
eventResult.hitTarget = state.dockHostState.hoveredTarget;
eventResult.hitTarget = pointerHitTarget;
eventResult.activeSplitterNodeId = splitter->nodeId;
}
} else {
@@ -643,7 +663,10 @@ UIEditorDockHostInteractionFrame UpdateUIEditorDockHostInteraction(
state.dockHostState.hoveredTarget.kind !=
UIEditorDockHostHitTargetKind::None;
eventResult.consumed = state.dockHostState.focused;
eventResult.hitTarget = state.dockHostState.hoveredTarget;
eventResult.hitTarget =
pointerHitTarget.kind != UIEditorDockHostHitTargetKind::None
? pointerHitTarget
: state.dockHostState.hoveredTarget;
}
}
break;
@@ -668,6 +691,7 @@ UIEditorDockHostInteractionFrame UpdateUIEditorDockHostInteraction(
UIEditorWorkspaceLayoutOperationStatus::Changed;
}
EndUISplitterDrag(state.splitterDragState);
ClearAllTabStripTransientInteractions(state);
eventResult.consumed = true;
eventResult.releasePointerCapture = true;
eventResult.activeSplitterNodeId = state.dockHostState.activeSplitterNodeId;