for (QList<FxViewItem*>::Iterator it = releasePendingTransition.begin();
it != releasePendingTransition.end(); ) {
FxViewItem *item = *it;
- if (item->transitionRunning() || prepareNonVisibleItemTransition(item, viewBounds)) {
+ if (prepareNonVisibleItemTransition(item, viewBounds)) {
++it;
} else {
releaseItem(item);
visibleItems[i]->startTransition(transitioner);
for (int i=0; i<releasePendingTransition.count(); i++)
releasePendingTransition[i]->startTransition(transitioner);
+
transitioner->setPopulateTransitionEnabled(false);
+ transitioner->resetTargetLists();
}
runDelayedRemoveTransition = false;
if (!transitioner)
return;
- transitioner->addTransitionIndexes.clear();
- transitioner->addTransitionTargets.clear();
- transitioner->moveTransitionIndexes.clear();
- transitioner->moveTransitionTargets.clear();
-
+ // must call for every visible item to init or discard transitions
QRectF viewBounds(0, position(), q->width(), q->height());
- for (int i=0; i<visibleItems.count(); i++) {
- // must call for every visible item to init or discard transitions
- if (!visibleItems[i]->prepareTransition(viewBounds))
- continue;
- if (visibleItems[i]->isTransitionTarget) {
- switch (visibleItems[i]->nextTransitionType) {
- case QQuickItemViewTransitioner::NoTransition:
- break;
- case QQuickItemViewTransitioner::PopulateTransition:
- case QQuickItemViewTransitioner::AddTransition:
- transitioner->addTransitionIndexes.append(visibleItems[i]->index);
- transitioner->addTransitionTargets.append(visibleItems[i]->item);
- break;
- case QQuickItemViewTransitioner::MoveTransition:
- transitioner->moveTransitionIndexes.append(visibleItems[i]->index);
- transitioner->moveTransitionTargets.append(visibleItems[i]->item);
- break;
- case QQuickItemViewTransitioner::RemoveTransition:
- // removed targets won't be in visibleItems, handle these
- // in prepareNonVisibleItemTransition()
- break;
- }
- }
- }
+ for (int i=0; i<visibleItems.count(); i++)
+ visibleItems[i]->prepareTransition(transitioner, viewBounds);
}
void QQuickItemViewPrivate::prepareRemoveTransitions(QHash<QQuickChangeSet::MoveKey, FxViewItem *> *removedItems)
if (!transitioner)
return;
- transitioner->removeTransitionIndexes.clear();
- transitioner->removeTransitionTargets.clear();
-
- if (transitioner->canTransition(QQuickItemViewTransitioner::RemoveTransition, true)) {
+ if (transitioner->canTransition(QQuickItemViewTransitioner::RemoveTransition, true)
+ || transitioner->canTransition(QQuickItemViewTransitioner::RemoveTransition, false)) {
for (QHash<QQuickChangeSet::MoveKey, FxViewItem *>::Iterator it = removedItems->begin();
it != removedItems->end(); ) {
bool isRemove = it.key().moveId < 0;
if (item->nextTransitionType == QQuickItemViewTransitioner::MoveTransition)
repositionItemAt(item, item->index, 0);
- if (!item->prepareTransition(viewBounds))
- return false;
- if (item->isTransitionTarget) {
- if (item->nextTransitionType == QQuickItemViewTransitioner::MoveTransition) {
- transitioner->moveTransitionIndexes.append(item->index);
- transitioner->moveTransitionTargets.append(item->item);
- } else if (item->nextTransitionType == QQuickItemViewTransitioner::RemoveTransition) {
- transitioner->removeTransitionIndexes.append(item->index);
- transitioner->removeTransitionTargets.append(item->item);
- }
+ if (item->prepareTransition(transitioner, viewBounds)) {
+ item->releaseAfterTransition = true;
+ return true;
}
-
- item->releaseAfterTransition = true;
- return true;
+ return false;
}
void QQuickItemViewPrivate::viewItemTransitionFinished(QQuickViewItem *i)
bool QQuickItemViewTransitioner::canTransition(QQuickItemViewTransitioner::TransitionType type, bool asTarget) const
{
if (!asTarget
- && type != QQuickItemViewTransitioner::NoTransition && type != QQuickItemViewTransitioner::PopulateTransition
+ && type != NoTransition && type != PopulateTransition
&& displacedTransition && displacedTransition->enabled()) {
return true;
}
switch (type) {
- case QQuickItemViewTransitioner::NoTransition:
+ case NoTransition:
break;
- case QQuickItemViewTransitioner::PopulateTransition:
+ case PopulateTransition:
return usePopulateTransition
&& populateTransition && populateTransition->enabled();
- case QQuickItemViewTransitioner::AddTransition:
+ case AddTransition:
+ if (usePopulateTransition)
+ return false;
if (asTarget)
return addTransition && addTransition->enabled();
else
return addDisplacedTransition && addDisplacedTransition->enabled();
- case QQuickItemViewTransitioner::MoveTransition:
+ case MoveTransition:
if (asTarget)
return moveTransition && moveTransition->enabled();
else
return moveDisplacedTransition && moveDisplacedTransition->enabled();
- case QQuickItemViewTransitioner::RemoveTransition:
+ case RemoveTransition:
if (asTarget)
return removeTransition && removeTransition->enabled();
else
void QQuickItemViewTransitioner::transitionNextReposition(QQuickViewItem *item, QQuickItemViewTransitioner::TransitionType type, bool isTarget)
{
- bool matchedTransition = false;
- if (type == QQuickItemViewTransitioner::AddTransition) {
- // don't run add transitions for added items while populating
- if (usePopulateTransition)
- matchedTransition = false;
- else
- matchedTransition = canTransition(type, isTarget);
- } else {
- matchedTransition = canTransition(type, isTarget);
- }
+ item->setNextTransition(type, isTarget);
+}
- if (matchedTransition) {
- item->setNextTransition(type, isTarget);
- } else {
- // the requested transition type is not valid, but the item is scheduled/in another
- // transition, so cancel it to allow the item to move directly to the correct pos
- if (item->transitionScheduledOrRunning())
- item->stopTransition();
+void QQuickItemViewTransitioner::addToTargetLists(QQuickItemViewTransitioner::TransitionType type, QQuickViewItem *item, int index)
+{
+ switch (type) {
+ case NoTransition:
+ break;
+ case PopulateTransition:
+ case AddTransition:
+ addTransitionIndexes << index;
+ addTransitionTargets << item->item;
+ break;
+ case MoveTransition:
+ moveTransitionIndexes << index;
+ moveTransitionTargets << item->item;
+ break;
+ case RemoveTransition:
+ removeTransitionIndexes << index;
+ removeTransitionTargets << item->item;
+ break;
}
}
+void QQuickItemViewTransitioner::resetTargetLists()
+{
+ addTransitionIndexes.clear();
+ addTransitionTargets.clear();
+
+ removeTransitionIndexes.clear();
+ removeTransitionTargets.clear();
+
+ moveTransitionIndexes.clear();
+ moveTransitionTargets.clear();
+}
+
QQuickTransition *QQuickItemViewTransitioner::transitionObject(QQuickItemViewTransitioner::TransitionType type, bool asTarget)
{
if (type == QQuickItemViewTransitioner::NoTransition)
const QList<int> &QQuickItemViewTransitioner::targetIndexes(QQuickItemViewTransitioner::TransitionType type) const
{
switch (type) {
- case QQuickItemViewTransitioner::NoTransition:
+ case NoTransition:
break;
- case QQuickItemViewTransitioner::PopulateTransition:
- case QQuickItemViewTransitioner::AddTransition:
+ case PopulateTransition:
+ case AddTransition:
return addTransitionIndexes;
- case QQuickItemViewTransitioner::MoveTransition:
+ case MoveTransition:
return moveTransitionIndexes;
- case QQuickItemViewTransitioner::RemoveTransition:
+ case RemoveTransition:
return removeTransitionIndexes;
}
const QList<QObject *> &QQuickItemViewTransitioner::targetItems(QQuickItemViewTransitioner::TransitionType type) const
{
switch (type) {
- case QQuickItemViewTransitioner::NoTransition:
+ case NoTransition:
break;
- case QQuickItemViewTransitioner::PopulateTransition:
- case QQuickItemViewTransitioner::AddTransition:
+ case PopulateTransition:
+ case AddTransition:
return addTransitionTargets;
- case QQuickItemViewTransitioner::MoveTransition:
+ case MoveTransition:
return moveTransitionTargets;
- case QQuickItemViewTransitioner::RemoveTransition:
+ case RemoveTransition:
return removeTransitionTargets;
}
, index(-1)
, isTransitionTarget(false)
, nextTransitionToSet(false)
+ , prepared(false)
{
}
return false;
}
-bool QQuickViewItem::prepareTransition(const QRectF &viewBounds)
+bool QQuickViewItem::prepareTransition(QQuickItemViewTransitioner *transitioner, const QRectF &viewBounds)
{
bool doTransition = false;
}
case QQuickItemViewTransitioner::PopulateTransition:
{
- return true;
+ doTransition = true;
+ break;
}
case QQuickItemViewTransitioner::AddTransition:
case QQuickItemViewTransitioner::RemoveTransition:
break;
}
+ if (doTransition) {
+ // add item to target lists even if canTransition() is false for a target transition,
+ // since the target lists still need to be filled for displaced transitions
+ if (isTransitionTarget)
+ transitioner->addToTargetLists(nextTransitionType, this, index);
+ doTransition = transitioner->canTransition(nextTransitionType, isTransitionTarget);
+ }
+
if (!doTransition) {
+ // if transition type is not valid, the previous transition still has to be
+ // canceled so that the item can move immediately to the right position
if (transition)
transition->cancel();
item->setPos(nextTransitionTo);
resetTransitionData();
}
+
+ prepared = true;
return doTransition;
}
if (nextTransitionType == QQuickItemViewTransitioner::NoTransition)
return;
+ if (!prepared) {
+ qWarning("QQuickViewItem::prepareTransition() not called!");
+ return;
+ }
+
if (!transition || transition->m_type != nextTransitionType || transition->m_isTarget != isTransitionTarget) {
delete transition;
transition = new QQuickItemViewTransitionJob;
transition->startTransition(this, transitioner, nextTransitionType, nextTransitionTo, isTransitionTarget);
nextTransitionType = QQuickItemViewTransitioner::NoTransition;
-}
-
-void QQuickViewItem::stopTransition()
-{
- if (transition) {
- transition->cancel();
- delete transition;
- transition = 0;
- }
- resetTransitionData();
- finishedTransition();
+ prepared = false;
}
void QQuickViewItem::setNextTransition(QQuickItemViewTransitioner::TransitionType type, bool isTargetItem)
bool canTransition(QQuickItemViewTransitioner::TransitionType type, bool asTarget) const;
void transitionNextReposition(QQuickViewItem *item, QQuickItemViewTransitioner::TransitionType type, bool isTarget);
+ void addToTargetLists(QQuickItemViewTransitioner::TransitionType type, QQuickViewItem *item, int index);
+ void resetTargetLists();
+
QQuickTransition *transitionObject(QQuickItemViewTransitioner::TransitionType type, bool asTarget);
const QList<int> &targetIndexes(QQuickItemViewTransitioner::TransitionType type) const;
const QList<QObject *> &targetItems(QQuickItemViewTransitioner::TransitionType type) const;
bool transitionRunning() const;
bool isPendingRemoval() const;
- bool prepareTransition(const QRectF &viewBounds);
+ bool prepareTransition(QQuickItemViewTransitioner *transitioner, const QRectF &viewBounds);
void startTransition(QQuickItemViewTransitioner *transitioner);
- void stopTransition();
QPointF nextTransitionTo;
QQuickItem *item;
int index;
bool isTransitionTarget;
bool nextTransitionToSet;
+ bool prepared;
private:
friend class QQuickItemViewTransitioner;
if (addedIndex < 0)
addedIndex = posItem.index;
PositionedItem *theItem = &positionedItems[positionedItems.count()-1];
-
d->transitioner->transitionNextReposition(theItem,
QQuickItemViewTransitioner::AddTransition, true);
- d->transitioner->addTransitionIndexes << posItem.index;
- d->transitioner->addTransitionTargets << posItem.item;
}
}
} else {
addedIndex = item->index;
d->transitioner->transitionNextReposition(&positionedItems[positionedItems.count()-1],
QQuickItemViewTransitioner::AddTransition, true);
- d->transitioner->addTransitionIndexes << item->index;
- d->transitioner->addTransitionTargets << item->item;
}
} else {
item->isNew = false;
if (d->transitioner) {
QRectF viewBounds;
- for (int i=0; i<positionedItems.count(); i++) {
- if (positionedItems[i].prepareTransition(viewBounds))
- positionedItems[i].startTransition(d->transitioner);
- }
- d->transitioner->addTransitionIndexes.clear();
- d->transitioner->addTransitionTargets.clear();
+ for (int i=0; i<positionedItems.count(); i++)
+ positionedItems[i].prepareTransition(d->transitioner, viewBounds);
+ for (int i=0; i<positionedItems.count(); i++)
+ positionedItems[i].startTransition(d->transitioner);
+ d->transitioner->resetTargetLists();
}
d->doingPositioning = false;
text: number
}
color: GridView.isCurrentItem ? "lightsteelblue" : "white"
+ border.width: 1
onXChanged: checkPos()
onYChanged: checkPos()
property int targetTransitionsDone
property int displaceTransitionsDone
+ property var displacedTargetIndexes: new Array()
+ property var displacedTargetItems: new Array()
+
+ // for QDeclarativeListProperty types
+ function copyList(propList) {
+ var temp = new Array()
+ for (var i=0; i<propList.length; i++)
+ temp.push(propList[i])
+ return temp
+ }
+
objectName: "grid"
focus: true
anchors.centerIn: parent
id: displaced
enabled: displacedEnabled
SequentialAnimation {
+ ScriptAction {
+ script: {
+ grid.displacedTargetIndexes.push(displaced.ViewTransition.targetIndexes)
+ grid.displacedTargetItems.push(grid.copyList(displaced.ViewTransition.targetItems))
+ }
+ }
ParallelAnimation {
NumberAnimation { properties: "x"; to: displaced_transitionVia.x; duration: root.duration }
NumberAnimation { properties: "y"; to: displaced_transitionVia.y; duration: root.duration }
id: addDisplaced
enabled: addDisplacedEnabled
SequentialAnimation {
+ ScriptAction {
+ script: {
+ grid.displacedTargetIndexes.push(addDisplaced.ViewTransition.targetIndexes)
+ grid.displacedTargetItems.push(grid.copyList(addDisplaced.ViewTransition.targetItems))
+ }
+ }
ParallelAnimation {
NumberAnimation { properties: "x"; to: addDisplaced_transitionVia.x; duration: root.duration }
NumberAnimation { properties: "y"; to: addDisplaced_transitionVia.y; duration: root.duration }
id: moveDisplaced
enabled: moveDisplacedEnabled
SequentialAnimation {
+ ScriptAction {
+ script: {
+ grid.displacedTargetIndexes.push(moveDisplaced.ViewTransition.targetIndexes)
+ grid.displacedTargetItems.push(grid.copyList(moveDisplaced.ViewTransition.targetItems))
+ }
+ }
ParallelAnimation {
NumberAnimation { properties: "x"; to: moveDisplaced_transitionVia.x; duration: root.duration }
NumberAnimation { properties: "y"; to: moveDisplaced_transitionVia.y; duration: root.duration }
id: removeDisplaced
enabled: removeDisplacedEnabled
SequentialAnimation {
+ ScriptAction {
+ script: {
+ grid.displacedTargetIndexes.push(removeDisplaced.ViewTransition.targetIndexes)
+ grid.displacedTargetItems.push(grid.copyList(removeDisplaced.ViewTransition.targetItems))
+ }
+ }
ParallelAnimation {
NumberAnimation { properties: "x"; to: removeDisplaced_transitionVia.x; duration: root.duration }
NumberAnimation { properties: "y"; to: removeDisplaced_transitionVia.y; duration: root.duration }
case ListChange::SetContentY:
break;
}
+
+ QVariantList resultTargetIndexes = gridview->property("displacedTargetIndexes").toList();
+ QVariantList resultTargetItems = gridview->property("displacedTargetItems").toList();
+
if ((useDisplaced && displacedEnabled)
|| (useAddDisplaced && addDisplacedEnabled)
|| (useMoveDisplaced && moveDisplacedEnabled)
|| (useRemoveDisplaced && removeDisplacedEnabled)) {
QTRY_VERIFY(gridview->property("displaceTransitionsDone").toBool());
+
+ // check the correct number of target items and indexes were received
+ QCOMPARE(resultTargetIndexes.count(), expectedDisplacedIndexes.count());
+ for (int i=0; i<resultTargetIndexes.count(); i++)
+ QCOMPARE(resultTargetIndexes[i].value<QList<int> >().count(), change.count);
+ QCOMPARE(resultTargetItems.count(), expectedDisplacedIndexes.count());
+ for (int i=0; i<resultTargetItems.count(); i++)
+ QCOMPARE(resultTargetItems[i].toList().count(), change.count);
+ } else {
+ QCOMPARE(resultTargetIndexes.count(), 0);
+ QCOMPARE(resultTargetItems.count(), 0);
}
if (change.type == ListChange::Inserted && useAddDisplaced && addDisplacedEnabled)
property int targetTransitionsDone
property int displaceTransitionsDone
+ property var displacedTargetIndexes: new Array()
+ property var displacedTargetItems: new Array()
+
+ // for QDeclarativeListProperty types
+ function copyList(propList) {
+ var temp = new Array()
+ for (var i=0; i<propList.length; i++)
+ temp.push(propList[i])
+ return temp
+ }
+
objectName: "list"
focus: true
anchors.centerIn: parent
id: displaced
enabled: displacedEnabled
SequentialAnimation {
+ ScriptAction {
+ script: {
+ list.displacedTargetIndexes.push(displaced.ViewTransition.targetIndexes)
+ list.displacedTargetItems.push(list.copyList(displaced.ViewTransition.targetItems))
+ }
+ }
ParallelAnimation {
NumberAnimation { properties: "x"; to: displaced_transitionVia.x; duration: root.duration }
NumberAnimation { properties: "y"; to: displaced_transitionVia.y; duration: root.duration }
id: addDisplaced
enabled: addDisplacedEnabled
SequentialAnimation {
+ ScriptAction {
+ script: {
+ list.displacedTargetIndexes.push(addDisplaced.ViewTransition.targetIndexes)
+ list.displacedTargetItems.push(list.copyList(addDisplaced.ViewTransition.targetItems))
+ }
+ }
ParallelAnimation {
NumberAnimation { properties: "x"; to: addDisplaced_transitionVia.x; duration: root.duration }
NumberAnimation { properties: "y"; to: addDisplaced_transitionVia.y; duration: root.duration }
id: moveDisplaced
enabled: moveDisplacedEnabled
SequentialAnimation {
+ ScriptAction {
+ script: {
+ list.displacedTargetIndexes.push(moveDisplaced.ViewTransition.targetIndexes)
+ list.displacedTargetItems.push(list.copyList(moveDisplaced.ViewTransition.targetItems))
+ }
+ }
ParallelAnimation {
NumberAnimation { properties: "x"; to: moveDisplaced_transitionVia.x; duration: root.duration }
NumberAnimation { properties: "y"; to: moveDisplaced_transitionVia.y; duration: root.duration }
id: removeDisplaced
enabled: removeDisplacedEnabled
SequentialAnimation {
+ ScriptAction {
+ script: {
+ list.displacedTargetIndexes.push(removeDisplaced.ViewTransition.targetIndexes)
+ list.displacedTargetItems.push(list.copyList(removeDisplaced.ViewTransition.targetItems))
+ }
+ }
ParallelAnimation {
NumberAnimation { properties: "x"; to: removeDisplaced_transitionVia.x; duration: root.duration }
NumberAnimation { properties: "y"; to: removeDisplaced_transitionVia.y; duration: root.duration }
case ListChange::SetContentY:
break;
}
+
+ QVariantList resultTargetIndexes = listview->property("displacedTargetIndexes").toList();
+ QVariantList resultTargetItems = listview->property("displacedTargetItems").toList();
+
if ((useDisplaced && displacedEnabled)
|| (useAddDisplaced && addDisplacedEnabled)
|| (useMoveDisplaced && moveDisplacedEnabled)
|| (useRemoveDisplaced && removeDisplacedEnabled)) {
QTRY_VERIFY(listview->property("displaceTransitionsDone").toBool());
+
+ // check the correct number of target items and indexes were received
+ QCOMPARE(resultTargetIndexes.count(), expectedDisplacedIndexes.count());
+ for (int i=0; i<resultTargetIndexes.count(); i++)
+ QCOMPARE(resultTargetIndexes[i].value<QList<int> >().count(), change.count);
+ QCOMPARE(resultTargetItems.count(), expectedDisplacedIndexes.count());
+ for (int i=0; i<resultTargetItems.count(); i++)
+ QCOMPARE(resultTargetItems[i].toList().count(), change.count);
+ } else {
+ QCOMPARE(resultTargetIndexes.count(), 0);
+ QCOMPARE(resultTargetItems.count(), 0);
}
if (change.type == ListChange::Inserted && useAddDisplaced && addDisplacedEnabled)