fix(editor_ui): resolve splitter and tab drag gesture conflict
This commit is contained in:
@@ -143,6 +143,18 @@ const UIEditorDockHostTabStackLayout* FindTabStackByNodeId(
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
const XCEngine::UI::Editor::Widgets::UIEditorDockHostSplitterLayout* FindSplitterByNodeId(
|
||||
const UIEditorDockHostLayout& layout,
|
||||
std::string_view nodeId) {
|
||||
for (const auto& splitter : layout.splitters) {
|
||||
if (splitter.nodeId == nodeId) {
|
||||
return &splitter;
|
||||
}
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
TEST(UIEditorDockHostInteractionTest, SplitterDragUpdatesWorkspaceSplitRatio) {
|
||||
@@ -216,6 +228,87 @@ TEST(UIEditorDockHostInteractionTest, FocusLostWhileDraggingSplitterRequestsPoin
|
||||
EXPECT_TRUE(state.dockHostState.activeSplitterNodeId.empty());
|
||||
}
|
||||
|
||||
TEST(UIEditorDockHostInteractionTest, SplitterGestureDoesNotLeaveGhostTabDragWhenHitZoneOverlapsTabHeader) {
|
||||
auto controller =
|
||||
BuildDefaultUIEditorWorkspaceController(BuildPanelRegistry(), BuildWorkspace());
|
||||
UIEditorDockHostInteractionState state = {};
|
||||
|
||||
auto frame = UpdateUIEditorDockHostInteraction(
|
||||
state,
|
||||
controller,
|
||||
UIRect(0.0f, 0.0f, 800.0f, 600.0f),
|
||||
{});
|
||||
const auto* consoleStack = FindTabStackByNodeId(frame.layout, "console-node");
|
||||
const auto* rightSplitter = FindSplitterByNodeId(frame.layout, "right-split");
|
||||
ASSERT_NE(consoleStack, nullptr);
|
||||
ASSERT_NE(rightSplitter, nullptr);
|
||||
|
||||
const UIRect overlapRect(
|
||||
(std::max)(consoleStack->tabStripLayout.headerRect.x, rightSplitter->handleHitRect.x),
|
||||
(std::max)(consoleStack->tabStripLayout.headerRect.y, rightSplitter->handleHitRect.y),
|
||||
(std::min)(
|
||||
consoleStack->tabStripLayout.headerRect.x + consoleStack->tabStripLayout.headerRect.width,
|
||||
rightSplitter->handleHitRect.x + rightSplitter->handleHitRect.width) -
|
||||
(std::max)(consoleStack->tabStripLayout.headerRect.x, rightSplitter->handleHitRect.x),
|
||||
(std::min)(
|
||||
consoleStack->tabStripLayout.headerRect.y + consoleStack->tabStripLayout.headerRect.height,
|
||||
rightSplitter->handleHitRect.y + rightSplitter->handleHitRect.height) -
|
||||
(std::max)(consoleStack->tabStripLayout.headerRect.y, rightSplitter->handleHitRect.y));
|
||||
ASSERT_GT(overlapRect.width, 0.0f);
|
||||
ASSERT_GT(overlapRect.height, 0.0f);
|
||||
const UIPoint overlapPoint = RectCenter(overlapRect);
|
||||
const UIPoint splitterDragPoint(overlapPoint.x, overlapPoint.y + 24.0f);
|
||||
const UIPoint probeMovePoint(
|
||||
consoleStack->tabStripLayout.headerRect.x + 8.0f,
|
||||
consoleStack->tabStripLayout.headerRect.y + consoleStack->tabStripLayout.headerRect.height * 0.5f);
|
||||
|
||||
frame = UpdateUIEditorDockHostInteraction(
|
||||
state,
|
||||
controller,
|
||||
UIRect(0.0f, 0.0f, 800.0f, 600.0f),
|
||||
{ MakePointerMove(overlapPoint.x, overlapPoint.y) });
|
||||
|
||||
frame = UpdateUIEditorDockHostInteraction(
|
||||
state,
|
||||
controller,
|
||||
UIRect(0.0f, 0.0f, 800.0f, 600.0f),
|
||||
{ MakePointerDown(overlapPoint.x, overlapPoint.y) });
|
||||
EXPECT_TRUE(frame.result.consumed);
|
||||
EXPECT_TRUE(frame.result.requestPointerCapture);
|
||||
EXPECT_EQ(frame.result.activeSplitterNodeId, "right-split");
|
||||
|
||||
frame = UpdateUIEditorDockHostInteraction(
|
||||
state,
|
||||
controller,
|
||||
UIRect(0.0f, 0.0f, 800.0f, 600.0f),
|
||||
{ MakePointerMove(splitterDragPoint.x, splitterDragPoint.y) });
|
||||
EXPECT_TRUE(frame.result.consumed);
|
||||
EXPECT_TRUE(frame.result.layoutChanged);
|
||||
|
||||
frame = UpdateUIEditorDockHostInteraction(
|
||||
state,
|
||||
controller,
|
||||
UIRect(0.0f, 0.0f, 800.0f, 600.0f),
|
||||
{ MakePointerUp(splitterDragPoint.x, splitterDragPoint.y) });
|
||||
EXPECT_TRUE(frame.result.releasePointerCapture);
|
||||
EXPECT_TRUE(state.dockHostState.activeSplitterNodeId.empty());
|
||||
EXPECT_TRUE(state.activeTabDragNodeId.empty());
|
||||
EXPECT_TRUE(state.activeTabDragPanelId.empty());
|
||||
EXPECT_FALSE(state.dockHostState.dropPreview.visible);
|
||||
|
||||
frame = UpdateUIEditorDockHostInteraction(
|
||||
state,
|
||||
controller,
|
||||
UIRect(0.0f, 0.0f, 800.0f, 600.0f),
|
||||
{ MakePointerMove(probeMovePoint.x, probeMovePoint.y) });
|
||||
EXPECT_FALSE(frame.result.requestPointerCapture);
|
||||
EXPECT_FALSE(frame.result.releasePointerCapture);
|
||||
EXPECT_FALSE(frame.result.layoutChanged);
|
||||
EXPECT_TRUE(state.activeTabDragNodeId.empty());
|
||||
EXPECT_TRUE(state.activeTabDragPanelId.empty());
|
||||
EXPECT_FALSE(state.dockHostState.dropPreview.visible);
|
||||
}
|
||||
|
||||
TEST(UIEditorDockHostInteractionTest, ClickingTabActivatesTargetPanel) {
|
||||
auto controller =
|
||||
BuildDefaultUIEditorWorkspaceController(BuildPanelRegistry(), BuildWorkspace());
|
||||
|
||||
Reference in New Issue
Block a user