Item views: do not track the geometry of items being removed
authorJ-P Nurmi <jpnurmi@gmail.com>
Sat, 22 Jun 2013 13:49:26 +0000 (15:49 +0200)
committerThe Qt Project <gerrit-noreply@qt-project.org>
Thu, 4 Jul 2013 06:26:59 +0000 (08:26 +0200)
Task-number: QTBUG-31873
Change-Id: I4230893ccb2925ed9c2429d26b411264bf7c1c65
Reviewed-by: Andrew den Exter <andrew.den.exter@qinetic.com.au>
src/quick/items/qquickgridview.cpp
src/quick/items/qquickitemview.cpp
src/quick/items/qquickitemview_p_p.h
src/quick/items/qquicklistview.cpp

index bc71a1c..37276d5 100644 (file)
@@ -65,19 +65,8 @@ QT_BEGIN_NAMESPACE
 class FxGridItemSG : public FxViewItem
 {
 public:
-    FxGridItemSG(QQuickItem *i, QQuickGridView *v, bool own, bool trackGeometry) : FxViewItem(i, own, trackGeometry), view(v) {
+    FxGridItemSG(QQuickItem *i, QQuickGridView *v, bool own) : FxViewItem(i, v, own), view(v) {
         attached = static_cast<QQuickGridViewAttached*>(qmlAttachedPropertiesObject<QQuickGridView>(item));
-        if (trackGeometry) {
-            QQuickItemPrivate *itemPrivate = QQuickItemPrivate::get(item);
-            itemPrivate->addItemChangeListener(QQuickItemViewPrivate::get(view), QQuickItemPrivate::Geometry);
-        }
-    }
-
-    ~FxGridItemSG() {
-        if (trackGeom) {
-            QQuickItemPrivate *itemPrivate = QQuickItemPrivate::get(item);
-            itemPrivate->removeItemChangeListener(QQuickItemViewPrivate::get(view), QQuickItemPrivate::Geometry);
-        }
     }
 
     qreal position() const {
@@ -470,7 +459,7 @@ FxViewItem *QQuickGridViewPrivate::newViewItem(int modelIndex, QQuickItem *item)
 {
     Q_Q(QQuickGridView);
     Q_UNUSED(modelIndex);
-    return new FxGridItemSG(item, q, false, false);
+    return new FxGridItemSG(item, q, false);
 }
 
 void QQuickGridViewPrivate::initializeViewItem(FxViewItem *item)
@@ -478,8 +467,7 @@ void QQuickGridViewPrivate::initializeViewItem(FxViewItem *item)
     QQuickItemViewPrivate::initializeViewItem(item);
 
     // need to track current items that are animating
-    QQuickItemPrivate *itemPrivate = QQuickItemPrivate::get(item->item);
-    itemPrivate->addItemChangeListener(this, QQuickItemPrivate::Geometry);
+    item->trackGeometry(true);
 }
 
 bool QQuickGridViewPrivate::addVisibleItems(qreal fillFrom, qreal fillTo, qreal bufferFrom, qreal bufferTo, bool doBuffer)
@@ -739,7 +727,8 @@ void QQuickGridViewPrivate::createHighlight()
     if (currentItem) {
         QQuickItem *item = createHighlightItem();
         if (item) {
-            FxGridItemSG *newHighlight = new FxGridItemSG(item, q, true, true);
+            FxGridItemSG *newHighlight = new FxGridItemSG(item, q, true);
+            newHighlight->trackGeometry(true);
             if (autoHighlight)
                 resetHighlightPosition();
             highlightXAnimator = new QSmoothedAnimation;
@@ -817,7 +806,8 @@ void QQuickGridViewPrivate::updateFooter()
         QQuickItem *item = createComponentItem(footerComponent, 1.0);
         if (!item)
             return;
-        footer = new FxGridItemSG(item, q, true, true);
+        footer = new FxGridItemSG(item, q, true);
+        footer->trackGeometry(true);
         created = true;
     }
 
@@ -861,7 +851,8 @@ void QQuickGridViewPrivate::updateHeader()
         QQuickItem *item = createComponentItem(headerComponent, 1.0);
         if (!item)
             return;
-        header = new FxGridItemSG(item, q, true, true);
+        header = new FxGridItemSG(item, q, true);
+        header->trackGeometry(true);
         created = true;
     }
 
index a6dabee..f8f622a 100644 (file)
@@ -51,13 +51,14 @@ QT_BEGIN_NAMESPACE
 #define QML_VIEW_DEFAULTCACHEBUFFER 320
 #endif
 
-FxViewItem::FxViewItem(QQuickItem *i, bool own, bool trackGeometry)
+FxViewItem::FxViewItem(QQuickItem *i, QQuickItemView *v, bool own)
     : item(i)
+    , view(v)
     , transitionableItem(0)
     , attached(0)
     , ownItem(own)
     , releaseAfterTransition(false)
-    , trackGeom(trackGeometry)
+    , trackGeom(false)
 {
 }
 
@@ -96,6 +97,23 @@ void FxViewItem::setVisible(bool visible)
     QQuickItemPrivate::get(item)->setCulled(!visible);
 }
 
+void FxViewItem::trackGeometry(bool track)
+{
+    if (track) {
+        if (!trackGeom) {
+            QQuickItemPrivate *itemPrivate = QQuickItemPrivate::get(item);
+            itemPrivate->addItemChangeListener(QQuickItemViewPrivate::get(view), QQuickItemPrivate::Geometry);
+            trackGeom = true;
+        }
+    } else {
+        if (trackGeom) {
+            QQuickItemPrivate *itemPrivate = QQuickItemPrivate::get(item);
+            itemPrivate->removeItemChangeListener(QQuickItemViewPrivate::get(view), QQuickItemPrivate::Geometry);
+            trackGeom = false;
+        }
+    }
+}
+
 QQuickItemViewTransitioner::TransitionType FxViewItem::scheduledTransitionType() const
 {
     return transitionableItem ? transitionableItem->nextTransitionType : QQuickItemViewTransitioner::NoTransition;
@@ -2131,6 +2149,7 @@ void QQuickItemViewPrivate::prepareRemoveTransitions(QHash<QQmlChangeSet::MoveKe
             bool isRemove = it.key().moveId < 0;
             if (isRemove) {
                 FxViewItem *item = *it;
+                item->trackGeometry(false);
                 item->releaseAfterTransition = true;
                 releasePendingTransition.append(item);
                 item->transitionNextReposition(transitioner, QQuickItemViewTransitioner::RemoveTransition, true);
@@ -2272,8 +2291,8 @@ bool QQuickItemViewPrivate::releaseItem(FxViewItem *item)
         return true;
     if (trackedItem == item)
         trackedItem = 0;
-    QQuickItemPrivate *itemPrivate = QQuickItemPrivate::get(item->item);
-    itemPrivate->removeItemChangeListener(this, QQuickItemPrivate::Geometry);
+    item->trackGeometry(false);
+
     QQmlInstanceModel::ReleaseFlags flags = model->release(item->item);
     if (flags == 0) {
         // item was not destroyed, and we no longer reference it.
index 1fa933e..32e94e0 100644 (file)
@@ -56,7 +56,7 @@ QT_BEGIN_NAMESPACE
 class FxViewItem
 {
 public:
-    FxViewItem(QQuickItem *, bool own, bool trackGeometry);
+    FxViewItem(QQuickItem *, QQuickItemView *, bool own);
     virtual ~FxViewItem();
 
     qreal itemX() const;
@@ -64,6 +64,7 @@ public:
 
     void moveTo(const QPointF &pos, bool immediate);
     void setVisible(bool visible);
+    void trackGeometry(bool track);
 
     QQuickItemViewTransitioner::TransitionType scheduledTransitionType() const;
     bool transitionScheduledOrRunning() const;
@@ -83,6 +84,7 @@ public:
     virtual bool contains(qreal x, qreal y) const = 0;
 
     QQuickItem *item;
+    QQuickItemView *view;
     QQuickItemViewTransitionableItem *transitionableItem;
     QQuickItemViewAttached *attached;
     int index;
index 4d42c9e..dfdd27e 100644 (file)
@@ -244,19 +244,8 @@ void QQuickViewSection::setLabelPositioning(int l)
 class FxListItemSG : public FxViewItem
 {
 public:
-    FxListItemSG(QQuickItem *i, QQuickListView *v, bool own, bool trackGeometry) : FxViewItem(i, own, trackGeometry), view(v) {
+    FxListItemSG(QQuickItem *i, QQuickListView *v, bool own) : FxViewItem(i, v, own), view(v) {
         attached = static_cast<QQuickListViewAttached*>(qmlAttachedPropertiesObject<QQuickListView>(item));
-        if (trackGeometry) {
-            QQuickItemPrivate *itemPrivate = QQuickItemPrivate::get(item);
-            itemPrivate->addItemChangeListener(QQuickItemViewPrivate::get(view), QQuickItemPrivate::Geometry);
-        }
-    }
-
-    ~FxListItemSG() {
-        if (trackGeom) {
-            QQuickItemPrivate *itemPrivate = QQuickItemPrivate::get(item);
-            itemPrivate->removeItemChangeListener(QQuickItemViewPrivate::get(view), QQuickItemPrivate::Geometry);
-        }
     }
 
     inline QQuickItem *section() const {
@@ -570,7 +559,7 @@ FxViewItem *QQuickListViewPrivate::newViewItem(int modelIndex, QQuickItem *item)
 {
     Q_Q(QQuickListView);
 
-    FxListItemSG *listItem = new FxListItemSG(item, q, false, false);
+    FxListItemSG *listItem = new FxListItemSG(item, q, false);
     listItem->index = modelIndex;
 
     // initialise attached properties
@@ -598,8 +587,8 @@ void QQuickListViewPrivate::initializeViewItem(FxViewItem *item)
 {
     QQuickItemViewPrivate::initializeViewItem(item);
 
-    QQuickItemPrivate *itemPrivate = QQuickItemPrivate::get(item->item);
-    itemPrivate->addItemChangeListener(this, QQuickItemPrivate::Geometry);
+    // need to track current items that are animating
+    item->trackGeometry(true);
 
     if (sectionCriteria && sectionCriteria->delegate()) {
         if (QString::compare(item->attached->m_prevSection, item->attached->m_section, Qt::CaseInsensitive))
@@ -876,7 +865,8 @@ void QQuickListViewPrivate::createHighlight()
     if (currentItem) {
         QQuickItem *item = createHighlightItem();
         if (item) {
-            FxListItemSG *newHighlight = new FxListItemSG(item, q, true, true);
+            FxListItemSG *newHighlight = new FxListItemSG(item, q, true);
+            newHighlight->trackGeometry(true);
 
             if (autoHighlight) {
                 newHighlight->setSize(static_cast<FxListItemSG*>(currentItem)->itemSize());
@@ -1299,7 +1289,8 @@ void QQuickListViewPrivate::updateFooter()
         QQuickItem *item = createComponentItem(footerComponent, 1.0);
         if (!item)
             return;
-        footer = new FxListItemSG(item, q, true, true);
+        footer = new FxListItemSG(item, q, true);
+        footer->trackGeometry(true);
         created = true;
     }
 
@@ -1329,7 +1320,8 @@ void QQuickListViewPrivate::updateHeader()
         QQuickItem *item = createComponentItem(headerComponent, 1.0);
         if (!item)
             return;
-        header = new FxListItemSG(item, q, true, true);
+        header = new FxListItemSG(item, q, true);
+        header->trackGeometry(true);
         created = true;
     }