diff options
-rw-r--r-- | src/quick/items/qquicklistview.cpp | 59 | ||||
-rw-r--r-- | tests/auto/quick/qquicklistview/BLACKLIST | 2 | ||||
-rw-r--r-- | tests/auto/quick/qquicklistview/tst_qquicklistview.cpp | 18 |
3 files changed, 62 insertions, 17 deletions
diff --git a/src/quick/items/qquicklistview.cpp b/src/quick/items/qquicklistview.cpp index c7df855282..9f53586893 100644 --- a/src/quick/items/qquicklistview.cpp +++ b/src/quick/items/qquicklistview.cpp @@ -3122,12 +3122,13 @@ bool QQuickListViewPrivate::applyInsertionChange(const QQmlChangeSet::Change &ch int i = 0; qreal from = tempPos - displayMarginBeginning - buffer; - for (i = count-1; i >= 0; --i) { - if (pos > from && insertionIdx < visibleIndex) { - // item won't be visible, just note the size for repositioning - insertResult->sizeChangesBeforeVisiblePos += averageSize + spacing; - pos -= averageSize + spacing; - } else { + if (insertionIdx < visibleIndex) { + if (pos >= from) { + // items won't be visible, just note the size for repositioning + insertResult->sizeChangesBeforeVisiblePos += count * (averageSize + spacing); + } + } else { + for (i = count-1; i >= 0 && pos >= from; --i) { // item is before first visible e.g. in cache buffer FxViewItem *item = 0; if (change.isMove() && (item = currentChanges.removedItems.take(change.moveKey(modelIndex + i)))) @@ -3142,17 +3143,33 @@ bool QQuickListViewPrivate::applyInsertionChange(const QQmlChangeSet::Change &ch insertResult->changedFirstItem = true; if (!change.isMove()) { addedItems->append(item); - item->transitionNextReposition(transitioner, QQuickItemViewTransitioner::AddTransition, true); + if (transitioner) + item->transitionNextReposition(transitioner, QQuickItemViewTransitioner::AddTransition, true); + else + static_cast<FxListItemSG *>(item)->setPosition(pos, true); } insertResult->sizeChangesBeforeVisiblePos += item->size() + spacing; pos -= item->size() + spacing; + index++; + } + } + + int firstOkIdx = -1; + for (int i = 0; i <= insertionIdx && i < visibleItems.count() - 1; i++) { + if (visibleItems.at(i)->index + 1 != visibleItems.at(i + 1)->index) { + firstOkIdx = i + 1; + break; } - index++; } + for (int i = 0; i < firstOkIdx; i++) { + FxViewItem *nvItem = visibleItems.takeFirst(); + addedItems->removeOne(nvItem); + removeItem(nvItem); + } + } else { - int i = 0; qreal to = buffer + displayMarginEnd + tempPos + size(); - for (i = 0; i < count && pos <= to; ++i) { + for (int i = 0; i < count && pos <= to; ++i) { FxViewItem *item = 0; if (change.isMove() && (item = currentChanges.removedItems.take(change.moveKey(modelIndex + i)))) item->index = modelIndex + i; @@ -3172,12 +3189,32 @@ bool QQuickListViewPrivate::applyInsertionChange(const QQmlChangeSet::Change &ch movingIntoView->append(MovedItem(item, change.moveKey(item->index))); } else { addedItems->append(item); - item->transitionNextReposition(transitioner, QQuickItemViewTransitioner::AddTransition, true); + if (transitioner) + item->transitionNextReposition(transitioner, QQuickItemViewTransitioner::AddTransition, true); + else + static_cast<FxListItemSG *>(item)->setPosition(pos, true); } insertResult->sizeChangesAfterVisiblePos += item->size() + spacing; pos += item->size() + spacing; ++index; } + + if (0 < index && index < visibleItems.count()) { + FxViewItem *prevItem = visibleItems.at(index - 1); + FxViewItem *item = visibleItems.at(index); + if (prevItem->index != item->index - 1) { + int i = index; + qreal prevPos = prevItem->position(); + while (i < visibleItems.count()) { + FxListItemSG *nvItem = static_cast<FxListItemSG *>(visibleItems.takeLast()); + insertResult->sizeChangesAfterVisiblePos -= nvItem->size() + spacing; + addedItems->removeOne(nvItem); + if (nvItem->transitionScheduledOrRunning()) + nvItem->setPosition(prevPos + (nvItem->index - prevItem->index) * averageSize); + removeItem(nvItem); + } + } + } } updateVisibleIndex(); diff --git a/tests/auto/quick/qquicklistview/BLACKLIST b/tests/auto/quick/qquicklistview/BLACKLIST index 02adeacf05..269696ce8c 100644 --- a/tests/auto/quick/qquicklistview/BLACKLIST +++ b/tests/auto/quick/qquicklistview/BLACKLIST @@ -2,5 +2,3 @@ * [enforceRange_withoutHighlight] osx -[QTBUG_48870_fastModelUpdates] -* diff --git a/tests/auto/quick/qquicklistview/tst_qquicklistview.cpp b/tests/auto/quick/qquicklistview/tst_qquicklistview.cpp index ce2337ccb2..b3a6edb66a 100644 --- a/tests/auto/quick/qquicklistview/tst_qquicklistview.cpp +++ b/tests/auto/quick/qquicklistview/tst_qquicklistview.cpp @@ -592,8 +592,7 @@ void tst_QQuickListView::inserted(const QUrl &source) QQuickItem *item = findItem<QQuickItem>(contentItem, "wrapper", 0); QVERIFY(item); - QCOMPARE(item->y(), 0.); - QTRY_COMPARE(listview->contentY(), qreal(0)); + QTRY_COMPARE(item->y() - listview->contentY(), 0.); delete window; delete testObject; @@ -644,7 +643,8 @@ void tst_QQuickListView::inserted_more(QQuickItemView::VerticalLayoutDirection v QTRY_COMPARE(listview->property("count").toInt(), model.count()); - + // FIXME This is NOT checking anything about visibleItems.first() +#if 0 // check visibleItems.first() is in correct position QQuickItem *item0 = findItem<QQuickItem>(contentItem, "wrapper", 0); QVERIFY(item0); @@ -652,6 +652,7 @@ void tst_QQuickListView::inserted_more(QQuickItemView::VerticalLayoutDirection v QCOMPARE(item0->y(), -item0->height() - itemsOffsetAfterMove); else QCOMPARE(item0->y(), itemsOffsetAfterMove); +#endif QList<QQuickItem*> items = findItems<QQuickItem>(contentItem, "wrapper"); int firstVisibleIndex = -1; @@ -667,12 +668,21 @@ void tst_QQuickListView::inserted_more(QQuickItemView::VerticalLayoutDirection v // Confirm items positioned correctly and indexes correct QQuickText *name; QQuickText *number; + const qreal visibleFromPos = listview->contentY() - listview->displayMarginBeginning() - listview->cacheBuffer(); + const qreal visibleToPos = listview->contentY() + listview->height() + listview->displayMarginEnd() + listview->cacheBuffer(); for (int i = firstVisibleIndex; i < model.count() && i < items.count(); ++i) { QQuickItem *item = findItem<QQuickItem>(contentItem, "wrapper", i); QVERIFY2(item, QTest::toString(QString("Item %1 not found").arg(i))); qreal pos = i*20.0 + itemsOffsetAfterMove; if (verticalLayoutDirection == QQuickItemView::BottomToTop) - pos = -item0->height() - pos; + pos = -item->height() - pos; + // Items outside the visible area (including cache buffer) should be skipped + if (pos > visibleToPos || pos < visibleFromPos) { + QTRY_VERIFY2(QQuickItemPrivate::get(item)->culled || item->y() < visibleFromPos || item->y() > visibleToPos, + QTest::toString(QString("index %5, y %1, from %2, to %3, expected pos %4, culled %6"). + arg(item->y()).arg(visibleFromPos).arg(visibleToPos).arg(pos).arg(i).arg(bool(QQuickItemPrivate::get(item)->culled)))); + continue; + } QTRY_COMPARE(item->y(), pos); name = findItem<QQuickText>(contentItem, "textName", i); QVERIFY(name != 0); |