diff options
-rw-r--r-- | src/quick/items/qquickitemsmodule.cpp | 1 | ||||
-rw-r--r-- | src/quick/items/qquickpathview.cpp | 55 | ||||
-rw-r--r-- | src/quick/items/qquickpathview_p.h | 7 | ||||
-rw-r--r-- | src/quick/items/qquickpathview_p_p.h | 4 | ||||
-rw-r--r-- | tests/auto/quick/qquickpathview/data/movementDirection.qml | 43 | ||||
-rw-r--r-- | tests/auto/quick/qquickpathview/tst_qquickpathview.cpp | 68 |
6 files changed, 170 insertions, 8 deletions
diff --git a/src/quick/items/qquickitemsmodule.cpp b/src/quick/items/qquickitemsmodule.cpp index 23245e4a7b..08d95119d7 100644 --- a/src/quick/items/qquickitemsmodule.cpp +++ b/src/quick/items/qquickitemsmodule.cpp @@ -285,6 +285,7 @@ static void qt_quickitems_defineModule(const char *uri, int major, int minor) qmlRegisterType<QQuickGridView, 7>(uri, 2, 7, "GridView"); qmlRegisterType<QQuickTextInput, 7>(uri, 2, 7, "TextInput"); qmlRegisterType<QQuickTextEdit, 7>(uri, 2, 7, "TextEdit"); + qmlRegisterType<QQuickPathView, 7>(uri, 2, 7, "PathView"); qmlRegisterUncreatableType<QQuickMouseEvent, 7>(uri, 2, 7, nullptr, QQuickMouseEvent::tr("MouseEvent is only available within handlers in MouseArea")); } diff --git a/src/quick/items/qquickpathview.cpp b/src/quick/items/qquickpathview.cpp index a56d0fc06e..e3d218ff01 100644 --- a/src/quick/items/qquickpathview.cpp +++ b/src/quick/items/qquickpathview.cpp @@ -105,7 +105,8 @@ QQuickPathViewPrivate::QQuickPathViewPrivate() , dragMargin(0), deceleration(100), maximumFlickVelocity(QML_FLICK_DEFAULTMAXVELOCITY) , moveOffset(this, &QQuickPathViewPrivate::setAdjustedOffset), flickDuration(0) , pathItems(-1), requestedIndex(-1), cacheSize(0), requestedZ(0) - , moveReason(Other), moveDirection(Shortest), attType(0), highlightComponent(0), highlightItem(0) + , moveReason(Other), movementDirection(QQuickPathView::Shortest), moveDirection(QQuickPathView::Shortest) + , attType(0), highlightComponent(0), highlightItem(0) , moveHighlight(this, &QQuickPathViewPrivate::setHighlightPosition) , highlightPosition(0) , highlightRangeStart(0), highlightRangeEnd(0) @@ -790,7 +791,7 @@ QQuickItem *QQuickPathView::currentItem() const void QQuickPathView::incrementCurrentIndex() { Q_D(QQuickPathView); - d->moveDirection = QQuickPathViewPrivate::Positive; + d->moveDirection = QQuickPathView::Positive; setCurrentIndex(currentIndex()+1); } @@ -804,7 +805,7 @@ void QQuickPathView::incrementCurrentIndex() void QQuickPathView::decrementCurrentIndex() { Q_D(QQuickPathView); - d->moveDirection = QQuickPathViewPrivate::Negative; + d->moveDirection = QQuickPathView::Negative; setCurrentIndex(currentIndex()-1); } @@ -1373,6 +1374,48 @@ void QQuickPathView::setSnapMode(SnapMode mode) } /*! + \qmlproperty enumeration QtQuick::PathView::movementDirection + \since 5.7 + + This property determines the direction in which items move when setting the current index. + The possible values are: + + \list + \li PathView.Shortest (default) - the items move in the direction that requires the least + movement, which could be either \c Negative or \c Positive. + \li PathView.Negative - the items move backwards towards their destination. + \li PathView.Positive - the items move forwards towards their destination. + \endlist + + For example, suppose that there are 5 items in the model, and \l currentIndex is \c 0. + If currentIndex is set to \c 2, + + \list + \li a \c Positive movement direction will result in the following order: 0, 1, 2 + \li a \c Negative movement direction will result in the following order: 0, 5, 4, 3, 2 + \li a \c Shortest movement direction will result in same order with \c Positive . + \endlist + + \note this property doesn't affect the movement of \l incrementCurrentIndex() and \l decrementCurrentIndex(). +*/ +QQuickPathView::MovementDirection QQuickPathView::movementDirection() const +{ + Q_D(const QQuickPathView); + return d->movementDirection; +} + +void QQuickPathView::setMovementDirection(QQuickPathView::MovementDirection dir) +{ + Q_D(QQuickPathView); + if (dir == d->movementDirection) + return; + d->movementDirection = dir; + if (!d->tl.isActive()) + d->moveDirection = d->movementDirection; + emit movementDirectionChanged(); +} + +/*! \qmlmethod QtQuick::PathView::positionViewAtIndex(int index, PositionMode mode) Positions the view such that the \a index is at the position specified by @@ -2231,6 +2274,7 @@ void QQuickPathView::movementEnding() emit movingChanged(); emit movementEnded(); } + d->moveDirection = d->movementDirection; } // find the item closest to the snap position @@ -2340,7 +2384,7 @@ void QQuickPathViewPrivate::snapToIndex(int index, MovementReason reason) if (!duration) { tl.set(moveOffset, targetOffset); - } else if (moveDirection == Positive || (moveDirection == Shortest && targetOffset - offset > modelCount/2.0)) { + } else if (moveDirection == QQuickPathView::Positive || (moveDirection == QQuickPathView::Shortest && targetOffset - offset > modelCount/2.0)) { qreal distance = modelCount - targetOffset + offset; if (targetOffset > moveOffset) { tl.move(moveOffset, 0.0, QEasingCurve(QEasingCurve::InQuad), int(duration * offset / distance)); @@ -2349,7 +2393,7 @@ void QQuickPathViewPrivate::snapToIndex(int index, MovementReason reason) } else { tl.move(moveOffset, targetOffset, QEasingCurve(QEasingCurve::InOutQuad), duration); } - } else if (moveDirection == Negative || targetOffset - offset <= -modelCount/2.0) { + } else if (moveDirection == QQuickPathView::Negative || targetOffset - offset <= -modelCount/2.0) { qreal distance = modelCount - offset + targetOffset; if (targetOffset < moveOffset) { tl.move(moveOffset, modelCount, QEasingCurve(targetOffset == 0 ? QEasingCurve::InOutQuad : QEasingCurve::InQuad), int(duration * (modelCount-offset) / distance)); @@ -2361,7 +2405,6 @@ void QQuickPathViewPrivate::snapToIndex(int index, MovementReason reason) } else { tl.move(moveOffset, targetOffset, QEasingCurve(QEasingCurve::InOutQuad), duration); } - moveDirection = Shortest; } QQuickPathViewAttached *QQuickPathView::qmlAttachedProperties(QObject *obj) diff --git a/src/quick/items/qquickpathview_p.h b/src/quick/items/qquickpathview_p.h index 341af02013..daec965f02 100644 --- a/src/quick/items/qquickpathview_p.h +++ b/src/quick/items/qquickpathview_p.h @@ -92,6 +92,7 @@ class Q_AUTOTEST_EXPORT QQuickPathView : public QQuickItem Q_PROPERTY(QQmlComponent *delegate READ delegate WRITE setDelegate NOTIFY delegateChanged) Q_PROPERTY(int pathItemCount READ pathItemCount WRITE setPathItemCount RESET resetPathItemCount NOTIFY pathItemCountChanged) Q_PROPERTY(SnapMode snapMode READ snapMode WRITE setSnapMode NOTIFY snapModeChanged) + Q_PROPERTY(MovementDirection movementDirection READ movementDirection WRITE setMovementDirection NOTIFY movementDirectionChanged REVISION 7) Q_PROPERTY(int cacheItemCount READ cacheItemCount WRITE setCacheItemCount NOTIFY cacheItemCountChanged) @@ -164,6 +165,11 @@ public: SnapMode snapMode() const; void setSnapMode(SnapMode mode); + enum MovementDirection { Shortest, Negative, Positive }; + Q_ENUM(MovementDirection) + MovementDirection movementDirection() const; + void setMovementDirection(MovementDirection dir); + enum PositionMode { Beginning, Center, End, Contain=4, SnapPosition }; // 3 == Visible in other views Q_ENUM(PositionMode) Q_INVOKABLE void positionViewAtIndex(int index, int mode); @@ -201,6 +207,7 @@ Q_SIGNALS: void highlightMoveDurationChanged(); void movementStarted(); void movementEnded(); + Q_REVISION(7) void movementDirectionChanged(); void flickStarted(); void flickEnded(); void dragStarted(); diff --git a/src/quick/items/qquickpathview_p_p.h b/src/quick/items/qquickpathview_p_p.h index 8236d9efd2..d9c4baf572 100644 --- a/src/quick/items/qquickpathview_p_p.h +++ b/src/quick/items/qquickpathview_p_p.h @@ -171,8 +171,8 @@ public: QPointer<QQmlInstanceModel> model; QVariant modelVariant; MovementReason moveReason; - enum MovementDirection { Shortest, Negative, Positive }; - MovementDirection moveDirection; + QQuickPathView::MovementDirection movementDirection; // default + QQuickPathView::MovementDirection moveDirection; // next movement QQmlOpenMetaObjectType *attType; QQmlComponent *highlightComponent; QQuickItem *highlightItem; diff --git a/tests/auto/quick/qquickpathview/data/movementDirection.qml b/tests/auto/quick/qquickpathview/data/movementDirection.qml new file mode 100644 index 0000000000..fce914dd68 --- /dev/null +++ b/tests/auto/quick/qquickpathview/data/movementDirection.qml @@ -0,0 +1,43 @@ +import QtQuick 2.0 + +Item { + id: root + width: 320; height: 480 + + PathView { + id: view + objectName: "view" + anchors.fill: parent + + model: ListModel { + ListElement { lColor: "red" } + ListElement { lColor: "green" } + ListElement { lColor: "yellow" } + ListElement { lColor: "blue" } + ListElement { lColor: "purple" } + ListElement { lColor: "gray" } + ListElement { lColor: "brown" } + ListElement { lColor: "thistle" } + } + + delegate: Component { + id: photoDelegate + Rectangle { + id: wrapper + objectName: "wrapper" + width: 40; height: 40; color: lColor + + Text { text: index } + } + } + + snapMode: PathView.SnapToItem + highlightMoveDuration: 1000 + path: Path { + startX: 0+20; startY: root.height/2 + PathLine { x: root.width*2; y: root.height/2 } + } + + Text { text: "Offset: " + view.offset } + } +} diff --git a/tests/auto/quick/qquickpathview/tst_qquickpathview.cpp b/tests/auto/quick/qquickpathview/tst_qquickpathview.cpp index 51c772f540..6761313210 100644 --- a/tests/auto/quick/qquickpathview/tst_qquickpathview.cpp +++ b/tests/auto/quick/qquickpathview/tst_qquickpathview.cpp @@ -137,6 +137,8 @@ private slots: void jsArrayChange(); void qtbug42716(); void addCustomAttribute(); + void movementDirection_data(); + void movementDirection(); }; class TestObject : public QObject @@ -2383,6 +2385,72 @@ void tst_QQuickPathView::addCustomAttribute() window->show(); } +void tst_QQuickPathView::movementDirection_data() +{ + QTest::addColumn<QQuickPathView::MovementDirection>("movementdirection"); + QTest::addColumn<int>("toidx"); + QTest::addColumn<qreal>("fromoffset"); + QTest::addColumn<qreal>("tooffset"); + + QTest::newRow("default-shortest") << QQuickPathView::Shortest << 3 << 8.0 << 5.0; + QTest::newRow("negative") << QQuickPathView::Negative << 2 << 0.0 << 6.0; + QTest::newRow("positive") << QQuickPathView::Positive << 3 << 8.0 << 5.0; + +} + +static void verify_offsets(QQuickPathView *pathview, int toidx, qreal fromoffset, qreal tooffset) +{ + pathview->setCurrentIndex(toidx); + bool started = false; + qreal first, second; + QTest::qWait(100); + first = pathview->offset(); + while (1) { + QTest::qWait(10); // highlightMoveDuration: 1000 + second = pathview->offset(); + if (!started && second != first) { // animation started + started = true; + break; + } + } + + if (tooffset > fromoffset) { + QVERIFY(fromoffset <= first); + QVERIFY(first <= second); + QVERIFY(second <= tooffset); + } else { + QVERIFY(fromoffset >= first); + QVERIFY(first >= second); + QVERIFY(second >= tooffset); + } + QTRY_COMPARE(pathview->offset(), tooffset); +} + +void tst_QQuickPathView::movementDirection() +{ + QFETCH(QQuickPathView::MovementDirection, movementdirection); + QFETCH(int, toidx); + QFETCH(qreal, fromoffset); + QFETCH(qreal, tooffset); + + QScopedPointer<QQuickView> window(createView()); + QQuickViewTestUtil::moveMouseAway(window.data()); + window->setSource(testFileUrl("movementDirection.qml")); + window->show(); + window->requestActivate(); + QVERIFY(QTest::qWaitForWindowActive(window.data())); + QCOMPARE(window.data(), qGuiApp->focusWindow()); + + QQuickPathView *pathview = window->rootObject()->findChild<QQuickPathView*>("view"); + QVERIFY(pathview != 0); + QVERIFY(pathview->offset() == 0.0); + QVERIFY(pathview->currentIndex() == 0); + pathview->setMovementDirection(movementdirection); + QVERIFY(pathview->movementDirection() == movementdirection); + + verify_offsets(pathview, toidx, fromoffset, tooffset); +} + QTEST_MAIN(tst_QQuickPathView) #include "tst_qquickpathview.moc" |