Fix flicker when changing ListView currentIndex with VisualItemModel.
authorAndrew den Exter <andrew.den-exter@nokia.com>
Mon, 28 May 2012 04:06:13 +0000 (14:06 +1000)
committerQt by Nokia <qt-info@nokia.com>
Mon, 28 May 2012 05:17:09 +0000 (07:17 +0200)
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 <bea.lam@nokia.com>
src/quick/items/qquickvisualitemmodel.cpp
tests/auto/quick/qquicklistview/data/itemlist-flicker.qml [new file with mode: 0644]
tests/auto/quick/qquicklistview/tst_qquicklistview.cpp

index 1cefcb4..1cb595e 100644 (file)
@@ -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 (file)
index 0000000..c0cc807
--- /dev/null
@@ -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
+    }
+}
index 8d4453a..45337e2 100644 (file)
@@ -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<QQuickListView>(canvas->rootObject(), "view");
+    QTRY_VERIFY(listview != 0);
+
+    QQuickItem *contentItem = listview->contentItem();
+    QTRY_VERIFY(contentItem != 0);
+
+    QQuickVisualItemModel *model = canvas->rootObject()->findChild<QQuickVisualItemModel*>("itemModel");
+    QTRY_VERIFY(model != 0);
+
+    QTRY_VERIFY(model->count() == 3);
+    QTRY_COMPARE(listview->currentIndex(), 0);
+
+    QQuickItem *item;
+
+    QVERIFY(item = findItem<QQuickItem>(contentItem, "item1"));
+    QVERIFY(item->isVisible());
+    QVERIFY(item = findItem<QQuickItem>(contentItem, "item2"));
+    QVERIFY(item->isVisible());
+    QVERIFY(item = findItem<QQuickItem>(contentItem, "item3"));
+    QVERIFY(item->isVisible());
+
+    listview->setCurrentIndex(1);
+
+    QVERIFY(item = findItem<QQuickItem>(contentItem, "item1"));
+    QVERIFY(item->isVisible());
+    QVERIFY(item = findItem<QQuickItem>(contentItem, "item2"));
+    QVERIFY(item->isVisible());
+    QVERIFY(item = findItem<QQuickItem>(contentItem, "item3"));
+    QVERIFY(item->isVisible());
+
+    listview->setCurrentIndex(2);
+
+    QVERIFY(item = findItem<QQuickItem>(contentItem, "item1"));
+    QVERIFY(item->isVisible());
+    QVERIFY(item = findItem<QQuickItem>(contentItem, "item2"));
+    QVERIFY(item->isVisible());
+    QVERIFY(item = findItem<QQuickItem>(contentItem, "item3"));
+    QVERIFY(item->isVisible());
+
+    delete canvas;
+}
+
 void tst_QQuickListView::cacheBuffer()
 {
     QQuickView *canvas = createView();