PathView needs drag events similar to Flickable
authorMartin Jones <martin.jones@nokia.com>
Tue, 3 Jul 2012 03:57:54 +0000 (13:57 +1000)
committerQt by Nokia <qt-info@nokia.com>
Wed, 4 Jul 2012 08:12:10 +0000 (10:12 +0200)
Added dragging property and dragStarted() and dragEnded() signals.

Task-number: QTBUG-21740
Change-Id: I718835ff7e46af615951ec5f248eba41bac31071
Reviewed-by: Andrew den Exter <andrew.den-exter@nokia.com>
src/quick/items/qquickpathview.cpp
src/quick/items/qquickpathview_p.h
src/quick/items/qquickpathview_p_p.h
tests/auto/quick/qquickpathview/tst_qquickpathview.cpp

index 33c5b8c..afa988a 100644 (file)
@@ -118,7 +118,7 @@ QQuickPathViewPrivate::QQuickPathViewPrivate()
     , offset(0.0), offsetAdj(0.0), mappedRange(1.0)
     , stealMouse(false), ownModel(false), interactive(true), haveHighlightRange(true)
     , autoHighlight(true), highlightUp(false), layoutScheduled(false)
-    , moving(false), flicking(false), requestedOnPath(false), inRequest(false)
+    , moving(false), flicking(false), dragging(false), requestedOnPath(false), inRequest(false)
     , dragMargin(0), deceleration(100), maximumFlickVelocity(QML_FLICK_DEFAULTMAXVELOCITY)
     , moveOffset(this, &QQuickPathViewPrivate::setAdjustedOffset), flickDuration(0)
     , firstIndex(-1), pathItems(-1), requestedIndex(-1), requestedZ(0)
@@ -435,6 +435,21 @@ void QQuickPathViewPrivate::regenerate()
     q->refill();
 }
 
+void QQuickPathViewPrivate::setDragging(bool d)
+{
+    Q_Q(QQuickPathView);
+    if (dragging == d)
+        return;
+
+    dragging = d;
+    if (dragging)
+        emit q->dragStarted();
+    else
+        emit q->dragEnded();
+
+    emit q->draggingChanged();
+}
+
 /*!
     \qmlclass PathView QQuickPathView
     \inqmlmodule QtQuick 2
@@ -1078,6 +1093,18 @@ bool QQuickPathView::isFlicking() const
 }
 
 /*!
+    \qmlproperty bool QtQuick2::PathView::dragging
+
+    This property holds whether the view is currently moving
+    due to the user dragging the view.
+*/
+bool QQuickPathView::isDragging() const
+{
+    Q_D(const QQuickPathView);
+    return d->dragging;
+}
+
+/*!
     \qmlsignal QtQuick2::PathView::onMovementStarted()
 
     This handler is called when the view begins moving due to user
@@ -1109,6 +1136,22 @@ bool QQuickPathView::isFlicking() const
 */
 
 /*!
+    \qmlsignal QtQuick2::PathView::onDragStarted()
+
+    This handler is called when the view starts to be dragged due to user
+    interaction.
+*/
+
+/*!
+    \qmlsignal QtQuick2::PathView::onDragEnded()
+
+    This handler is called when the user stops dragging the view.
+
+    If the velocity of the drag is suffient at the time the
+    touch/mouse button is released then a flick will start.
+*/
+
+/*!
     \qmlproperty Component QtQuick2::PathView::delegate
 
     The delegate provides a template defining each item instantiated by the view.
@@ -1377,6 +1420,7 @@ void QQuickPathViewPrivate::handleMouseMoveEvent(QMouseEvent *event)
             emit q->movingChanged();
             emit q->movementStarted();
         }
+        setDragging(true);
     }
     startPc = newPc;
     lastPosTime = currentTimestamp;
@@ -1399,6 +1443,7 @@ void QQuickPathViewPrivate::handleMouseReleaseEvent(QMouseEvent *)
     Q_Q(QQuickPathView);
     stealMouse = false;
     q->setKeepMouseGrab(false);
+    setDragging(false);
     if (!interactive || !timer.isValid() || !model || !modelCount) {
         timer.invalidate();
         if (!tl.isActive())
@@ -1535,6 +1580,7 @@ void QQuickPathView::mouseUngrabEvent()
         setKeepMouseGrab(false);
         d->timer.invalidate();
         d->fixOffset();
+        d->setDragging(false);
         if (!d->tl.isActive())
             movementEnding();
     }
index 2c0c106..ee24282 100644 (file)
@@ -79,6 +79,7 @@ class Q_AUTOTEST_EXPORT QQuickPathView : public QQuickItem
 
     Q_PROPERTY(bool moving READ isMoving NOTIFY movingChanged)
     Q_PROPERTY(bool flicking READ isFlicking NOTIFY flickingChanged)
+    Q_PROPERTY(bool dragging READ isDragging NOTIFY draggingChanged)
 
     Q_PROPERTY(int count READ count NOTIFY countChanged)
     Q_PROPERTY(QQmlComponent *delegate READ delegate WRITE setDelegate NOTIFY delegateChanged)
@@ -137,6 +138,7 @@ public:
 
     bool isMoving() const;
     bool isFlicking() const;
+    bool isDragging() const;
 
     int count() const;
 
@@ -175,6 +177,7 @@ Q_SIGNALS:
     void interactiveChanged();
     void movingChanged();
     void flickingChanged();
+    void draggingChanged();
     void highlightChanged();
     void highlightItemChanged();
     void highlightMoveDurationChanged();
@@ -182,6 +185,8 @@ Q_SIGNALS:
     void movementEnded();
     void flickStarted();
     void flickEnded();
+    void dragStarted();
+    void dragEnded();
     void snapModeChanged();
 
 protected:
index 3285b40..2a547d9 100644 (file)
@@ -127,6 +127,7 @@ public:
     void addVelocitySample(qreal v);
     qreal calcVelocity() const;
     qint64 computeCurrentTime(QInputEvent *event);
+    void setDragging(bool d);
 
     QQuickPath *path;
     int currentIndex;
@@ -146,6 +147,7 @@ public:
     bool layoutScheduled : 1;
     bool moving : 1;
     bool flicking : 1;
+    bool dragging : 1;
     bool requestedOnPath : 1;
     bool inRequest : 1;
     QElapsedTimer timer;
index d164563..d857535 100644 (file)
@@ -1428,6 +1428,13 @@ void tst_QQuickPathView::mouseDrag()
     QQuickPathView *pathview = qobject_cast<QQuickPathView*>(canvas->rootObject());
     QVERIFY(pathview != 0);
 
+    QSignalSpy movingSpy(pathview, SIGNAL(movingChanged()));
+    QSignalSpy moveStartedSpy(pathview, SIGNAL(movementStarted()));
+    QSignalSpy moveEndedSpy(pathview, SIGNAL(movementEnded()));
+    QSignalSpy draggingSpy(pathview, SIGNAL(draggingChanged()));
+    QSignalSpy dragStartedSpy(pathview, SIGNAL(dragStarted()));
+    QSignalSpy dragEndedSpy(pathview, SIGNAL(dragEnded()));
+
     int current = pathview->currentIndex();
 
     QTest::mousePress(canvas, Qt::LeftButton, 0, QPoint(10,100));
@@ -1439,6 +1446,13 @@ void tst_QQuickPathView::mouseDrag()
     }
     // first move beyond threshold does not trigger drag
     QVERIFY(!pathview->isMoving());
+    QVERIFY(!pathview->isDragging());
+    QCOMPARE(movingSpy.count(), 0);
+    QCOMPARE(moveStartedSpy.count(), 0);
+    QCOMPARE(moveEndedSpy.count(), 0);
+    QCOMPARE(draggingSpy.count(), 0);
+    QCOMPARE(dragStartedSpy.count(), 0);
+    QCOMPARE(dragEndedSpy.count(), 0);
 
     {
         QMouseEvent mv(QEvent::MouseMove, QPoint(90,100), Qt::LeftButton, Qt::LeftButton,Qt::NoModifier);
@@ -1446,10 +1460,24 @@ void tst_QQuickPathView::mouseDrag()
     }
     // next move beyond threshold does trigger drag
     QVERIFY(pathview->isMoving());
+    QVERIFY(pathview->isDragging());
+    QCOMPARE(movingSpy.count(), 1);
+    QCOMPARE(moveStartedSpy.count(), 1);
+    QCOMPARE(moveEndedSpy.count(), 0);
+    QCOMPARE(draggingSpy.count(), 1);
+    QCOMPARE(dragStartedSpy.count(), 1);
+    QCOMPARE(dragEndedSpy.count(), 0);
 
     QVERIFY(pathview->currentIndex() != current);
 
     QTest::mouseRelease(canvas, Qt::LeftButton, 0, QPoint(40,100));
+    QVERIFY(!pathview->isDragging());
+    QCOMPARE(draggingSpy.count(), 2);
+    QCOMPARE(dragStartedSpy.count(), 1);
+    QCOMPARE(dragEndedSpy.count(), 1);
+    QTRY_COMPARE(movingSpy.count(), 2);
+    QTRY_COMPARE(moveEndedSpy.count(), 1);
+    QCOMPARE(moveStartedSpy.count(), 1);
 
     delete canvas;
 }
@@ -1691,6 +1719,10 @@ void tst_QQuickPathView::cancelDrag()
     QQuickPathView *pathview = qobject_cast<QQuickPathView*>(canvas->rootObject());
     QVERIFY(pathview != 0);
 
+    QSignalSpy draggingSpy(pathview, SIGNAL(draggingChanged()));
+    QSignalSpy dragStartedSpy(pathview, SIGNAL(dragStarted()));
+    QSignalSpy dragEndedSpy(pathview, SIGNAL(dragEnded()));
+
     // drag between snap points
     QTest::mousePress(canvas, Qt::LeftButton, 0, QPoint(10,100));
     QTest::qWait(100);
@@ -1699,6 +1731,10 @@ void tst_QQuickPathView::cancelDrag()
 
     QTRY_VERIFY(pathview->offset() != qFloor(pathview->offset()));
     QTRY_VERIFY(pathview->isMoving());
+    QVERIFY(pathview->isDragging());
+    QCOMPARE(draggingSpy.count(), 1);
+    QCOMPARE(dragStartedSpy.count(), 1);
+    QCOMPARE(dragEndedSpy.count(), 0);
 
     // steal mouse grab - cancels PathView dragging
     QQuickItem *item = canvas->rootObject()->findChild<QQuickItem*>("text");
@@ -1707,6 +1743,10 @@ void tst_QQuickPathView::cancelDrag()
     // returns to a snap point.
     QTRY_VERIFY(pathview->offset() == qFloor(pathview->offset()));
     QTRY_VERIFY(!pathview->isMoving());
+    QVERIFY(!pathview->isDragging());
+    QCOMPARE(draggingSpy.count(), 2);
+    QCOMPARE(dragStartedSpy.count(), 1);
+    QCOMPARE(dragEndedSpy.count(), 1);
 
     QTest::mouseRelease(canvas, Qt::LeftButton, 0, QPoint(40,100));