aboutsummaryrefslogtreecommitdiffstats
path: root/tests
diff options
context:
space:
mode:
authorBea Lam <bea.lam@nokia.com>2011-07-14 13:55:20 +1000
committerQt by Nokia <qt-info@nokia.com>2011-07-21 06:23:11 +0200
commitc0fc795feb06a8e2f813690e47b2cb981c67546c (patch)
tree6d4b20b85d140bb55599ac55a2c0c37fa4aa0853 /tests
parent6b8e98aec3f382fedea704691da40376cbe88e5e (diff)
Always position headers at a negative position
Previously headers were either positioned at 0 if there were no items in the view, or at (0 - headerSize) if items were present. With this fix they are always positioned at (0 - headerSize) to be consistent. Due to the change, setPosition(-headerSize()) is now called from componentCompleted() to ensure the header is visible. This change also fixes GridView's header and footer positioning in TopToBottom + RightToLeft mode. Also added extra tests for header and footer positioning and fixed incorrect test value in tst_QSGGridView::positionViewAtIndex() (was 460 instead of 430 because previously rowPosAt() always added the header size, so if positionViewAtIndex() jumped past all visible items and caused them to be released, the new items started at +headerSize() instead of 0). Change-Id: I1015bed457d4ae964a7fb13702e2dfc470a168a9 Reviewed-on: http://codereview.qt.nokia.com/1618 Reviewed-by: Qt Sanity Bot <qt_sanity_bot@ovi.com> Reviewed-by: Martin Jones <martin.jones@nokia.com>
Diffstat (limited to 'tests')
-rw-r--r--tests/auto/declarative/qsggridview/data/footer.qml12
-rw-r--r--tests/auto/declarative/qsggridview/data/header.qml4
-rw-r--r--tests/auto/declarative/qsggridview/tst_qsggridview.cpp205
-rw-r--r--tests/auto/declarative/qsglistview/data/footer.qml16
-rw-r--r--tests/auto/declarative/qsglistview/data/header.qml7
-rw-r--r--tests/auto/declarative/qsglistview/data/headerfooter.qml2
-rw-r--r--tests/auto/declarative/qsglistview/tst_qsglistview.cpp291
7 files changed, 445 insertions, 92 deletions
diff --git a/tests/auto/declarative/qsggridview/data/footer.qml b/tests/auto/declarative/qsggridview/data/footer.qml
index b0d1117287..9083f9f57c 100644
--- a/tests/auto/declarative/qsggridview/data/footer.qml
+++ b/tests/auto/declarative/qsggridview/data/footer.qml
@@ -1,6 +1,8 @@
import QtQuick 2.0
Rectangle {
+ property bool showHeader: false
+
function changeFooter() {
grid.footer = footer2
}
@@ -21,6 +23,11 @@ Rectangle {
color: GridView.isCurrentItem ? "lightsteelblue" : "white"
}
}
+ Component {
+ id: headerComponent
+ Text { objectName: "header"; text: "Header " + x + "," + y; width: 100; height: 30 }
+ }
+
GridView {
id: grid
objectName: "grid"
@@ -30,11 +37,12 @@ Rectangle {
cellHeight: 60
model: testModel
delegate: myDelegate
- footer: Text { objectName: "footer"; text: "Footer"; height: 30 }
+ header: parent.showHeader ? headerComponent : null
+ footer: Text { objectName: "footer"; text: "Footer " + x + "," + y; width: 100; height: 30 }
}
Component {
id: footer2
- Text { objectName: "footer2"; text: "Footer 2"; height: 20 }
+ Text { objectName: "footer2"; text: "Footer 2" + x + "," + y; width: 50; height: 20 }
}
}
diff --git a/tests/auto/declarative/qsggridview/data/header.qml b/tests/auto/declarative/qsggridview/data/header.qml
index f725b683a2..5978317a76 100644
--- a/tests/auto/declarative/qsggridview/data/header.qml
+++ b/tests/auto/declarative/qsggridview/data/header.qml
@@ -30,11 +30,11 @@ Rectangle {
cellHeight: 60
model: testModel
delegate: myDelegate
- header: Text { objectName: "header"; text: "Header"; height: 30 }
+ header: Text { objectName: "header"; text: "Header " + x + "," + y; width: 100; height: 30 }
}
Component {
id: header2
- Text { objectName: "header2"; text: "Header 2"; height: 20 }
+ Text { objectName: "header2"; text: "Header 2 " + x + "," + y; width: 50; height: 20 }
}
}
diff --git a/tests/auto/declarative/qsggridview/tst_qsggridview.cpp b/tests/auto/declarative/qsggridview/tst_qsggridview.cpp
index 39359d1c10..c97a42b68b 100644
--- a/tests/auto/declarative/qsggridview/tst_qsggridview.cpp
+++ b/tests/auto/declarative/qsggridview/tst_qsggridview.cpp
@@ -59,6 +59,9 @@
#define SRCDIR "."
#endif
+Q_DECLARE_METATYPE(Qt::LayoutDirection)
+Q_DECLARE_METATYPE(QSGGridView::Flow)
+
class tst_QSGGridView : public QObject
{
Q_OBJECT
@@ -92,7 +95,9 @@ private slots:
void QTBUG_8456();
void manualHighlight();
void footer();
+ void footer_data();
void header();
+ void header_data();
void indexAt();
void onAdd();
void onAdd_data();
@@ -1359,7 +1364,15 @@ void tst_QSGGridView::positionViewAtIndex()
gridview->setContentX(80);
canvas->rootObject()->setProperty("showFooter", true);
gridview->positionViewAtEnd();
- QTRY_COMPARE(gridview->contentX(), 460.);
+ QTRY_COMPARE(gridview->contentX(), 430.);
+
+ // set current item to outside visible view, position at beginning
+ // and ensure highlight moves to current item
+ gridview->setCurrentIndex(6);
+ gridview->positionViewAtBeginning();
+ QTRY_COMPARE(gridview->contentX(), -30.);
+ QVERIFY(gridview->highlightItem());
+ QCOMPARE(gridview->highlightItem()->x(), 80.);
delete canvas;
}
@@ -1816,8 +1829,17 @@ void tst_QSGGridView::manualHighlight()
delete canvas;
}
+
void tst_QSGGridView::footer()
{
+ QFETCH(QSGGridView::Flow, flow);
+ QFETCH(Qt::LayoutDirection, layoutDirection);
+ QFETCH(QPointF, initialFooterPos);
+ QFETCH(QPointF, changedFooterPos);
+ QFETCH(QPointF, initialContentPos);
+ QFETCH(QPointF, changedContentPos);
+ QFETCH(QPointF, firstDelegatePos);
+
QSGView *canvas = createView();
canvas->show();
@@ -1833,6 +1855,8 @@ void tst_QSGGridView::footer()
QSGGridView *gridview = findItem<QSGGridView>(canvas->rootObject(), "grid");
QTRY_VERIFY(gridview != 0);
+ gridview->setFlow(flow);
+ gridview->setLayoutDirection(layoutDirection);
QSGItem *contentItem = gridview->contentItem();
QTRY_VERIFY(contentItem != 0);
@@ -1840,18 +1864,46 @@ void tst_QSGGridView::footer()
QSGText *footer = findItem<QSGText>(contentItem, "footer");
QVERIFY(footer);
- QCOMPARE(footer->y(), 180.0);
- QCOMPARE(footer->height(), 30.0);
+ QCOMPARE(footer->pos(), initialFooterPos);
+ QCOMPARE(footer->width(), 100.);
+ QCOMPARE(footer->height(), 30.);
+ QCOMPARE(QPointF(gridview->contentX(), gridview->contentY()), initialContentPos);
- model.removeItem(2);
- QTRY_COMPARE(footer->y(), 120.0);
+ QSGItem *item = findItem<QSGItem>(contentItem, "wrapper", 0);
+ QVERIFY(item);
+ QCOMPARE(item->pos(), firstDelegatePos);
+
+ if (flow == QSGGridView::LeftToRight) {
+ // shrink by one row
+ model.removeItem(2);
+ QTRY_COMPARE(footer->y(), initialFooterPos.y() - gridview->cellHeight());
+ } else {
+ // shrink by one column
+ model.removeItem(2);
+ model.removeItem(3);
+ if (layoutDirection == Qt::LeftToRight)
+ QTRY_COMPARE(footer->x(), initialFooterPos.x() - gridview->cellWidth());
+ else
+ QTRY_COMPARE(footer->x(), initialFooterPos.x() + gridview->cellWidth());
+ }
+ // remove all items
model.clear();
- QTRY_COMPARE(footer->y(), 0.0);
+ QPointF posWhenNoItems(0, 0);
+ if (layoutDirection == Qt::RightToLeft)
+ posWhenNoItems.setX(flow == QSGGridView::LeftToRight ? gridview->width() - footer->width() : -footer->width());
+ QTRY_COMPARE(footer->pos(), posWhenNoItems);
+
+ // if header is present, it's at a negative pos, so the footer should not move
+ canvas->rootObject()->setProperty("showHeader", true);
+ QVERIFY(findItem<QSGItem>(contentItem, "header") != 0);
+ QTRY_COMPARE(footer->pos(), posWhenNoItems);
+ canvas->rootObject()->setProperty("showHeader", false);
+
+ // add 30 items
for (int i = 0; i < 30; i++)
model.addItem("Item" + QString::number(i), "");
-
QMetaObject::invokeMethod(canvas->rootObject(), "changeFooter");
footer = findItem<QSGText>(contentItem, "footer");
@@ -1859,15 +1911,76 @@ void tst_QSGGridView::footer()
footer = findItem<QSGText>(contentItem, "footer2");
QVERIFY(footer);
- QCOMPARE(footer->y(), 600.0);
- QCOMPARE(footer->height(), 20.0);
- QCOMPARE(gridview->contentY(), 0.0);
+ QCOMPARE(footer->pos(), changedFooterPos);
+ QCOMPARE(footer->width(), 50.);
+ QCOMPARE(footer->height(), 20.);
+ QTRY_COMPARE(QPointF(gridview->contentX(), gridview->contentY()), changedContentPos);
+
+ item = findItem<QSGItem>(contentItem, "wrapper", 0);
+ QVERIFY(item);
+ QCOMPARE(item->pos(), firstDelegatePos);
delete canvas;
}
+void tst_QSGGridView::footer_data()
+{
+ QTest::addColumn<QSGGridView::Flow>("flow");
+ QTest::addColumn<Qt::LayoutDirection>("layoutDirection");
+ QTest::addColumn<QPointF>("initialFooterPos");
+ QTest::addColumn<QPointF>("changedFooterPos");
+ QTest::addColumn<QPointF>("initialContentPos");
+ QTest::addColumn<QPointF>("changedContentPos");
+ QTest::addColumn<QPointF>("firstDelegatePos");
+
+ // footer1 = 100 x 30
+ // footer2 = 100 x 20
+ // cells = 80 * 60
+ // view width = 240
+
+ // footer below items, bottom left
+ QTest::newRow("flow left to right") << QSGGridView::LeftToRight << Qt::LeftToRight
+ << QPointF(0, 3 * 60) // 180 = height of 3 rows (cell height is 60)
+ << QPointF(0, 10 * 60) // 30 items = 10 rows
+ << QPointF(0, 0)
+ << QPointF(0, 0)
+ << QPointF(0, 0);
+
+ // footer below items, bottom right
+ QTest::newRow("flow left to right, layout right to left") << QSGGridView::LeftToRight << Qt::RightToLeft
+ << QPointF(240 - 100, 3 * 60)
+ << QPointF((240 - 100) + 50, 10 * 60) // 50 = width diff between old and new footers
+ << QPointF(0, 0)
+ << QPointF(0, 0)
+ << QPointF(240 - 80, 0);
+
+ // footer to right of items
+ QTest::newRow("flow top to bottom, layout left to right") << QSGGridView::TopToBottom << Qt::LeftToRight
+ << QPointF(2 * 80, 0) // 2 columns, cell width 80
+ << QPointF(6 * 80, 0) // 30 items = 6 columns
+ << QPointF(0, 0)
+ << QPointF(0, 0)
+ << QPointF(0, 0);
+
+ // footer to left of items
+ QTest::newRow("flow top to bottom, layout right to left") << QSGGridView::TopToBottom << Qt::RightToLeft
+ << QPointF(-(2 * 80) - 100, 0)
+ << QPointF(-(6 * 80) - 50, 0) // 50 = new footer width
+ << QPointF(-240, 0)
+ << QPointF(-240, 0) // unchanged, footer change doesn't change content pos
+ << QPointF(-80, 0);
+}
+
void tst_QSGGridView::header()
{
+ QFETCH(QSGGridView::Flow, flow);
+ QFETCH(Qt::LayoutDirection, layoutDirection);
+ QFETCH(QPointF, initialHeaderPos);
+ QFETCH(QPointF, changedHeaderPos);
+ QFETCH(QPointF, initialContentPos);
+ QFETCH(QPointF, changedContentPos);
+ QFETCH(QPointF, firstDelegatePos);
+
QSGView *canvas = createView();
TestModel model;
@@ -1882,6 +1995,8 @@ void tst_QSGGridView::header()
QSGGridView *gridview = findItem<QSGGridView>(canvas->rootObject(), "grid");
QTRY_VERIFY(gridview != 0);
+ gridview->setFlow(flow);
+ gridview->setLayoutDirection(layoutDirection);
QSGItem *contentItem = gridview->contentItem();
QTRY_VERIFY(contentItem != 0);
@@ -1889,16 +2004,17 @@ void tst_QSGGridView::header()
QSGText *header = findItem<QSGText>(contentItem, "header");
QVERIFY(header);
- QCOMPARE(header->y(), 0.0);
- QCOMPARE(header->height(), 30.0);
- QCOMPARE(gridview->contentY(), 0.0);
+ QCOMPARE(header->pos(), initialHeaderPos);
+ QCOMPARE(header->width(), 100.);
+ QCOMPARE(header->height(), 30.);
+ QCOMPARE(QPointF(gridview->contentX(), gridview->contentY()), initialContentPos);
QSGItem *item = findItem<QSGItem>(contentItem, "wrapper", 0);
QVERIFY(item);
- QCOMPARE(item->y(), 30.0);
+ QCOMPARE(item->pos(), firstDelegatePos);
model.clear();
- QTRY_COMPARE(header->y(), 0.0);
+ QCOMPARE(header->pos(), initialHeaderPos); // header should stay where it is
for (int i = 0; i < 30; i++)
model.addItem("Item" + QString::number(i), "");
@@ -1910,13 +2026,66 @@ void tst_QSGGridView::header()
header = findItem<QSGText>(contentItem, "header2");
QVERIFY(header);
- QCOMPARE(header->y(), 10.0);
- QCOMPARE(header->height(), 20.0);
- QCOMPARE(gridview->contentY(), 10.0);
+ QCOMPARE(header->pos(), changedHeaderPos);
+ QCOMPARE(header->width(), 50.);
+ QCOMPARE(header->height(), 20.);
+ QTRY_COMPARE(QPointF(gridview->contentX(), gridview->contentY()), changedContentPos);
+
+ item = findItem<QSGItem>(contentItem, "wrapper", 0);
+ QVERIFY(item);
+ QCOMPARE(item->pos(), firstDelegatePos);
delete canvas;
}
+void tst_QSGGridView::header_data()
+{
+ QTest::addColumn<QSGGridView::Flow>("flow");
+ QTest::addColumn<Qt::LayoutDirection>("layoutDirection");
+ QTest::addColumn<QPointF>("initialHeaderPos");
+ QTest::addColumn<QPointF>("changedHeaderPos");
+ QTest::addColumn<QPointF>("initialContentPos");
+ QTest::addColumn<QPointF>("changedContentPos");
+ QTest::addColumn<QPointF>("firstDelegatePos");
+
+ // header1 = 100 x 30
+ // header2 = 100 x 20
+ // cells = 80 x 60
+ // view width = 240
+
+ // header above items, top left
+ QTest::newRow("flow left to right") << QSGGridView::LeftToRight << Qt::LeftToRight
+ << QPointF(0, -30)
+ << QPointF(0, -20)
+ << QPointF(0, -30)
+ << QPointF(0, -20)
+ << QPointF(0, 0);
+
+ // header above items, top right
+ QTest::newRow("flow left to right, layout right to left") << QSGGridView::LeftToRight << Qt::RightToLeft
+ << QPointF(240 - 100, -30)
+ << QPointF((240 - 100) + 50, -20) // 50 = width diff between old and new headers
+ << QPointF(0, -30)
+ << QPointF(0, -20)
+ << QPointF(160, 0);
+
+ // header to left of items
+ QTest::newRow("flow top to bottom, layout left to right") << QSGGridView::TopToBottom << Qt::LeftToRight
+ << QPointF(-100, 0)
+ << QPointF(-50, 0)
+ << QPointF(-100, 0)
+ << QPointF(-50, 0)
+ << QPointF(0, 0);
+
+ // header to right of items
+ QTest::newRow("flow top to bottom, layout right to left") << QSGGridView::TopToBottom << Qt::RightToLeft
+ << QPointF(0, 0)
+ << QPointF(0, 0)
+ << QPointF(-(240 - 100), 0)
+ << QPointF(-(240 - 50), 0)
+ << QPointF(-80, 0);
+}
+
void tst_QSGGridView::indexAt()
{
QSGView *canvas = createView();
diff --git a/tests/auto/declarative/qsglistview/data/footer.qml b/tests/auto/declarative/qsglistview/data/footer.qml
index 49e1944b6a..2a5619999e 100644
--- a/tests/auto/declarative/qsglistview/data/footer.qml
+++ b/tests/auto/declarative/qsglistview/data/footer.qml
@@ -1,6 +1,8 @@
import QtQuick 2.0
Rectangle {
+ property bool showHeader: false
+
function changeFooter() {
list.footer = footer2
}
@@ -13,13 +15,18 @@ Rectangle {
id: wrapper
objectName: "wrapper"
height: 20
- width: 240
+ width: 40
Text {
- text: index
+ text: index + " " + x + "," + y
}
color: ListView.isCurrentItem ? "lightsteelblue" : "white"
}
}
+ Component {
+ id: headerComponent
+ Text { objectName: "header"; text: "Header " + x + "," + y; width: 100; height: 30 }
+ }
+
ListView {
id: list
objectName: "list"
@@ -28,11 +35,12 @@ Rectangle {
height: 320
model: testModel
delegate: myDelegate
- footer: Text { objectName: "footer"; text: "Footer"; height: 30 }
+ header: parent.showHeader ? headerComponent : null
+ footer: Text { objectName: "footer"; text: "Footer " + x + "," + y; width: 100; height: 30 }
}
Component {
id: footer2
- Text { objectName: "footer2"; text: "Footer 2"; height: 20 }
+ Text { objectName: "footer2"; text: "Footer 2 " + x + "," + y; width: 50; height: 20 }
}
}
diff --git a/tests/auto/declarative/qsglistview/data/header.qml b/tests/auto/declarative/qsglistview/data/header.qml
index 455159f39d..b073146582 100644
--- a/tests/auto/declarative/qsglistview/data/header.qml
+++ b/tests/auto/declarative/qsglistview/data/header.qml
@@ -15,7 +15,7 @@ Rectangle {
height: 30
width: 240
Text {
- text: index
+ text: index + " " + x + "," + y
}
color: ListView.isCurrentItem ? "lightsteelblue" : "white"
}
@@ -29,10 +29,11 @@ Rectangle {
snapMode: ListView.SnapToItem
model: testModel
delegate: myDelegate
- header: Text { objectName: "header"; text: "Header"; height: 20 }
+ header: Text { objectName: "header"; text: "Header " + x + "," + y; width: 100; height: 30 }
}
Component {
id: header2
- Text { objectName: "header2"; text: "Header 2"; height: 10 }
+ Text { objectName: "header2"; text: "Header " + x + "," + y; width: 50; height: 20 }
}
+
}
diff --git a/tests/auto/declarative/qsglistview/data/headerfooter.qml b/tests/auto/declarative/qsglistview/data/headerfooter.qml
index 30b7199445..8e8463d645 100644
--- a/tests/auto/declarative/qsglistview/data/headerfooter.qml
+++ b/tests/auto/declarative/qsglistview/data/headerfooter.qml
@@ -20,7 +20,7 @@ ListView {
height: horizontal ? view.height : 30
color: "blue"
}
-// model: testModel
+
delegate: Text { width: 30; height: 30; text: index + "(" + x + ")" }
layoutDirection: rtl ? Qt.RightToLeft : Qt.LeftToRight
}
diff --git a/tests/auto/declarative/qsglistview/tst_qsglistview.cpp b/tests/auto/declarative/qsglistview/tst_qsglistview.cpp
index 3abca71182..75b68e484b 100644
--- a/tests/auto/declarative/qsglistview/tst_qsglistview.cpp
+++ b/tests/auto/declarative/qsglistview/tst_qsglistview.cpp
@@ -60,6 +60,9 @@
#define SRCDIR "."
#endif
+Q_DECLARE_METATYPE(Qt::LayoutDirection)
+Q_DECLARE_METATYPE(QSGListView::Orientation)
+
class tst_QSGListView : public QObject
{
Q_OBJECT
@@ -105,7 +108,10 @@ private slots:
void manualHighlight();
void QTBUG_11105();
void header();
+ void header_data();
+ void header_delayItemCreation();
void footer();
+ void footer_data();
void headerFooter();
void resizeView();
void sizeLessThan1();
@@ -1574,6 +1580,14 @@ void tst_QSGListView::positionViewAtIndex()
listview->positionViewAtEnd();
QTRY_COMPARE(listview->contentY(), 510.);
+ // set current item to outside visible view, position at beginning
+ // and ensure highlight moves to current item
+ listview->setCurrentIndex(1);
+ listview->positionViewAtBeginning();
+ QTRY_COMPARE(listview->contentY(), -30.);
+ QVERIFY(listview->highlightItem());
+ QCOMPARE(listview->highlightItem()->y(), 20.);
+
delete canvas;
delete testObject;
}
@@ -1885,80 +1899,153 @@ void tst_QSGListView::QTBUG_11105()
void tst_QSGListView::header()
{
- {
- QSGView *canvas = createView();
+ QFETCH(QSGListView::Orientation, orientation);
+ QFETCH(Qt::LayoutDirection, layoutDirection);
+ QFETCH(QPointF, initialHeaderPos);
+ QFETCH(QPointF, firstDelegatePos);
+ QFETCH(QPointF, initialContentPos);
+ QFETCH(QPointF, changedHeaderPos);
+ QFETCH(QPointF, changedContentPos);
- TestModel model;
- for (int i = 0; i < 30; i++)
- model.addItem("Item" + QString::number(i), "");
+ QSGView *canvas = createView();
- QDeclarativeContext *ctxt = canvas->rootContext();
- ctxt->setContextProperty("testModel", &model);
+ TestModel model;
+ for (int i = 0; i < 30; i++)
+ model.addItem("Item" + QString::number(i), "");
- canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/header.qml"));
- qApp->processEvents();
+ QDeclarativeContext *ctxt = canvas->rootContext();
+ ctxt->setContextProperty("testModel", &model);
- QSGListView *listview = findItem<QSGListView>(canvas->rootObject(), "list");
- QTRY_VERIFY(listview != 0);
+ canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/header.qml"));
+ qApp->processEvents();
- QSGItem *contentItem = listview->contentItem();
- QTRY_VERIFY(contentItem != 0);
+ QSGListView *listview = findItem<QSGListView>(canvas->rootObject(), "list");
+ QTRY_VERIFY(listview != 0);
+ listview->setOrientation(orientation);
+ listview->setLayoutDirection(layoutDirection);
- QSGText *header = findItem<QSGText>(contentItem, "header");
- QVERIFY(header);
- QCOMPARE(header->y(), 0.0);
- QCOMPARE(header->height(), 20.0);
+ QSGItem *contentItem = listview->contentItem();
+ QTRY_VERIFY(contentItem != 0);
- QCOMPARE(listview->contentY(), 0.0);
+ QSGText *header = findItem<QSGText>(contentItem, "header");
+ QVERIFY(header);
- model.clear();
- QTRY_COMPARE(header->y(), 0.0);
+ QCOMPARE(header->width(), 100.);
+ QCOMPARE(header->height(), 30.);
+ QCOMPARE(header->pos(), initialHeaderPos);
+ QCOMPARE(QPointF(listview->contentX(), listview->contentY()), initialContentPos);
- for (int i = 0; i < 30; i++)
- model.addItem("Item" + QString::number(i), "");
+ QSGItem *item = findItem<QSGItem>(contentItem, "wrapper", 0);
+ QVERIFY(item);
+ QCOMPARE(item->pos(), firstDelegatePos);
- QMetaObject::invokeMethod(canvas->rootObject(), "changeHeader");
+ model.clear();
+ QCOMPARE(header->pos(), initialHeaderPos); // header should stay where it is
- header = findItem<QSGText>(contentItem, "header");
- QVERIFY(!header);
- header = findItem<QSGText>(contentItem, "header2");
- QVERIFY(header);
+ for (int i = 0; i < 30; i++)
+ model.addItem("Item" + QString::number(i), "");
- QCOMPARE(header->y(), 10.0);
- QCOMPARE(header->height(), 10.0);
- QCOMPARE(listview->contentY(), 10.0);
+ QMetaObject::invokeMethod(canvas->rootObject(), "changeHeader");
- delete canvas;
- }
- {
- QSGView *canvas = createView();
+ header = findItem<QSGText>(contentItem, "header");
+ QVERIFY(!header);
+ header = findItem<QSGText>(contentItem, "header2");
+ QVERIFY(header);
- TestModel model;
+ QCOMPARE(header->pos(), changedHeaderPos);
+ QCOMPARE(header->width(), 50.);
+ QCOMPARE(header->height(), 20.);
+ QTRY_COMPARE(QPointF(listview->contentX(), listview->contentY()), changedContentPos);
+ QCOMPARE(item->pos(), firstDelegatePos);
- canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/header1.qml"));
- qApp->processEvents();
+ delete canvas;
+}
- QSGListView *listview = findItem<QSGListView>(canvas->rootObject(), "list");
- QTRY_VERIFY(listview != 0);
+void tst_QSGListView::header_data()
+{
+ QTest::addColumn<QSGListView::Orientation>("orientation");
+ QTest::addColumn<Qt::LayoutDirection>("layoutDirection");
+ QTest::addColumn<QPointF>("initialHeaderPos");
+ QTest::addColumn<QPointF>("changedHeaderPos");
+ QTest::addColumn<QPointF>("initialContentPos");
+ QTest::addColumn<QPointF>("changedContentPos");
+ QTest::addColumn<QPointF>("firstDelegatePos");
+
+ // header1 = 100 x 30
+ // header2 = 50 x 20
+ // delegates = 240 x 20
+ // view width = 240
+
+ // header above items, top left
+ QTest::newRow("vertical, left to right") << QSGListView::Vertical << Qt::LeftToRight
+ << QPointF(0, -30)
+ << QPointF(0, -20)
+ << QPointF(0, -30)
+ << QPointF(0, -20)
+ << QPointF(0, 0);
+
+ // header above items, top right
+ QTest::newRow("vertical, layout right to left") << QSGListView::Vertical << Qt::RightToLeft
+ << QPointF(0, -30)
+ << QPointF(0, -20)
+ << QPointF(0, -30)
+ << QPointF(0, -20)
+ << QPointF(0, 0);
+
+ // header to left of items
+ QTest::newRow("horizontal, layout left to right") << QSGListView::Horizontal << Qt::LeftToRight
+ << QPointF(-100, 0)
+ << QPointF(-50, 0)
+ << QPointF(-100, 0)
+ << QPointF(-50, 0)
+ << QPointF(0, 0);
+
+ // header to right of items
+ QTest::newRow("horizontal, layout right to left") << QSGListView::Horizontal << Qt::RightToLeft
+ << QPointF(0, 0)
+ << QPointF(0, 0)
+ << QPointF(-240 + 100, 0)
+ << QPointF(-240 + 50, 0)
+ << QPointF(-240, 0);
+}
- QSGItem *contentItem = listview->contentItem();
- QTRY_VERIFY(contentItem != 0);
+void tst_QSGListView::header_delayItemCreation()
+{
+ QSGView *canvas = createView();
- QSGText *header = findItem<QSGText>(contentItem, "header");
- QVERIFY(header);
- QCOMPARE(header->y(), 0.0);
+ TestModel model;
- QCOMPARE(listview->contentY(), 0.0);
+ canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/header1.qml"));
+ qApp->processEvents();
- model.clear();
- QTRY_COMPARE(header->y(), 0.0);
+ QSGListView *listview = findItem<QSGListView>(canvas->rootObject(), "list");
+ QTRY_VERIFY(listview != 0);
- delete canvas;
- }
+ QSGItem *contentItem = listview->contentItem();
+ QTRY_VERIFY(contentItem != 0);
+
+ QSGText *header = findItem<QSGText>(contentItem, "header");
+ QVERIFY(header);
+ QCOMPARE(header->y(), -header->height());
+
+ QCOMPARE(listview->contentY(), -header->height());
+
+ model.clear();
+ QTRY_COMPARE(header->y(), -header->height());
+
+ delete canvas;
}
void tst_QSGListView::footer()
{
+ QFETCH(QSGListView::Orientation, orientation);
+ QFETCH(Qt::LayoutDirection, layoutDirection);
+ QFETCH(QPointF, initialFooterPos);
+ QFETCH(QPointF, firstDelegatePos);
+ QFETCH(QPointF, initialContentPos);
+ QFETCH(QPointF, changedFooterPos);
+ QFETCH(QPointF, changedContentPos);
+
QSGView *canvas = createView();
TestModel model;
@@ -1974,21 +2061,48 @@ void tst_QSGListView::footer()
QSGListView *listview = findItem<QSGListView>(canvas->rootObject(), "list");
QTRY_VERIFY(listview != 0);
+ listview->setOrientation(orientation);
+ listview->setLayoutDirection(layoutDirection);
QSGItem *contentItem = listview->contentItem();
QTRY_VERIFY(contentItem != 0);
QSGText *footer = findItem<QSGText>(contentItem, "footer");
QVERIFY(footer);
- QCOMPARE(footer->y(), 60.0);
- QCOMPARE(footer->height(), 30.0);
+ QCOMPARE(footer->pos(), initialFooterPos);
+ QCOMPARE(footer->width(), 100.);
+ QCOMPARE(footer->height(), 30.);
+ QCOMPARE(QPointF(listview->contentX(), listview->contentY()), initialContentPos);
+
+ QSGItem *item = findItem<QSGItem>(contentItem, "wrapper", 0);
+ QVERIFY(item);
+ QCOMPARE(item->pos(), firstDelegatePos);
+
+ // remove one item
model.removeItem(1);
- QTRY_COMPARE(footer->y(), 40.0);
+ if (orientation == QSGListView::Vertical) {
+ QTRY_COMPARE(footer->y(), initialFooterPos.y() - 20); // delegate height = 20
+ } else {
+ QTRY_COMPARE(footer->x(), layoutDirection == Qt::LeftToRight ?
+ initialFooterPos.x() - 40 : initialFooterPos.x() + 40); // delegate width = 40
+ }
+
+ // remove all items
model.clear();
- QTRY_COMPARE(footer->y(), 0.0);
+ QPointF posWhenNoItems(0, 0);
+ if (orientation == QSGListView::Horizontal && layoutDirection == Qt::RightToLeft)
+ posWhenNoItems.setX(-100);
+ QTRY_COMPARE(footer->pos(), posWhenNoItems);
+
+ // if header is present, it's at a negative pos, so the footer should not move
+ canvas->rootObject()->setProperty("showHeader", true);
+ QTRY_COMPARE(footer->pos(), posWhenNoItems);
+ canvas->rootObject()->setProperty("showHeader", false);
+
+ // add 30 items
for (int i = 0; i < 30; i++)
model.addItem("Item" + QString::number(i), "");
@@ -1999,13 +2113,66 @@ void tst_QSGListView::footer()
footer = findItem<QSGText>(contentItem, "footer2");
QVERIFY(footer);
- QCOMPARE(footer->y(), 600.0);
- QCOMPARE(footer->height(), 20.0);
- QCOMPARE(listview->contentY(), 0.0);
+ QCOMPARE(footer->pos(), changedFooterPos);
+ QCOMPARE(footer->width(), 50.);
+ QCOMPARE(footer->height(), 20.);
+ QTRY_COMPARE(QPointF(listview->contentX(), listview->contentY()), changedContentPos);
+
+ item = findItem<QSGItem>(contentItem, "wrapper", 0);
+ QVERIFY(item);
+ QCOMPARE(item->pos(), firstDelegatePos);
delete canvas;
}
+void tst_QSGListView::footer_data()
+{
+ QTest::addColumn<QSGListView::Orientation>("orientation");
+ QTest::addColumn<Qt::LayoutDirection>("layoutDirection");
+ QTest::addColumn<QPointF>("initialFooterPos");
+ QTest::addColumn<QPointF>("changedFooterPos");
+ QTest::addColumn<QPointF>("initialContentPos");
+ QTest::addColumn<QPointF>("changedContentPos");
+ QTest::addColumn<QPointF>("firstDelegatePos");
+
+ // footer1 = 100 x 30
+ // footer2 = 100 x 20
+ // delegates = 40 x 20
+ // view width = 240
+
+ // footer below items, bottom left
+ QTest::newRow("vertical, layout left to right") << QSGListView::Vertical << Qt::LeftToRight
+ << QPointF(0, 3 * 20)
+ << QPointF(0, 30 * 20) // added 30 items
+ << QPointF(0, 0)
+ << QPointF(0, 0)
+ << QPointF(0, 0);
+
+ // footer below items, bottom right
+ QTest::newRow("vertical, layout right to left") << QSGListView::Vertical << Qt::RightToLeft
+ << QPointF(0, 3 * 20)
+ << QPointF(0, 30 * 20)
+ << QPointF(0, 0)
+ << QPointF(0, 0)
+ << QPointF(0, 0);
+
+ // footer to right of items
+ QTest::newRow("horizontal, layout left to right") << QSGListView::Horizontal << Qt::LeftToRight
+ << QPointF(40 * 3, 0)
+ << QPointF(40 * 30, 0)
+ << QPointF(0, 0)
+ << QPointF(0, 0)
+ << QPointF(0, 0);
+
+ // footer to left of items
+ QTest::newRow("horizontal, layout right to left") << QSGListView::Horizontal << Qt::RightToLeft
+ << QPointF(-(40 * 3) - 100, 0)
+ << QPointF(-(40 * 30) - 50, 0) // 50 = new footer width
+ << QPointF(-240, 0)
+ << QPointF(-240, 0)
+ << QPointF(-40, 0);
+}
+
class LVAccessor : public QSGListView
{
public:
@@ -2036,11 +2203,11 @@ void tst_QSGListView::headerFooter()
QSGItem *header = findItem<QSGItem>(contentItem, "header");
QVERIFY(header);
- QCOMPARE(header->y(), 0.0);
+ QCOMPARE(header->y(), -header->height());
QSGItem *footer = findItem<QSGItem>(contentItem, "footer");
QVERIFY(footer);
- QCOMPARE(footer->y(), 20.0);
+ QCOMPARE(footer->y(), 0.);
QVERIFY(static_cast<LVAccessor*>(listview)->minY() == 0);
QVERIFY(static_cast<LVAccessor*>(listview)->maxY() == 0);
@@ -2067,11 +2234,11 @@ void tst_QSGListView::headerFooter()
QSGItem *header = findItem<QSGItem>(contentItem, "header");
QVERIFY(header);
- QCOMPARE(header->x(), 0.0);
+ QCOMPARE(header->x(), -header->width());
QSGItem *footer = findItem<QSGItem>(contentItem, "footer");
QVERIFY(footer);
- QCOMPARE(footer->x(), 20.0);
+ QCOMPARE(footer->x(), 0.);
QVERIFY(static_cast<LVAccessor*>(listview)->minX() == 0);
QVERIFY(static_cast<LVAccessor*>(listview)->maxX() == 0);
@@ -2099,11 +2266,11 @@ void tst_QSGListView::headerFooter()
QSGItem *header = findItem<QSGItem>(contentItem, "header");
QVERIFY(header);
- QCOMPARE(header->x(), -20.0);
+ QCOMPARE(header->x(), 0.);
QSGItem *footer = findItem<QSGItem>(contentItem, "footer");
QVERIFY(footer);
- QCOMPARE(footer->x(), -50.0);
+ QCOMPARE(footer->x(), -footer->width());
QCOMPARE(static_cast<LVAccessor*>(listview)->minX(), 240.);
QCOMPARE(static_cast<LVAccessor*>(listview)->maxX(), 240.);