diff options
-rw-r--r-- | src/quick/items/qquickpathview.cpp | 10 | ||||
-rw-r--r-- | src/quick/items/qquickpathview_p_p.h | 1 | ||||
-rw-r--r-- | tests/auto/quick/qquickpathview/data/changePathDuringRefill.qml | 45 | ||||
-rw-r--r-- | tests/auto/quick/qquickpathview/tst_qquickpathview.cpp | 40 |
4 files changed, 96 insertions, 0 deletions
diff --git a/src/quick/items/qquickpathview.cpp b/src/quick/items/qquickpathview.cpp index 45cd8e184c..335e7611f1 100644 --- a/src/quick/items/qquickpathview.cpp +++ b/src/quick/items/qquickpathview.cpp @@ -104,6 +104,7 @@ QQuickPathViewPrivate::QQuickPathViewPrivate() , stealMouse(false), ownModel(false), interactive(true), haveHighlightRange(true) , autoHighlight(true), highlightUp(false), layoutScheduled(false) , moving(false), flicking(false), dragging(false), inRequest(false), delegateValidated(false) + , inRefill(false) , dragMargin(0), deceleration(100), maximumFlickVelocity(QML_FLICK_DEFAULTMAXVELOCITY) , moveOffset(this, &QQuickPathViewPrivate::setAdjustedOffset), flickDuration(0) , firstIndex(-1), pathItems(-1), requestedIndex(-1), cacheSize(0), requestedZ(0) @@ -1873,11 +1874,18 @@ void QQuickPathView::refill() { Q_D(QQuickPathView); + if (d->inRefill) { + d->scheduleLayout(); + return; + } + d->layoutScheduled = false; if (!d->isValid() || !isComponentComplete()) return; + d->inRefill = true; + bool currentVisible = false; int count = d->pathItems == -1 ? d->modelCount : qMin(d->pathItems, d->modelCount); @@ -2010,6 +2018,8 @@ void QQuickPathView::refill() } while (d->itemCache.count()) d->releaseItem(d->itemCache.takeLast()); + + d->inRefill = false; } void QQuickPathView::modelUpdated(const QQmlChangeSet &changeSet, bool reset) diff --git a/src/quick/items/qquickpathview_p_p.h b/src/quick/items/qquickpathview_p_p.h index 813f472072..e21f3757e6 100644 --- a/src/quick/items/qquickpathview_p_p.h +++ b/src/quick/items/qquickpathview_p_p.h @@ -152,6 +152,7 @@ public: bool requestedOnPath : 1; bool inRequest : 1; bool delegateValidated : 1; + bool inRefill : 1; QElapsedTimer timer; qint64 lastPosTime; QPointF lastPos; diff --git a/tests/auto/quick/qquickpathview/data/changePathDuringRefill.qml b/tests/auto/quick/qquickpathview/data/changePathDuringRefill.qml new file mode 100644 index 0000000000..f02ab35faf --- /dev/null +++ b/tests/auto/quick/qquickpathview/data/changePathDuringRefill.qml @@ -0,0 +1,45 @@ +import QtQuick 2.3 + +PathView { + id: view + objectName: "pathView" + width: 100 + height: delegateHeight * pathItemCount + model: ["A", "B", "C"] + pathItemCount: 3 + anchors.centerIn: parent + + property int delegateHeight: 0 + + activeFocusOnTab: true + Keys.onDownPressed: view.incrementCurrentIndex() + Keys.onUpPressed: view.decrementCurrentIndex() + preferredHighlightBegin: 0.5 + preferredHighlightEnd: 0.5 + + delegate: Rectangle { + objectName: "delegate" + modelData + width: view.width + height: textItem.height + border.color: "red" + + onHeightChanged: { + if (index == 0) + view.delegateHeight = textItem.height + } + + Text { + id: textItem + text: modelData + } + } + + path: Path { + startX: view.width / 2 + startY: 0 + PathLine { + x: view.width / 2 + y: view.pathItemCount * view.delegateHeight + } + } +} diff --git a/tests/auto/quick/qquickpathview/tst_qquickpathview.cpp b/tests/auto/quick/qquickpathview/tst_qquickpathview.cpp index 405e0267ff..1960775ad3 100644 --- a/tests/auto/quick/qquickpathview/tst_qquickpathview.cpp +++ b/tests/auto/quick/qquickpathview/tst_qquickpathview.cpp @@ -144,6 +144,7 @@ private slots: void indexAt_itemAt_data(); void cacheItemCount(); void incorrectSteal(); + void changePathDuringRefill(); }; class TestObject : public QObject @@ -2122,7 +2123,46 @@ void tst_QQuickPathView::cacheItemCount() bool b = true; controller.incubateWhile(&b); } +} + +static void testCurrentIndexChange(QQuickPathView *pathView, const QStringList &objectNamesInOrder) +{ + for (int visualIndex = 0; visualIndex < objectNamesInOrder.size() - 1; ++visualIndex) { + QQuickRectangle *delegate = findItem<QQuickRectangle>(pathView, objectNamesInOrder.at(visualIndex)); + QVERIFY(delegate); + + QQuickRectangle *nextDelegate = findItem<QQuickRectangle>(pathView, objectNamesInOrder.at(visualIndex + 1)); + QVERIFY(nextDelegate); + + QVERIFY(delegate->y() < nextDelegate->y()); + } +} + +void tst_QQuickPathView::changePathDuringRefill() +{ + QScopedPointer<QQuickView> window(createView()); + + window->setSource(testFileUrl("changePathDuringRefill.qml")); + window->show(); + QVERIFY(QTest::qWaitForWindowActive(window.data())); + QCOMPARE(window.data(), qGuiApp->focusWindow()); + + QQuickPathView *pathView = qobject_cast<QQuickPathView*>(window->rootObject()); + QVERIFY(pathView != 0); + + testCurrentIndexChange(pathView, QStringList() << "delegateC" << "delegateA" << "delegateB"); + + pathView->incrementCurrentIndex(); + /* + Decrementing moves delegateA down, resulting in an offset of 1, + so incrementing will move it up, resulting in an offset of 2: + delegateC delegateA + delegateA => delegateB + delegateB delegateC + */ + QTRY_COMPARE(pathView->offset(), 2.0); + testCurrentIndexChange(pathView, QStringList() << "delegateA" << "delegateB" << "delegateC"); } void tst_QQuickPathView::incorrectSteal() |