diff options
author | Qt Forward Merge Bot <qt_forward_merge_bot@qt-project.org> | 2019-12-12 01:00:07 +0100 |
---|---|---|
committer | Ulf Hermann <ulf.hermann@qt.io> | 2019-12-12 10:06:06 +0100 |
commit | 1196b1ef6c5d2cb05ceba5d6f178dc7e2432ed61 (patch) | |
tree | 2a99ee28d15d8ee51fc28096e5559bfc2d453e3f /src/quick/items/qquicklistview.cpp | |
parent | fb54af6638dcbeae8ad21249fe234ef4d82c005b (diff) | |
parent | ca206bceaff3667469986402e6143bf4c666b228 (diff) |
Merge remote-tracking branch 'origin/5.15' into dev
Conflicts:
src/qml/types/qqmlbind.cpp
Change-Id: Ib992d1a7ac6c1a96d39819be6f23955dc31b44b2
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" |