diff options
author | Gabriel de Dietrich <gabriel.dedietrich@theqtcompany.com> | 2015-09-04 13:32:55 +0200 |
---|---|---|
committer | Gabriel de Dietrich <gabriel.dedietrich@theqtcompany.com> | 2015-09-21 13:33:48 +0000 |
commit | c5b083b2a256823f4f47fcaa3140d4f79d99029f (patch) | |
tree | 6a23160e03901fe90f419cf9c6bad9214cb841dd /tests | |
parent | 4c1a7050506fddbf0199d928b2e6db7d6a2047ed (diff) |
ListView: Set currentItem's culled state on geometry change
When the viewport is moved, the ListView may cull its currentItem
if it's out of the viewport bounds. However, it could be that this
is only a transient state while the currentItem is being animated.
Unfortunately, we don't uncull the currentItem at any moment during
the animation.
To solve this, we simply set the currentItem's culled state every
time its geometry changes.
Change-Id: I72d548f13f229029ccd8568721ea23e73f7b4392
Task-number: QTBUG-48044
Reviewed-by: J-P Nurmi <jpnurmi@theqtcompany.com>
Diffstat (limited to 'tests')
-rw-r--r-- | tests/auto/quick/qquicklistview/data/qtbug48044.qml | 144 | ||||
-rw-r--r-- | tests/auto/quick/qquicklistview/tst_qquicklistview.cpp | 37 |
2 files changed, 181 insertions, 0 deletions
diff --git a/tests/auto/quick/qquicklistview/data/qtbug48044.qml b/tests/auto/quick/qquicklistview/data/qtbug48044.qml new file mode 100644 index 0000000000..d318643c1c --- /dev/null +++ b/tests/auto/quick/qquicklistview/data/qtbug48044.qml @@ -0,0 +1,144 @@ +import QtQuick 2.0 + +Item { + width: 200 + height: 442 + + ListModel { + id: listModel + ListElement { + name: "h1" + txt: "Header 1" + header: true + collapsed: true + } + ListElement { + name: "h2" + txt: "Header 2" + header: true + collapsed: true + } + ListElement { + name: "h3" + txt: "Header 3" + header: true + collapsed: true + } + + function indexFromName(name) { + for (var i = 0; i < count; i++) + if (get(i).name === name) + return i + + console.warn("Did not find index for name " + name) + return -1 + } + } + + function populateModel(prefix, index, n) { + for (var k = 1; k <= n; k++) { + var name = prefix + k + var data = { + "collapsed": false, + "name": name, + "txt": name, + "header": false + } + listModel.insert(index + k, data) + } + } + + function h2(open) { + var i = listModel.indexFromName("h2") + if (listModel.get(i).collapsed === !open) + return + + listModel.setProperty(i, "collapsed", !open) + + var n = 15 + if (open) { + h3(false) + populateModel("c2_", listModel.indexFromName("h2"), n) + } else { + listModel.remove(i + 1, n) + } + + } + + function h3(open) { + var i = listModel.indexFromName("h3") + if (listModel.get(i).collapsed === !open) + return + + listModel.setProperty(i, "collapsed", !open) + + var n = 6 + if (open) { + h2(false) + populateModel("c3_", listModel.indexFromName("h3"), n) + } else { + listModel.remove(i + 1, n) + } + } + + ListView { + id: listView + width: parent.width + height: parent.height + cacheBuffer: 0 + model: listModel + + property bool transitionsDone: false + property int runningTransitions: 0 + onRunningTransitionsChanged: { + if (runningTransitions === 0) + transitionsDone = true + } + + displaced: Transition { + id: dispTrans + SequentialAnimation { + ScriptAction { + script: listView.runningTransitions++ + } + NumberAnimation { + property: "y"; + duration: 250 + } + ScriptAction { + script: listView.runningTransitions-- + } + } + } + + delegate: Rectangle { + id: rect + color: header ? "yellow" : "cyan" + border.color: "black" + height: 50 + width: parent.width + + Text { + anchors.centerIn: parent + font.pixelSize: 20 + text: txt + } + + MouseArea { + anchors.fill: parent + onClicked: { + listView.currentIndex = index + var i = listModel.indexFromName("h3") + if (i === -1) + return; + var isCollapsed = listModel.get(i).collapsed + if (name === "h2") + h2(isCollapsed) + else if (name === "h3") + h3(isCollapsed) + } + } + } + } +} + diff --git a/tests/auto/quick/qquicklistview/tst_qquicklistview.cpp b/tests/auto/quick/qquicklistview/tst_qquicklistview.cpp index 8e7f93849c..e02c053208 100644 --- a/tests/auto/quick/qquicklistview/tst_qquicklistview.cpp +++ b/tests/auto/quick/qquicklistview/tst_qquicklistview.cpp @@ -247,6 +247,8 @@ private slots: void contentHeightWithDelayRemove(); void contentHeightWithDelayRemove_data(); + void QTBUG_48044_currentItemNotVisibleAfterTransition(); + private: template <class T> void items(const QUrl &source); template <class T> void changed(const QUrl &source); @@ -8231,6 +8233,41 @@ void tst_QQuickListView::contentHeightWithDelayRemove() delete window; } +void tst_QQuickListView::QTBUG_48044_currentItemNotVisibleAfterTransition() +{ + QQuickView *window = createView(); + window->setSource(testFileUrl("qtbug48044.qml")); + window->show(); + QVERIFY(QTest::qWaitForWindowExposed(window)); + + QQuickListView *listview = window->rootObject()->findChild<QQuickListView*>(); + QTRY_VERIFY(listview != 0); + + // Expand 2nd header + listview->setProperty("transitionsDone", QVariant(false)); + QTest::mouseClick(window, Qt::LeftButton, Qt::NoModifier, QPoint(window->width() / 2, 75)); + QTRY_VERIFY(listview->property("transitionsDone").toBool()); + + // Flick listview to the bottom + flick(window, QPoint(window->width() / 2, 400), QPoint(window->width() / 2, 0), 100); + QTRY_VERIFY(!listview->isMoving()); + + // Expand 3rd header + listview->setProperty("transitionsDone", QVariant(false)); + QTest::mouseClick(window, Qt::LeftButton, Qt::NoModifier, QPoint(window->width() / 2, window->height() - 25)); + QTRY_VERIFY(listview->property("transitionsDone").toBool()); + + // Check current item is what we expect + QCOMPARE(listview->currentIndex(), 2); + QQuickItem *currentItem = listview->currentItem(); + QVERIFY(currentItem); + QVERIFY(currentItem->isVisible()); + + // This is the actual test + QQuickItemPrivate *currentPriv = QQuickItemPrivate::get(currentItem); + QVERIFY(!currentPriv->culled); +} + QTEST_MAIN(tst_QQuickListView) #include "tst_qquicklistview.moc" |