diff options
Diffstat (limited to 'src/quick/items/qquickitemview.cpp')
-rw-r--r-- | src/quick/items/qquickitemview.cpp | 76 |
1 files changed, 60 insertions, 16 deletions
diff --git a/src/quick/items/qquickitemview.cpp b/src/quick/items/qquickitemview.cpp index 66be3c79f8..05cdc1749d 100644 --- a/src/quick/items/qquickitemview.cpp +++ b/src/quick/items/qquickitemview.cpp @@ -197,6 +197,8 @@ void QQuickItemView::setModel(const QVariant &m) disconnect(d->model, SIGNAL(initItem(int,QObject*)), this, SLOT(initItem(int,QObject*))); disconnect(d->model, SIGNAL(createdItem(int,QObject*)), this, SLOT(createdItem(int,QObject*))); disconnect(d->model, SIGNAL(destroyingItem(QObject*)), this, SLOT(destroyingItem(QObject*))); + disconnect(d->model, SIGNAL(itemPooled(int, QObject *)), this, SLOT(onItemPooled(int, QObject *))); + disconnect(d->model, SIGNAL(itemReused(int, QObject *)), this, SLOT(onItemReused(int, QObject *))); } QQmlInstanceModel *oldModel = d->model; @@ -232,6 +234,8 @@ void QQuickItemView::setModel(const QVariant &m) connect(d->model, SIGNAL(createdItem(int,QObject*)), this, SLOT(createdItem(int,QObject*))); connect(d->model, SIGNAL(initItem(int,QObject*)), this, SLOT(initItem(int,QObject*))); connect(d->model, SIGNAL(destroyingItem(QObject*)), this, SLOT(destroyingItem(QObject*))); + connect(d->model, SIGNAL(itemPooled(int, QObject *)), this, SLOT(onItemPooled(int, QObject *))); + connect(d->model, SIGNAL(itemReused(int, QObject *)), this, SLOT(onItemReused(int, QObject *))); if (isComponentComplete()) { d->updateSectionCriteria(); d->refill(); @@ -694,6 +698,28 @@ void QQuickItemView::setHighlightMoveDuration(int duration) } } +bool QQuickItemView::reuseItems() const +{ + return bool(d_func()->reusableFlag == QQmlDelegateModel::Reusable); +} + +void QQuickItemView::setReuseItems(bool reuse) +{ + Q_D(QQuickItemView); + if (reuseItems() == reuse) + return; + + d->reusableFlag = reuse ? QQmlDelegateModel::Reusable : QQmlDelegateModel::NotReusable; + + if (!reuse && d->model) { + // When we're told to not reuse items, we + // immediately, as documented, drain the pool. + d->model->drainReusableItemsPool(0); + } + + emit reuseItemsChanged(); +} + QQuickTransition *QQuickItemView::populateTransition() const { Q_D(const QQuickItemView); @@ -848,7 +874,7 @@ void QQuickItemViewPrivate::positionViewAtIndex(int index, int mode) setPosition(qMin(itemPos, maxExtent)); // now release the reference to all the old visible items. for (FxViewItem *item : oldVisible) - releaseItem(item); + releaseItem(item, reusableFlag); item = visibleItem(idx); } if (item) { @@ -1091,8 +1117,8 @@ qreal QQuickItemViewPrivate::calculatedMaxExtent() const void QQuickItemViewPrivate::applyDelegateChange() { - releaseVisibleItems(); - releaseItem(currentItem); + releaseVisibleItems(QQmlDelegateModel::NotReusable); + releaseItem(currentItem, QQmlDelegateModel::NotReusable); currentItem = nullptr; updateSectionCriteria(); refill(); @@ -1194,7 +1220,7 @@ void QQuickItemView::destroyRemoved() } else { if (hasRemoveTransition) d->runDelayedRemoveTransition = true; - d->releaseItem(item); + d->releaseItem(item, d->reusableFlag); it = d->visibleItems.erase(it); } } else { @@ -1638,7 +1664,7 @@ void QQuickItemViewPrivate::updateCurrent(int modelIndex) if (currentItem) { if (currentItem->attached) currentItem->attached->setIsCurrentItem(false); - releaseItem(currentItem); + releaseItem(currentItem, reusableFlag); currentItem = nullptr; currentIndex = modelIndex; emit q->currentIndexChanged(); @@ -1675,7 +1701,7 @@ void QQuickItemViewPrivate::updateCurrent(int modelIndex) if (oldCurrentItem != currentItem && (!oldCurrentItem || !currentItem || oldCurrentItem->item != currentItem->item)) emit q->currentItemChanged(); - releaseItem(oldCurrentItem); + releaseItem(oldCurrentItem, reusableFlag); } void QQuickItemViewPrivate::clear(bool onDestruction) @@ -1685,17 +1711,17 @@ void QQuickItemViewPrivate::clear(bool onDestruction) bufferedChanges.reset(); timeline.clear(); - releaseVisibleItems(); + releaseVisibleItems(QQmlInstanceModel::NotReusable); visibleIndex = 0; for (FxViewItem *item : qAsConst(releasePendingTransition)) { item->releaseAfterTransition = false; - releaseItem(item); + releaseItem(item, QQmlInstanceModel::NotReusable); } releasePendingTransition.clear(); auto oldCurrentItem = currentItem; - releaseItem(currentItem); + releaseItem(currentItem, QQmlDelegateModel::NotReusable); currentItem = nullptr; if (oldCurrentItem) emit q->currentItemChanged(); @@ -1754,7 +1780,7 @@ void QQuickItemViewPrivate::refill(qreal from, qreal to) if (currentChanges.hasPendingChanges() || bufferedChanges.hasPendingChanges()) { currentChanges.reset(); bufferedChanges.reset(); - releaseVisibleItems(); + releaseVisibleItems(reusableFlag); } int prevCount = itemCount; @@ -1918,7 +1944,7 @@ void QQuickItemViewPrivate::layout() continue; } if (!success) { - releaseItem(*it); + releaseItem(*it, reusableFlag); it = releasePendingTransition.erase(it); continue; } @@ -2065,7 +2091,7 @@ bool QQuickItemViewPrivate::applyModelChanges(ChangeResult *totalInsertionResult prepareRemoveTransitions(¤tChanges.removedItems); for (QHash<QQmlChangeSet::MoveKey, FxViewItem *>::Iterator it = currentChanges.removedItems.begin(); it != currentChanges.removedItems.end(); ++it) { - releaseItem(it.value()); + releaseItem(it.value(), reusableFlag); } currentChanges.removedItems.clear(); @@ -2074,7 +2100,7 @@ bool QQuickItemViewPrivate::applyModelChanges(ChangeResult *totalInsertionResult if (currentItem->item && currentItem->attached) currentItem->attached->setIsCurrentItem(false); auto oldCurrentItem = currentItem; - releaseItem(currentItem); + releaseItem(currentItem, reusableFlag); currentItem = nullptr; if (oldCurrentItem) emit q->currentItemChanged(); @@ -2281,7 +2307,7 @@ void QQuickItemViewPrivate::viewItemTransitionFinished(QQuickItemViewTransitiona { for (int i=0; i<releasePendingTransition.count(); i++) { if (releasePendingTransition.at(i)->transitionableItem == item) { - releaseItem(releasePendingTransition.takeAt(i)); + releaseItem(releasePendingTransition.takeAt(i), reusableFlag); return; } } @@ -2387,7 +2413,23 @@ void QQuickItemView::destroyingItem(QObject *object) } } -bool QQuickItemViewPrivate::releaseItem(FxViewItem *item) +void QQuickItemView::onItemPooled(int modelIndex, QObject *object) +{ + Q_UNUSED(modelIndex); + + if (auto *attached = d_func()->getAttachedObject(object)) + emit attached->pooled(); +} + +void QQuickItemView::onItemReused(int modelIndex, QObject *object) +{ + Q_UNUSED(modelIndex); + + if (auto *attached = d_func()->getAttachedObject(object)) + emit attached->reused(); +} + +bool QQuickItemViewPrivate::releaseItem(FxViewItem *item, QQmlInstanceModel::ReusableFlag reusableFlag) { Q_Q(QQuickItemView); if (!item) @@ -2398,7 +2440,7 @@ bool QQuickItemViewPrivate::releaseItem(FxViewItem *item) QQmlInstanceModel::ReleaseFlags flags = {}; if (model && item->item) { - flags = model->release(item->item); + flags = model->release(item->item, reusableFlag); if (!flags) { // item was not destroyed, and we no longer reference it. if (item->item->parentItem() == contentItem) { @@ -2409,6 +2451,8 @@ bool QQuickItemViewPrivate::releaseItem(FxViewItem *item) unrequestedItems.insert(item->item, model->indexOf(item->item, q)); } else if (flags & QQmlInstanceModel::Destroyed) { item->item->setParentItem(nullptr); + } else if (flags & QQmlInstanceModel::Pooled) { + item->setVisible(false); } } delete item; |