diff options
Diffstat (limited to 'src/quick/items/qquicklistview.cpp')
-rw-r--r-- | src/quick/items/qquicklistview.cpp | 94 |
1 files changed, 87 insertions, 7 deletions
diff --git a/src/quick/items/qquicklistview.cpp b/src/quick/items/qquicklistview.cpp index 23925871e5..1615c9ecea 100644 --- a/src/quick/items/qquicklistview.cpp +++ b/src/quick/items/qquicklistview.cpp @@ -92,7 +92,7 @@ public: FxViewItem *newViewItem(int index, QQuickItem *item) override; void initializeViewItem(FxViewItem *item) override; - bool releaseItem(FxViewItem *item) override; + bool releaseItem(FxViewItem *item, QQmlInstanceModel::ReusableFlag reusableFlag) override; void repositionItemAt(FxViewItem *item, int index, qreal sizeBuffer) override; void repositionPackageItemAt(QQuickItem *item, int index) override; void resetFirstItemPosition(qreal pos = 0.0) override; @@ -139,6 +139,8 @@ public: bool flick(QQuickItemViewPrivate::AxisData &data, qreal minExtent, qreal maxExtent, qreal vSize, QQuickTimeLineCallback::Callback fixupCallback, qreal velocity) override; + QQuickItemViewAttached *getAttachedObject(const QObject *object) const override; + QQuickListView::Orientation orient; qreal visiblePos; qreal averageSize; @@ -634,15 +636,15 @@ void QQuickListViewPrivate::initializeViewItem(FxViewItem *item) } } -bool QQuickListViewPrivate::releaseItem(FxViewItem *item) +bool QQuickListViewPrivate::releaseItem(FxViewItem *item, QQmlInstanceModel::ReusableFlag reusableFlag) { if (!item || !model) - return QQuickItemViewPrivate::releaseItem(item); + return QQuickItemViewPrivate::releaseItem(item, reusableFlag); QPointer<QQuickItem> it = item->item; QQuickListViewAttached *att = static_cast<QQuickListViewAttached*>(item->attached); - bool released = QQuickItemViewPrivate::releaseItem(item); + bool released = QQuickItemViewPrivate::releaseItem(item, reusableFlag); if (released && it && att && att->m_sectionItem) { // We hold no more references to this item int i = 0; @@ -682,7 +684,7 @@ bool QQuickListViewPrivate::addVisibleItems(qreal fillFrom, qreal fillTo, qreal int newModelIdx = qBound(0, modelIndex + count, model->count()); count = newModelIdx - modelIndex; if (count) { - releaseVisibleItems(); + releaseVisibleItems(reusableFlag); modelIndex = newModelIdx; visibleIndex = modelIndex; visiblePos = itemEnd + count * (averageSize + spacing); @@ -737,7 +739,7 @@ void QQuickListViewPrivate::removeItem(FxViewItem *item) releasePendingTransition.append(item); } else { qCDebug(lcItemViewDelegateLifecycle) << "\treleasing stationary item" << item->index << (QObject *)(item->item); - releaseItem(item); + releaseItem(item, reusableFlag); } } @@ -808,6 +810,7 @@ void QQuickListViewPrivate::layoutVisibleItems(int fromModelIndex) FxViewItem *firstItem = *visibleItems.constBegin(); bool fixedCurrent = currentItem && firstItem->item == currentItem->item; + firstVisibleItemPosition = firstItem->position(); qreal sum = firstItem->size(); qreal pos = firstItem->position() + firstItem->size() + spacing; firstItem->setVisible(firstItem->endPosition() >= from && firstItem->position() <= to); @@ -1771,6 +1774,12 @@ void QQuickListViewPrivate::setSectionHelper(QQmlContext *context, QQuickItem *s sectionItem->setProperty("section", section); } +QQuickItemViewAttached *QQuickListViewPrivate::getAttachedObject(const QObject *object) const +{ + QObject *attachedObject = qmlAttachedPropertiesObject<QQuickListView>(object); + return static_cast<QQuickItemViewAttached *>(attachedObject); +} + //---------------------------------------------------------------------------- /*! @@ -1919,6 +1928,39 @@ void QQuickListViewPrivate::setSectionHelper(QQmlContext *context, QQuickItem *s of type \l [QML] {real}, so it is possible to set fractional values like \c 0.1. + \section1 Reusing items + + Since 5.15, ListView can be configured to recycle items instead of instantiating + from the \l delegate whenever new rows are flicked into view. This approach improves + performance, depending on the complexity of the delegate. Reusing + items is off by default (for backwards compatibility reasons), but can be switched + on by setting the \l reuseItems property to \c true. + + When an item is flicked out, it moves to the \e{reuse pool}, which is an + internal cache of unused items. When this happens, the \l ListView::pooled + signal is emitted to inform the item about it. Likewise, when the item is + moved back from the pool, the \l ListView::reused signal is emitted. + + Any item properties that come from the model are updated when the + item is reused. This includes \c index and \c row, but also + any model roles. + + \note Avoid storing any state inside a delegate. If you do, reset it + manually on receiving the \l ListView::reused signal. + + If an item has timers or animations, consider pausing them on receiving + the \l ListView::pooled signal. That way you avoid using the CPU resources + for items that are not visible. Likewise, if an item has resources that + cannot be reused, they could be freed up. + + \note While an item is in the pool, it might still be alive and respond + to connected signals and bindings. + + The following example shows a delegate that animates a spinning rectangle. When + it is pooled, the animation is temporarily paused: + + \snippet qml/listview/reusabledelegate.qml 0 + \sa {QML Data Models}, GridView, PathView, {Qt Quick Examples - Views} */ QQuickListView::QQuickListView(QQuickItem *parent) @@ -2085,6 +2127,20 @@ QQuickListView::~QQuickListView() */ /*! + \qmlproperty bool QtQuick::ListView::reuseItems + + This property enables you to reuse items that are instantiated + from the \l delegate. If set to \c false, any currently + pooled items are destroyed. + + This property is \c false by default. + + \since 5.15 + + \sa {Reusing items}, ListView::pooled, ListView::reused +*/ + +/*! \qmlproperty Component QtQuick::ListView::highlight This property holds the component to use as the highlight. @@ -2095,7 +2151,7 @@ QQuickListView::~QQuickListView() highlight item is \c 0. \sa highlightItem, highlightFollowsCurrentItem, - {Qt Quick Examples - Views#Highlight}{ListView highlight example}, + {Qt Quick Examples - Views#Using Highlight}{ListView Highlight Example}, {Stacking Order in ListView} */ @@ -3185,6 +3241,13 @@ void QQuickListView::keyPressEvent(QKeyEvent *event) void QQuickListView::geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry) { Q_D(QQuickListView); + + if (d->model) { + // When the view changes size, we force the pool to + // shrink by releasing all pooled items. + d->model->drainReusableItemsPool(0); + } + if (d->isRightToLeft()) { // maintain position relative to the right edge qreal dx = newGeometry.width() - oldGeometry.width(); @@ -3592,6 +3655,23 @@ QQuickListViewAttached *QQuickListView::qmlAttachedProperties(QObject *obj) return new QQuickListViewAttached(obj); } +bool QQuickListView::contains(const QPointF &point) const +{ + bool ret = QQuickItemView::contains(point); + // QTBUG-74046: if a mouse press "falls through" a floating header or footer, don't allow dragging the list from there + if (ret) { + if (auto header = headerItem()) { + if (headerPositioning() != QQuickListView::InlineHeader && header->contains(mapToItem(header, point))) + ret = false; + } + if (auto footer = footerItem()) { + if (footerPositioning() != QQuickListView::InlineFooter && footer->contains(mapToItem(footer, point))) + ret = false; + } + } + return ret; +} + QT_END_NAMESPACE #include "moc_qquicklistview_p.cpp" |