summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/declarative/graphicsitems/qdeclarativeflickable.cpp3
-rw-r--r--src/declarative/graphicsitems/qdeclarativegridview.cpp94
-rw-r--r--src/declarative/graphicsitems/qdeclarativegridview_p.h2
-rw-r--r--src/declarative/graphicsitems/qdeclarativelistview.cpp81
-rw-r--r--src/declarative/graphicsitems/qdeclarativelistview_p.h1
-rw-r--r--tests/auto/declarative/qdeclarativelistview/tst_qdeclarativelistview.cpp3
6 files changed, 121 insertions, 63 deletions
diff --git a/src/declarative/graphicsitems/qdeclarativeflickable.cpp b/src/declarative/graphicsitems/qdeclarativeflickable.cpp
index 67068a0..9ccb3b6 100644
--- a/src/declarative/graphicsitems/qdeclarativeflickable.cpp
+++ b/src/declarative/graphicsitems/qdeclarativeflickable.cpp
@@ -264,6 +264,7 @@ void QDeclarativeFlickablePrivate::fixupY()
void QDeclarativeFlickablePrivate::fixup(AxisData &data, qreal minExtent, qreal maxExtent)
{
+ Q_Q(QDeclarativeFlickable);
if (data.move.value() > minExtent || maxExtent > minExtent) {
timeline.reset(data.move);
if (data.move.value() != minExtent) {
@@ -273,6 +274,7 @@ void QDeclarativeFlickablePrivate::fixup(AxisData &data, qreal minExtent, qreal
timeline.move(data.move, minExtent, QEasingCurve(QEasingCurve::OutQuint), 3*fixupDuration/4);
} else {
data.move.setValue(minExtent);
+ q->viewportMoved();
}
}
//emit flickingChanged();
@@ -284,6 +286,7 @@ void QDeclarativeFlickablePrivate::fixup(AxisData &data, qreal minExtent, qreal
timeline.move(data.move, maxExtent, QEasingCurve(QEasingCurve::OutQuint), 3*fixupDuration/4);
} else {
data.move.setValue(maxExtent);
+ q->viewportMoved();
}
//emit flickingChanged();
} else {
diff --git a/src/declarative/graphicsitems/qdeclarativegridview.cpp b/src/declarative/graphicsitems/qdeclarativegridview.cpp
index f35b903..af22e08 100644
--- a/src/declarative/graphicsitems/qdeclarativegridview.cpp
+++ b/src/declarative/graphicsitems/qdeclarativegridview.cpp
@@ -97,7 +97,7 @@ class QDeclarativeGridViewPrivate : public QDeclarativeFlickablePrivate
public:
QDeclarativeGridViewPrivate()
: currentItem(0), flow(QDeclarativeGridView::LeftToRight)
- , visiblePos(0), visibleIndex(0) , currentIndex(-1)
+ , visibleIndex(0) , currentIndex(-1)
, cellWidth(100), cellHeight(100), columns(1), requestedIndex(-1)
, highlightRangeStart(0), highlightRangeEnd(0), highlightRange(QDeclarativeGridView::NoHighlightRange)
, highlightComponent(0), highlight(0), trackedItem(0)
@@ -305,7 +305,6 @@ public:
QHash<QDeclarativeItem*,int> unrequestedItems;
FxGridItem *currentItem;
QDeclarativeGridView::Flow flow;
- int visiblePos;
int visibleIndex;
int currentIndex;
int cellWidth;
@@ -350,7 +349,6 @@ void QDeclarativeGridViewPrivate::clear()
for (int i = 0; i < visibleItems.count(); ++i)
releaseItem(visibleItems.at(i));
visibleItems.clear();
- visiblePos = 0;
visibleIndex = 0;
releaseItem(currentItem);
currentItem = 0;
@@ -536,7 +534,7 @@ void QDeclarativeGridViewPrivate::scheduleLayout()
Q_Q(QDeclarativeGridView);
if (!layoutScheduled) {
layoutScheduled = true;
- QMetaObject::invokeMethod(q, "layout", Qt::QueuedConnection);
+ QCoreApplication::postEvent(q, new QEvent(QEvent::User), Qt::HighEventPriority);
}
}
@@ -748,10 +746,12 @@ void QDeclarativeGridViewPrivate::fixup(AxisData &data, qreal minExtent, qreal m
if (currentItem && currentItem->rowPos() - position() != highlightRangeStart) {
qreal pos = currentItem->rowPos() - highlightRangeStart;
timeline.reset(data.move);
- if (fixupDuration)
+ if (fixupDuration) {
timeline.move(data.move, -pos, QEasingCurve(QEasingCurve::InOutQuad), fixupDuration/2);
- else
+ } else {
data.move.setValue(-pos);
+ q->viewportMoved();
+ }
vTime = timeline.time();
}
} else if (snapMode != QDeclarativeGridView::NoSnap) {
@@ -760,10 +760,12 @@ void QDeclarativeGridViewPrivate::fixup(AxisData &data, qreal minExtent, qreal m
qreal dist = qAbs(data.move.value() - pos);
if (dist > 0) {
timeline.reset(data.move);
- if (fixupDuration)
+ if (fixupDuration) {
timeline.move(data.move, pos, QEasingCurve(QEasingCurve::InOutQuad), fixupDuration/2);
- else
+ } else {
data.move.setValue(pos);
+ q->viewportMoved();
+ }
vTime = timeline.time();
}
} else {
@@ -1423,6 +1425,17 @@ void QDeclarativeGridView::setSnapMode(SnapMode mode)
}
}
+bool QDeclarativeGridView::event(QEvent *event)
+{
+ Q_D(QDeclarativeGridView);
+ if (event->type() == QEvent::User) {
+ d->layout();
+ return true;
+ }
+
+ return QDeclarativeFlickable::event(event);
+}
+
void QDeclarativeGridView::viewportMoved()
{
Q_D(QDeclarativeGridView);
@@ -1765,7 +1778,7 @@ void QDeclarativeGridView::itemsInserted(int modelIndex, int count)
{
Q_D(QDeclarativeGridView);
if (!d->visibleItems.count() || d->model->count() <= 1) {
- refill();
+ d->scheduleLayout();
d->updateCurrent(qMax(0, qMin(d->currentIndex, d->model->count()-1)));
emit countChanged();
return;
@@ -1795,7 +1808,7 @@ void QDeclarativeGridView::itemsInserted(int modelIndex, int count)
if (d->currentItem)
d->currentItem->index = d->currentIndex;
}
- d->layout();
+ d->scheduleLayout();
emit countChanged();
return;
}
@@ -1825,9 +1838,21 @@ void QDeclarativeGridView::itemsInserted(int modelIndex, int count)
}
}
+ // Update the indexes of the following visible items.
+ for (int i = 0; i < d->visibleItems.count(); ++i) {
+ FxGridItem *listItem = d->visibleItems.at(i);
+ if (listItem->index != -1 && listItem->index >= modelIndex)
+ listItem->index += count;
+ }
+
+ bool addedVisible = false;
QList<FxGridItem*> added;
int i = 0;
while (i < insertCount && rowPos <= to + d->rowSize()*(d->columns - (colPos/d->colSize()))/qreal(d->columns)) {
+ if (!addedVisible) {
+ d->scheduleLayout();
+ addedVisible = true;
+ }
FxGridItem *item = d->createItem(modelIndex + i);
d->visibleItems.insert(index, item);
item->setPosition(colPos, rowPos);
@@ -1848,6 +1873,15 @@ void QDeclarativeGridView::itemsInserted(int modelIndex, int count)
}
}
+ // update visibleIndex
+ d->visibleIndex = 0;
+ for (QList<FxGridItem*>::Iterator it = d->visibleItems.begin(); it != d->visibleItems.end(); ++it) {
+ if ((*it)->index != -1) {
+ d->visibleIndex = (*it)->index;
+ break;
+ }
+ }
+
if (d->currentIndex >= modelIndex) {
// adjust current item index
d->currentIndex += count;
@@ -1856,17 +1890,11 @@ void QDeclarativeGridView::itemsInserted(int modelIndex, int count)
d->currentItem->setPosition(d->colPosAt(d->currentIndex), d->rowPosAt(d->currentIndex));
}
}
- // Update the indexes of the following visible items.
- for (; index < d->visibleItems.count(); ++index) {
- FxGridItem *listItem = d->visibleItems.at(index);
- if (listItem->index != -1)
- listItem->index += count;
- }
// everything is in order now - emit add() signal
for (int j = 0; j < added.count(); ++j)
added.at(j)->attached->emitAdd();
- d->layout();
+
emit countChanged();
}
@@ -1882,8 +1910,10 @@ void QDeclarativeGridView::itemsRemoved(int modelIndex, int count)
FxGridItem *item = *it;
if (item->index == -1 || item->index < modelIndex) {
// already removed, or before removed items
- if (item->index < modelIndex)
+ if (item->index < modelIndex && !removedVisible) {
+ d->scheduleLayout();
removedVisible = true;
+ }
++it;
} else if (item->index >= modelIndex + count) {
// after removed items
@@ -1891,7 +1921,10 @@ void QDeclarativeGridView::itemsRemoved(int modelIndex, int count)
++it;
} else {
// removed item
- removedVisible = true;
+ if (!removedVisible) {
+ d->scheduleLayout();
+ removedVisible = true;
+ }
item->attached->emitRemove();
if (item->attached->delayRemove()) {
item->index = -1;
@@ -1909,6 +1942,7 @@ void QDeclarativeGridView::itemsRemoved(int modelIndex, int count)
d->currentIndex -= count;
if (d->currentItem)
d->currentItem->index -= count;
+ emit currentIndexChanged();
} else if (currentRemoved) {
// current item has been removed.
d->releaseItem(d->currentItem);
@@ -1918,6 +1952,7 @@ void QDeclarativeGridView::itemsRemoved(int modelIndex, int count)
}
// update visibleIndex
+ d->visibleIndex = 0;
for (it = d->visibleItems.begin(); it != d->visibleItems.end(); ++it) {
if ((*it)->index != -1) {
d->visibleIndex = (*it)->index;
@@ -1925,27 +1960,16 @@ void QDeclarativeGridView::itemsRemoved(int modelIndex, int count)
}
}
- if (removedVisible) {
- if (d->visibleItems.isEmpty()) {
- d->visibleIndex = 0;
- d->setPosition(0);
- refill();
- } else {
- // Correct the positioning of the items
- d->scheduleLayout();
- }
+ if (removedVisible && d->visibleItems.isEmpty()) {
+ d->timeline.clear();
+ d->setPosition(0);
+ if (d->model->count() == 0)
+ update();
}
emit countChanged();
}
-void QDeclarativeGridView::layout()
-{
- Q_D(QDeclarativeGridView);
- if (d->layoutScheduled)
- d->layout();
-}
-
void QDeclarativeGridView::destroyRemoved()
{
Q_D(QDeclarativeGridView);
diff --git a/src/declarative/graphicsitems/qdeclarativegridview_p.h b/src/declarative/graphicsitems/qdeclarativegridview_p.h
index 183bb05..8e253e5 100644
--- a/src/declarative/graphicsitems/qdeclarativegridview_p.h
+++ b/src/declarative/graphicsitems/qdeclarativegridview_p.h
@@ -164,6 +164,7 @@ Q_SIGNALS:
void snapModeChanged();
protected:
+ virtual bool event(QEvent *event);
virtual void viewportMoved();
virtual qreal minYExtent() const;
virtual qreal maxYExtent() const;
@@ -181,7 +182,6 @@ private Q_SLOTS:
void destroyRemoved();
void createdItem(int index, QDeclarativeItem *item);
void destroyingItem(QDeclarativeItem *item);
- void layout();
private:
void refill();
diff --git a/src/declarative/graphicsitems/qdeclarativelistview.cpp b/src/declarative/graphicsitems/qdeclarativelistview.cpp
index 6385ddd..007b31b 100644
--- a/src/declarative/graphicsitems/qdeclarativelistview.cpp
+++ b/src/declarative/graphicsitems/qdeclarativelistview.cpp
@@ -158,7 +158,7 @@ public:
, bufferMode(NoBuffer)
, ownModel(false), wrap(false), autoHighlight(true), haveHighlightRange(false)
, correctFlick(true), inFlickCorrection(false), lazyRelease(false)
- , deferredRelease(false), minExtentDirty(true), maxExtentDirty(true)
+ , deferredRelease(false), layoutScheduled(false), minExtentDirty(true), maxExtentDirty(true)
{}
void init();
@@ -414,6 +414,7 @@ public:
}
void refill(qreal from, qreal to, bool doBuffer = false);
+ void scheduleLayout();
void layout();
void updateUnrequestedIndexes();
void updateUnrequestedPositions();
@@ -480,6 +481,7 @@ public:
bool inFlickCorrection : 1;
bool lazyRelease : 1;
bool deferredRelease : 1;
+ bool layoutScheduled : 1;
mutable bool minExtentDirty : 1;
mutable bool maxExtentDirty : 1;
};
@@ -680,9 +682,19 @@ void QDeclarativeListViewPrivate::refill(qreal from, qreal to, bool doBuffer)
lazyRelease = false;
}
+void QDeclarativeListViewPrivate::scheduleLayout()
+{
+ Q_Q(QDeclarativeListView);
+ if (!layoutScheduled) {
+ layoutScheduled = true;
+ QCoreApplication::postEvent(q, new QEvent(QEvent::User), Qt::HighEventPriority);
+ }
+}
+
void QDeclarativeListViewPrivate::layout()
{
Q_Q(QDeclarativeListView);
+ layoutScheduled = false;
updateSections();
if (!visibleItems.isEmpty()) {
int oldEnd = visibleItems.last()->endPosition();
@@ -1082,10 +1094,12 @@ void QDeclarativeListViewPrivate::fixup(AxisData &data, qreal minExtent, qreal m
if (currentItem && currentItem->position() - position() != highlightRangeStart) {
qreal pos = currentItem->position() - highlightRangeStart;
timeline.reset(data.move);
- if (fixupDuration)
+ if (fixupDuration) {
timeline.move(data.move, -pos, QEasingCurve(QEasingCurve::InOutQuad), fixupDuration/2);
- else
+ } else {
data.move.setValue(-pos);
+ q->viewportMoved();
+ }
vTime = timeline.time();
}
} else if (snapMode != QDeclarativeListView::NoSnap) {
@@ -1094,10 +1108,12 @@ void QDeclarativeListViewPrivate::fixup(AxisData &data, qreal minExtent, qreal m
qreal dist = qAbs(data.move + pos);
if (dist > 0) {
timeline.reset(data.move);
- if (fixupDuration)
+ if (fixupDuration) {
timeline.move(data.move, -pos, QEasingCurve(QEasingCurve::InOutQuad), fixupDuration/2);
- else
+ } else {
data.move.setValue(-pos);
+ q->viewportMoved();
+ }
vTime = timeline.time();
}
}
@@ -1167,7 +1183,6 @@ void QDeclarativeListViewPrivate::flick(AxisData &data, qreal minExtent, qreal m
} else {
data.flickTarget = velocity > 0 ? minExtent : maxExtent;
overshootDist = overShoot ? overShootDistance(v, vSize) : 0;
- qDebug() << "boundary" << overshootDist;
}
timeline.reset(data.move);
timeline.accel(data.move, v, accel, maxDistance + overshootDist);
@@ -1946,6 +1961,17 @@ void QDeclarativeListView::setHeader(QDeclarativeComponent *header)
}
}
+bool QDeclarativeListView::event(QEvent *event)
+{
+ Q_D(QDeclarativeListView);
+ if (event->type() == QEvent::User) {
+ d->layout();
+ return true;
+ }
+
+ return QDeclarativeFlickable::event(event);
+}
+
void QDeclarativeListView::viewportMoved()
{
Q_D(QDeclarativeListView);
@@ -2276,7 +2302,7 @@ void QDeclarativeListView::itemsInserted(int modelIndex, int count)
d->updateUnrequestedIndexes();
d->moveReason = QDeclarativeListViewPrivate::Other;
if (!d->visibleItems.count() || d->model->count() <= 1) {
- d->layout();
+ d->scheduleLayout();
d->updateCurrent(qMax(0, qMin(d->currentIndex, d->model->count()-1)));
emit countChanged();
return;
@@ -2307,7 +2333,7 @@ void QDeclarativeListView::itemsInserted(int modelIndex, int count)
if (d->currentItem)
d->currentItem->index = d->currentIndex;
}
- d->layout();
+ d->scheduleLayout();
emit countChanged();
return;
}
@@ -2330,7 +2356,10 @@ void QDeclarativeListView::itemsInserted(int modelIndex, int count)
int i = 0;
int from = d->position() - d->buffer;
for (i = count-1; i >= 0 && pos > from; --i) {
- addedVisible = true;
+ if (!addedVisible) {
+ d->scheduleLayout();
+ addedVisible = true;
+ }
FxListItem *item = d->createItem(modelIndex + i);
d->visibleItems.insert(insertionIdx, item);
pos -= item->size() + d->spacing;
@@ -2357,7 +2386,10 @@ void QDeclarativeListView::itemsInserted(int modelIndex, int count)
int i = 0;
int to = d->buffer+d->position()+d->size()-1;
for (i = 0; i < count && pos <= to; ++i) {
- addedVisible = true;
+ if (!addedVisible) {
+ d->scheduleLayout();
+ addedVisible = true;
+ }
FxListItem *item = d->createItem(modelIndex + i);
d->visibleItems.insert(index, item);
item->setPosition(pos);
@@ -2393,8 +2425,6 @@ void QDeclarativeListView::itemsInserted(int modelIndex, int count)
for (int j = 0; j < added.count(); ++j)
added.at(j)->attached->emitAdd();
- if (addedVisible)
- d->layout();
emit countChanged();
}
@@ -2420,7 +2450,10 @@ void QDeclarativeListView::itemsRemoved(int modelIndex, int count)
++it;
} else {
// removed item
- removedVisible = true;
+ if (!removedVisible) {
+ d->scheduleLayout();
+ removedVisible = true;
+ }
item->attached->emitRemove();
if (item->attached->delayRemove()) {
item->index = -1;
@@ -2445,6 +2478,7 @@ void QDeclarativeListView::itemsRemoved(int modelIndex, int count)
d->currentIndex -= count;
if (d->currentItem)
d->currentItem->index -= count;
+ emit currentIndexChanged();
} else if (d->currentIndex >= modelIndex && d->currentIndex < modelIndex + count) {
// current item has been removed.
d->currentItem->attached->setIsCurrentItem(false);
@@ -2462,20 +2496,13 @@ void QDeclarativeListView::itemsRemoved(int modelIndex, int count)
}
}
- if (removedVisible) {
- if (d->visibleItems.isEmpty()) {
- d->visibleIndex = 0;
- d->visiblePos = d->header ? d->header->size() : 0;
- d->timeline.clear();
- d->setPosition(0);
- if (d->model->count() == 0)
- update();
- else
- refill();
- } else {
- // Correct the positioning of the items
- d->layout();
- }
+ if (removedVisible && d->visibleItems.isEmpty()) {
+ d->visibleIndex = 0;
+ d->visiblePos = d->header ? d->header->size() : 0;
+ d->timeline.clear();
+ d->setPosition(0);
+ if (d->model->count() == 0)
+ update();
}
emit countChanged();
diff --git a/src/declarative/graphicsitems/qdeclarativelistview_p.h b/src/declarative/graphicsitems/qdeclarativelistview_p.h
index d66ac2b..1bf9652 100644
--- a/src/declarative/graphicsitems/qdeclarativelistview_p.h
+++ b/src/declarative/graphicsitems/qdeclarativelistview_p.h
@@ -219,6 +219,7 @@ Q_SIGNALS:
void footerChanged();
protected:
+ virtual bool event(QEvent *event);
virtual void viewportMoved();
virtual qreal minYExtent() const;
virtual qreal maxYExtent() const;
diff --git a/tests/auto/declarative/qdeclarativelistview/tst_qdeclarativelistview.cpp b/tests/auto/declarative/qdeclarativelistview/tst_qdeclarativelistview.cpp
index 75fbbf8..17257ae 100644
--- a/tests/auto/declarative/qdeclarativelistview/tst_qdeclarativelistview.cpp
+++ b/tests/auto/declarative/qdeclarativelistview/tst_qdeclarativelistview.cpp
@@ -925,6 +925,7 @@ void tst_QDeclarativeListView::sections()
// Remove section boundary
model.removeItem(5);
+ QTest::qWait(100);
// New section header created
QDeclarativeItem *item = findItem<QDeclarativeItem>(viewport, "wrapper", 5);
@@ -932,6 +933,7 @@ void tst_QDeclarativeListView::sections()
QCOMPARE(item->height(), 40.0);
model.insertItem(3, "New Item", "0");
+ QTest::qWait(100);
// Section header moved
item = findItem<QDeclarativeItem>(viewport, "wrapper", 5);
@@ -944,6 +946,7 @@ void tst_QDeclarativeListView::sections()
// insert item which will become a section header
model.insertItem(6, "Replace header", "1");
+ QTest::qWait(100);
item = findItem<QDeclarativeItem>(viewport, "wrapper", 6);
QVERIFY(item);