aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/quick/items/qquickpathview.cpp10
-rw-r--r--src/quick/items/qquickpathview_p_p.h1
-rw-r--r--tests/auto/quick/qquickpathview/data/changePathDuringRefill.qml45
-rw-r--r--tests/auto/quick/qquickpathview/tst_qquickpathview.cpp40
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()