Section headers ignore list delegate size changes when "colliding"
[profile/ivi/qtdeclarative.git] / src / quick / items / qquicklistview.cpp
index 062cd58..80b4cb5 100644 (file)
@@ -110,9 +110,11 @@ 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);
+    void releaseSectionItems();
     void updateInlineSection(FxListItemSG *);
     void updateCurrentSection();
     void updateStickySections();
@@ -143,8 +145,8 @@ public:
 
     QSmoothedAnimation *highlightPosAnimator;
     QSmoothedAnimation *highlightSizeAnimator;
-    qreal highlightMoveSpeed;
-    qreal highlightResizeSpeed;
+    qreal highlightMoveVelocity;
+    qreal highlightResizeVelocity;
     int highlightResizeDuration;
 
     QQuickViewSection *sectionCriteria;
@@ -168,7 +170,7 @@ public:
         , averageSize(100.0), spacing(0.0)
         , snapMode(QQuickListView::NoSnap)
         , highlightPosAnimator(0), highlightSizeAnimator(0)
-        , highlightMoveSpeed(400), highlightResizeSpeed(400), highlightResizeDuration(-1)
+        , highlightMoveVelocity(400), highlightResizeVelocity(400), highlightResizeDuration(-1)
         , sectionCriteria(0), currentSectionItem(0), nextSectionItem(0)
         , overshootDist(0.0), correctFlick(false), inFlickCorrection(false)
     {}
@@ -193,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();
     }
 }
 
@@ -202,16 +205,19 @@ 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();
     }
 }
 
 void QQuickViewSection::setDelegate(QQmlComponent *delegate)
 {
     if (delegate != m_delegate) {
+        if (m_delegate)
+            m_view->releaseSectionItems();
         m_delegate = delegate;
         emit delegateChanged();
-        m_view->updateSections();
+        m_view->forceLayoutPolish();
     }
 }
 
@@ -228,7 +234,7 @@ void QQuickViewSection::setLabelPositioning(int l)
     if (m_labelPositioning != l) {
         m_labelPositioning = l;
         emit labelPositioningChanged();
-        m_view->updateSections();
+        m_view->forceLayoutPolish();
     }
 }
 
@@ -802,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();
     }
 }
 
@@ -875,12 +884,12 @@ void QQuickListViewPrivate::createHighlight()
             const QLatin1String posProp(orient == QQuickListView::Vertical ? "y" : "x");
             highlightPosAnimator = new QSmoothedAnimation;
             highlightPosAnimator->target = QQmlProperty(item, posProp);
-            highlightPosAnimator->velocity = highlightMoveSpeed;
+            highlightPosAnimator->velocity = highlightMoveVelocity;
             highlightPosAnimator->userDuration = highlightMoveDuration;
 
             const QLatin1String sizeProp(orient == QQuickListView::Vertical ? "height" : "width");
             highlightSizeAnimator = new QSmoothedAnimation;
-            highlightSizeAnimator->velocity = highlightResizeSpeed;
+            highlightSizeAnimator->velocity = highlightResizeVelocity;
             highlightSizeAnimator->userDuration = highlightResizeDuration;
             highlightSizeAnimator->target = QQmlProperty(item, sizeProp);
 
@@ -980,6 +989,24 @@ void QQuickListViewPrivate::releaseSectionItem(QQuickItem *item)
     delete item;
 }
 
+
+void QQuickListViewPrivate::releaseSectionItems()
+{
+    for (int i = 0; i < visibleItems.count(); ++i) {
+        FxListItemSG *listItem = static_cast<FxListItemSG *>(visibleItems.at(i));
+        if (listItem->section()) {
+            qreal pos = listItem->position();
+            releaseSectionItem(listItem->section());
+            listItem->setSection(0);
+            listItem->setPosition(pos);
+        }
+    }
+    for (int i = 0; i < sectionCacheSize; ++i) {
+        delete sectionCache[i];
+        sectionCache[i] = 0;
+    }
+}
+
 void QQuickListViewPrivate::updateInlineSection(FxListItemSG *listItem)
 {
     if (!sectionCriteria || !sectionCriteria->delegate())
@@ -1142,10 +1169,6 @@ void QQuickListViewPrivate::updateSections()
     }
 
     lastVisibleSection = QString();
-    updateCurrentSection();
-    updateStickySections();
-    forceLayout = true;
-    q->polish();
 }
 
 void QQuickListViewPrivate::updateCurrentSection()
@@ -1357,8 +1380,7 @@ void QQuickListViewPrivate::itemGeometryChanged(QQuickItem *item, const QRectF &
                         listItem->setPosition(listItem->position() + diff, true);
                 }
             }
-            forceLayout = true;
-            q->polish();
+            forceLayoutPolish();
         }
     }
 }
@@ -1907,7 +1929,7 @@ QQuickListView::~QQuickListView()
     is scrolled.  This is because the view moves to maintain the
     highlight within the preferred highlight range (or visible viewport).
 
-    \sa highlight, highlightMoveSpeed
+    \sa highlight, highlightMoveVelocity
 */
 //###Possibly rename these properties, since they are very useful even without a highlight?
 /*!
@@ -1972,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();
     }
 }
@@ -2178,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;
 }
 
@@ -2196,17 +2215,18 @@ QString QQuickListView::currentSection() const
 }
 
 /*!
-    \qmlproperty real QtQuick2::ListView::highlightMoveSpeed
+    \qmlproperty real QtQuick2::ListView::highlightMoveVelocity
     \qmlproperty int QtQuick2::ListView::highlightMoveDuration
-    \qmlproperty real QtQuick2::ListView::highlightResizeSpeed
+    \qmlproperty real QtQuick2::ListView::highlightResizeVelocity
     \qmlproperty int QtQuick2::ListView::highlightResizeDuration
 
-    These properties hold the move and resize animation speed of the highlight delegate.
+    These properties control the speed of the move and resize animations for the
+    highlight delegate.
 
     \l highlightFollowsCurrentItem must be true for these properties
     to have effect.
 
-    The default value for the speed properties is 400 pixels/second.
+    The default value for the velocity properties is 400 pixels/second.
     The default value for the duration properties is -1, i.e. the
     highlight will take as much time as necessary to move at the set speed.
 
@@ -2214,20 +2234,20 @@ QString QQuickListView::currentSection() const
 
     \sa highlightFollowsCurrentItem
 */
-qreal QQuickListView::highlightMoveSpeed() const
+qreal QQuickListView::highlightMoveVelocity() const
 {
     Q_D(const QQuickListView);
-    return d->highlightMoveSpeed;
+    return d->highlightMoveVelocity;
 }
 
-void QQuickListView::setHighlightMoveSpeed(qreal speed)
+void QQuickListView::setHighlightMoveVelocity(qreal speed)
 {
     Q_D(QQuickListView);
-    if (d->highlightMoveSpeed != speed) {
-        d->highlightMoveSpeed = speed;
+    if (d->highlightMoveVelocity != speed) {
+        d->highlightMoveVelocity = speed;
         if (d->highlightPosAnimator)
-            d->highlightPosAnimator->velocity = d->highlightMoveSpeed;
-        emit highlightMoveSpeedChanged();
+            d->highlightPosAnimator->velocity = d->highlightMoveVelocity;
+        emit highlightMoveVelocityChanged();
     }
 }
 
@@ -2241,20 +2261,20 @@ void QQuickListView::setHighlightMoveDuration(int duration)
     }
 }
 
-qreal QQuickListView::highlightResizeSpeed() const
+qreal QQuickListView::highlightResizeVelocity() const
 {
     Q_D(const QQuickListView);
-    return d->highlightResizeSpeed;
+    return d->highlightResizeVelocity;
 }
 
-void QQuickListView::setHighlightResizeSpeed(qreal speed)
+void QQuickListView::setHighlightResizeVelocity(qreal speed)
 {
     Q_D(QQuickListView);
-    if (d->highlightResizeSpeed != speed) {
-        d->highlightResizeSpeed = speed;
+    if (d->highlightResizeVelocity != speed) {
+        d->highlightResizeVelocity = speed;
         if (d->highlightSizeAnimator)
-            d->highlightSizeAnimator->velocity = d->highlightResizeSpeed;
-        emit highlightResizeSpeedChanged();
+            d->highlightSizeAnimator->velocity = d->highlightResizeVelocity;
+        emit highlightResizeVelocityChanged();
     }
 }
 
@@ -2831,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();
     }
 }