From 81726bcb8d2ea58f785f7d1f3bb3de8bb089d6ec Mon Sep 17 00:00:00 2001 From: Andrew den Exter Date: Mon, 28 May 2012 14:06:13 +1000 Subject: [PATCH] Fix flicker when changing ListView currentIndex with VisualItemModel. Return the Referenced flag when the view has outstanding references otherwise it will attempt to hide an item if believes shouldn't be visible. Task-number: QTBUG-25849 Change-Id: I7387ab8322a1cd7f3386685086b2b8ad10c8b4f0 Reviewed-by: Bea Lam --- src/quick/items/qquickvisualitemmodel.cpp | 8 +++- .../quick/qquicklistview/data/itemlist-flicker.qml | 46 ++++++++++++++++++++ .../quick/qquicklistview/tst_qquicklistview.cpp | 50 ++++++++++++++++++++++ 3 files changed, 102 insertions(+), 2 deletions(-) create mode 100644 tests/auto/quick/qquicklistview/data/itemlist-flicker.qml diff --git a/src/quick/items/qquickvisualitemmodel.cpp b/src/quick/items/qquickvisualitemmodel.cpp index 1cefcb4..1cb595e 100644 --- a/src/quick/items/qquickvisualitemmodel.cpp +++ b/src/quick/items/qquickvisualitemmodel.cpp @@ -192,8 +192,10 @@ QQuickItem *QQuickVisualItemModel::item(int index, bool) Q_D(QQuickVisualItemModel); QQuickVisualItemModelPrivate::Item &item = d->children[index]; item.addRef(); - emit initItem(index, item.item); - emit createdItem(index, item.item); + if (item.ref == 1) { + emit initItem(index, item.item); + emit createdItem(index, item.item); + } return item.item; } @@ -205,6 +207,8 @@ QQuickVisualModel::ReleaseFlags QQuickVisualItemModel::release(QQuickItem *item) if (d->children[idx].deref()) { // XXX todo - the original did item->scene()->removeItem(). Why? item->setParentItem(0); + } else { + return QQuickVisualModel::Referenced; } } return 0; diff --git a/tests/auto/quick/qquicklistview/data/itemlist-flicker.qml b/tests/auto/quick/qquicklistview/data/itemlist-flicker.qml new file mode 100644 index 0000000..c0cc807 --- /dev/null +++ b/tests/auto/quick/qquicklistview/data/itemlist-flicker.qml @@ -0,0 +1,46 @@ +// This example demonstrates placing items in a view using +// a VisualItemModel + +import QtQuick 2.0 + +Rectangle { + color: "lightgray" + width: 240 + height: 320 + + VisualItemModel { + id: itemModel + objectName: "itemModel" + Rectangle { + objectName: "item1" + height: view.height / 3 + width: view.width; color: "#FFFEF0" + Text { objectName: "text1"; text: "index: " + parent.VisualItemModel.index; font.bold: true; anchors.centerIn: parent } + } + Rectangle { + objectName: "item2" + height: view.height / 3 + width: view.width; color: "#F0FFF7" + Text { objectName: "text2"; text: "index: " + parent.VisualItemModel.index; font.bold: true; anchors.centerIn: parent } + } + Rectangle { + objectName: "item3" + height: view.height / 3 + width: view.width; color: "#F4F0FF" + Text { objectName: "text3"; text: "index: " + parent.VisualItemModel.index; font.bold: true; anchors.centerIn: parent } + } + } + + ListView { + id: view + objectName: "view" + anchors.fill: parent + anchors.bottomMargin: 30 + model: itemModel + preferredHighlightBegin: 0 + preferredHighlightEnd: 0 + highlightRangeMode: "StrictlyEnforceRange" + orientation: ListView.Vertical + flickDeceleration: 2000 + } +} diff --git a/tests/auto/quick/qquicklistview/tst_qquicklistview.cpp b/tests/auto/quick/qquicklistview/tst_qquicklistview.cpp index 8d4453a..45337e2 100644 --- a/tests/auto/quick/qquicklistview/tst_qquicklistview.cpp +++ b/tests/auto/quick/qquicklistview/tst_qquicklistview.cpp @@ -126,6 +126,7 @@ private slots: void insertBeforeVisible_data(); void swapWithFirstItem(); void itemList(); + void itemListFlicker(); void currentIndex_delayedItemCreation(); void currentIndex_delayedItemCreation_data(); void currentIndex(); @@ -2642,6 +2643,55 @@ void tst_QQuickListView::itemList() delete canvas; } +void tst_QQuickListView::itemListFlicker() +{ + QQuickView *canvas = createView(); + canvas->setSource(testFileUrl("itemlist-flicker.qml")); + canvas->show(); + qApp->processEvents(); + + QQuickListView *listview = findItem(canvas->rootObject(), "view"); + QTRY_VERIFY(listview != 0); + + QQuickItem *contentItem = listview->contentItem(); + QTRY_VERIFY(contentItem != 0); + + QQuickVisualItemModel *model = canvas->rootObject()->findChild("itemModel"); + QTRY_VERIFY(model != 0); + + QTRY_VERIFY(model->count() == 3); + QTRY_COMPARE(listview->currentIndex(), 0); + + QQuickItem *item; + + QVERIFY(item = findItem(contentItem, "item1")); + QVERIFY(item->isVisible()); + QVERIFY(item = findItem(contentItem, "item2")); + QVERIFY(item->isVisible()); + QVERIFY(item = findItem(contentItem, "item3")); + QVERIFY(item->isVisible()); + + listview->setCurrentIndex(1); + + QVERIFY(item = findItem(contentItem, "item1")); + QVERIFY(item->isVisible()); + QVERIFY(item = findItem(contentItem, "item2")); + QVERIFY(item->isVisible()); + QVERIFY(item = findItem(contentItem, "item3")); + QVERIFY(item->isVisible()); + + listview->setCurrentIndex(2); + + QVERIFY(item = findItem(contentItem, "item1")); + QVERIFY(item->isVisible()); + QVERIFY(item = findItem(contentItem, "item2")); + QVERIFY(item->isVisible()); + QVERIFY(item = findItem(contentItem, "item3")); + QVERIFY(item->isVisible()); + + delete canvas; +} + void tst_QQuickListView::cacheBuffer() { QQuickView *canvas = createView(); -- 2.7.4