QQuickItemView: Take sticky header/footer into account for positionViewAtIndex().

When using an overlaid header or footer, we must adjust the position we come up
with by the appropriate size in order to end up at the correct place.

Change-Id: I218b9aef7fdf37f56ffb63dc395f97045b55a186
Task-number: QTBUG-50097
Reviewed-by: J-P Nurmi <jpnurmi@theqtcompany.com>
This commit is contained in:
Robin Burchell 2015-12-22 00:06:06 +01:00 committed by Robin Burchell
parent f4fb1ff188
commit 96f1bb07eb
5 changed files with 80 additions and 14 deletions

View File

@ -928,7 +928,7 @@ void QQuickItemViewPrivate::positionViewAtIndex(int index, int mode)
switch (mode) {
case QQuickItemView::Beginning:
pos = itemPos;
if (index < 0 && header)
if (header && (index < 0 || hasStickyHeader()))
pos -= headerSize();
break;
case QQuickItemView::Center:
@ -936,7 +936,7 @@ void QQuickItemViewPrivate::positionViewAtIndex(int index, int mode)
break;
case QQuickItemView::End:
pos = itemPos - size() + item->size();
if (index >= model->count() && footer)
if (footer && (index >= model->count() || hasStickyFooter()))
pos += footerSize();
break;
case QQuickItemView::Visible:

View File

@ -336,6 +336,8 @@ protected:
virtual bool showFooterForIndex(int index) const = 0;
virtual void updateHeader() = 0;
virtual void updateFooter() = 0;
virtual bool hasStickyHeader() const { return false; };
virtual bool hasStickyFooter() const { return false; };
virtual void createHighlight() = 0;
virtual void updateHighlight() = 0;

View File

@ -117,8 +117,8 @@ public:
bool showFooterForIndex(int index) const Q_DECL_OVERRIDE;
void updateHeader() Q_DECL_OVERRIDE;
void updateFooter() Q_DECL_OVERRIDE;
bool hasStickyHeader() const;
bool hasStickyFooter() const;
bool hasStickyHeader() const Q_DECL_OVERRIDE;
bool hasStickyFooter() const Q_DECL_OVERRIDE;
void changedVisibleIndex(int newIndex) Q_DECL_OVERRIDE;
void initializeCurrentItem() Q_DECL_OVERRIDE;

View File

@ -0,0 +1,47 @@
import QtQuick 2.6
ListView {
id: lv
// How many rows per page
property int pageSize: 5
// The current page number
property int currentPage: 1
// How large a single item is
property int itemSize: 100
// Arbitrary
property int totalPages: 5
height: itemSize * pageSize // display one full page at a time
width: 500 // arbitrary.
model: pageSize * totalPages
delegate: Text {
height: itemSize
text: "Item " + (index + 1) + " of " + lv.count
}
// contentY should be < 0 to account for header visibility
onContentYChanged: console.log(contentY)
headerPositioning: ListView.OverlayHeader
header: Rectangle {
height: itemSize
width: 500
z: 1000
visible: false
color: "black"
Text {
anchors.centerIn: parent
color: "red"
text: "List header"
}
}
onCurrentPageChanged: {
lv.positionViewAtIndex((currentPage - 1) * pageSize, ListView.Beginning);
}
}

View File

@ -253,6 +253,7 @@ private slots:
void QTBUG_48870_fastModelUpdates();
void QTBUG_50105();
void QTBUG_50097_stickyHeader_positionViewAtIndex();
private:
template <class T> void items(const QUrl &source);
@ -7550,7 +7551,7 @@ void tst_QQuickListView::stickyPositioning_data()
QTest::newRow("top header") << "stickyPositioning-header.qml"
<< Qt::Vertical << Qt::LeftToRight << QQuickListView::TopToBottom
<< 0 << QQuickItemView::Beginning << QList<QPointF>()
<< QPointF(0,-10) << QPointF();
<< QPointF(0,0) << QPointF();
QTest::newRow("top header: 1/2 up") << "stickyPositioning-header.qml"
<< Qt::Vertical << Qt::LeftToRight << QQuickListView::TopToBottom
@ -7577,7 +7578,7 @@ void tst_QQuickListView::stickyPositioning_data()
QTest::newRow("top footer") << "stickyPositioning-footer.qml"
<< Qt::Vertical << Qt::LeftToRight << QQuickListView::BottomToTop
<< 19 << QQuickItemView::End << QList<QPointF>()
<< QPointF() << QPointF(0,-10);
<< QPointF() << QPointF(0,0);
QTest::newRow("top footer: 1/2 up") << "stickyPositioning-footer.qml"
<< Qt::Vertical << Qt::LeftToRight << QQuickListView::BottomToTop
@ -7604,7 +7605,7 @@ void tst_QQuickListView::stickyPositioning_data()
QTest::newRow("bottom header") << "stickyPositioning-header.qml"
<< Qt::Vertical << Qt::LeftToRight << QQuickListView::BottomToTop
<< 0 << QQuickItemView::Beginning << QList<QPointF>()
<< QPointF(0,100) << QPointF();
<< QPointF(0,90) << QPointF();
QTest::newRow("bottom header: 1/2 down") << "stickyPositioning-header.qml"
<< Qt::Vertical << Qt::LeftToRight << QQuickListView::BottomToTop
@ -7631,7 +7632,7 @@ void tst_QQuickListView::stickyPositioning_data()
QTest::newRow("bottom footer") << "stickyPositioning-footer.qml"
<< Qt::Vertical << Qt::LeftToRight << QQuickListView::TopToBottom
<< 19 << QQuickItemView::End << QList<QPointF>()
<< QPointF() << QPointF(0,100);
<< QPointF() << QPointF(0,90);
QTest::newRow("bottom footer: 1/2 down") << "stickyPositioning-footer.qml"
<< Qt::Vertical << Qt::LeftToRight << QQuickListView::TopToBottom
@ -7658,7 +7659,7 @@ void tst_QQuickListView::stickyPositioning_data()
QTest::newRow("top header & bottom footer") << "stickyPositioning-both.qml"
<< Qt::Vertical << Qt::LeftToRight << QQuickListView::TopToBottom
<< 0 << QQuickItemView::Beginning << QList<QPointF>()
<< QPointF(0,-10) << QPointF(0,90);
<< QPointF(0,0) << QPointF(0,100);
QTest::newRow("top header & bottom footer: 1/2 up") << "stickyPositioning-both.qml"
<< Qt::Vertical << Qt::LeftToRight << QQuickListView::TopToBottom
@ -7711,7 +7712,7 @@ void tst_QQuickListView::stickyPositioning_data()
QTest::newRow("left header") << "stickyPositioning-header.qml"
<< Qt::Horizontal << Qt::LeftToRight << QQuickListView::TopToBottom
<< 0 << QQuickItemView::Beginning << QList<QPointF>()
<< QPointF(-10,0) << QPointF();
<< QPointF(0,0) << QPointF();
QTest::newRow("left header: 1/2 left") << "stickyPositioning-header.qml"
<< Qt::Horizontal << Qt::LeftToRight << QQuickListView::TopToBottom
@ -7738,7 +7739,7 @@ void tst_QQuickListView::stickyPositioning_data()
QTest::newRow("left footer") << "stickyPositioning-footer.qml"
<< Qt::Horizontal << Qt::RightToLeft << QQuickListView::TopToBottom
<< 19 << QQuickItemView::End << QList<QPointF>()
<< QPointF() << QPointF(-10,0);
<< QPointF() << QPointF(0,0);
QTest::newRow("left footer: 1/2 left") << "stickyPositioning-footer.qml"
<< Qt::Horizontal << Qt::RightToLeft << QQuickListView::TopToBottom
@ -7765,7 +7766,7 @@ void tst_QQuickListView::stickyPositioning_data()
QTest::newRow("right header") << "stickyPositioning-header.qml"
<< Qt::Horizontal << Qt::RightToLeft << QQuickListView::TopToBottom
<< 0 << QQuickItemView::Beginning << QList<QPointF>()
<< QPointF(100,0) << QPointF();
<< QPointF(90,0) << QPointF();
QTest::newRow("right header: 1/2 right") << "stickyPositioning-header.qml"
<< Qt::Horizontal << Qt::RightToLeft << QQuickListView::TopToBottom
@ -7792,7 +7793,7 @@ void tst_QQuickListView::stickyPositioning_data()
QTest::newRow("right footer") << "stickyPositioning-footer.qml"
<< Qt::Horizontal << Qt::LeftToRight << QQuickListView::TopToBottom
<< 19 << QQuickItemView::End << QList<QPointF>()
<< QPointF() << QPointF(100,0);
<< QPointF() << QPointF(90,0);
QTest::newRow("right footer: 1/2 right") << "stickyPositioning-footer.qml"
<< Qt::Horizontal << Qt::LeftToRight << QQuickListView::TopToBottom
@ -7819,7 +7820,7 @@ void tst_QQuickListView::stickyPositioning_data()
QTest::newRow("left header & right footer") << "stickyPositioning-both.qml"
<< Qt::Horizontal << Qt::LeftToRight << QQuickListView::TopToBottom
<< 0 << QQuickItemView::Beginning << QList<QPointF>()
<< QPointF(-10,0) << QPointF(90,0);
<< QPointF(0,0) << QPointF(100,0);
QTest::newRow("left header & right footer: 1/2 left") << "stickyPositioning-both.qml"
<< Qt::Horizontal << Qt::LeftToRight << QQuickListView::TopToBottom
@ -8451,6 +8452,22 @@ void tst_QQuickListView::QTBUG_50105()
QVERIFY(QTest::qWaitForWindowExposed(window.data()));
}
void tst_QQuickListView::QTBUG_50097_stickyHeader_positionViewAtIndex()
{
QQuickView *window = createView();
window->setSource(testFileUrl("qtbug50097.qml"));
window->show();
QVERIFY(QTest::qWaitForWindowExposed(window));
QQuickListView *listview = qobject_cast<QQuickListView*>(window->rootObject());
QVERIFY(listview != 0);
QTRY_COMPARE(listview->contentY(), -100.0); // the header size, since the header is overlaid
listview->setProperty("currentPage", 2);
QTRY_COMPARE(listview->contentY(), 400.0); // a full page of items down, sans the original negative header position
listview->setProperty("currentPage", 1);
QTRY_COMPARE(listview->contentY(), -100.0); // back to the same position: header visible, items not under the header.
}
QTEST_MAIN(tst_QQuickListView)
#include "tst_qquicklistview.moc"