src/declarative/graphicsitems/qdeclarativepathview.cpp
changeset 33 3e2da88830cd
parent 30 5dc02b23752f
child 37 758a864f9613
--- a/src/declarative/graphicsitems/qdeclarativepathview.cpp	Tue Jul 06 15:10:48 2010 +0300
+++ b/src/declarative/graphicsitems/qdeclarativepathview.cpp	Wed Aug 18 10:37:55 2010 +0300
@@ -110,6 +110,8 @@
             att->setOnPath(true);
         }
         item->setParentItem(q);
+        QDeclarativeItemPrivate *itemPrivate = static_cast<QDeclarativeItemPrivate*>(QGraphicsItemPrivate::get(item));
+        itemPrivate->addItemChangeListener(this, QDeclarativeItemPrivate::Geometry);
     }
     requestedIndex = -1;
     return item;
@@ -121,6 +123,8 @@
         return;
     if (QDeclarativePathViewAttached *att = attached(item))
         att->setOnPath(false);
+    QDeclarativeItemPrivate *itemPrivate = static_cast<QDeclarativeItemPrivate*>(QGraphicsItemPrivate::get(item));
+    itemPrivate->removeItemChangeListener(this, QDeclarativeItemPrivate::Geometry);
     model->release(item);
 }
 
@@ -280,8 +284,8 @@
             att->setValue(attr.toUtf8(), path->attributeAt(attr, percent));
     }
     QPointF pf = path->pointAt(percent);
-    item->setX(qRound(pf.x() - item->width()*item->scale()/2));
-    item->setY(qRound(pf.y() - item->height()*item->scale()/2));
+    item->setX(qRound(pf.x() - item->width()/2));
+    item->setY(qRound(pf.y() - item->height()/2));
 }
 
 void QDeclarativePathViewPrivate::regenerate()
@@ -306,15 +310,29 @@
     \brief The PathView element lays out model-provided items on a path.
     \inherits Item
 
-    The model is typically provided by a QAbstractListModel "C++ model object", but can also be created directly in QML.
+    A PathView displays data from models created from built-in QML elements like ListModel
+    and XmlListModel, or custom model classes defined in C++ that inherit from
+    QAbstractListModel.
 
+    A ListView has a \l model, which defines the data to be displayed, and
+    a \l delegate, which defines how the data should be displayed.  
     The \l delegate is instantiated for each item on the \l path.
     The items may be flicked to move them along the path.
 
+    For example, if there is a simple list model defined in a file \c ContactModel.qml like this:
+
+    \snippet doc/src/snippets/declarative/pathview/ContactModel.qml 0
+
+    This data can be represented as a PathView, like this:
+
     \snippet doc/src/snippets/declarative/pathview/pathview.qml 0
 
     \image pathview.gif
 
+    (Note the above example uses PathAttribute to scale and modify the
+    opacity of the items as they rotate. This additional code can be seen in the
+    PathAttribute documentation.)
+
     Delegates are instantiated as needed and may be destroyed at any time.
     State should \e never be stored in a delegate.
 
@@ -344,6 +362,13 @@
 }
 
 /*!
+    \qmlattachedproperty PathView PathView::view
+    This attached property holds the view that manages this delegate instance.
+
+    It is attached to each instance of the delegate.
+*/
+
+/*!
     \qmlattachedproperty bool PathView::onPath
     This attached property holds whether the item is currently on the path.
 
@@ -531,6 +556,8 @@
     \qmlmethod PathView::incrementCurrentIndex()
 
     Increments the current index.
+
+    \bold Note: methods should only be called after the Component has completed.
 */
 void QDeclarativePathView::incrementCurrentIndex()
 {
@@ -542,6 +569,8 @@
     \qmlmethod PathView::decrementCurrentIndex()
 
     Decrements the current index.
+
+    \bold Note: methods should only be called after the Component has completed.
 */
 void QDeclarativePathView::decrementCurrentIndex()
 {
@@ -881,6 +910,7 @@
     if (i < 1)
         i = 1;
     d->pathItems = i;
+    d->updateMappedRange();
     if (d->isValid() && isComponentComplete()) {
         d->regenerate();
     }
@@ -944,7 +974,7 @@
 void QDeclarativePathView::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
 {
     Q_D(QDeclarativePathView);
-    if (!d->interactive || d->lastPosTime.isNull())
+    if (!d->interactive || !d->lastPosTime.isValid())
         return;
 
     if (!d->stealMouse) {
@@ -978,7 +1008,7 @@
     Q_D(QDeclarativePathView);
     d->stealMouse = false;
     setKeepMouseGrab(false);
-    if (!d->interactive || d->lastPosTime.isNull())
+    if (!d->interactive || !d->lastPosTime.isValid())
         return;
 
     qreal elapsed = qreal(d->lastElapsed + QDeclarativeItemPrivate::elapsed(d->lastPosTime)) / 1000.;
@@ -1013,7 +1043,7 @@
         d->fixOffset();
     }
 
-    d->lastPosTime = QTime();
+    d->lastPosTime.invalidate();
     ungrabMouse();
 }
 
@@ -1055,8 +1085,8 @@
             grabMouse();
 
         return d->stealMouse;
-    } else if (!d->lastPosTime.isNull()) {
-        d->lastPosTime = QTime();
+    } else if (d->lastPosTime.isValid()) {
+        d->lastPosTime.invalidate();
     }
     return false;
 }
@@ -1084,6 +1114,16 @@
     return QDeclarativeItem::sceneEventFilter(i, e);
 }
 
+bool QDeclarativePathView::event(QEvent *event)
+{
+    if (event->type() == QEvent::User) {
+        refill();
+        return true;
+    }
+
+    return QDeclarativeItem::event(event);
+}
+
 void QDeclarativePathView::componentComplete()
 {
     Q_D(QDeclarativePathView);
@@ -1103,6 +1143,7 @@
     if (!d->isValid() || !isComponentComplete())
         return;
 
+    d->layoutScheduled = false;
     bool currentVisible = false;
 
     // first move existing items and remove items off path