summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMartin Jones <martin.jones@nokia.com>2011-04-13 06:34:06 (GMT)
committerMartin Jones <martin.jones@nokia.com>2011-04-14 01:06:05 (GMT)
commit52187b084491641ef80536c743c2261af8bfe11c (patch)
treede416ae39ce46f468651c8ce159677e624ddda92
parentc7833b8f5ecc7a47e35bdf9fbb528e1869979ef5 (diff)
downloadQt-52187b084491641ef80536c743c2261af8bfe11c.zip
Qt-52187b084491641ef80536c743c2261af8bfe11c.tar.gz
Qt-52187b084491641ef80536c743c2261af8bfe11c.tar.bz2
Moving contentY by large values in List/GridView is slow
We needed to create/destroy every delegate between the current position and the new position. Now we estimate element at the new position and just create the elements from that item. Change-Id: I9da1354cbadb4e44fafc1a0bee619d058d1e06a2 Task-number: QTBUG-14974 Reviewed-by: Bea Lam
-rw-r--r--src/declarative/graphicsitems/qdeclarativegridview.cpp20
-rw-r--r--src/declarative/graphicsitems/qdeclarativelistview.cpp22
-rw-r--r--tests/auto/declarative/qdeclarativegridview/tst_qdeclarativegridview.cpp51
-rw-r--r--tests/auto/declarative/qdeclarativelistview/tst_qdeclarativelistview.cpp56
4 files changed, 149 insertions, 0 deletions
diff --git a/src/declarative/graphicsitems/qdeclarativegridview.cpp b/src/declarative/graphicsitems/qdeclarativegridview.cpp
index 3ec29c1..21bfc59 100644
--- a/src/declarative/graphicsitems/qdeclarativegridview.cpp
+++ b/src/declarative/graphicsitems/qdeclarativegridview.cpp
@@ -584,6 +584,26 @@ void QDeclarativeGridViewPrivate::refill(qreal from, qreal to, bool doBuffer)
--i;
modelIndex = visibleItems.at(i)->index + 1;
}
+
+ if (visibleItems.count() && (fillFrom > rowPos + rowSize()*2
+ || fillTo < rowPosAt(visibleIndex) - rowSize())) {
+ // We've jumped more than a page. Estimate which items are now
+ // visible and fill from there.
+ int count = (fillFrom - (rowPos + rowSize())) / (rowSize()) * columns;
+ for (int i = 0; i < visibleItems.count(); ++i)
+ releaseItem(visibleItems.at(i));
+ visibleItems.clear();
+ modelIndex += count;
+ if (modelIndex >= model->count())
+ modelIndex = model->count() - 1;
+ else if (modelIndex < 0)
+ modelIndex = 0;
+ modelIndex = modelIndex / columns * columns;
+ visibleIndex = modelIndex;
+ colPos = colPosAt(visibleIndex);
+ rowPos = rowPosAt(visibleIndex);
+ }
+
int colNum = colPos / colSize();
FxGridItem *item = 0;
diff --git a/src/declarative/graphicsitems/qdeclarativelistview.cpp b/src/declarative/graphicsitems/qdeclarativelistview.cpp
index cb751f6..7c01293 100644
--- a/src/declarative/graphicsitems/qdeclarativelistview.cpp
+++ b/src/declarative/graphicsitems/qdeclarativelistview.cpp
@@ -744,6 +744,28 @@ void QDeclarativeListViewPrivate::refill(qreal from, qreal to, bool doBuffer)
if (visibleItems.at(i)->index != -1)
modelIndex = visibleItems.at(i)->index + 1;
}
+
+ if (visibleItems.count() && (fillFrom > itemEnd+averageSize+spacing
+ || fillTo < visiblePos - averageSize - spacing)) {
+ // We've jumped more than a page. Estimate which items are now
+ // visible and fill from there.
+ int count = (fillFrom - itemEnd) / (averageSize + spacing);
+ for (int i = 0; i < visibleItems.count(); ++i)
+ releaseItem(visibleItems.at(i));
+ visibleItems.clear();
+ modelIndex += count;
+ if (modelIndex >= model->count()) {
+ count -= modelIndex - model->count() + 1;
+ modelIndex = model->count() - 1;
+ } else if (modelIndex < 0) {
+ count -= modelIndex;
+ modelIndex = 0;
+ }
+ visibleIndex = modelIndex;
+ visiblePos = itemEnd + count * (averageSize + spacing) + 1;
+ itemEnd = visiblePos-1;
+ }
+
bool changed = false;
FxListItem *item = 0;
qreal pos = itemEnd + 1;
diff --git a/tests/auto/declarative/qdeclarativegridview/tst_qdeclarativegridview.cpp b/tests/auto/declarative/qdeclarativegridview/tst_qdeclarativegridview.cpp
index c183934..c8e7817 100644
--- a/tests/auto/declarative/qdeclarativegridview/tst_qdeclarativegridview.cpp
+++ b/tests/auto/declarative/qdeclarativegridview/tst_qdeclarativegridview.cpp
@@ -97,6 +97,7 @@ private slots:
void onRemove_data();
void testQtQuick11Attributes();
void testQtQuick11Attributes_data();
+ void contentPosJump();
private:
QDeclarativeView *createView();
@@ -2077,6 +2078,56 @@ void tst_QDeclarativeGridView::testQtQuick11Attributes_data()
<< "";
}
+void tst_QDeclarativeGridView::contentPosJump()
+{
+ QDeclarativeView *canvas = createView();
+
+ TestModel model;
+ for (int i = 0; i < 100; i++)
+ model.addItem("Item" + QString::number(i), "");
+
+ QDeclarativeContext *ctxt = canvas->rootContext();
+ ctxt->setContextProperty("testModel", &model);
+ ctxt->setContextProperty("testRightToLeft", QVariant(false));
+ ctxt->setContextProperty("testTopToBottom", QVariant(false));
+
+ canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/gridview1.qml"));
+ qApp->processEvents();
+
+ QDeclarativeGridView *gridview = findItem<QDeclarativeGridView>(canvas->rootObject(), "grid");
+ QVERIFY(gridview != 0);
+
+ QDeclarativeItem *contentItem = gridview->contentItem();
+ QVERIFY(contentItem != 0);
+
+ // Test jumping more than a page of items.
+ gridview->setContentY(500);
+
+ // Confirm items positioned correctly
+ int itemCount = findItems<QDeclarativeItem>(contentItem, "wrapper").count();
+ for (int i = 24; i < model.count() && i < itemCount; ++i) {
+ QDeclarativeItem *item = findItem<QDeclarativeItem>(contentItem, "wrapper", i);
+ if (!item) qWarning() << "Item" << i << "not found";
+ QVERIFY(item);
+ QVERIFY(item->x() == (i%3)*80);
+ QVERIFY(item->y() == (i/3)*60);
+ }
+
+ gridview->setContentY(-100);
+ itemCount = findItems<QDeclarativeItem>(contentItem, "wrapper").count();
+ QVERIFY(itemCount < 15);
+ // Confirm items positioned correctly
+ for (int i = 0; i < model.count() && i < itemCount; ++i) {
+ QDeclarativeItem *item = findItem<QDeclarativeItem>(contentItem, "wrapper", i);
+ if (!item) qWarning() << "Item" << i << "not found";
+ QVERIFY(item);
+ QVERIFY(item->x() == (i%3)*80);
+ QVERIFY(item->y() == (i/3)*60);
+ }
+
+ delete canvas;
+}
+
QDeclarativeView *tst_QDeclarativeGridView::createView()
{
QDeclarativeView *canvas = new QDeclarativeView(0);
diff --git a/tests/auto/declarative/qdeclarativelistview/tst_qdeclarativelistview.cpp b/tests/auto/declarative/qdeclarativelistview/tst_qdeclarativelistview.cpp
index ec60e8a..0c96587 100644
--- a/tests/auto/declarative/qdeclarativelistview/tst_qdeclarativelistview.cpp
+++ b/tests/auto/declarative/qdeclarativelistview/tst_qdeclarativelistview.cpp
@@ -120,6 +120,7 @@ private slots:
void rightToLeft();
void test_mirroring();
void orientationChange();
+ void contentPosJump();
private:
template <class T> void items();
@@ -2630,6 +2631,61 @@ void tst_QDeclarativeListView::orientationChange()
delete canvas;
}
+void tst_QDeclarativeListView::contentPosJump()
+{
+ QDeclarativeView *canvas = createView();
+
+ TestModel model;
+ for (int i = 0; i < 50; i++)
+ model.addItem("Item" + QString::number(i), "");
+
+ QDeclarativeContext *ctxt = canvas->rootContext();
+ ctxt->setContextProperty("testModel", &model);
+
+ TestObject *testObject = new TestObject;
+ ctxt->setContextProperty("testObject", testObject);
+
+ canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/listviewtest.qml"));
+ qApp->processEvents();
+
+ QDeclarativeListView *listview = findItem<QDeclarativeListView>(canvas->rootObject(), "list");
+ QTRY_VERIFY(listview != 0);
+
+ QDeclarativeItem *contentItem = listview->contentItem();
+ QTRY_VERIFY(contentItem != 0);
+
+ // Confirm items positioned correctly
+ int itemCount = findItems<QDeclarativeItem>(contentItem, "wrapper").count();
+ for (int i = 0; i < model.count() && i < itemCount; ++i) {
+ QDeclarativeItem *item = findItem<QDeclarativeItem>(contentItem, "wrapper", i);
+ if (!item) qWarning() << "Item" << i << "not found";
+ QTRY_VERIFY(item);
+ QTRY_VERIFY(item->y() == i*20);
+ }
+
+ // Test jumping more than a page of items.
+ listview->setContentY(500);
+ itemCount = findItems<QDeclarativeItem>(contentItem, "wrapper").count();
+ for (int i = 25; i < model.count() && i < itemCount; ++i) {
+ QDeclarativeItem *item = findItem<QDeclarativeItem>(contentItem, "wrapper", i);
+ if (!item) qWarning() << "Item" << i << "not found";
+ QTRY_VERIFY(item);
+ QTRY_VERIFY(item->y() == i*20);
+ }
+
+ listview->setContentY(-100);
+ itemCount = findItems<QDeclarativeItem>(contentItem, "wrapper").count();
+ QVERIFY(itemCount < 20);
+ for (int i = 0; i < model.count() && i < itemCount; ++i) {
+ QDeclarativeItem *item = findItem<QDeclarativeItem>(contentItem, "wrapper", i);
+ if (!item) qWarning() << "Item" << i << "not found";
+ QTRY_VERIFY(item);
+ QTRY_VERIFY(item->y() == i*20);
+ }
+
+ delete canvas;
+}
+
void tst_QDeclarativeListView::qListModelInterface_items()
{
items<TestModel>();