Show header/footer if current index is set to first/last item or row
authorBea Lam <bea.lam@nokia.com>
Fri, 5 Aug 2011 05:48:16 +0000 (15:48 +1000)
committerQt by Nokia <qt-info@nokia.com>
Fri, 5 Aug 2011 07:23:48 +0000 (09:23 +0200)
Task-number: QTBUG-17853
Change-Id: I1d679cee31d6ee2a4bb2f2bf90f73eb12898189b
Reviewed-on: http://codereview.qt.nokia.com/2664
Reviewed-by: Qt Sanity Bot <qt_sanity_bot@ovi.com>
Reviewed-by: Martin Jones <martin.jones@nokia.com>
src/declarative/items/qsggridview.cpp
src/declarative/items/qsgitemview.cpp
src/declarative/items/qsgitemview_p_p.h
src/declarative/items/qsglistview.cpp
tests/auto/declarative/qsggridview/data/gridview-initCurrent.qml
tests/auto/declarative/qsggridview/tst_qsggridview.cpp
tests/auto/declarative/qsglistview/data/listview-initCurrent.qml
tests/auto/declarative/qsglistview/tst_qsglistview.cpp

index ac86ebb..c9e02a0 100644 (file)
@@ -176,6 +176,8 @@ public:
 
     virtual qreal headerSize() const;
     virtual qreal footerSize() const;
+    virtual bool showHeaderForIndex(int index) const;
+    virtual bool showFooterForIndex(int index) const;
     virtual void updateHeader();
     virtual void updateFooter();
 
@@ -638,6 +640,16 @@ qreal QSGGridViewPrivate::footerSize() const
     return flow == QSGGridView::LeftToRight? footer->item->height() : footer->item->width();
 }
 
+bool QSGGridViewPrivate::showHeaderForIndex(int index) const
+{
+    return index / columns == 0;
+}
+
+bool QSGGridViewPrivate::showFooterForIndex(int index) const
+{
+    return index / columns == (model->count()-1) / columns;
+}
+
 void QSGGridViewPrivate::updateFooter()
 {
     Q_Q(QSGGridView);
index 402bbbf..bf5d190 100644 (file)
@@ -756,16 +756,32 @@ void QSGItemView::trackedPositionChanged()
                     pos = d->startPosition();
             }
         } else {
-            if (trackedPos < viewPos && d->currentItem->position() < viewPos) {
-                pos = qMax(trackedPos, d->currentItem->position());
-            } else if (d->trackedItem->endPosition() >= viewPos + d->size()
-                && d->currentItem->endPosition() >= viewPos + d->size()) {
-                if (d->trackedItem->endPosition() <= d->currentItem->endPosition()) {
-                    pos = d->trackedItem->endPosition() - d->size();
+            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 (trackedPos < viewPos && toItemPos < viewPos) {
+                pos = qMax(trackedPos, toItemPos);
+            } else if (trackedEndPos >= viewPos + d->size()
+                && toItemEndPos >= viewPos + d->size()) {
+                if (trackedEndPos <= toItemEndPos) {
+                    pos = trackedEndPos - d->size();
                     if (trackedSize > d->size())
                         pos = trackedPos;
                 } else {
-                    pos = d->currentItem->endPosition() - d->size();
+                    pos = toItemEndPos - d->size();
                     if (d->currentItem->size() > d->size())
                         pos = d->currentItem->position();
                 }
index b1ee2e6..f20f4cc 100644 (file)
@@ -177,6 +177,8 @@ protected:
 
     virtual qreal headerSize() const = 0;
     virtual qreal footerSize() const = 0;
+    virtual bool showHeaderForIndex(int index) const = 0;
+    virtual bool showFooterForIndex(int index) const = 0;
     virtual void updateHeader() = 0;
     virtual void updateFooter() = 0;
 
index c8e8817..c3466be 100644 (file)
@@ -223,6 +223,8 @@ public:
 
     virtual qreal headerSize() const;
     virtual qreal footerSize() const;
+    virtual bool showHeaderForIndex(int index) const;
+    virtual bool showFooterForIndex(int index) const;
     virtual void updateHeader();
     virtual void updateFooter();
 
@@ -925,6 +927,16 @@ qreal QSGListViewPrivate::footerSize() const
     return footer ? footer->size() : 0.0;
 }
 
+bool QSGListViewPrivate::showHeaderForIndex(int index) const
+{
+    return index == 0;
+}
+
+bool QSGListViewPrivate::showFooterForIndex(int index) const
+{
+    return index == model->count()-1;
+}
+
 void QSGListViewPrivate::updateFooter()
 {
     Q_Q(QSGListView);
index c012b4c..e3ec8f2 100644 (file)
@@ -1,7 +1,12 @@
 import QtQuick 2.0
 
 Rectangle {
+    id: root
+
     property int current: grid.currentIndex
+    property bool showHeader: false
+    property bool showFooter: false
+
     width: 240
     height: 320
     color: "#ffffff"
@@ -37,6 +42,12 @@ Rectangle {
             }
         }
     ]
+
+    Component {
+        id: headerFooter
+        Rectangle { height: 30; width: 240; color: "blue" }
+    }
+
     GridView {
         id: grid
         objectName: "grid"
@@ -48,5 +59,7 @@ Rectangle {
         cellHeight: 60
         delegate: myDelegate
         model: testModel
+        header: root.showHeader ? headerFooter : null
+        footer: root.showFooter ? headerFooter : null
     }
 }
index c478f0d..49c3080 100644 (file)
@@ -880,6 +880,26 @@ void tst_QSGGridView::currentIndex()
 
     QTRY_COMPARE(gridview->contentY(), 0.0);
 
+
+    // footer should become visible if it is out of view, and then current index moves to the first row
+    canvas->rootObject()->setProperty("showFooter", true);
+    QTRY_VERIFY(gridview->footerItem());
+    gridview->setCurrentIndex(model.count()-3);
+    QTRY_VERIFY(gridview->footerItem()->y() > gridview->contentY() + gridview->height());
+    gridview->setCurrentIndex(model.count()-2);
+    QTRY_COMPARE(gridview->contentY() + gridview->height(), (60.0 * model.count()/3) + gridview->footerItem()->height());
+    canvas->rootObject()->setProperty("showFooter", false);
+
+    // header should become visible if it is out of view, and then current index moves to the last row
+    canvas->rootObject()->setProperty("showHeader", true);
+    QTRY_VERIFY(gridview->headerItem());
+    gridview->setCurrentIndex(3);
+    QTRY_VERIFY(gridview->headerItem()->y() + gridview->headerItem()->height() < gridview->contentY());
+    gridview->setCurrentIndex(1);
+    QTRY_COMPARE(gridview->contentY(), -gridview->headerItem()->height());
+    canvas->rootObject()->setProperty("showHeader", false);
+
+
     // Test keys
     qApp->setActiveWindow(canvas);
 #ifdef Q_WS_X11
@@ -889,6 +909,8 @@ void tst_QSGGridView::currentIndex()
     QTRY_VERIFY(canvas->hasFocus());
     qApp->processEvents();
 
+    gridview->setCurrentIndex(0);
+
     QTest::keyClick(canvas, Qt::Key_Down);
     QCOMPARE(gridview->currentIndex(), 3);
 
index ee1a333..c4f1860 100644 (file)
@@ -1,7 +1,12 @@
 import QtQuick 2.0
 
 Rectangle {
+    id: root
+
     property int current: list.currentIndex
+    property bool showHeader: false
+    property bool showFooter: false
+
     width: 240
     height: 320
     color: "#ffffff"
@@ -36,6 +41,12 @@ Rectangle {
             }
         }
     ]
+
+    Component {
+        id: headerFooter
+        Rectangle { height: 30; width: 240; color: "blue" }
+    }
+
     ListView {
         id: list
         objectName: "list"
@@ -47,5 +58,7 @@ Rectangle {
         delegate: myDelegate
         highlightMoveSpeed: 1000
         model: testModel
+        header: root.showHeader ? headerFooter : null
+        footer: root.showFooter ? headerFooter : null
     }
 }
index 59847d3..e1e6edd 100644 (file)
@@ -1478,6 +1478,26 @@ void tst_QSGListView::currentIndex()
 
     QTRY_COMPARE(listview->contentY(), 0.0);
 
+
+    // footer should become visible if it is out of view, and then current index is set to count-1
+    canvas->rootObject()->setProperty("showFooter", true);
+    QTRY_VERIFY(listview->footerItem());
+    listview->setCurrentIndex(model.count()-2);
+    QTRY_VERIFY(listview->footerItem()->y() > listview->contentY() + listview->height());
+    listview->setCurrentIndex(model.count()-1);
+    QTRY_COMPARE(listview->contentY() + listview->height(), (20.0 * model.count()) + listview->footerItem()->height());
+    canvas->rootObject()->setProperty("showFooter", false);
+
+    // header should become visible if it is out of view, and then current index is set to 0
+    canvas->rootObject()->setProperty("showHeader", true);
+    QTRY_VERIFY(listview->headerItem());
+    listview->setCurrentIndex(1);
+    QTRY_VERIFY(listview->headerItem()->y() + listview->headerItem()->height() < listview->contentY());
+    listview->setCurrentIndex(0);
+    QTRY_COMPARE(listview->contentY(), -listview->headerItem()->height());
+    canvas->rootObject()->setProperty("showHeader", false);
+
+
     // Test keys
     canvas->show();
     qApp->setActiveWindow(canvas);
@@ -1488,6 +1508,8 @@ void tst_QSGListView::currentIndex()
     QTRY_VERIFY(canvas->hasFocus());
     qApp->processEvents();
 
+    listview->setCurrentIndex(0);
+
     QTest::keyClick(canvas, Qt::Key_Down);
     QCOMPARE(listview->currentIndex(), 1);