Section headers ignore list delegate size changes when "colliding"
authorMartin Jones <martin.jones@nokia.com>
Fri, 29 Jun 2012 01:57:02 +0000 (11:57 +1000)
committerQt by Nokia <qt-info@nokia.com>
Wed, 4 Jul 2012 01:02:49 +0000 (03:02 +0200)
Make section header updates part of the layout process.

Task-number: QTBUG-23298
Change-Id: I4586bc58bc195fcc47f6db79346727eb6e3d3845
Reviewed-by: Bea Lam <bea.lam@nokia.com>
src/quick/items/qquickgridview.cpp
src/quick/items/qquickitemview.cpp
src/quick/items/qquickitemview_p.h
src/quick/items/qquickitemview_p_p.h
src/quick/items/qquicklistview.cpp
src/quick/items/qquicklistview_p.h
tests/auto/quick/qquicklistview/tst_qquicklistview.cpp

index fd5b50c..666ee8e 100644 (file)
@@ -1614,8 +1614,7 @@ void QQuickGridView::setCellWidth(qreal cellWidth)
         d->cellWidth = qMax(qreal(1), cellWidth);
         d->updateViewport();
         emit cellWidthChanged();
-        d->forceLayout = true;
-        polish();
+        d->forceLayoutPolish();
     }
 }
 
@@ -1632,8 +1631,7 @@ void QQuickGridView::setCellHeight(qreal cellHeight)
         d->cellHeight = qMax(qreal(1), cellHeight);
         d->updateViewport();
         emit cellHeightChanged();
-        d->forceLayout = true;
-        polish();
+        d->forceLayoutPolish();
     }
 }
 /*!
index cc2a352..34a8cf5 100644 (file)
@@ -307,7 +307,7 @@ void QQuickItemView::setModel(const QVariant &model)
         connect(d->model, SIGNAL(initItem(int,QQuickItem*)), this, SLOT(initItem(int,QQuickItem*)));
         connect(d->model, SIGNAL(destroyingItem(QQuickItem*)), this, SLOT(destroyingItem(QQuickItem*)));
         if (isComponentComplete()) {
-            updateSections();
+            d->updateSectionCriteria();
             d->refill();
             if ((d->currentIndex >= d->model->count() || d->currentIndex < 0) && !d->currentIndexCleared) {
                 setCurrentIndex(0);
@@ -324,9 +324,8 @@ void QQuickItemView::setModel(const QVariant &model)
             d->updateViewport();
 
             if (d->transitioner && d->transitioner->populateTransition) {
-                d->forceLayout = true;
                 d->transitioner->setPopulateTransitionEnabled(true);
-                polish();
+                d->forceLayoutPolish();
             }
         }
         connect(d->model, SIGNAL(modelUpdated(QQuickChangeSet,bool)),
@@ -365,7 +364,7 @@ void QQuickItemView::setDelegate(QQmlComponent *delegate)
             d->visibleItems.clear();
             d->releaseItem(d->currentItem);
             d->currentItem = 0;
-            updateSections();
+            d->updateSectionCriteria();
             d->refill();
             d->moveReason = QQuickItemViewPrivate::SetIndex;
             d->updateCurrent(d->currentIndex);
@@ -1135,9 +1134,7 @@ void QQuickItemView::destroyRemoved()
     }
 
     // Correct the positioning of the items
-    d->updateSections();
-    d->forceLayout = true;
-    polish();
+    d->forceLayoutPolish();
 }
 
 void QQuickItemView::modelUpdated(const QQuickChangeSet &changeSet, bool reset)
@@ -1155,10 +1152,8 @@ void QQuickItemView::modelUpdated(const QQuickChangeSet &changeSet, bool reset)
         }
         d->moveReason = QQuickItemViewPrivate::Other;
         emit countChanged();
-        if (d->transitioner && d->transitioner->populateTransition) {
-            d->forceLayout = true;
-            polish();
-        }
+        if (d->transitioner && d->transitioner->populateTransition)
+            d->forceLayoutPolish();
     } else {
         if (d->inLayout) {
             d->bufferedChanges.prepare(d->currentIndex, d->itemCount);
@@ -1268,10 +1263,8 @@ void QQuickItemView::geometryChanged(const QRectF &newGeometry, const QRectF &ol
 {
     Q_D(QQuickItemView);
     d->markExtentsDirty();
-    if (isComponentComplete() && d->isValid()) {
-        d->forceLayout = true;
-        polish();
-    }
+    if (isComponentComplete() && d->isValid())
+        d->forceLayoutPolish();
     QQuickFlickable::geometryChanged(newGeometry, oldGeometry);
 }
 
@@ -1384,7 +1377,7 @@ void QQuickItemView::componentComplete()
 
     QQuickFlickable::componentComplete();
 
-    updateSections();
+    d->updateSectionCriteria();
     d->updateHeader();
     d->updateFooter();
     d->updateViewport();
@@ -1779,6 +1772,8 @@ void QQuickItemViewPrivate::layout()
                 visibleItems.at(i)->transitionNextReposition(transitioner, QQuickItemViewTransitioner::PopulateTransition, true);
         }
     }
+
+    updateSections();
     layoutVisibleItems();
 
     int lastIndexInView = findLastIndexInView();
index 93a3f52..e1cb020 100644 (file)
@@ -258,7 +258,6 @@ protected:
     virtual qreal maxXExtent() const;
 
 protected slots:
-    virtual void updateSections() {}
     void destroyRemoved();
     void createdItem(int index, QQuickItem *item);
     virtual void initItem(int index, QQuickItem *item);
index b580181..7cf9425 100644 (file)
@@ -247,6 +247,12 @@ public:
             refill();
     }
 
+    void forceLayoutPolish() {
+        Q_Q(QQuickItemView);
+        forceLayout = true;
+        q->polish();
+    }
+
     QQmlGuard<QQuickVisualModel> model;
     QVariant modelVariant;
     int itemCount;
@@ -350,6 +356,7 @@ protected:
 
     virtual void initializeViewItem(FxViewItem *) {}
     virtual void initializeCurrentItem() {}
+    virtual void updateSectionCriteria() {}
     virtual void updateSections() {}
 
     virtual void itemGeometryChanged(QQuickItem *item, const QRectF &newGeometry, const QRectF &oldGeometry);
index f12da43..80b4cb5 100644 (file)
@@ -110,6 +110,7 @@ public:
     virtual bool applyInsertionChange(const QQuickChangeSet::Insert &insert, ChangeResult *changeResult, QList<FxViewItem *> *addedItems, QList<MovedItem> *movingIntoView);
     virtual void translateAndTransitionItemsAfter(int afterIndex, const ChangeResult &insertionResult, const ChangeResult &removalResult);
 
+    virtual void updateSectionCriteria();
     virtual void updateSections();
     QQuickItem *getSectionItem(const QString &section);
     void releaseSectionItem(QQuickItem *item);
@@ -194,7 +195,8 @@ void QQuickViewSection::setProperty(const QString &property)
     if (property != m_property) {
         m_property = property;
         emit propertyChanged();
-        m_view->updateSections();
+        // notify view that the contents of the sections must be recalculated
+        m_view->updateSectionCriteria();
     }
 }
 
@@ -203,7 +205,8 @@ void QQuickViewSection::setCriteria(QQuickViewSection::SectionCriteria criteria)
     if (criteria != m_criteria) {
         m_criteria = criteria;
         emit criteriaChanged();
-        m_view->updateSections();
+        // notify view that the contents of the sections must be recalculated
+        m_view->updateSectionCriteria();
     }
 }
 
@@ -214,7 +217,7 @@ void QQuickViewSection::setDelegate(QQmlComponent *delegate)
             m_view->releaseSectionItems();
         m_delegate = delegate;
         emit delegateChanged();
-        m_view->updateSections();
+        m_view->forceLayoutPolish();
     }
 }
 
@@ -231,7 +234,7 @@ void QQuickViewSection::setLabelPositioning(int l)
     if (m_labelPositioning != l) {
         m_labelPositioning = l;
         emit labelPositioningChanged();
-        m_view->updateSections();
+        m_view->forceLayoutPolish();
     }
 }
 
@@ -805,6 +808,9 @@ void QQuickListViewPrivate::layoutVisibleItems(int fromModelIndex)
         // move current item if it is not a visible item.
         if (currentIndex >= 0 && currentItem && !fixedCurrent)
             static_cast<FxListItemSG*>(currentItem)->setPosition(positionAt(currentIndex));
+
+        updateCurrentSection();
+        updateStickySections();
     }
 }
 
@@ -1163,10 +1169,6 @@ void QQuickListViewPrivate::updateSections()
     }
 
     lastVisibleSection = QString();
-    updateCurrentSection();
-    updateStickySections();
-    forceLayout = true;
-    q->polish();
 }
 
 void QQuickListViewPrivate::updateCurrentSection()
@@ -1378,8 +1380,7 @@ void QQuickListViewPrivate::itemGeometryChanged(QQuickItem *item, const QRectF &
                         listItem->setPosition(listItem->position() + diff, true);
                 }
             }
-            forceLayout = true;
-            q->polish();
+            forceLayoutPolish();
         }
     }
 }
@@ -1993,8 +1994,7 @@ void QQuickListView::setSpacing(qreal spacing)
     Q_D(QQuickListView);
     if (spacing != d->spacing) {
         d->spacing = spacing;
-        d->forceLayout = true;
-        polish();
+        d->forceLayoutPolish();
         emit spacingChanged();
     }
 }
@@ -2199,10 +2199,8 @@ void QQuickListView::setOrientation(QQuickListView::Orientation orientation)
 QQuickViewSection *QQuickListView::sectionCriteria()
 {
     Q_D(QQuickListView);
-    if (!d->sectionCriteria) {
+    if (!d->sectionCriteria)
         d->sectionCriteria = new QQuickViewSection(this);
-        connect(d->sectionCriteria, SIGNAL(propertyChanged()), this, SLOT(updateSections()));
-    }
     return d->sectionCriteria;
 }
 
@@ -2853,19 +2851,17 @@ void QQuickListView::decrementCurrentIndex()
     }
 }
 
-void QQuickListView::updateSections()
+void QQuickListViewPrivate::updateSectionCriteria()
 {
-    Q_D(QQuickListView);
-    if (isComponentComplete() && d->model) {
+    Q_Q(QQuickListView);
+    if (q->isComponentComplete() && model) {
         QList<QByteArray> roles;
-        if (d->sectionCriteria && !d->sectionCriteria->property().isEmpty())
-            roles << d->sectionCriteria->property().toUtf8();
-        d->model->setWatchedRoles(roles);
-        d->updateSections();
-        if (d->itemCount) {
-            d->forceLayout = true;
-            polish();
-        }
+        if (sectionCriteria && !sectionCriteria->property().isEmpty())
+            roles << sectionCriteria->property().toUtf8();
+        model->setWatchedRoles(roles);
+        updateSections();
+        if (itemCount)
+            forceLayoutPolish();
     }
 }
 
index a40a01a..827dac0 100644 (file)
@@ -81,6 +81,7 @@ public:
     void setLabelPositioning(int pos);
 
 Q_SIGNALS:
+    void sectionsChanged();
     void propertyChanged();
     void criteriaChanged();
     void delegateChanged();
@@ -169,9 +170,6 @@ protected:
     virtual void keyPressEvent(QKeyEvent *);
     virtual void geometryChanged(const QRectF &newGeometry,const QRectF &oldGeometry);
     virtual void initItem(int index, QQuickItem *item);
-
-protected Q_SLOTS:
-    void updateSections();
 };
 
 class QQuickListViewAttached : public QQuickItemViewAttached
index 7dba3a6..56bf270 100644 (file)
@@ -2332,17 +2332,31 @@ void tst_QQuickListView::sectionsPositioning()
     QTRY_VERIFY(bottomItem = findVisibleChild(contentItem, "sect_new")); // section footer
     QTRY_COMPARE(bottomItem->y(), 300.);
 
+    // delegate size increase should push section footer down
+    listview->setContentY(70);
+    QTRY_COMPARE(QQuickItemPrivate::get(listview)->polishScheduled, false);
+    QTRY_VERIFY(bottomItem = findVisibleChild(contentItem, "sect_3")); // section footer
+    QTRY_COMPARE(bottomItem->y(), 370.);
+    QQuickItem *inlineSection = findVisibleChild(contentItem, "sect_new");
+    item = findItem<QQuickItem>(contentItem, "wrapper", 13);
+    QVERIFY(item);
+    item->setHeight(40.);
+    QTRY_COMPARE(QQuickItemPrivate::get(listview)->polishScheduled, false);
+    QTRY_COMPARE(bottomItem->y(), 380.);
+    QCOMPARE(inlineSection->y(), 360.);
+    item->setHeight(20.);
+
     // Turn sticky footer off
     listview->setContentY(20);
-    QTRY_COMPARE(QQuickItemPrivate::get(listview)->polishScheduled, false);
     canvas->rootObject()->setProperty("sectionPositioning", QVariant(int(QQuickViewSection::InlineLabels | QQuickViewSection::CurrentLabelAtStart)));
+    QTRY_COMPARE(QQuickItemPrivate::get(listview)->polishScheduled, false);
     QTRY_VERIFY(item = findVisibleChild(contentItem, "sect_new")); // inline label restored
     QCOMPARE(item->y(), 340.);
 
     // Turn sticky header off
     listview->setContentY(30);
-    QTRY_COMPARE(QQuickItemPrivate::get(listview)->polishScheduled, false);
     canvas->rootObject()->setProperty("sectionPositioning", QVariant(int(QQuickViewSection::InlineLabels)));
+    QTRY_COMPARE(QQuickItemPrivate::get(listview)->polishScheduled, false);
     QTRY_VERIFY(item = findVisibleChild(contentItem, "sect_aaa")); // inline label restored
     QCOMPARE(item->y(), 0.);