diff options
author | Martin Jones <martin.jones@nokia.com> | 2009-04-30 07:06:10 (GMT) |
---|---|---|
committer | Martin Jones <martin.jones@nokia.com> | 2009-04-30 07:06:10 (GMT) |
commit | 0b5f394208d5aaf803e2100f2ffe12bdef44a7e8 (patch) | |
tree | df4464b975888b40af0cd6cfc6bc7f8f337e8966 /src/declarative/fx/qfxpathview.cpp | |
parent | 0ee6bf1226f3069f117d0b0b75df14ddf38e75de (diff) | |
download | Qt-0b5f394208d5aaf803e2100f2ffe12bdef44a7e8.zip Qt-0b5f394208d5aaf803e2100f2ffe12bdef44a7e8.tar.gz Qt-0b5f394208d5aaf803e2100f2ffe12bdef44a7e8.tar.bz2 |
Item insertion and removal for PathView.
Not animated at the moment.
Diffstat (limited to 'src/declarative/fx/qfxpathview.cpp')
-rw-r--r-- | src/declarative/fx/qfxpathview.cpp | 166 |
1 files changed, 101 insertions, 65 deletions
diff --git a/src/declarative/fx/qfxpathview.cpp b/src/declarative/fx/qfxpathview.cpp index c0d3ab2..5c24d86 100644 --- a/src/declarative/fx/qfxpathview.cpp +++ b/src/declarative/fx/qfxpathview.cpp @@ -140,28 +140,6 @@ QFxPathView::~QFxPathView() The model provides a set of data that is used to create the items for the view. For large or dynamic datasets the model is usually provided by a C++ model object. - However, models can also be created directly in XML, for example: - \code -<model> - <ListModel> - <Contact> - <portrait>pics/john.png</portrait> - <firstName>John</firstName> - <lastName>Smith</lastName> - </Contact> - <Contact> - <portrait>pics/bill.png</portrait> - <firstName>Bill</firstName> - <lastName>Jones</lastName> - </Contact> - <Contact> - <portrait>pics/jane.png</portrait> - <firstName>Jane</firstName> - <lastName>Doe</lastName> - </Contact> - </ListModel> -</model> - \endcode */ /*! @@ -180,6 +158,10 @@ QVariant QFxPathView::model() const void QFxPathView::setModel(const QVariant &model) { Q_D(QFxPathView); + 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))); + } if (QFxVisualItemModel *m = qvariant_cast<QFxVisualItemModel*>(model)) { if (d->ownModel) { delete d->model; @@ -193,6 +175,12 @@ void QFxPathView::setModel(const QVariant &model) } d->model->setModel(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))); + } + d->firstIndex = 0; + d->pathOffset = 0; d->regenerate(); d->fixOffset(); } @@ -425,6 +413,8 @@ QPointF QFxPathViewPrivate::pointNear(const QPointF &point, qreal *nearPercent) void QFxPathView::mousePressEvent(QGraphicsSceneMouseEvent *event) { Q_D(QFxPathView); + if (!d->items.count()) + return; QPointF scenePoint = mapToScene(event->pos()); int idx = 0; for (; idx < d->items.count(); ++idx) { @@ -576,9 +566,6 @@ bool QFxPathView::mouseFilter(QGraphicsSceneMouseEvent *e) void QFxPathViewPrivate::regenerate() { Q_Q(QFxPathView); - if (!model || model->count() <= 0 || !model->delegate() || !path) - return; - for (int i=0; i<items.count(); i++){ QFxItem *p = items[i]; q->attachedProperties.remove(p); @@ -586,29 +573,23 @@ void QFxPathViewPrivate::regenerate() } items.clear(); - firstIndex = 0; - pathOffset = 0; + if (!model || model->count() <= 0 || !model->delegate() || !path) + return; - int numItems = (pathItems>=0 ? pathItems : model->count()); - qreal minDiff = 1e9; - int minI = -1; - for (int i=0; i<numItems; i++){ - QFxItem *item = model->item(i); + if (firstIndex >= model->count()) + firstIndex = model->count()-1; + if (pathOffset >= model->count()) + pathOffset = model->count()-1; + + 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) return; items.append(item); item->setZ(i); item->setParent(q); - qreal percent = i * (100.0 / (numItems)); - percent /= 100.0; - updateItem(items.last(), percent); - qreal diff = qAbs(percent - snapPos); - if (diff < minDiff){ - minDiff = diff; - minI = i; - } } - q->setCurrentIndex(minI); q->refill(); } @@ -639,10 +620,9 @@ void QFxPathView::refill() positions << qAbs(percent/100.0); } - if (d->pathItems==-1){ - for (int i=0; i<positions.count(); i++){ + if (d->pathItems==-1) { + for (int i=0; i<positions.count(); i++) d->updateItem(d->items.at(i), positions[i]); - } return; } @@ -650,54 +630,110 @@ void QFxPathView::refill() for (int i=0; i<d->items.count(); i++) rotatedPositions << positions[(i + d->pathOffset + d->items.count()) % d->items.count()]; - int firstFind = -1; - int i; - for (i=0; i<d->items.count()-1; i++) - { + int wrapIndex= -1; + for (int i=0; i<d->items.count()-1; i++) { if (rotatedPositions[i] > rotatedPositions[i+1]){ - firstFind = i; + wrapIndex = i; break; } } - if (firstFind!=-1 ){ + if (wrapIndex != -1 ){ //A wraparound has occured - if (firstFind<(d->items.count()/2)){ - while(firstFind-- >= 0){ + if (wrapIndex < d->items.count()/2){ + while(wrapIndex-- >= 0){ QFxItem* p = d->items.takeFirst(); attachedProperties.remove(p); d->model->release(p); d->firstIndex++; - d->firstIndex%=d->model->count(); + d->firstIndex %= d->model->count(); int index = (d->firstIndex + d->items.count())%d->model->count(); d->items << d->model->item(index); - d->items.last()->setZ(i); + d->items.last()->setZ(wrapIndex); d->items.last()->setParent(this); d->pathOffset++; d->pathOffset=d->pathOffset % d->items.count(); } - }else{ - while(firstFind++ < (d->items.count()-1)){ + } else { + while(wrapIndex++ < d->items.count()-1){ QFxItem* p = d->items.takeLast(); attachedProperties.remove(p); d->model->release(p); d->firstIndex--; - if (d->firstIndex<0) + if (d->firstIndex < 0) d->firstIndex = d->model->count() - 1; d->items.prepend(d->model->item(d->firstIndex)); d->items.first()->setZ(d->firstIndex); d->items.first()->setParent(this); d->pathOffset--; - if (d->pathOffset<0) + if (d->pathOffset < 0) d->pathOffset = d->items.count() - 1; } } for (int i=0; i<d->items.count(); i++) rotatedPositions[i] = positions[(i + d->pathOffset + d->items.count()) - % d->items.count()]; + % d->items.count()]; } - for (int i=0; i<d->items.count(); i++){ + for (int i=0; i<d->items.count(); i++) d->updateItem(d->items.at(i), rotatedPositions[i]); +} + +void QFxPathView::itemsInserted(int modelIndex, int count) +{ + //XXX support animated insertion + Q_D(QFxPathView); + if (d->pathItems == -1 || d->items.count() < d->pathItems) { + for (int i = 0; i < count; ++i) { + QFxItem *item = d->model->item(modelIndex + i); + item->setZ(modelIndex + i); + item->setParent(this); + d->items.insert(modelIndex + i, item); + } + refill(); + } else { + //XXX This is pretty heavy handed until we reference count items. + d->regenerate(); } + + // make sure the current item is still at the snap position + int itemIndex = (d->currentIndex - d->firstIndex + d->model->count())%d->model->count(); + itemIndex += d->pathOffset; + itemIndex %= d->items.count(); + qreal targetOffset = fmod(100 + (d->snapPos*100) - 100.0 * itemIndex / d->items.count(), 100); + + if (targetOffset < 0) + targetOffset = 100.0 + targetOffset; + if (targetOffset != d->_offset) + d->moveOffset.setValue(targetOffset); +} + +void QFxPathView::itemsRemoved(int modelIndex, int count) +{ + //XXX support animated removal + Q_D(QFxPathView); + if (d->pathItems == -1) { + for (int i = 0; i < count; ++i) { + QFxItem* p = d->items.takeAt(modelIndex); + attachedProperties.remove(p); + d->model->release(p); + } + d->snapToCurrent(); + refill(); + } else { + d->regenerate(); + } + + // make sure the current item is still at the snap position + if (d->currentIndex >= d->model->count()) + d->currentIndex = d->model->count() - 1; + int itemIndex = (d->currentIndex - d->firstIndex + d->model->count())%d->model->count(); + itemIndex += d->pathOffset; + itemIndex %= d->items.count(); + qreal targetOffset = fmod(100 + (d->snapPos*100) - 100.0 * itemIndex / d->items.count(), 100); + + if (targetOffset < 0) + targetOffset = 100.0 + targetOffset; + if (targetOffset != d->_offset) + d->moveOffset.setValue(targetOffset); } void QFxPathView::ticked() @@ -715,7 +751,7 @@ int QFxPathViewPrivate::calcCurrentIndex() if (_offset < 0) _offset += 100.0; - if (pathItems == -1){ + if (pathItems == -1) { qreal delta = fmod(_offset - snapPos, 100.0); if (delta < 0) delta = 100.0 + delta; @@ -723,7 +759,7 @@ int QFxPathViewPrivate::calcCurrentIndex() if (ii < 0) ii = 0; current = ii; - }else{ + } else { qreal bestDiff=1e9; int bestI=-1; for (int i=0; i<items.count(); i++){ @@ -778,11 +814,11 @@ void QFxPathViewPrivate::snapToCurrent() if (!model || model->count() <= 0) return; - int itemIndex = (currentIndex - firstIndex + model->count())%model->count(); + int itemIndex = (currentIndex - firstIndex + model->count()) % model->count(); //Rounds is the number of times round to make the current item visible int rounds = itemIndex / items.count(); - int otherWayRounds = (model->count() - (itemIndex))/items.count() + 1; + int otherWayRounds = (model->count() - (itemIndex)) / items.count() + 1; if (otherWayRounds < rounds) rounds = -otherWayRounds; @@ -792,7 +828,7 @@ void QFxPathViewPrivate::snapToCurrent() if (targetOffset < 0) targetOffset = 100.0 + targetOffset; - if (targetOffset == _offset && rounds==0) + if (targetOffset == _offset && rounds == 0) return; moveReason = Other; |