diff options
Diffstat (limited to 'src/declarative/items/qquickpathview.cpp')
-rw-r--r-- | src/declarative/items/qquickpathview.cpp | 207 |
1 files changed, 118 insertions, 89 deletions
diff --git a/src/declarative/items/qquickpathview.cpp b/src/declarative/items/qquickpathview.cpp index 1963307a1e..f262562edf 100644 --- a/src/declarative/items/qquickpathview.cpp +++ b/src/declarative/items/qquickpathview.cpp @@ -106,34 +106,71 @@ void QQuickPathViewPrivate::init() FAST_CONNECT(&tl, SIGNAL(completed()), q, SLOT(movementEnding())) } -QQuickItem *QQuickPathViewPrivate::getItem(int modelIndex, bool onPath) +QQuickItem *QQuickPathViewPrivate::getItem(int modelIndex, qreal z, bool onPath) { Q_Q(QQuickPathView); requestedIndex = modelIndex; + requestedOnPath = onPath; + requestedZ = z; + inRequest = true; QQuickItem *item = model->item(modelIndex, false); if (item) { - if (!attType) { - // pre-create one metatype to share with all attached objects - attType = new QDeclarativeOpenMetaObjectType(&QQuickPathViewAttached::staticMetaObject, qmlEngine(q)); - foreach (const QString &attr, path->attributes()) - attType->createProperty(attr.toUtf8()); - } + QDeclarative_setParent_noEvent(item, q); + item->setParentItem(q); + requestedIndex = -1; qPathViewAttachedType = attType; QQuickPathViewAttached *att = static_cast<QQuickPathViewAttached *>(qmlAttachedPropertiesObject<QQuickPathView>(item)); qPathViewAttachedType = 0; - if (att) { - att->m_view = q; + if (att) att->setOnPath(onPath); - } - QDeclarative_setParent_noEvent(item, q); - item->setParentItem(q); QQuickItemPrivate *itemPrivate = QQuickItemPrivate::get(item); itemPrivate->addItemChangeListener(this, QQuickItemPrivate::Geometry); } - requestedIndex = -1; + inRequest = false; return item; } +void QQuickPathView::createdItem(int index, QQuickItem *item) +{ + Q_D(QQuickPathView); + if (d->requestedIndex != index) { + qPathViewAttachedType = d->attachedType(); + QQuickPathViewAttached *att = static_cast<QQuickPathViewAttached *>(qmlAttachedPropertiesObject<QQuickPathView>(item)); + qPathViewAttachedType = 0; + if (att) { + att->m_view = this; + att->setOnPath(false); + } + item->setParentItem(this); + QDeclarative_setParent_noEvent(item, this); + d->updateItem(item, index < d->firstIndex ? 0.0 : 1.0); + } else { + d->requestedIndex = -1; + if (!d->inRequest) + refill(); + } +} + +void QQuickPathView::initItem(int index, QQuickItem *item) +{ + Q_D(QQuickPathView); + if (d->requestedIndex == index) { + item->setParentItem(this); + qPathViewAttachedType = d->attachedType(); + QQuickPathViewAttached *att = static_cast<QQuickPathViewAttached *>(qmlAttachedPropertiesObject<QQuickPathView>(item)); + qPathViewAttachedType = 0; + if (att) { + att->m_view = this; + qreal percent = d->positionOfIndex(index); + foreach (const QString &attr, d->path->attributes()) + att->setValue(attr.toUtf8(), d->path->attributeAt(attr, percent)); + item->setZ(d->requestedZ); + if (att) + att->setOnPath(d->requestedOnPath); + } + } +} + void QQuickPathViewPrivate::releaseItem(QQuickItem *item) { if (!item || !model) @@ -152,6 +189,19 @@ QQuickPathViewAttached *QQuickPathViewPrivate::attached(QQuickItem *item) return static_cast<QQuickPathViewAttached *>(qmlAttachedPropertiesObject<QQuickPathView>(item, false)); } +QDeclarativeOpenMetaObjectType *QQuickPathViewPrivate::attachedType() +{ + Q_Q(QQuickPathView); + if (!attType) { + // pre-create one metatype to share with all attached objects + attType = new QDeclarativeOpenMetaObjectType(&QQuickPathViewAttached::staticMetaObject, qmlEngine(q)); + foreach (const QString &attr, path->attributes()) + attType->createProperty(attr.toUtf8()); + } + + return attType; +} + void QQuickPathViewPrivate::clear() { if (currentItem) { @@ -493,6 +543,7 @@ void QQuickPathView::setModel(const QVariant &model) disconnect(d->model, SIGNAL(modelUpdated(QDeclarativeChangeSet,bool)), this, SLOT(modelUpdated(QDeclarativeChangeSet,bool))); disconnect(d->model, SIGNAL(createdItem(int,QQuickItem*)), this, SLOT(createdItem(int,QQuickItem*))); + disconnect(d->model, SIGNAL(initItem(int,QQuickItem*)), this, SLOT(initItem(int,QQuickItem*))); for (int i=0; i<d->items.count(); i++){ QQuickItem *p = d->items[i]; d->releaseItem(p); @@ -524,6 +575,7 @@ void QQuickPathView::setModel(const QVariant &model) connect(d->model, SIGNAL(modelUpdated(QDeclarativeChangeSet,bool)), this, SLOT(modelUpdated(QDeclarativeChangeSet,bool))); connect(d->model, SIGNAL(createdItem(int,QQuickItem*)), this, SLOT(createdItem(int,QQuickItem*))); + connect(d->model, SIGNAL(initItem(int,QQuickItem*)), this, SLOT(initItem(int,QQuickItem*))); d->modelCount = d->model->count(); if (d->model->count()) d->offset = qmlMod(d->offset, qreal(d->model->count())); @@ -595,36 +647,28 @@ void QQuickPathView::setCurrentIndex(int idx) Q_D(QQuickPathView); if (d->model && d->modelCount) idx = qAbs(idx % d->modelCount); - if (d->model && idx != d->currentIndex) { + if (d->model && (idx != d->currentIndex || !d->currentItem)) { if (d->currentItem) { if (QQuickPathViewAttached *att = d->attached(d->currentItem)) att->setIsCurrentItem(false); d->releaseItem(d->currentItem); } + int oldCurrentIdx = d->currentIndex; + QQuickItem *oldCurrentItem = d->currentItem; d->currentItem = 0; d->moveReason = QQuickPathViewPrivate::SetIndex; d->currentIndex = idx; if (d->modelCount) { - int itemIndex = (idx - d->firstIndex + d->modelCount) % d->modelCount; - if (itemIndex < d->items.count()) { - d->currentItem = d->model->item(d->currentIndex, true); - d->currentItem->setFocus(true); - if (QQuickPathViewAttached *att = d->attached(d->currentItem)) - att->setIsCurrentItem(true); - } else { - d->currentItem = d->getItem(d->currentIndex, false); - d->updateItem(d->currentItem, d->currentIndex < d->firstIndex ? 0.0 : 1.0); - if (QQuickPathViewAttached *att = d->attached(d->currentItem)) - att->setIsCurrentItem(true); - if (d->model->completePending()) - d->model->completeItem(); - } + d->createCurrentItem(); if (d->haveHighlightRange && d->highlightRangeMode == QQuickPathView::StrictlyEnforceRange) d->snapToCurrent(); d->currentItemOffset = d->positionOfIndex(d->currentIndex); d->updateHighlight(); } - emit currentIndexChanged(); + if (oldCurrentIdx != d->currentIndex) + emit currentIndexChanged(); + if (oldCurrentItem != d->currentItem) + emit currentItemChanged(); } } @@ -1392,6 +1436,7 @@ void QQuickPathView::refill() if (!d->items.count()) d->firstIndex = -1; + bool waiting = false; if (d->modelCount) { // add items to beginning and end int count = d->pathItems == -1 ? d->modelCount : qMin(d->pathItems, d->modelCount); @@ -1406,10 +1451,12 @@ void QQuickPathView::refill() } qreal pos = d->positionOfIndex(idx); while ((pos > startPos || !d->items.count()) && d->items.count() < count) { - // qDebug() << "append" << idx; - QQuickItem *item = d->getItem(idx); - if (d->model->completePending()) - item->setZ(idx+1); +// qDebug() << "append" << idx; + QQuickItem *item = d->getItem(idx, idx+1); + if (!item) { + waiting = true; + break; + } if (d->currentIndex == idx) { currentVisible = true; d->currentItemOffset = pos; @@ -1418,8 +1465,6 @@ void QQuickPathView::refill() d->firstIndex = idx; d->items.append(item); d->updateItem(item, pos); - if (d->model->completePending()) - d->model->completeItem(); ++idx; if (idx >= d->modelCount) idx = 0; @@ -1430,19 +1475,19 @@ void QQuickPathView::refill() if (idx < 0) idx = d->modelCount - 1; pos = d->positionOfIndex(idx); - while ((pos >= 0.0 && pos < startPos) && d->items.count() < count) { - // qDebug() << "prepend" << idx; - QQuickItem *item = d->getItem(idx); - if (d->model->completePending()) - item->setZ(idx+1); + while (!waiting && (pos >= 0.0 && pos < startPos) && d->items.count() < count) { +// qDebug() << "prepend" << idx; + QQuickItem *item = d->getItem(idx, idx+1); + if (!item) { + waiting = true; + break; + } if (d->currentIndex == idx) { currentVisible = true; d->currentItemOffset = pos; } d->items.prepend(item); d->updateItem(item, pos); - if (d->model->completePending()) - d->model->completeItem(); d->firstIndex = idx; idx = d->firstIndex - 1; if (idx < 0) @@ -1457,19 +1502,19 @@ void QQuickPathView::refill() if (d->currentItem) { if (QQuickPathViewAttached *att = d->attached(d->currentItem)) att->setOnPath(false); - } else if (d->currentIndex >= 0 && d->currentIndex < d->modelCount) { - d->currentItem = d->getItem(d->currentIndex, false); - d->updateItem(d->currentItem, d->currentIndex < d->firstIndex ? 0.0 : 1.0); + } else if (!waiting && d->currentIndex >= 0 && d->currentIndex < d->modelCount) { + if (d->currentItem = d->getItem(d->currentIndex, d->currentIndex, false)) { + d->updateItem(d->currentItem, d->currentIndex < d->firstIndex ? 0.0 : 1.0); + if (QQuickPathViewAttached *att = d->attached(d->currentItem)) + att->setIsCurrentItem(true); + } + } + } else if (!waiting && !d->currentItem) { + if (d->currentItem = d->getItem(d->currentIndex, d->currentIndex, true)) { + d->currentItem->setFocus(true); if (QQuickPathViewAttached *att = d->attached(d->currentItem)) att->setIsCurrentItem(true); - if (d->model->completePending()) - d->model->completeItem(); } - } else if (!d->currentItem) { - d->currentItem = d->model->item(d->currentIndex, true); - d->currentItem->setFocus(true); - if (QQuickPathViewAttached *att = d->attached(d->currentItem)) - att->setIsCurrentItem(true); } if (d->highlightItem && d->haveHighlightRange && d->highlightRangeMode == QQuickPathView::StrictlyEnforceRange) { @@ -1582,29 +1627,6 @@ void QQuickPathView::modelUpdated(const QDeclarativeChangeSet &changeSet, bool r emit countChanged(); } -void QQuickPathView::createdItem(int index, QQuickItem *item) -{ - Q_D(QQuickPathView); - if (d->requestedIndex != index) { - if (!d->attType) { - // pre-create one metatype to share with all attached objects - d->attType = new QDeclarativeOpenMetaObjectType(&QQuickPathViewAttached::staticMetaObject, qmlEngine(this)); - foreach (const QString &attr, d->path->attributes()) - d->attType->createProperty(attr.toUtf8()); - } - qPathViewAttachedType = d->attType; - QQuickPathViewAttached *att = static_cast<QQuickPathViewAttached *>(qmlAttachedPropertiesObject<QQuickPathView>(item)); - qPathViewAttachedType = 0; - if (att) { - att->m_view = this; - att->setOnPath(false); - } - QDeclarative_setParent_noEvent(item, this); - item->setParentItem(this); - d->updateItem(item, index < d->firstIndex ? 0.0 : 1.0); - } -} - void QQuickPathView::destroyingItem(QQuickItem *item) { Q_UNUSED(item); @@ -1646,6 +1668,26 @@ int QQuickPathViewPrivate::calcCurrentIndex() return current; } +void QQuickPathViewPrivate::createCurrentItem() +{ + if (requestedIndex != -1) + return; + int itemIndex = (currentIndex - firstIndex + modelCount) % modelCount; + if (itemIndex < items.count()) { + if (currentItem = getItem(currentIndex, currentIndex, true)) { + currentItem->setFocus(true); + if (QQuickPathViewAttached *att = attached(currentItem)) + att->setIsCurrentItem(true); + } + } else if (currentIndex >= 0 && currentIndex < modelCount) { + if (currentItem = getItem(currentIndex, currentIndex, false)) { + updateItem(currentItem, currentIndex < firstIndex ? 0.0 : 1.0); + if (QQuickPathViewAttached *att = attached(currentItem)) + att->setIsCurrentItem(true); + } + } +} + void QQuickPathViewPrivate::updateCurrent() { Q_Q(QQuickPathView); @@ -1663,20 +1705,7 @@ void QQuickPathViewPrivate::updateCurrent() } currentIndex = idx; currentItem = 0; - int itemIndex = (idx - firstIndex + modelCount) % modelCount; - if (itemIndex < items.count()) { - currentItem = model->item(currentIndex, true); - currentItem->setFocus(true); - if (QQuickPathViewAttached *att = attached(currentItem)) - att->setIsCurrentItem(true); - } else if (currentIndex >= 0 && currentIndex < modelCount) { - currentItem = getItem(currentIndex, false); - updateItem(currentItem, currentIndex < firstIndex ? 0.0 : 1.0); - if (QQuickPathViewAttached *att = attached(currentItem)) - att->setIsCurrentItem(true); - if (model->completePending()) - model->completeItem(); - } + createCurrentItem(); emit q->currentIndexChanged(); } } |