diff options
-rw-r--r-- | src/quick/items/qquickgridview.cpp | 53 | ||||
-rw-r--r-- | src/quick/items/qquickitemview.cpp | 81 | ||||
-rw-r--r-- | src/quick/items/qquickitemview_p_p.h | 18 | ||||
-rw-r--r-- | src/quick/items/qquicklistview.cpp | 48 | ||||
-rw-r--r-- | src/quick/items/qquickvisualdatamodel.cpp | 4 | ||||
-rw-r--r-- | tests/auto/qtquick2/qquickgridview/tst_qquickgridview.cpp | 64 | ||||
-rw-r--r-- | tests/auto/qtquick2/qquicklistview/tst_qquicklistview.cpp | 13 |
7 files changed, 157 insertions, 124 deletions
diff --git a/src/quick/items/qquickgridview.cpp b/src/quick/items/qquickgridview.cpp index ef79a4de42..8cc9b4248d 100644 --- a/src/quick/items/qquickgridview.cpp +++ b/src/quick/items/qquickgridview.cpp @@ -59,6 +59,8 @@ QT_BEGIN_NAMESPACE #define QML_FLICK_SNAPONETHRESHOLD 30 #endif +//#define DEBUG_DELEGATE_LIFECYCLE + //---------------------------------------------------------------------------- class FxGridItemSG : public FxViewItem @@ -172,7 +174,7 @@ public: virtual FxViewItem *newViewItem(int index, QQuickItem *item); virtual void repositionPackageItemAt(QQuickItem *item, int index); virtual void resetFirstItemPosition(qreal pos = 0.0); - virtual void adjustFirstItem(qreal forwards, qreal backwards); + virtual void adjustFirstItem(qreal forwards, qreal backwards, int changeBeforeVisible); virtual void createHighlight(); virtual void updateHighlight(); @@ -442,7 +444,9 @@ bool QQuickGridViewPrivate::addVisibleItems(qreal fillFrom, qreal fillTo, bool d bool changed = false; while (modelIndex < model->count() && rowPos <= fillTo + rowSize()*(columns - colNum)/(columns+1)) { -// qDebug() << "refill: append item" << modelIndex << colPos << rowPos; +#ifdef DEBUG_DELEGATE_LIFECYCLE + qDebug() << "refill: append item" << modelIndex << colPos << rowPos; +#endif if (!(item = static_cast<FxGridItemSG*>(createItem(modelIndex, doBuffer)))) break; item->setPosition(colPos, rowPos); @@ -457,6 +461,9 @@ bool QQuickGridViewPrivate::addVisibleItems(qreal fillFrom, qreal fillTo, bool d changed = true; } + if (doBuffer && requestedIndex != -1) // already waiting for an item + return changed; + // Find first column if (visibleItems.count()) { FxGridItemSG *firstItem = static_cast<FxGridItemSG*>(visibleItems.first()); @@ -473,7 +480,9 @@ bool QQuickGridViewPrivate::addVisibleItems(qreal fillFrom, qreal fillTo, bool d // Prepend colPos = colNum * colSize(); while (visibleIndex > 0 && rowPos + rowSize() - 1 >= fillFrom - rowSize()*(colNum+1)/(columns+1)){ -// qDebug() << "refill: prepend item" << visibleIndex-1 << "top pos" << rowPos << colPos; +#ifdef DEBUG_DELEGATE_LIFECYCLE + qDebug() << "refill: prepend item" << visibleIndex-1 << "top pos" << rowPos << colPos; +#endif if (!(item = static_cast<FxGridItemSG*>(createItem(visibleIndex-1, doBuffer)))) break; --visibleIndex; @@ -501,7 +510,9 @@ bool QQuickGridViewPrivate::removeNonVisibleItems(qreal bufferFrom, qreal buffer && item->rowPos()+rowSize()-1 < bufferFrom - rowSize()*(item->colPos()/colSize()+1)/(columns+1)) { if (item->attached->delayRemove()) break; -// qDebug() << "refill: remove first" << visibleIndex << "top end pos" << item->endRowPos(); +#ifdef DEBUG_DELEGATE_LIFECYCLE + qDebug() << "refill: remove first" << visibleIndex << "top end pos" << item->endRowPos(); +#endif if (item->index != -1) visibleIndex++; visibleItems.removeFirst(); @@ -513,7 +524,9 @@ bool QQuickGridViewPrivate::removeNonVisibleItems(qreal bufferFrom, qreal buffer && item->rowPos() > bufferTo + rowSize()*(columns - item->colPos()/colSize())/(columns+1)) { if (item->attached->delayRemove()) break; -// qDebug() << "refill: remove last" << visibleIndex+visibleItems.count()-1; +#ifdef DEBUG_DELEGATE_LIFECYCLE + qDebug() << "refill: remove last" << visibleIndex+visibleItems.count()-1; +#endif visibleItems.removeLast(); releaseItem(item); changed = true; @@ -590,12 +603,15 @@ void QQuickGridViewPrivate::resetFirstItemPosition(qreal pos) item->setPosition(0, pos); } -void QQuickGridViewPrivate::adjustFirstItem(qreal forwards, qreal backwards) +void QQuickGridViewPrivate::adjustFirstItem(qreal forwards, qreal backwards, int changeBeforeVisible) { if (!visibleItems.count()) return; - int moveCount = (forwards / rowSize()) - (backwards / rowSize()); + int moveCount = (forwards - backwards) / rowSize(); + + if (changeBeforeVisible) + moveCount += (changeBeforeVisible%columns) - (columns - 1); FxGridItemSG *gridItem = static_cast<FxGridItemSG*>(visibleItems.first()); gridItem->setPosition(gridItem->colPos(), gridItem->rowPos() + ((moveCount / columns) * rowSize())); @@ -1419,7 +1435,7 @@ void QQuickGridView::setCellWidth(qreal cellWidth) d->updateViewport(); emit cellWidthChanged(); d->forceLayout = true; - d->layout(); + polish(); } } @@ -1437,7 +1453,7 @@ void QQuickGridView::setCellHeight(qreal cellHeight) d->updateViewport(); emit cellHeightChanged(); d->forceLayout = true; - d->layout(); + polish(); } } /*! @@ -1521,14 +1537,6 @@ void QQuickGridView::viewportMoved() return; d->inViewportMoved = true; - // Set visibility of items to eliminate cost of items outside the visible area. - qreal from = d->isContentFlowReversed() ? -d->position()-d->size() : d->position(); - qreal to = d->isContentFlowReversed() ? -d->position() : d->position()+d->size(); - for (int i = 0; i < d->visibleItems.count(); ++i) { - FxGridItemSG *item = static_cast<FxGridItemSG*>(d->visibleItems.at(i)); - item->item->setVisible(item->rowPos() + d->rowSize() >= from && item->rowPos() <= to); - } - if (yflick()) d->bufferMode = d->vData.smoothVelocity < 0 ? QQuickItemViewPrivate::BufferBefore : QQuickItemViewPrivate::BufferAfter; else if (d->isRightToLeftTopToBottom()) @@ -1537,6 +1545,15 @@ void QQuickGridView::viewportMoved() d->bufferMode = d->hData.smoothVelocity < 0 ? QQuickItemViewPrivate::BufferBefore : QQuickItemViewPrivate::BufferAfter; d->refill(); + + // Set visibility of items to eliminate cost of items outside the visible area. + qreal from = d->isContentFlowReversed() ? -d->position()-d->size() : d->position(); + qreal to = d->isContentFlowReversed() ? -d->position() : d->position()+d->size(); + for (int i = 0; i < d->visibleItems.count(); ++i) { + FxGridItemSG *item = static_cast<FxGridItemSG*>(d->visibleItems.at(i)); + item->item->setVisible(item->rowPos() + d->rowSize() >= from && item->rowPos() <= to); + } + if (d->hData.flicking || d->vData.flicking || d->hData.moving || d->vData.moving) d->moveReason = QQuickGridViewPrivate::Mouse; if (d->moveReason != QQuickGridViewPrivate::SetIndex) { @@ -1817,7 +1834,7 @@ bool QQuickGridViewPrivate::applyInsertionChange(const QDeclarativeChangeSet::In while (i >= 0) { if (rowPos > from && insertionIdx < visibleIndex) { // item won't be visible, just note the size for repositioning - insertResult->sizeChangesBeforeVisiblePos += rowSize(); + insertResult->changeBeforeVisible++; } else { // item is before first visible e.g. in cache buffer FxViewItem *item = 0; diff --git a/src/quick/items/qquickitemview.cpp b/src/quick/items/qquickitemview.cpp index 8ff8b8860c..3341402acd 100644 --- a/src/quick/items/qquickitemview.cpp +++ b/src/quick/items/qquickitemview.cpp @@ -775,7 +775,7 @@ void QQuickItemView::destroyRemoved() // Correct the positioning of the items d->updateSections(); d->forceLayout = true; - d->layout(); + polish(); } void QQuickItemView::modelUpdated(const QDeclarativeChangeSet &changeSet, bool reset) @@ -1114,7 +1114,7 @@ QQuickItemViewPrivate::QQuickItemViewPrivate() , highlightMoveDuration(150) , headerComponent(0), header(0), footerComponent(0), footer(0) , minExtent(0), maxExtent(0) - , ownModel(false), wrap(false), deferredRelease(false) + , ownModel(false), wrap(false) , inApplyModelChanges(false), inViewportMoved(false), forceLayout(false), currentIndexCleared(false) , haveHighlightRange(false), autoHighlight(true), highlightRangeStartValid(false), highlightRangeEndValid(false) , fillCacheBuffer(false), inRequest(false), requestedAsync(false) @@ -1301,7 +1301,7 @@ void QQuickItemViewPrivate::refill() refill(position(), position()+s); } -void QQuickItemViewPrivate::refill(qreal from, qreal to, bool doBuffer) +void QQuickItemViewPrivate::refill(qreal from, qreal to) { Q_Q(QQuickItemView); if (!isValid() || !q->isComponentComplete()) @@ -1315,35 +1315,22 @@ void QQuickItemViewPrivate::refill(qreal from, qreal to, bool doBuffer) qreal bufferTo = to + buffer; qreal fillFrom = from; qreal fillTo = to; - if (doBuffer && (bufferMode & BufferAfter)) - fillTo = bufferTo; - if (doBuffer && (bufferMode & BufferBefore)) - fillFrom = bufferFrom; - - // Item creation and release is staggered in order to avoid - // creating/releasing multiple items in one frame - // while flicking (as much as possible). - bool changed = addVisibleItems(fillFrom, fillTo, doBuffer); + bool added = addVisibleItems(fillFrom, fillTo, false); + bool removed = removeNonVisibleItems(bufferFrom, bufferTo); - if (!changed || deferredRelease) { // avoid destroying items in the same frame that we create - if (removeNonVisibleItems(bufferFrom, bufferTo)) - changed = true; - deferredRelease = false; - } else { - deferredRelease = true; + if (buffer && bufferMode != NoBuffer) { + if (bufferMode & BufferAfter) + fillTo = bufferTo; + if (bufferMode & BufferBefore) + fillFrom = bufferFrom; + added |= addVisibleItems(fillFrom, fillTo, true); } - if (changed) { + if (added || removed) { markExtentsDirty(); + updateBeginningEnd(); visibleItemsChanged(); - } else if (!doBuffer && buffer && bufferMode != NoBuffer) { - refill(from, to, true); - } - - if (!q->isMoving() && changed) { - fillCacheBuffer = true; - q->polish(); } if (prevCount != itemCount) @@ -1393,8 +1380,10 @@ void QQuickItemViewPrivate::layout() } if (!applyModelChanges() && !forceLayout) { - if (fillCacheBuffer) + if (fillCacheBuffer) { + fillCacheBuffer = false; refill(); + } return; } forceLayout = false; @@ -1459,7 +1448,7 @@ bool QQuickItemViewPrivate::applyModelChanges() // set positions correctly for the next insertion if (!insertions.isEmpty()) { - repositionFirstItem(prevVisibleItemsFirst, prevVisibleItemsFirstPos, prevFirstVisible, insertionResult, removalResult); + repositionFirstItem(prevVisibleItemsFirst, prevVisibleItemsFirstPos, prevFirstVisible, &insertionResult, &removalResult); layoutVisibleItems(removals.first().index); } } @@ -1476,7 +1465,7 @@ bool QQuickItemViewPrivate::applyModelChanges() // set positions correctly for the next insertion if (i < insertions.count() - 1) { - repositionFirstItem(prevVisibleItemsFirst, prevVisibleItemsFirstPos, prevFirstVisible, insertionResult, removalResult); + repositionFirstItem(prevVisibleItemsFirst, prevVisibleItemsFirstPos, prevFirstVisible, &insertionResult, &removalResult); layoutVisibleItems(insertions[i].index); } @@ -1487,7 +1476,7 @@ bool QQuickItemViewPrivate::applyModelChanges() // reposition visibleItems.first() correctly so that the content y doesn't jump if (removedCount != prevVisibleItemsCount) - repositionFirstItem(prevVisibleItemsFirst, prevVisibleItemsFirstPos, prevFirstVisible, insertionResult, removalResult); + repositionFirstItem(prevVisibleItemsFirst, prevVisibleItemsFirstPos, prevFirstVisible, &insertionResult, &removalResult); // Whatever removed/moved items remain are no longer visible items. for (QHash<QDeclarativeChangeSet::MoveKey, FxViewItem *>::Iterator it = currentChanges.removedItems.begin(); @@ -1567,27 +1556,31 @@ bool QQuickItemViewPrivate::applyRemovalChange(const QDeclarativeChangeSet::Remo } } } + + if (removal.index + removal.count < visibleIndex) + removeResult->changeBeforeVisible -= removal.count; + return visibleAffected; } void QQuickItemViewPrivate::repositionFirstItem(FxViewItem *prevVisibleItemsFirst, qreal prevVisibleItemsFirstPos, FxViewItem *prevFirstVisible, - const ChangeResult &insertionResult, - const ChangeResult &removalResult) + ChangeResult *insertionResult, + ChangeResult *removalResult) { - const QDeclarativeNullableValue<qreal> prevViewPos = insertionResult.visiblePos; + const QDeclarativeNullableValue<qreal> prevViewPos = insertionResult->visiblePos; // reposition visibleItems.first() correctly so that the content y doesn't jump if (visibleItems.count()) { - if (prevVisibleItemsFirst && insertionResult.changedFirstItem) + if (prevVisibleItemsFirst && insertionResult->changedFirstItem) resetFirstItemPosition(prevVisibleItemsFirstPos); if (prevFirstVisible && prevVisibleItemsFirst == prevFirstVisible && prevFirstVisible != *visibleItems.constBegin()) { // the previous visibleItems.first() was also the first visible item, and it has been // moved/removed, so move the new visibleItems.first() to the pos of the previous one - if (!insertionResult.changedFirstItem) + if (!insertionResult->changedFirstItem) resetFirstItemPosition(prevVisibleItemsFirstPos); } else if (prevViewPos.isValid()) { @@ -1596,14 +1589,16 @@ void QQuickItemViewPrivate::repositionFirstItem(FxViewItem *prevVisibleItemsFirs // shift visibleItems.first() relative to the number of added/removed items if (visibleItems.first()->position() > prevViewPos) { - moveForwardsBy = insertionResult.sizeChangesAfterVisiblePos; - moveBackwardsBy = removalResult.sizeChangesAfterVisiblePos; + moveForwardsBy = insertionResult->sizeChangesAfterVisiblePos; + moveBackwardsBy = removalResult->sizeChangesAfterVisiblePos; } else if (visibleItems.first()->position() < prevViewPos) { - moveForwardsBy = removalResult.sizeChangesBeforeVisiblePos; - moveBackwardsBy = insertionResult.sizeChangesBeforeVisiblePos; + moveForwardsBy = removalResult->sizeChangesBeforeVisiblePos; + moveBackwardsBy = insertionResult->sizeChangesBeforeVisiblePos; } - adjustFirstItem(moveForwardsBy, moveBackwardsBy); + adjustFirstItem(moveForwardsBy, moveBackwardsBy, insertionResult->changeBeforeVisible + removalResult->changeBeforeVisible); } + insertionResult->reset(); + removalResult->reset(); } } @@ -1619,6 +1614,8 @@ FxViewItem *QQuickItemViewPrivate::createItem(int modelIndex, bool asynchronous) return 0; if (requestedIndex != -1 && requestedIndex != modelIndex) { + if (requestedItem && requestedItem->item) + requestedItem->item->setParentItem(0); delete requestedItem; requestedItem = 0; } @@ -1631,7 +1628,6 @@ FxViewItem *QQuickItemViewPrivate::createItem(int modelIndex, bool asynchronous) item->setParentItem(q->contentItem()); QDeclarative_setParent_noEvent(item, q->contentItem()); requestedIndex = -1; - fillCacheBuffer = false; FxViewItem *viewItem = requestedItem; if (!viewItem) viewItem = newViewItem(modelIndex, item); // already in cache, so viewItem not initialized in initItem() @@ -1665,9 +1661,6 @@ void QQuickItemView::createdItem(int index, QQuickItem *item) if (index == d->currentIndex) d->updateCurrent(index); d->refill(); - } else { - d->fillCacheBuffer = true; - polish(); } } } diff --git a/src/quick/items/qquickitemview_p_p.h b/src/quick/items/qquickitemview_p_p.h index a2dd963dd2..52463afaaa 100644 --- a/src/quick/items/qquickitemview_p_p.h +++ b/src/quick/items/qquickitemview_p_p.h @@ -104,9 +104,18 @@ public: qreal sizeChangesBeforeVisiblePos; qreal sizeChangesAfterVisiblePos; bool changedFirstItem; + int changeBeforeVisible; ChangeResult(const QDeclarativeNullableValue<qreal> &p) - : visiblePos(p), sizeChangesBeforeVisiblePos(0), sizeChangesAfterVisiblePos(0), changedFirstItem(false) {} + : visiblePos(p), sizeChangesBeforeVisiblePos(0), sizeChangesAfterVisiblePos(0), + changedFirstItem(false), changeBeforeVisible(0) {} + + void reset() { + sizeChangesBeforeVisiblePos = 0.0; + sizeChangesAfterVisiblePos = 0.0; + changedFirstItem = false; + changeBeforeVisible = 0; + } }; enum BufferMode { NoBuffer = 0x00, BufferBefore = 0x01, BufferAfter = 0x02 }; @@ -130,7 +139,7 @@ public: void regenerate(); void layout(); void refill(); - void refill(qreal from, qreal to, bool doBuffer = false); + void refill(qreal from, qreal to); void mirrorChange(); FxViewItem *createItem(int modelIndex, bool asynchronous = false); @@ -149,7 +158,7 @@ public: bool applyModelChanges(); bool applyRemovalChange(const QDeclarativeChangeSet::Remove &removal, ChangeResult *changeResult, int *removedCount); void repositionFirstItem(FxViewItem *prevVisibleItemsFirst, qreal prevVisibleItemsFirstPos, - FxViewItem *prevFirstVisible, const ChangeResult &insertionResult, const ChangeResult &removalResult); + FxViewItem *prevFirstVisible, ChangeResult *insertionResult, ChangeResult *removalResult); void checkVisible() const; @@ -197,7 +206,6 @@ public: bool ownModel : 1; bool wrap : 1; - bool deferredRelease : 1; bool inApplyModelChanges : 1; bool inViewportMoved : 1; bool forceLayout : 1; @@ -240,7 +248,7 @@ protected: virtual FxViewItem *newViewItem(int index, QQuickItem *item) = 0; virtual void repositionPackageItemAt(QQuickItem *item, int index) = 0; virtual void resetFirstItemPosition(qreal pos = 0.0) = 0; - virtual void adjustFirstItem(qreal forwards, qreal backwards) = 0; + virtual void adjustFirstItem(qreal forwards, qreal backwards, int changeBeforeVisible) = 0; virtual void layoutVisibleItems(int fromModelIndex = 0) = 0; virtual void changedVisibleIndex(int newIndex) = 0; diff --git a/src/quick/items/qquicklistview.cpp b/src/quick/items/qquicklistview.cpp index f0ced5fc71..62155272c4 100644 --- a/src/quick/items/qquicklistview.cpp +++ b/src/quick/items/qquicklistview.cpp @@ -60,6 +60,8 @@ QT_BEGIN_NAMESPACE #define QML_FLICK_SNAPONETHRESHOLD 30 #endif +//#define DEBUG_DELEGATE_LIFECYCLE + class FxListItemSG; class QQuickListViewPrivate : public QQuickItemViewPrivate @@ -94,7 +96,7 @@ public: virtual void releaseItem(FxViewItem *item); virtual void repositionPackageItemAt(QQuickItem *item, int index); virtual void resetFirstItemPosition(qreal pos = 0.0); - virtual void adjustFirstItem(qreal forwards, qreal backwards); + virtual void adjustFirstItem(qreal forwards, qreal backwards, int); virtual void createHighlight(); virtual void updateHighlight(); @@ -601,7 +603,9 @@ bool QQuickListViewPrivate::addVisibleItems(qreal fillFrom, qreal fillTo, bool d FxListItemSG *item = 0; qreal pos = itemEnd; while (modelIndex < model->count() && pos <= fillTo) { -// qDebug() << "refill: append item" << modelIndex << "pos" << pos; +#ifdef DEBUG_DELEGATE_LIFECYCLE + qDebug() << "refill: append item" << modelIndex << "pos" << pos; +#endif if (!(item = static_cast<FxListItemSG*>(createItem(modelIndex, doBuffer)))) break; item->setPosition(pos); @@ -611,8 +615,14 @@ bool QQuickListViewPrivate::addVisibleItems(qreal fillFrom, qreal fillTo, bool d ++modelIndex; changed = true; } + + if (doBuffer && requestedIndex != -1) // already waiting for an item + return changed; + while (visibleIndex > 0 && visibleIndex <= model->count() && visiblePos > fillFrom) { -// qDebug() << "refill: prepend item" << visibleIndex-1 << "current top pos" << visiblePos; +#ifdef DEBUG_DELEGATE_LIFECYCLE + qDebug() << "refill: prepend item" << visibleIndex-1 << "current top pos" << visiblePos; +#endif if (!(item = static_cast<FxListItemSG*>(createItem(visibleIndex-1, doBuffer)))) break; --visibleIndex; @@ -641,8 +651,9 @@ bool QQuickListViewPrivate::removeNonVisibleItems(qreal bufferFrom, qreal buffer if (item->attached->delayRemove()) break; if (item->size() > 0) { -// qDebug() << "refill: remove first" << visibleIndex << "top end pos" << item->endPosition(); - +#ifdef DEBUG_DELEGATE_LIFECYCLE + qDebug() << "refill: remove first" << visibleIndex << "top end pos" << item->endPosition(); +#endif // remove this item and all zero-sized items before it while (item) { if (item->index != -1) @@ -662,7 +673,9 @@ bool QQuickListViewPrivate::removeNonVisibleItems(qreal bufferFrom, qreal buffer while (visibleItems.count() > 1 && (item = visibleItems.last()) && item->position() > bufferTo) { if (item->attached->delayRemove()) break; -// qDebug() << "refill: remove last" << visibleIndex+visibleItems.count()-1 << item->position(); +#ifdef DEBUG_DELEGATE_LIFECYCLE + qDebug() << "refill: remove last" << visibleIndex+visibleItems.count()-1 << item->position(); +#endif visibleItems.removeLast(); releaseItem(item); changed = true; @@ -741,7 +754,7 @@ void QQuickListViewPrivate::resetFirstItemPosition(qreal pos) item->setPosition(pos); } -void QQuickListViewPrivate::adjustFirstItem(qreal forwards, qreal backwards) +void QQuickListViewPrivate::adjustFirstItem(qreal forwards, qreal backwards, int) { if (!visibleItems.count()) return; @@ -1822,7 +1835,7 @@ void QQuickListView::setSpacing(qreal spacing) if (spacing != d->spacing) { d->spacing = spacing; d->forceLayout = true; - d->layout(); + polish(); emit spacingChanged(); } } @@ -2188,14 +2201,6 @@ void QQuickListView::viewportMoved() return; d->inViewportMoved = true; - // Set visibility of items to eliminate cost of items outside the visible area. - qreal from = d->isContentFlowReversed() ? -d->position()-d->size() : d->position(); - qreal to = d->isContentFlowReversed() ? -d->position() : d->position()+d->size(); - for (int i = 0; i < d->visibleItems.count(); ++i) { - FxViewItem *item = static_cast<FxListItemSG*>(d->visibleItems.at(i)); - item->item->setVisible(item->endPosition() >= from && item->position() <= to); - } - if (yflick()) d->bufferMode = d->vData.smoothVelocity < 0 ? QQuickListViewPrivate::BufferBefore : QQuickListViewPrivate::BufferAfter; else if (d->isRightToLeft()) @@ -2204,6 +2209,15 @@ void QQuickListView::viewportMoved() d->bufferMode = d->hData.smoothVelocity < 0 ? QQuickListViewPrivate::BufferBefore : QQuickListViewPrivate::BufferAfter; d->refill(); + + // Set visibility of items to eliminate cost of items outside the visible area. + qreal from = d->isContentFlowReversed() ? -d->position()-d->size() : d->position(); + qreal to = d->isContentFlowReversed() ? -d->position() : d->position()+d->size(); + for (int i = 0; i < d->visibleItems.count(); ++i) { + FxViewItem *item = static_cast<FxListItemSG*>(d->visibleItems.at(i)); + item->item->setVisible(item->endPosition() >= from && item->position() <= to); + } + if (d->hData.flicking || d->vData.flicking || d->hData.moving || d->vData.moving) d->moveReason = QQuickListViewPrivate::Mouse; if (d->moveReason != QQuickListViewPrivate::SetIndex) { @@ -2365,7 +2379,7 @@ void QQuickListView::updateSections() d->updateSections(); if (d->itemCount) { d->forceLayout = true; - d->layout(); + polish(); } } } diff --git a/src/quick/items/qquickvisualdatamodel.cpp b/src/quick/items/qquickvisualdatamodel.cpp index 3de1e91f7f..d52aec0433 100644 --- a/src/quick/items/qquickvisualdatamodel.cpp +++ b/src/quick/items/qquickvisualdatamodel.cpp @@ -425,6 +425,10 @@ QQuickVisualDataModel::ReleaseFlags QQuickVisualDataModelPrivate::release(QObjec if (QQuickItem *item = qobject_cast<QQuickItem *>(object)) emitDestroyingItem(item); cacheItem->object = 0; + if (cacheItem->incubationTask) { + releaseIncubator(cacheItem->incubationTask); + cacheItem->incubationTask = 0; + } stat |= QQuickVisualModel::Destroyed; } else { stat |= QQuickVisualDataModel::Referenced; diff --git a/tests/auto/qtquick2/qquickgridview/tst_qquickgridview.cpp b/tests/auto/qtquick2/qquickgridview/tst_qquickgridview.cpp index 132fa5fad3..15abe325fa 100644 --- a/tests/auto/qtquick2/qquickgridview/tst_qquickgridview.cpp +++ b/tests/auto/qtquick2/qquickgridview/tst_qquickgridview.cpp @@ -467,7 +467,7 @@ void tst_QQuickGridView::inserted_more() // check visibleItems.first() is in correct position QQuickItem *item0 = findItem<QQuickItem>(contentItem, "wrapper", 0); QVERIFY(item0); - QCOMPARE(item0->y(), itemsOffsetAfterMove); + QCOMPARE(item0->y(), 0.0); QList<QQuickItem*> items = findItems<QQuickItem>(contentItem, "wrapper"); int firstVisibleIndex = -1; @@ -840,6 +840,7 @@ void tst_QQuickGridView::removed_more() QFETCH(int, removeIndex); QFETCH(int, removeCount); QFETCH(qreal, itemsOffsetAfterMove); + QFETCH(QString, firstVisible); QQuickText *name; QQuickText *number; @@ -868,22 +869,20 @@ void tst_QQuickGridView::removed_more() model.removeItems(removeIndex, removeCount); QTRY_COMPARE(gridview->property("count").toInt(), model.count()); - // check visibleItems.first() is in correct position - QQuickItem *item0 = findItem<QQuickItem>(contentItem, "wrapper", 0); -// qApp->exec(); - QVERIFY(item0); - QCOMPARE(item0->y(), itemsOffsetAfterMove); - + QString firstName; int firstVisibleIndex = -1; QList<QQuickItem*> items = findItems<QQuickItem>(contentItem, "wrapper"); for (int i=0; i<items.count(); i++) { if (items[i]->y() >= contentY) { QDeclarativeExpression e(qmlContext(items[i]), items[i], "index"); firstVisibleIndex = e.evaluate().toInt(); + QDeclarativeExpression en(qmlContext(items[i]), items[i], "name"); + firstName = en.evaluate().toString(); break; } } QVERIFY2(firstVisibleIndex >= 0, QTest::toString(firstVisibleIndex)); + QCOMPARE(firstName, firstVisible); // Confirm items positioned correctly and indexes correct int itemCount = findItems<QQuickItem>(contentItem, "wrapper").count(); @@ -911,21 +910,27 @@ void tst_QQuickGridView::removed_more_data() QTest::addColumn<int>("removeIndex"); QTest::addColumn<int>("removeCount"); QTest::addColumn<qreal>("itemsOffsetAfterMove"); + QTest::addColumn<QString>("firstVisible"); QTest::newRow("remove 1, before visible items") << 120.0 // show 6-23 << 3 << 1 - << 0.0; + << 0.0 << "Item7"; QTest::newRow("remove multiple, all before visible items") << 120.0 << 1 << 3 - << 60.0; // removed top row, slide down by 1 row + << 60.0 << "Item6"; // removed top row, slide down by 1 row QTest::newRow("remove multiple, all before visible items, remove item 0") << 120.0 << 0 << 4 - << 60.0; // removed top row, slide down by 1 row + << 60.0 << "Item7"; // removed top row, slide down by 1 row + + QTest::newRow("remove multiple rows, all before visible items") + << 240.0 // show 12-29 + << 1 << 7 + << 120.0 << "Item13"; // remove 3,4,5 before the visible pos, first row moves down to just before the visible pos, @@ -933,80 +938,80 @@ void tst_QQuickGridView::removed_more_data() QTest::newRow("remove multiple, mix of items from before and within visible items") << 120.0 << 3 << 5 - << 60.0; // adjust for the 1 row removed before the visible + << 60.0 << "Item8"; // adjust for the 1 row removed before the visible QTest::newRow("remove multiple, mix of items from before and within visible items, remove item 0") << 120.0 << 0 << 8 - << 60.0 * 2; // adjust for the 2 rows removed before the visible + << 60.0 * 2 << "Item8"; // adjust for the 2 rows removed before the visible QTest::newRow("remove 1, from start of visible, content at start") << 0.0 << 0 << 1 - << 0.0; + << 0.0 << "Item1"; QTest::newRow("remove multiple, from start of visible, content at start") << 0.0 << 0 << 3 - << 0.0; + << 0.0 << "Item3"; QTest::newRow("remove 1, from start of visible, content not at start") << 120.0 // show 6-23 << 4 << 1 - << 0.0; + << 0.0 << "Item7"; QTest::newRow("remove multiple, from start of visible, content not at start") << 120.0 // show 6-23 << 4 << 3 - << 0.0; + << 0.0 << "Item9"; QTest::newRow("remove 1, from middle of visible, content at start") << 0.0 << 10 << 1 - << 0.0; + << 0.0 << "Item0"; QTest::newRow("remove multiple, from middle of visible, content at start") << 0.0 << 10 << 5 - << 0.0; + << 0.0 << "Item0"; QTest::newRow("remove 1, from middle of visible, content not at start") << 120.0 // show 6-23 << 10 << 1 - << 0.0; + << 0.0 << "Item6"; QTest::newRow("remove multiple, from middle of visible, content not at start") << 120.0 // show 6-23 << 10 << 5 - << 0.0; + << 0.0 << "Item6"; QTest::newRow("remove 1, after visible, content at start") << 0.0 << 16 << 1 - << 0.0; + << 0.0 << "Item0"; QTest::newRow("remove multiple, after visible, content at start") << 0.0 << 16 << 5 - << 0.0; + << 0.0 << "Item0"; QTest::newRow("remove 1, after visible, content not at start") << 120.0 // show 6-23 << 16+4 << 1 - << 0.0; + << 0.0 << "Item6"; QTest::newRow("remove multiple, after visible, content not at start") << 120.0 // show 6-23 << 16+4 << 5 - << 0.0; + << 0.0 << "Item6"; QTest::newRow("remove multiple, mix of items from within and after visible items") << 120.0 // show 6-23 << 20 << 5 - << 0.0; + << 0.0 << "Item6"; } void tst_QQuickGridView::addOrRemoveBeforeVisible() @@ -1092,7 +1097,7 @@ void tst_QQuickGridView::addOrRemoveBeforeVisible_data() QTest::addColumn<qreal>("newTopContentY"); QTest::newRow("add") << true << -60.0; - QTest::newRow("remove") << false << 0.0; + QTest::newRow("remove") << false << -60.0; } void tst_QQuickGridView::clear() @@ -1135,11 +1140,6 @@ void tst_QQuickGridView::clear() void tst_QQuickGridView::moved() { - if (QTest::currentDataTag() == QLatin1String("move 1 forwards, from non-visible -> visible") - || QTest::currentDataTag() == QLatin1String("move 1 forwards, from non-visible -> visible (move first item)")) { - QSKIP("QTBUG-23455"); - } - QFETCH(qreal, contentY); QFETCH(int, from); QFETCH(int, to); @@ -1223,13 +1223,11 @@ void tst_QQuickGridView::moved_data() << 1 << 8 << 1 << 0.0; - // skipped QTBUG-23455 QTest::newRow("move 1 forwards, from non-visible -> visible") << 120.0 // show 6-23 << 1 << 23 << 1 << 0.0; - // skipped QTBUG-23455 QTest::newRow("move 1 forwards, from non-visible -> visible (move first item)") << 120.0 // // show 6-23 << 0 << 6 << 1 diff --git a/tests/auto/qtquick2/qquicklistview/tst_qquicklistview.cpp b/tests/auto/qtquick2/qquicklistview/tst_qquicklistview.cpp index 1953cf7e73..bb168e4212 100644 --- a/tests/auto/qtquick2/qquicklistview/tst_qquicklistview.cpp +++ b/tests/auto/qtquick2/qquicklistview/tst_qquicklistview.cpp @@ -1961,8 +1961,8 @@ void tst_QQuickListView::spacing() QTRY_VERIFY(listview->spacing() == 10); // Confirm items positioned correctly - itemCount = findItems<QQuickItem>(contentItem, "wrapper").count(); - for (int i = 0; i < model.count() && i < itemCount; ++i) { + QTRY_VERIFY(findItems<QQuickItem>(contentItem, "wrapper").count() == 11); + for (int i = 0; i < 11; ++i) { QQuickItem *item = findItem<QQuickItem>(contentItem, "wrapper", i); if (!item) qWarning() << "Item" << i << "not found"; QTRY_VERIFY(item); @@ -1972,8 +1972,8 @@ void tst_QQuickListView::spacing() listview->setSpacing(0); // Confirm items positioned correctly - itemCount = findItems<QQuickItem>(contentItem, "wrapper").count(); - for (int i = 0; i < model.count() && i < itemCount; ++i) { + QTRY_VERIFY(findItems<QQuickItem>(contentItem, "wrapper").count() >= 16); + for (int i = 0; i < 16; ++i) { QQuickItem *item = findItem<QQuickItem>(contentItem, "wrapper", i); if (!item) qWarning() << "Item" << i << "not found"; QTRY_VERIFY(item); @@ -2264,7 +2264,7 @@ void tst_QQuickListView::sectionsPositioning() model.modifyItem(2, "Three", "aaa"); model.modifyItem(3, "Four", "aaa"); model.modifyItem(4, "Five", "aaa"); - QTest::qWait(300); + QTRY_COMPARE(QQuickItemPrivate::get(listview)->polishScheduled, false); QTRY_COMPARE(listview->currentSection(), QString("aaa")); @@ -2275,8 +2275,7 @@ void tst_QQuickListView::sectionsPositioning() QTRY_COMPARE(item->y(), qreal(i*20*6)); } - topItem = findVisibleChild(contentItem, "sect_aaa"); // section header - QVERIFY(topItem); + QTRY_VERIFY(topItem = findVisibleChild(contentItem, "sect_aaa")); // section header QCOMPARE(topItem->y(), 10.); // remove section boundary |