aboutsummaryrefslogtreecommitdiffstats
path: root/src/declarative/items/qquickpathview.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/declarative/items/qquickpathview.cpp')
-rw-r--r--src/declarative/items/qquickpathview.cpp207
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();
}
}