aboutsummaryrefslogtreecommitdiffstats
path: root/tests/auto/quick/qquickflickable
diff options
context:
space:
mode:
authorShawn Rutledge <shawn.rutledge@qt.io>2017-03-24 15:59:28 +0100
committerShawn Rutledge <shawn.rutledge@qt.io>2017-03-27 13:21:33 +0000
commit1f9c7b065f55f80f81b349ef64a718546dec4b49 (patch)
treeb86f36f6741f7be2b1c836d6b889dd35938080b2 /tests/auto/quick/qquickflickable
parent6d7c3c0743b3c6aac7d7faa1ffd18798ceced0ac (diff)
Add tst_qquickflickable::nestedSliderUsingTouch
to verify that when a touch-handling component is inside the Flickable, it can control whether the flickable can steal the grab by means of setKeepTouchGrab. Task-number: QTBUG-59416 Task-number: QTBUG-59707 Change-Id: I93cf3abb07a96a69290c3b5b055b688a62fe8fff Reviewed-by: J-P Nurmi <jpnurmi@qt.io>
Diffstat (limited to 'tests/auto/quick/qquickflickable')
-rw-r--r--tests/auto/quick/qquickflickable/data/nestedSlider.qml36
-rw-r--r--tests/auto/quick/qquickflickable/tst_qquickflickable.cpp161
2 files changed, 197 insertions, 0 deletions
diff --git a/tests/auto/quick/qquickflickable/data/nestedSlider.qml b/tests/auto/quick/qquickflickable/data/nestedSlider.qml
new file mode 100644
index 0000000000..2fd0cbfcc8
--- /dev/null
+++ b/tests/auto/quick/qquickflickable/data/nestedSlider.qml
@@ -0,0 +1,36 @@
+import QtQuick 2.0
+import Test 1.0
+
+Flickable {
+ width: 240
+ height: 320
+ contentWidth: width * 1.5
+ contentHeight: height * 1.5
+ contentY: height * 0.25
+
+ Rectangle {
+ id: slider
+ width: 50
+ height: 200
+ color: "lightgray"
+ border.color: drag.active ? "green" : "black"
+ anchors.centerIn: parent
+ radius: 4
+
+ TouchDragArea {
+ id: drag
+ objectName: "drag"
+ anchors.fill: parent
+ }
+
+ Rectangle {
+ width: parent.width - 2
+ height: 20
+ radius: 5
+ color: "darkgray"
+ border.color: "black"
+ x: 1
+ y: Math.min(slider.height - height, Math.max(0, drag.pos.y - height / 2))
+ }
+ }
+}
diff --git a/tests/auto/quick/qquickflickable/tst_qquickflickable.cpp b/tests/auto/quick/qquickflickable/tst_qquickflickable.cpp
index 21d02ff5de..3ecebfb48f 100644
--- a/tests/auto/quick/qquickflickable/tst_qquickflickable.cpp
+++ b/tests/auto/quick/qquickflickable/tst_qquickflickable.cpp
@@ -46,6 +46,99 @@
using namespace QQuickViewTestUtil;
using namespace QQuickVisualTestUtil;
+// an abstract Slider which only handles touch events
+class TouchDragArea : public QQuickItem
+{
+ Q_OBJECT
+ Q_PROPERTY(QPointF pos READ pos NOTIFY posChanged)
+ Q_PROPERTY(bool active READ active NOTIFY activeChanged)
+ Q_PROPERTY(bool keepMouseGrab READ keepMouseGrab WRITE setKeepMouseGrab NOTIFY keepMouseGrabChanged)
+ Q_PROPERTY(bool keepTouchGrab READ keepTouchGrab WRITE setKeepTouchGrab NOTIFY keepTouchGrabChanged)
+
+public:
+ TouchDragArea(QQuickItem *parent = 0)
+ : QQuickItem(parent)
+ , touchEvents(0)
+ , touchUpdates(0)
+ , touchReleases(0)
+ , ungrabs(0)
+ , m_active(false)
+ {
+ setFlags(ItemAcceptsDrops);
+ }
+
+ QPointF pos() const { return m_pos; }
+
+ bool active() const { return m_active; }
+
+ void setKeepMouseGrab(bool keepMouseGrab)
+ {
+ QQuickItem::setKeepMouseGrab(keepMouseGrab);
+ emit keepMouseGrabChanged();
+ }
+
+ void setKeepTouchGrab(bool keepTouchGrab)
+ {
+ QQuickItem::setKeepTouchGrab(keepTouchGrab);
+ emit keepTouchGrabChanged();
+ }
+
+ int touchEvents;
+ int touchUpdates;
+ int touchReleases;
+ int ungrabs;
+ QVector<Qt::TouchPointState> touchPointStates;
+
+protected:
+ void touchEvent(QTouchEvent *ev) override
+ {
+ QCOMPARE(ev->touchPoints().count(), 1);
+ auto touchpoint = ev->touchPoints().first();
+ switch (touchpoint.state()) {
+ case Qt::TouchPointPressed:
+ QVERIFY(!m_active);
+ m_active = true;
+ emit activeChanged();
+ grabTouchPoints(QVector<int>() << touchpoint.id());
+ break;
+ case Qt::TouchPointMoved:
+ ++touchUpdates;
+ break;
+ case Qt::TouchPointReleased:
+ QVERIFY(m_active);
+ m_active = false;
+ ++touchReleases;
+ emit activeChanged();
+ case Qt::TouchPointStationary:
+ break;
+ }
+ touchPointStates << touchpoint.state();
+ ++touchEvents;
+ m_pos = touchpoint.pos();
+ emit posChanged();
+ }
+
+ void touchUngrabEvent() override
+ {
+ ++ungrabs;
+ QVERIFY(m_active);
+ emit ungrabbed();
+ m_active = false;
+ emit activeChanged();
+ }
+
+signals:
+ void ungrabbed();
+ void posChanged();
+ void keepMouseGrabChanged();
+ void keepTouchGrabChanged();
+ void activeChanged();
+
+private:
+ QPointF m_pos;
+ bool m_active;
+};
+
class tst_qquickflickable : public QQmlDataTest
{
Q_OBJECT
@@ -55,6 +148,7 @@ public:
{}
private slots:
+ void initTestCase() override;
void create();
void horizontalViewportSize();
void verticalViewportSize();
@@ -92,6 +186,8 @@ private slots:
void stopAtBounds();
void stopAtBounds_data();
void nestedMouseAreaUsingTouch();
+ void nestedSliderUsingTouch();
+ void nestedSliderUsingTouch_data();
void pressDelayWithLoader();
void movementFromProgrammaticFlick();
void cleanup();
@@ -108,6 +204,12 @@ private:
QTouchDevice *touchDevice;
};
+void tst_qquickflickable::initTestCase()
+{
+ QQmlDataTest::initTestCase();
+ qmlRegisterType<TouchDragArea>("Test",1,0,"TouchDragArea");
+}
+
void tst_qquickflickable::cleanup()
{
QVERIFY(QGuiApplication::topLevelWindows().isEmpty());
@@ -1889,6 +1991,65 @@ void tst_qquickflickable::nestedMouseAreaUsingTouch()
QVERIFY(nested->y() < 100.0);
}
+void tst_qquickflickable::nestedSliderUsingTouch_data()
+{
+ QTest::addColumn<bool>("keepMouseGrab");
+ QTest::addColumn<bool>("keepTouchGrab");
+ QTest::addColumn<int>("updates");
+ QTest::addColumn<int>("releases");
+ QTest::addColumn<int>("ungrabs");
+
+ QTest::newRow("keepBoth") << true << true << 8 << 1 << 0;
+ QTest::newRow("keepMouse") << true << false << 8 << 1 << 0;
+ QTest::newRow("keepTouch") << false << true << 8 << 1 << 0;
+ QTest::newRow("keepNeither") << false << false << 6 << 0 << 1;
+}
+
+void tst_qquickflickable::nestedSliderUsingTouch()
+{
+ QFETCH(bool, keepMouseGrab);
+ QFETCH(bool, keepTouchGrab);
+ QFETCH(int, updates);
+ QFETCH(int, releases);
+ QFETCH(int, ungrabs);
+
+ QQuickView *window = new QQuickView;
+ QScopedPointer<QQuickView> windowPtr(window);
+ windowPtr->setSource(testFileUrl("nestedSlider.qml"));
+ QTRY_COMPARE(window->status(), QQuickView::Ready);
+ QQuickViewTestUtil::centerOnScreen(window);
+ QQuickViewTestUtil::moveMouseAway(window);
+ window->show();
+ QVERIFY(QTest::qWaitForWindowActive(window));
+ QVERIFY(window->rootObject() != 0);
+
+ QQuickFlickable *flickable = qobject_cast<QQuickFlickable*>(window->rootObject());
+ QVERIFY(flickable);
+
+ TouchDragArea *tda = flickable->findChild<TouchDragArea*>("drag");
+ QVERIFY(tda);
+
+ // Drag down and a little to the right: flickable will steal the grab only if tda allows it
+ const int dragThreshold = qApp->styleHints()->startDragDistance();
+ tda->setKeepMouseGrab(keepMouseGrab);
+ tda->setKeepTouchGrab(keepTouchGrab);
+ QPoint p0 = tda->mapToScene(QPoint(20, 20)).toPoint();
+ QTest::touchEvent(window, touchDevice).press(0, p0, window);
+ QQuickTouchUtils::flush(window);
+ for (int i = 0; i < 8; ++i) {
+ p0 += QPoint(dragThreshold / 6, dragThreshold / 4);
+ QTest::touchEvent(window, touchDevice).move(0, p0, window);
+ QQuickTouchUtils::flush(window);
+ }
+ QCOMPARE(tda->active(), !ungrabs);
+ QTest::touchEvent(window, touchDevice).release(0, p0, window);
+ QQuickTouchUtils::flush(window);
+ QCOMPARE(tda->touchPointStates.first(), Qt::TouchPointPressed);
+ QCOMPARE(tda->touchUpdates, updates);
+ QCOMPARE(tda->touchReleases, releases);
+ QCOMPARE(tda->ungrabs, ungrabs);
+}
+
// QTBUG-31328
void tst_qquickflickable::pressDelayWithLoader()
{