Emit movement signals for flick().
authorMichael Brasser <michael.brasser@live.com>
Tue, 21 Jul 2015 19:31:19 +0000 (14:31 -0500)
committerMichael Brasser <michael.brasser@live.com>
Wed, 22 Jul 2015 17:58:00 +0000 (17:58 +0000)
Make flick() more like a real flick and ensure the movement signals
and properties are updated. This allows them to be handled from QML.

This also fixes issues with flick() and dynamic delegates. Flickable
has several checks of the form:

    !d->pressed && !d->hData.moving && !d->vData.moving

That were processed incorrectly for flick(), as the moving variables
were not being updated.

[ChangeLog][QtQuick][Flickable] The movement related signals and
properties are now updated for flicks started via the flick function.

Change-Id: I7e96e2e12a4d0a0ee73ddd6f29d95f19c44667b0
Task-number: QTBUG-34507
Reviewed-by: Martin Jones <martin.jones@qinetic.com.au>
src/quick/items/qquickflickable.cpp
tests/auto/quick/qquickflickable/data/movementSignals.qml [new file with mode: 0644]
tests/auto/quick/qquickflickable/tst_qquickflickable.cpp

index bfb732554bd14d34cc4ba82a793e3b2526097ee3..fc4a3efb8e774c77c6f09bc7e2fedae6cbda4ac1 100644 (file)
@@ -619,7 +619,7 @@ is finished.
     \qmlsignal QtQuick::Flickable::movementStarted()
 
     This signal is emitted when the view begins moving due to user
-    interaction.
+    interaction or a generated flick().
 
     The corresponding handler is \c onMovementStarted.
 */
@@ -628,9 +628,9 @@ is finished.
     \qmlsignal QtQuick::Flickable::movementEnded()
 
     This signal is emitted when the view stops moving due to user
-    interaction.  If a flick was generated, this signal will
+    interaction or a generated flick().  If a flick was active, this signal will
     be emitted once the flick stops.  If a flick was not
-    generated, this signal will be emitted when the
+    active, this signal will be emitted when the
     user stops dragging - i.e. a mouse or touch release.
 
     The corresponding handler is \c onMovementEnded.
@@ -1654,6 +1654,9 @@ void QQuickFlickable::geometryChanged(const QRectF &newGeometry,
     \qmlmethod QtQuick::Flickable::flick(qreal xVelocity, qreal yVelocity)
 
     Flicks the content with \a xVelocity horizontally and \a yVelocity vertically in pixels/sec.
+
+    Calling this method will update the corresponding moving and flicking properties and signals,
+    just like a real flick.
 */
 
 void QQuickFlickable::flick(qreal xVelocity, qreal yVelocity)
@@ -1663,8 +1666,15 @@ void QQuickFlickable::flick(qreal xVelocity, qreal yVelocity)
     d->vData.reset();
     d->hData.velocity = xVelocity;
     d->vData.velocity = yVelocity;
+
     bool flickedX = d->flickX(xVelocity);
     bool flickedY = d->flickY(yVelocity);
+
+    if (flickedX)
+        d->hMoved = true;
+    if (flickedY)
+        d->vMoved = true;
+    movementStarting();
     d->flickingStarted(flickedX, flickedY);
 }
 
diff --git a/tests/auto/quick/qquickflickable/data/movementSignals.qml b/tests/auto/quick/qquickflickable/data/movementSignals.qml
new file mode 100644 (file)
index 0000000..581e882
--- /dev/null
@@ -0,0 +1,26 @@
+import QtQuick 2.0
+
+Flickable {
+    width: 400; height: 400
+    contentWidth: 400; contentHeight: 1200
+
+    property string signalString
+
+    Rectangle {
+        width: 400; height: 400
+        color: "red"
+    }
+    Rectangle {
+        y: 400; width: 400; height: 400
+        color: "yellow"
+    }
+    Rectangle {
+        y: 800; width: 400; height: 400
+        color: "green"
+    }
+
+    onMovementStarted: signalString += "ms"
+    onMovementEnded: signalString += "me"
+    onFlickStarted: signalString += "fs"
+    onFlickEnded: signalString += "fe"
+}
index 44da9a64e522516d921f1d0ed744cd3b0a0f5f4d..d6c1fd6eeaaf0084cd3799c5fb33749594d8e3db 100644 (file)
@@ -91,6 +91,7 @@ private slots:
     void stopAtBounds_data();
     void nestedMouseAreaUsingTouch();
     void pressDelayWithLoader();
+    void movementFromProgrammaticFlick();
     void cleanup();
 
 private:
@@ -1719,6 +1720,25 @@ void tst_qquickflickable::pressDelayWithLoader()
     QTest::mouseRelease(window.data(), Qt::LeftButton, 0, QPoint(150, 150));
 }
 
+// QTBUG-34507
+void tst_qquickflickable::movementFromProgrammaticFlick()
+{
+    QScopedPointer<QQuickView> window(new QQuickView);
+    window->setSource(testFileUrl("movementSignals.qml"));
+    QTRY_COMPARE(window->status(), QQuickView::Ready);
+    QQuickViewTestUtil::centerOnScreen(window.data());
+    QQuickViewTestUtil::moveMouseAway(window.data());
+    window->show();
+    QVERIFY(QTest::qWaitForWindowActive(window.data()));
+
+    QQuickFlickable *flickable = qobject_cast<QQuickFlickable*>(window->rootObject());
+    QVERIFY(flickable != 0);
+
+    // verify that the signals for movement and flicking are called in the right order
+    flickable->flick(0, -1000);
+    QTRY_COMPARE(flickable->property("signalString").toString(), QString("msfsfeme"));
+}
+
 QTEST_MAIN(tst_qquickflickable)
 
 #include "tst_qquickflickable.moc"