From 3f9534dc96eaa2154efe759215466cdbd247664c Mon Sep 17 00:00:00 2001 From: Martin Jones Date: Thu, 7 May 2009 17:24:12 +1000 Subject: Get view to view transitions working properly... for PathView. --- demos/declarative/flickr/flickr2.qml | 46 +++++++++++++----------- src/declarative/fx/qfxpathview.cpp | 59 ++++++++++++++++++++++--------- src/declarative/fx/qfxpathview.h | 2 ++ src/declarative/fx/qfxpathview_p.h | 21 +++++++++-- src/declarative/fx/qfxvisualitemmodel.cpp | 28 ++++++++++++++- src/declarative/fx/qfxvisualitemmodel.h | 7 ++++ 6 files changed, 123 insertions(+), 40 deletions(-) diff --git a/demos/declarative/flickr/flickr2.qml b/demos/declarative/flickr/flickr2.qml index 4875fa4..3b1208c 100644 --- a/demos/declarative/flickr/flickr2.qml +++ b/demos/declarative/flickr/flickr2.qml @@ -143,29 +143,31 @@ Item { ] transitions: [ Transition { - fromState: "*" - toState: "*" + fromState: "left" + toState: "right" SequentialAnimation { SetPropertyAction { target: Wrapper property: "moveToParent" - value: Bounce } ParallelAnimation { NumericAnimation { target: Wrapper - properties: "x" + properties: "x,y" to: 0 - duration: 250 - } - NumericAnimation { - target: Wrapper - properties: "y" - to: 0 - easing: "easeInQuad" - duration: 250 + easing: "easeOutQuad" + duration: 350 } } + } + }, + Transition { + fromState: "right" + toState: "left" + SequentialAnimation { + PauseAnimation { + duration: Math.floor(index/7)*100 + } SetPropertyAction { target: Wrapper property: "moveToParent" @@ -173,13 +175,7 @@ Item { ParallelAnimation { NumericAnimation { target: Wrapper - properties: "x" - to: 0 - duration: 250 - } - NumericAnimation { - target: Wrapper - properties: "y" + properties: "x,y" to: 0 easing: "easeOutQuad" duration: 250 @@ -203,14 +199,20 @@ Item { GridView { id: PhotoGridView; model: MyVisualModel.parts.leftBox cellWidth: 105; cellHeight: 105; x:32; y: 80; width: 800; height: 330; z: 1 + cacheBuffer: 100 } PathView { id: PhotoPathView; model: MyVisualModel.parts.rightBox y: 80; width: 800; height: 330; z: 1 + pathItemCount: 10; snapPosition: 0.001 path: Path { - startX: -50; startY: 40; + startX: -150; startY: 40; + PathPercent { value: 0 } + PathLine { x: -50; y: 40 } + + PathPercent { value: 0.001 } PathAttribute { name: "scale"; value: 1 } PathAttribute { name: "angle"; value: -45 } @@ -232,6 +234,10 @@ Item { PathAttribute { name: "scale"; value: 1 } PathAttribute { name: "angle"; value: -45 } + + PathPercent { value: 0.999 } + PathLine { x: 950; y: 40 } + PathPercent { value: 1.0 } } } diff --git a/src/declarative/fx/qfxpathview.cpp b/src/declarative/fx/qfxpathview.cpp index 715ae5a..2b39d6e 100644 --- a/src/declarative/fx/qfxpathview.cpp +++ b/src/declarative/fx/qfxpathview.cpp @@ -145,7 +145,7 @@ QFxPathView::~QFxPathView() QVariant QFxPathView::model() const { Q_D(const QFxPathView); - return d->model ? d->model->model() : QVariant(); + return d->modelVariant; } void QFxPathView::setModel(const QVariant &model) @@ -154,13 +154,24 @@ void QFxPathView::setModel(const QVariant &model) if (d->model) { disconnect(d->model, SIGNAL(itemsInserted(int,int)), this, SLOT(itemsInserted(int,int))); disconnect(d->model, SIGNAL(itemsRemoved(int,int)), this, SLOT(itemsRemoved(int,int))); + disconnect(d->model, SIGNAL(itemCreated(int, QFxItem*)), this, SLOT(itemCreated(int,QFxItem*))); + for (int i=0; iitems.count(); i++){ + QFxItem *p = d->items[i]; + attachedProperties.remove(p); + d->model->release(p); + } + d->items.clear(); } - if (QFxVisualItemModel *m = qvariant_cast(model)) { + + d->modelVariant = model; + QObject *object = qvariant_cast(model); + QFxVisualItemModel *vim = 0; + if (object && (vim = qobject_cast(object))) { if (d->ownModel) { delete d->model; d->ownModel = false; } - d->model = m; + d->model = vim; } else { if (!d->ownModel) { d->model = new QFxVisualItemModel(qmlContext(this)); @@ -171,6 +182,7 @@ void QFxPathView::setModel(const QVariant &model) if (d->model) { connect(d->model, SIGNAL(itemsInserted(int,int)), this, SLOT(itemsInserted(int,int))); connect(d->model, SIGNAL(itemsRemoved(int,int)), this, SLOT(itemsRemoved(int,int))); + connect(d->model, SIGNAL(itemCreated(int, QFxItem*)), this, SLOT(itemCreated(int,QFxItem*))); } d->firstIndex = 0; d->pathOffset = 0; @@ -550,7 +562,7 @@ void QFxPathViewPrivate::regenerate() } items.clear(); - if (!model || model->count() <= 0 || !model->delegate() || !path) + if (!isValid()) return; if (firstIndex >= model->count()) @@ -560,14 +572,14 @@ void QFxPathViewPrivate::regenerate() int numItems = pathItems >= 0 ? pathItems : model->count(); for (int i=0; i < numItems && i < model->count(); ++i){ - QFxItem *item = model->item((i + firstIndex) % model->count()); - if (!item) + QFxItem *item = getItem((i + firstIndex) % model->count()); + if (!item) { + qWarning() << "PathView: Cannot create item, index" << (i + firstIndex) % model->count(); return; + } items.append(item); item->setZ(i); - item->setParent(q); } - q->refill(); } @@ -577,7 +589,6 @@ void QFxPathViewPrivate::updateItem(QFxItem *item, qreal percent) foreach(const QString &attr, path->attributes()) static_cast(obj)->setValue(attr.toLatin1(), path->attributeAt(attr, percent)); } - QPointF pf = path->pointAt(percent); item->setX(pf.x() - item->width()*item->scale()/2); item->setY(pf.y() - item->height()*item->scale()/2); @@ -586,7 +597,7 @@ void QFxPathViewPrivate::updateItem(QFxItem *item, qreal percent) void QFxPathView::refill() { Q_D(QFxPathView); - if (!d->model || d->model->count() <= 0) + if (!d->isValid()) return; QList positions; @@ -619,28 +630,28 @@ void QFxPathView::refill() if (wrapIndex < d->items.count()/2){ while(wrapIndex-- >= 0){ QFxItem* p = d->items.takeFirst(); + d->updateItem(p, 0.0); attachedProperties.remove(p); d->model->release(p); d->firstIndex++; d->firstIndex %= d->model->count(); int index = (d->firstIndex + d->items.count())%d->model->count(); - d->items << d->model->item(index); + d->items << d->getItem(index); d->items.last()->setZ(wrapIndex); - d->items.last()->setParent(this); d->pathOffset++; d->pathOffset=d->pathOffset % d->items.count(); } } else { while(wrapIndex++ < d->items.count()-1){ QFxItem* p = d->items.takeLast(); + d->updateItem(p, 1.0); attachedProperties.remove(p); d->model->release(p); d->firstIndex--; if (d->firstIndex < 0) d->firstIndex = d->model->count() - 1; - d->items.prepend(d->model->item(d->firstIndex)); + d->items.prepend(d->getItem(d->firstIndex)); d->items.first()->setZ(d->firstIndex); - d->items.first()->setParent(this); d->pathOffset--; if (d->pathOffset < 0) d->pathOffset = d->items.count() - 1; @@ -658,11 +669,12 @@ void QFxPathView::itemsInserted(int modelIndex, int count) { //XXX support animated insertion Q_D(QFxPathView); + if (!d->isValid()) + return; if (d->pathItems == -1) { for (int i = 0; i < count; ++i) { - QFxItem *item = d->model->item(modelIndex + i); + QFxItem *item = d->getItem(modelIndex + i); item->setZ(modelIndex + i); - item->setParent(this); d->items.insert(modelIndex + i, item); } refill(); @@ -687,6 +699,8 @@ void QFxPathView::itemsRemoved(int modelIndex, int count) { //XXX support animated removal Q_D(QFxPathView); + if (!d->isValid()) + return; if (d->pathItems == -1) { for (int i = 0; i < count; ++i) { QFxItem* p = d->items.takeAt(modelIndex); @@ -719,6 +733,19 @@ void QFxPathView::itemsRemoved(int modelIndex, int count) d->moveOffset.setValue(targetOffset); } +void QFxPathView::itemCreated(int index, QFxItem *item) +{ + Q_D(QFxPathView); + if (d->requestedIndex != index) { + item->setItemParent(this); + d->updateItem(item, index < d->firstIndex ? 0.0 : 1.0); + } +} + +void QFxPathView::destroyingItem(QFxItem *item) +{ +} + void QFxPathView::ticked() { Q_D(QFxPathView); diff --git a/src/declarative/fx/qfxpathview.h b/src/declarative/fx/qfxpathview.h index 23f2f07..0e1ac6f 100644 --- a/src/declarative/fx/qfxpathview.h +++ b/src/declarative/fx/qfxpathview.h @@ -115,6 +115,8 @@ private Q_SLOTS: void ticked(); void itemsInserted(int index, int count); void itemsRemoved(int index, int count); + void itemCreated(int index, QFxItem *item); + void destroyingItem(QFxItem *item); protected: QFxPathView(QFxPathViewPrivate &dd, QFxItem *parent); diff --git a/src/declarative/fx/qfxpathview_p.h b/src/declarative/fx/qfxpathview_p.h index a19d778..358daf6 100644 --- a/src/declarative/fx/qfxpathview_p.h +++ b/src/declarative/fx/qfxpathview_p.h @@ -77,7 +77,7 @@ public: : path(0), currentIndex(0), startPc(0), lastDist(0) , lastElapsed(0), stealMouse(false), ownModel(false), activeItem(0) , snapPos(0), dragMargin(0), moveOffset(this, &QFxPathViewPrivate::setOffset) - , firstIndex(0), pathItems(-1), pathOffset(0), model(0) + , firstIndex(0), pathItems(-1), pathOffset(0), requestedIndex(-1), model(0) , moveReason(Other) { fixupOffsetEvent = QmlTimeLineEvent::timeLineEvent(&moveOffset, this); @@ -92,6 +92,20 @@ public: q->connect(&tl, SIGNAL(updated()), q, SLOT(ticked())); } + QFxItem *getItem(int modelIndex) { + Q_Q(QFxPathView); + requestedIndex = modelIndex; + QFxItem *item = model->item(modelIndex); + if (item) + item->setItemParent(q); + requestedIndex = -1; + return item; + } + + bool isValid() const { + return model && model->count() > 0 && model->delegate() && path; + } + int calcCurrentIndex(); void updateCurrent(); void fixOffset(); @@ -108,8 +122,8 @@ public: qreal lastDist; int lastElapsed; qreal _offset; - int stealMouse : 1; - int ownModel : 1; + bool stealMouse : 1; + bool ownModel : 1; QTime lastPosTime; QPointF lastPos; QFxItem *activeItem; @@ -121,6 +135,7 @@ public: int firstIndex; int pathItems; int pathOffset; + int requestedIndex; QList items; QFxVisualItemModel *model; QVariant modelVariant; diff --git a/src/declarative/fx/qfxvisualitemmodel.cpp b/src/declarative/fx/qfxvisualitemmodel.cpp index 7d0d7a5..9428281 100644 --- a/src/declarative/fx/qfxvisualitemmodel.cpp +++ b/src/declarative/fx/qfxvisualitemmodel.cpp @@ -336,6 +336,10 @@ void QFxVisualItemModel::setModel(const QVariant &model) this, SIGNAL(itemsRemoved(int,int))); QObject::disconnect(d->m_visualItemModel, SIGNAL(itemsMoved(int,int,int)), this, SIGNAL(itemsMoved(int,int,int))); + QObject::disconnect(d->m_visualItemModel, SIGNAL(packageCreated(int,QmlPackage*)), + this, SLOT(_q_packageCreated(int,QmlPackage*))); + QObject::disconnect(d->m_visualItemModel, SIGNAL(destroyingPackage(QmlPackage*)), + this, SLOT(_q_destroyingPackage(QmlPackage*))); d->m_visualItemModel = 0; } @@ -385,6 +389,10 @@ void QFxVisualItemModel::setModel(const QVariant &model) this, SIGNAL(itemsRemoved(int,int))); QObject::connect(d->m_visualItemModel, SIGNAL(itemsMoved(int,int,int)), this, SIGNAL(itemsMoved(int,int,int))); + QObject::connect(d->m_visualItemModel, SIGNAL(packageCreated(int,QmlPackage*)), + this, SLOT(_q_packageCreated(int,QmlPackage*))); + QObject::connect(d->m_visualItemModel, SIGNAL(destroyingPackage(QmlPackage*)), + this, SLOT(_q_destroyingPackage(QmlPackage*))); return; } if (!d->m_modelList) @@ -397,6 +405,8 @@ void QFxVisualItemModel::setModel(const QVariant &model) QmlComponent *QFxVisualItemModel::delegate() const { Q_D(const QFxVisualItemModel); + if (d->m_visualItemModel) + return d->m_visualItemModel->delegate(); return d->m_delegate; } @@ -404,7 +414,6 @@ void QFxVisualItemModel::setDelegate(QmlComponent *delegate) { Q_D(QFxVisualItemModel); d->m_delegate = delegate; - if (d->modelCount()) emit itemsInserted(0, d->modelCount()); } @@ -445,6 +454,7 @@ void QFxVisualItemModel::release(QFxItem *item) item->setItemParent(0); QObject *obj = item; + bool inPackage = false; if (QmlPackage *package = d->m_packaged.value(item)) { static_cast(item)->setParent(package); d->m_packaged.remove(item); @@ -454,6 +464,7 @@ void QFxVisualItemModel::release(QFxItem *item) if (*iter == package) return; } + inPackage = true; obj = package; // fall through and delete } @@ -461,6 +472,8 @@ void QFxVisualItemModel::release(QFxItem *item) for (QHash::Iterator iter = d->m_cache.begin(); iter != d->m_cache.end(); ++iter) { if (*iter == obj) { + if (inPackage) + emit destroyingPackage(qobject_cast(obj)); delete obj; d->m_cache.erase(iter); return; @@ -511,6 +524,7 @@ QFxItem *QFxVisualItemModel::item(int index, const QByteArray &viewId, bool comp QObject *o = package->part(QLatin1String(viewId)); item = qobject_cast(o); d->m_packaged[o] = package; + emit packageCreated(index, package); } } @@ -688,6 +702,18 @@ void QFxVisualItemModel::_q_dataChanged(const QModelIndex &begin, const QModelIn _q_itemsChanged(begin.row(), end.row() - begin.row() + 1, d->m_roles); } +void QFxVisualItemModel::_q_packageCreated(int index, QmlPackage *package) +{ + Q_D(QFxVisualItemModel); + emit itemCreated(index, qobject_cast(package->part(d->m_part))); +} + +void QFxVisualItemModel::_q_destroyingPackage(QmlPackage *package) +{ + Q_D(QFxVisualItemModel); + emit destroyingItem(qobject_cast(package->part(d->m_part))); +} + QML_DEFINE_TYPE(QFxVisualItemModel,VisualModel); QT_END_NAMESPACE diff --git a/src/declarative/fx/qfxvisualitemmodel.h b/src/declarative/fx/qfxvisualitemmodel.h index 5ec42e9..33017e2 100644 --- a/src/declarative/fx/qfxvisualitemmodel.h +++ b/src/declarative/fx/qfxvisualitemmodel.h @@ -60,6 +60,7 @@ QT_MODULE(Declarative) class QFxItem; class QmlComponent; +class QmlPackage; class QFxVisualItemModelPrivate; class QFxVisualItemModel : public QObject { @@ -98,6 +99,10 @@ Q_SIGNALS: void itemsInserted(int index, int count); void itemsRemoved(int index, int count); void itemsMoved(int from, int to, int count); + void itemCreated(int index, QFxItem *item); + void packageCreated(int index, QmlPackage *package); + void destroyingItem(QFxItem *item); + void destroyingPackage(QmlPackage *package); private Q_SLOTS: void _q_itemsChanged(int, int, const QList &); @@ -107,6 +112,8 @@ private Q_SLOTS: void _q_rowsInserted(const QModelIndex &,int,int); void _q_rowsRemoved(const QModelIndex &,int,int); void _q_dataChanged(const QModelIndex&,const QModelIndex&); + void _q_packageCreated(int index, QmlPackage *package); + void _q_destroyingPackage(QmlPackage *package); private: Q_DISABLE_COPY(QFxVisualItemModel) -- cgit v0.12