From 5a8de45440ad924e5e787e12e2396ffeed6cce80 Mon Sep 17 00:00:00 2001 From: Bea Lam Date: Fri, 5 Aug 2011 15:48:16 +1000 Subject: [PATCH] Show header/footer if current index is set to first/last item or row Task-number: QTBUG-17853 Change-Id: I1d679cee31d6ee2a4bb2f2bf90f73eb12898189b Reviewed-on: http://codereview.qt.nokia.com/2664 Reviewed-by: Qt Sanity Bot Reviewed-by: Martin Jones --- src/declarative/items/qsggridview.cpp | 12 +++++++++ src/declarative/items/qsgitemview.cpp | 30 +++++++++++++++++----- src/declarative/items/qsgitemview_p_p.h | 2 ++ src/declarative/items/qsglistview.cpp | 12 +++++++++ .../qsggridview/data/gridview-initCurrent.qml | 13 ++++++++++ .../declarative/qsggridview/tst_qsggridview.cpp | 22 ++++++++++++++++ .../qsglistview/data/listview-initCurrent.qml | 13 ++++++++++ .../declarative/qsglistview/tst_qsglistview.cpp | 22 ++++++++++++++++ 8 files changed, 119 insertions(+), 7 deletions(-) diff --git a/src/declarative/items/qsggridview.cpp b/src/declarative/items/qsggridview.cpp index ac86ebb..c9e02a0 100644 --- a/src/declarative/items/qsggridview.cpp +++ b/src/declarative/items/qsggridview.cpp @@ -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); diff --git a/src/declarative/items/qsgitemview.cpp b/src/declarative/items/qsgitemview.cpp index 402bbbf..bf5d190 100644 --- a/src/declarative/items/qsgitemview.cpp +++ b/src/declarative/items/qsgitemview.cpp @@ -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(); } diff --git a/src/declarative/items/qsgitemview_p_p.h b/src/declarative/items/qsgitemview_p_p.h index b1ee2e6..f20f4cc 100644 --- a/src/declarative/items/qsgitemview_p_p.h +++ b/src/declarative/items/qsgitemview_p_p.h @@ -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; diff --git a/src/declarative/items/qsglistview.cpp b/src/declarative/items/qsglistview.cpp index c8e8817..c3466be 100644 --- a/src/declarative/items/qsglistview.cpp +++ b/src/declarative/items/qsglistview.cpp @@ -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); diff --git a/tests/auto/declarative/qsggridview/data/gridview-initCurrent.qml b/tests/auto/declarative/qsggridview/data/gridview-initCurrent.qml index c012b4c..e3ec8f2 100644 --- a/tests/auto/declarative/qsggridview/data/gridview-initCurrent.qml +++ b/tests/auto/declarative/qsggridview/data/gridview-initCurrent.qml @@ -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 } } diff --git a/tests/auto/declarative/qsggridview/tst_qsggridview.cpp b/tests/auto/declarative/qsggridview/tst_qsggridview.cpp index c478f0d..49c3080 100644 --- a/tests/auto/declarative/qsggridview/tst_qsggridview.cpp +++ b/tests/auto/declarative/qsggridview/tst_qsggridview.cpp @@ -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); diff --git a/tests/auto/declarative/qsglistview/data/listview-initCurrent.qml b/tests/auto/declarative/qsglistview/data/listview-initCurrent.qml index ee1a333..c4f1860 100644 --- a/tests/auto/declarative/qsglistview/data/listview-initCurrent.qml +++ b/tests/auto/declarative/qsglistview/data/listview-initCurrent.qml @@ -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 } } diff --git a/tests/auto/declarative/qsglistview/tst_qsglistview.cpp b/tests/auto/declarative/qsglistview/tst_qsglistview.cpp index 59847d3..e1e6edd 100644 --- a/tests/auto/declarative/qsglistview/tst_qsglistview.cpp +++ b/tests/auto/declarative/qsglistview/tst_qsglistview.cpp @@ -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); -- 2.7.4