Incorrect initial pos after resizing view with margins.
authorMartin Jones <martin.jones@nokia.com>
Thu, 2 Feb 2012 01:46:55 +0000 (11:46 +1000)
committerQt by Nokia <qt-info@nokia.com>
Thu, 2 Feb 2012 08:09:37 +0000 (09:09 +0100)
The currentItem tracking didn't position the view to show the
margins.  This affects resizing the view and also changing
currentIndex.

Task-number: QTBUG-24028
Change-Id: I47d4c771c0d712c93abadfb6b2deb5194241fb6b
Reviewed-by: Bea Lam <bea.lam@nokia.com>
src/quick/items/qquickitemview.cpp
src/quick/items/qquickitemview_p_p.h
tests/auto/qtquick2/qquicklistview/data/Page.qml [new file with mode: 0644]
tests/auto/qtquick2/qquicklistview/data/margins2.qml [new file with mode: 0644]
tests/auto/qtquick2/qquicklistview/tst_qquicklistview.cpp

index a90d7cc..513a600 100644 (file)
@@ -186,7 +186,7 @@ void QQuickItemView::setModel(const QVariant &model)
     QQuickVisualModel *oldModel = d->model;
 
     d->clear();
-    d->setPosition(d->contentStartPosition());
+    d->setPosition(d->contentStartOffset());
     d->model = 0;
     d->modelVariant = model;
 
@@ -837,22 +837,27 @@ void QQuickItemView::trackedPositionChanged()
             qreal trackedEndPos = d->trackedItem->endPosition();
             qreal toItemPos = d->currentItem->position();
             qreal toItemEndPos = d->currentItem->endPosition();
-
-            if (d->header && d->showHeaderForIndex(d->currentIndex)) {
-                trackedPos -= d->headerSize();
-                trackedEndPos -= d->headerSize();
-                toItemPos -= d->headerSize();
-                toItemEndPos -= d->headerSize();
-            } else if (d->footer && d->showFooterForIndex(d->currentIndex)) {
-                trackedPos += d->footerSize();
-                trackedEndPos += d->footerSize();
-                toItemPos += d->footerSize();
-                toItemEndPos += d->footerSize();
+            if (d->showHeaderForIndex(d->currentIndex)) {
+                qreal startOffset = -d->contentStartOffset();
+                trackedPos -= startOffset;
+                trackedEndPos -= startOffset;
+                toItemPos -= startOffset;
+                toItemEndPos -= startOffset;
+            } else if (d->showFooterForIndex(d->currentIndex)) {
+                qreal endOffset = d->footerSize();
+                if (d->layoutOrientation() == Qt::Vertical)
+                    endOffset += d->vData.endMargin;
+                else if (d->isContentFlowReversed())
+                    endOffset += d->hData.endMargin;
+                else
+                    endOffset += d->hData.startMargin;
+                trackedPos += endOffset;
+                trackedEndPos += endOffset;
+                toItemPos += endOffset;
+                toItemEndPos += endOffset;
             }
 
-            if (trackedPos < viewPos && toItemPos < viewPos) {
-                pos = qMax(trackedPos, toItemPos);
-            } else if (trackedEndPos >= viewPos + d->size()
+            if (trackedEndPos >= viewPos + d->size()
                 && toItemEndPos >= viewPos + d->size()) {
                 if (trackedEndPos <= toItemEndPos) {
                     pos = trackedEndPos - d->size();
@@ -864,6 +869,8 @@ void QQuickItemView::trackedPositionChanged()
                         pos = d->currentItem->position();
                 }
             }
+            if (trackedPos < pos && toItemPos < pos)
+                pos = qMax(trackedPos, toItemPos);
         }
         if (viewPos != pos) {
             cancelFlick();
@@ -1078,7 +1085,7 @@ void QQuickItemView::componentComplete()
     d->updateHeader();
     d->updateFooter();
     d->updateViewport();
-    d->setPosition(d->contentStartPosition());
+    d->setPosition(d->contentStartOffset());
     if (d->isValid()) {
         d->refill();
         d->moveReason = QQuickItemViewPrivate::SetIndex;
@@ -1148,7 +1155,7 @@ qreal QQuickItemViewPrivate::endPosition() const
     return isContentFlowReversed() ? -originPosition() : lastPosition();
 }
 
-qreal QQuickItemViewPrivate::contentStartPosition() const
+qreal QQuickItemViewPrivate::contentStartOffset() const
 {
     qreal pos = -headerSize();
     if (layoutOrientation() == Qt::Vertical)
@@ -1353,7 +1360,7 @@ void QQuickItemViewPrivate::regenerate()
         updateFooter();
         clear();
         updateViewport();
-        setPosition(contentStartPosition());
+        setPosition(contentStartOffset());
         refill();
         updateCurrent(currentIndex);
     }
@@ -1378,7 +1385,7 @@ void QQuickItemViewPrivate::layout()
 
     if (!isValid() && !visibleItems.count()) {
         clear();
-        setPosition(contentStartPosition());
+        setPosition(contentStartOffset());
         return;
     }
 
index 56a2243..340349e 100644 (file)
@@ -126,7 +126,7 @@ public:
     qreal size() const;
     qreal startPosition() const;
     qreal endPosition() const;
-    qreal contentStartPosition() const;
+    qreal contentStartOffset() const;
     int findLastVisibleIndex(int defaultValue = -1) const;
     FxViewItem *visibleItem(int modelIndex) const;
     FxViewItem *firstVisibleItem() const;
diff --git a/tests/auto/qtquick2/qquicklistview/data/Page.qml b/tests/auto/qtquick2/qquicklistview/data/Page.qml
new file mode 100644 (file)
index 0000000..abe4364
--- /dev/null
@@ -0,0 +1,10 @@
+import QtQuick 2.0
+
+Item {
+    anchors.fill: parent
+    default property alias contentArea: contentItem.data
+    Item {
+        id: contentItem
+        anchors.fill: parent
+    }
+}
diff --git a/tests/auto/qtquick2/qquicklistview/data/margins2.qml b/tests/auto/qtquick2/qquicklistview/data/margins2.qml
new file mode 100644 (file)
index 0000000..e11c803
--- /dev/null
@@ -0,0 +1,29 @@
+import QtQuick 2.0
+
+Item {
+    width: 200; height: 200
+    Page {
+        Rectangle {
+            anchors.fill: parent
+            color: "lightsteelblue"
+        }
+        ListView {
+            objectName: "listview"
+            topMargin: 20
+            bottomMargin: 20
+            leftMargin: 20
+            rightMargin: 20
+            anchors.fill: parent
+
+            model: 20
+            delegate: Rectangle {
+                color: "skyblue"
+                width: 60; height: 60
+                Text {
+                    id: txt
+                    text: "test" + index
+                }
+            }
+        }
+    }
+}
index 4873a23..9dd72ae 100644 (file)
@@ -152,6 +152,8 @@ private slots:
     void rightToLeft();
     void test_mirroring();
     void margins();
+    void marginsResize();
+    void marginsResize_data();
     void creationContext();
     void snapToItem_data();
     void snapToItem();
@@ -4287,6 +4289,61 @@ void tst_QQuickListView::margins()
     delete canvas;
 }
 
+// QTBUG-24028
+void tst_QQuickListView::marginsResize()
+{
+    QFETCH(QQuickListView::Orientation, orientation);
+    QFETCH(Qt::LayoutDirection, layoutDirection);
+    QFETCH(qreal, start);
+    QFETCH(qreal, end);
+
+    QQuickView *canvas = createView();
+
+    canvas->setSource(testFileUrl("margins2.qml"));
+    canvas->show();
+    qApp->processEvents();
+
+    QQuickListView *listview = findItem<QQuickListView>(canvas->rootObject(), "listview");
+    QTRY_VERIFY(listview != 0);
+
+    listview->setOrientation(orientation);
+    listview->setLayoutDirection(layoutDirection);
+
+    // view is resized after componentCompleted - top margin should still be visible
+    if (orientation == QQuickListView::Vertical)
+        QCOMPARE(listview->contentY(), start);
+    else
+        QCOMPARE(listview->contentX(), start);
+
+    // move to last index and ensure bottom margin is visible.
+    listview->setCurrentIndex(19);
+    if (orientation == QQuickListView::Vertical)
+        QTRY_COMPARE(listview->contentY(), end);
+    else
+        QTRY_COMPARE(listview->contentX(), end);
+
+    // back to top - top margin should be visible.
+    listview->setCurrentIndex(0);
+    if (orientation == QQuickListView::Vertical)
+        QTRY_COMPARE(listview->contentY(), start);
+    else
+        QTRY_COMPARE(listview->contentX(), start);
+
+    delete canvas;
+}
+
+void tst_QQuickListView::marginsResize_data()
+{
+    QTest::addColumn<QQuickListView::Orientation>("orientation");
+    QTest::addColumn<Qt::LayoutDirection>("layoutDirection");
+    QTest::addColumn<qreal>("start");
+    QTest::addColumn<qreal>("end");
+
+    QTest::newRow("vertical") << QQuickListView::Vertical << Qt::LeftToRight << -20.0 << 1020.0;
+    QTest::newRow("horizontal") << QQuickListView::Horizontal << Qt::LeftToRight << -20.0 << 1020.0;
+    QTest::newRow("horizontal, rtl") << QQuickListView::Horizontal << Qt::RightToLeft << -180.0 << -1220.0;
+}
+
 void tst_QQuickListView::snapToItem_data()
 {
     QTest::addColumn<QQuickListView::Orientation>("orientation");