aboutsummaryrefslogtreecommitdiffstats
path: root/tests/auto/quick
diff options
context:
space:
mode:
authorJan Arve Sæther <jan-arve.saether@qt.io>2018-02-20 14:42:49 +0100
committerShawn Rutledge <shawn.rutledge@qt.io>2018-02-21 20:13:00 +0000
commite4bea7805a229d3625f110f844d908e2abe790b5 (patch)
treed6952df5ff40dfe8a4f7a675acaa86c903cf9b24 /tests/auto/quick
parent01cdc1798977ba6e53c2439fa45c14889685290a (diff)
Fix draghandler to respect axis constraints
..while its (ancestor) coordinate system has changed during the drag. For example, ensure that a DragHandler-based Slider keeps its knob centered. If the Slider is used on a Flickable which you are flicking with a second finger, then the coordinate system is changing underneath the Slider. The problem was that DragHandler stored the initial drag position of the target when the target item was pressed, and used that throughout the whole drag operation. Unfortunately if the target item was inside a Flickable that got flicked during a drag operation, that initial position was not updated (and thus, incorrect). Instead of storing the initial target position in scene coordinates, we now store the position that got pressed in local target coordinates, and ensure that in any further updates the touchpoint have the same local position (by moving the target). Task-number: QTBUG-64852 Change-Id: I25012d34d88f45c7eb9c711db0037d530cf10854 Reviewed-by: Shawn Rutledge <shawn.rutledge@qt.io>
Diffstat (limited to 'tests/auto/quick')
-rw-r--r--tests/auto/quick/pointerhandlers/flickableinterop/tst_flickableinterop.cpp86
1 files changed, 86 insertions, 0 deletions
diff --git a/tests/auto/quick/pointerhandlers/flickableinterop/tst_flickableinterop.cpp b/tests/auto/quick/pointerhandlers/flickableinterop/tst_flickableinterop.cpp
index c0b34f8246..f3513881cd 100644
--- a/tests/auto/quick/pointerhandlers/flickableinterop/tst_flickableinterop.cpp
+++ b/tests/auto/quick/pointerhandlers/flickableinterop/tst_flickableinterop.cpp
@@ -75,6 +75,7 @@ private slots:
void touchDragFlickableBehindItemWithHandlers();
void mouseDragFlickableBehindItemWithHandlers_data();
void mouseDragFlickableBehindItemWithHandlers();
+ void touchDragSliderAndFlickable();
private:
void createView(QScopedPointer<QQuickView> &window, const char *fileName);
@@ -560,6 +561,91 @@ void tst_FlickableInterop::mouseDragFlickableBehindItemWithHandlers()
QCOMPARE(originP1, rect->mapToScene(rect->clipRect().center()).toPoint());
}
+void tst_FlickableInterop::touchDragSliderAndFlickable()
+{
+ const int dragThreshold = QGuiApplication::styleHints()->startDragDistance();
+ QScopedPointer<QQuickView> windowPtr;
+ createView(windowPtr, "flickableWithHandlers.qml");
+ QQuickView * window = windowPtr.data();
+
+ QQuickItem *slider = window->rootObject()->findChild<QQuickItem*>("Slider");
+ QVERIFY(slider);
+ QQuickDragHandler *drag = slider->findChild<QQuickDragHandler*>();
+ QVERIFY(drag);
+ QQuickItem *knob = slider->findChild<QQuickItem*>("Slider Knob");
+ QVERIFY(knob);
+ QQuickFlickable *flickable = window->rootObject()->findChild<QQuickFlickable*>();
+ QVERIFY(flickable);
+
+ // The knob is initially centered over the slider's "groove"
+ qreal initialXOffset = qAbs(knob->mapToScene(knob->clipRect().center()).x() - slider->mapToScene
+ (slider->clipRect().center()).x());
+ QVERIFY(initialXOffset <= 1);
+
+ // Drag the slider in the allowed (vertical) direction with one finger
+ QPoint p1 = knob->mapToScene(knob->clipRect().center()).toPoint();
+ QTest::touchEvent(window, touchDevice).press(1, p1, window);
+ QQuickTouchUtils::flush(window);
+ p1 += QPoint(0, dragThreshold);
+ QTest::touchEvent(window, touchDevice).move(1, p1, window);
+ QQuickTouchUtils::flush(window);
+ p1 += QPoint(0, dragThreshold);
+ QTest::touchEvent(window, touchDevice).move(1, p1, window);
+ QQuickTouchUtils::flush(window);
+ p1 += QPoint(0, dragThreshold);
+ QTest::touchEvent(window, touchDevice).move(1, p1, window);
+ QQuickTouchUtils::flush(window);
+ QTRY_VERIFY(slider->property("value").toInt() < 49);
+ QVERIFY(!flickable->isMoving());
+
+ // Drag the Flickable with a second finger
+ QPoint p2(300,300);
+ QTest::touchEvent(window, touchDevice).stationary(1).press(2, p2, window);
+ QQuickTouchUtils::flush(window);
+ p1 += QPoint(-10, -10);
+ p2 += QPoint(dragThreshold, 0);
+ QTest::touchEvent(window, touchDevice).move(1, p1, window).stationary(2);
+ QQuickTouchUtils::flush(window);
+ p1 += QPoint(-10, -10);
+ p2 += QPoint(dragThreshold, 0);
+ QTest::touchEvent(window, touchDevice).stationary(1).move(2, p2, window);
+ QQuickTouchUtils::flush(window);
+ p1 += QPoint(-10, -10);
+ p2 += QPoint(dragThreshold, 0);
+ QTest::touchEvent(window, touchDevice).move(1, p1, window).stationary(2);
+ QQuickTouchUtils::flush(window);
+ p1 += QPoint(-10, -10);
+ p2 += QPoint(dragThreshold, 0);
+ QTest::touchEvent(window, touchDevice).stationary(1).move(2, p2, window);
+ QQuickTouchUtils::flush(window);
+ p1 += QPoint(-10, -10);
+ p2 += QPoint(dragThreshold, 0);
+ QTest::touchEvent(window, touchDevice).move(1, p1, window).stationary(2);
+ QQuickTouchUtils::flush(window);
+ p1 += QPoint(-10, -10);
+ p2 += QPoint(dragThreshold, 0);
+ QTest::touchEvent(window, touchDevice).stationary(1).move(2, p2, window);
+ QQuickTouchUtils::flush(window);
+ p1 += QPoint(-10, -10);
+ p2 += QPoint(dragThreshold, 0);
+ QTest::touchEvent(window, touchDevice).move(1, p1, window).stationary(2);
+ QQuickTouchUtils::flush(window);
+ p1 += QPoint(-10, -10);
+ p2 += QPoint(dragThreshold, 0);
+ QTest::touchEvent(window, touchDevice).stationary(1).move(2, p2, window);
+ QQuickTouchUtils::flush(window);
+ QTRY_VERIFY(flickable->isMoving());
+ qreal knobSliderXOffset = qAbs(knob->mapToScene(knob->clipRect().center()).toPoint().x() -
+ slider->mapToScene(slider->clipRect().center()).toPoint().x()) - initialXOffset;
+ if (knobSliderXOffset > 1)
+ qDebug() << "knob has slipped out of groove by" << knobSliderXOffset << "pixels";
+ // See if the knob is still centered over the slider's "groove"
+ QVERIFY(qAbs(knobSliderXOffset) <= 1);
+
+ // Release
+ QTest::touchEvent(window, touchDevice).release(1, p1, window).release(2, p2, window);
+}
+
QTEST_MAIN(tst_FlickableInterop)
#include "tst_flickableinterop.moc"