summaryrefslogtreecommitdiffstats
path: root/src/declarative/graphicsitems/qdeclarativepathview.cpp
diff options
context:
space:
mode:
authorMartin Jones <martin.jones@nokia.com>2010-03-08 02:38:17 (GMT)
committerMartin Jones <martin.jones@nokia.com>2010-03-08 02:38:17 (GMT)
commit2d3323d239c9d20c98e09c9398931e60bb799cca (patch)
treeb5484d2eb06cfc60759e45f7b8fc82176ab09b07 /src/declarative/graphicsitems/qdeclarativepathview.cpp
parent9bc81769eb6ebc9bd62fe3c1d86e67ddccbed8b6 (diff)
downloadQt-2d3323d239c9d20c98e09c9398931e60bb799cca.zip
Qt-2d3323d239c9d20c98e09c9398931e60bb799cca.tar.gz
Qt-2d3323d239c9d20c98e09c9398931e60bb799cca.tar.bz2
Add PathView.isCurrentIndex and PathView.view attached properties
Adding PathView attached properties to be in line with other views. Task-number: QT-319
Diffstat (limited to 'src/declarative/graphicsitems/qdeclarativepathview.cpp')
-rw-r--r--src/declarative/graphicsitems/qdeclarativepathview.cpp196
1 files changed, 126 insertions, 70 deletions
diff --git a/src/declarative/graphicsitems/qdeclarativepathview.cpp b/src/declarative/graphicsitems/qdeclarativepathview.cpp
index 50aa9ef..cc17157 100644
--- a/src/declarative/graphicsitems/qdeclarativepathview.cpp
+++ b/src/declarative/graphicsitems/qdeclarativepathview.cpp
@@ -44,7 +44,6 @@
#include <qdeclarativestate_p.h>
#include <qdeclarativeopenmetaobject_p.h>
-
#include <QDebug>
#include <QEvent>
#include <qlistmodelinterface_p.h>
@@ -64,48 +63,31 @@ inline qreal qmlMod(qreal x, qreal y)
return fmod(x, y);
}
+static QDeclarativeOpenMetaObjectType *qPathViewAttachedType = 0;
-class QDeclarativePathViewAttached : public QObject
+QDeclarativePathViewAttached::QDeclarativePathViewAttached(QObject *parent)
+: QObject(parent), m_view(0), m_onPath(false), m_isCurrent(false)
{
- Q_OBJECT
-
- Q_PROPERTY(bool onPath READ isOnPath NOTIFY onPathChanged)
-public:
- QDeclarativePathViewAttached(QObject *parent)
- : QObject(parent), mo(new QDeclarativeOpenMetaObject(this)), onPath(false)
- {
- }
-
- ~QDeclarativePathViewAttached()
- {
- QDeclarativePathView::attachedProperties.remove(parent());
- }
-
- QVariant value(const QByteArray &name) const
- {
- return mo->value(name);
- }
- void setValue(const QByteArray &name, const QVariant &val)
- {
- mo->setValue(name, val);
- }
-
- bool isOnPath() const { return onPath; }
- void setOnPath(bool on) {
- if (on != onPath) {
- onPath = on;
- emit onPathChanged();
- }
+ if (qPathViewAttachedType) {
+ m_metaobject = new QDeclarativeOpenMetaObject(this, qPathViewAttachedType);
+ m_metaobject->setCached(true);
+ } else {
+ m_metaobject = new QDeclarativeOpenMetaObject(this);
}
+}
-Q_SIGNALS:
- void onPathChanged();
-
-private:
- QDeclarativeOpenMetaObject *mo;
- bool onPath;
-};
+QDeclarativePathViewAttached::~QDeclarativePathViewAttached()
+{
+}
+QVariant QDeclarativePathViewAttached::value(const QByteArray &name) const
+{
+ return m_metaobject->value(name);
+}
+void QDeclarativePathViewAttached::setValue(const QByteArray &name, const QVariant &val)
+{
+ m_metaobject->setValue(name, val);
+}
QDeclarativeItem *QDeclarativePathViewPrivate::getItem(int modelIndex)
{
@@ -113,8 +95,20 @@ QDeclarativeItem *QDeclarativePathViewPrivate::getItem(int modelIndex)
requestedIndex = modelIndex;
QDeclarativeItem *item = model->item(modelIndex, false);
if (item) {
- if (QObject *obj = QDeclarativePathView::qmlAttachedProperties(item))
- static_cast<QDeclarativePathViewAttached *>(obj)->setOnPath(true);
+ if (!attType) {
+ // pre-create one metatype to share with all attached objects
+ attType = new QDeclarativeOpenMetaObjectType(&QDeclarativePathViewAttached::staticMetaObject, qmlEngine(q));
+ foreach(const QString &attr, path->attributes()) {
+ attType->createProperty(attr.toUtf8());
+ }
+ }
+ qPathViewAttachedType = attType;
+ QDeclarativePathViewAttached *att = static_cast<QDeclarativePathViewAttached *>(qmlAttachedPropertiesObject<QDeclarativePathView>(item));
+ qPathViewAttachedType = 0;
+ if (att) {
+ att->m_view = q;
+ att->setOnPath(true);
+ }
item->setParentItem(q);
}
requestedIndex = -1;
@@ -125,14 +119,26 @@ void QDeclarativePathViewPrivate::releaseItem(QDeclarativeItem *item)
{
if (!item || !model)
return;
- if (QObject *obj = QDeclarativePathView::qmlAttachedProperties(item))
- static_cast<QDeclarativePathViewAttached *>(obj)->setOnPath(false);
- if (model->release(item) == 0) {
- if (QObject *obj = QDeclarativePathView::qmlAttachedProperties(item))
- static_cast<QDeclarativePathViewAttached *>(obj)->setOnPath(false);
+ if (QDeclarativePathViewAttached *att = attached(item))
+ att->setOnPath(false);
+ model->release(item);
+}
+
+QDeclarativePathViewAttached *QDeclarativePathViewPrivate::attached(QDeclarativeItem *item)
+{
+ return static_cast<QDeclarativePathViewAttached *>(qmlAttachedPropertiesObject<QDeclarativePathView>(item, false));
+}
+
+void QDeclarativePathViewPrivate::clear()
+{
+ for (int i=0; i<items.count(); i++){
+ QDeclarativeItem *p = items[i];
+ releaseItem(p);
}
+ items.clear();
}
+
/*!
\qmlclass PathView QDeclarativePathView
\since 4.7
@@ -147,6 +153,11 @@ void QDeclarativePathViewPrivate::releaseItem(QDeclarativeItem *item)
\image pathview.gif
+ Note that views do not enable \e clip automatically. If the view
+ is not clipped by another item or the screen, it will be necessary
+ to set \e {clip: true} in order to have the out of view items clipped
+ nicely.
+
\sa Path
*/
@@ -160,6 +171,9 @@ QDeclarativePathView::QDeclarativePathView(QDeclarativeItem *parent)
QDeclarativePathView::~QDeclarativePathView()
{
Q_D(QDeclarativePathView);
+ d->clear();
+ if (d->attType)
+ d->attType->release();
if (d->ownModel)
delete d->model;
}
@@ -185,6 +199,15 @@ QDeclarativePathView::~QDeclarativePathView()
*/
/*!
+ \qmlattachedproperty bool PathView::isCurrentItem
+ This attached property is true if this delegate is the current item; otherwise false.
+
+ It is attached to each instance of the delegate.
+
+ This property may be used to adjust the appearance of the current item.
+*/
+
+/*!
\qmlproperty model PathView::model
This property holds the model providing data for the view.
@@ -275,8 +298,15 @@ void QDeclarativePathView::setPath(QDeclarativePath *path)
Q_D(QDeclarativePathView);
if (d->path == path)
return;
+ if (d->path)
+ disconnect(d->path, SIGNAL(changed()), this, SLOT(refill()));
d->path = path;
connect(d->path, SIGNAL(changed()), this, SLOT(refill()));
+ d->clear();
+ if (d->attType) {
+ d->attType->release();
+ d->attType = 0;
+ }
d->regenerate();
emit pathChanged();
}
@@ -297,12 +327,25 @@ void QDeclarativePathView::setCurrentIndex(int idx)
if (d->model && d->model->count())
idx = qAbs(idx % d->model->count());
if (d->model && idx != d->currentIndex) {
+ if (d->model->count()) {
+ int itemIndex = (d->currentIndex - d->firstIndex + d->model->count()) % d->model->count();
+ if (itemIndex < d->items.count()) {
+ if (QDeclarativeItem *item = d->items.at(d->currentIndex)) {
+ if (QDeclarativePathViewAttached *att = d->attached(item))
+ att->setIsCurrentItem(false);
+ }
+ }
+ }
d->currentIndex = idx;
if (d->model->count()) {
d->snapToCurrent();
int itemIndex = (idx - d->firstIndex + d->model->count()) % d->model->count();
- if (itemIndex < d->items.count())
- d->items.at(itemIndex)->setFocus(true);
+ if (itemIndex < d->items.count()) {
+ QDeclarativeItem *item = d->items.at(itemIndex);
+ item->setFocus(true);
+ if (QDeclarativePathViewAttached *att = d->attached(item))
+ att->setIsCurrentItem(true);
+ }
}
emit currentIndexChanged();
}
@@ -649,11 +692,7 @@ void QDeclarativePathViewPrivate::regenerate()
if (!q->isComponentComplete())
return;
- for (int i=0; i<items.count(); i++){
- QDeclarativeItem *p = items[i];
- releaseItem(p);
- }
- items.clear();
+ clear();
if (!isValid())
return;
@@ -673,18 +712,25 @@ void QDeclarativePathViewPrivate::regenerate()
}
items.append(item);
item->setZValue(i);
+ qreal percent = i * (100. / numItems) + _offset;
+ percent = qAbs(qmlMod(percent, qreal(100.0))/100.0);
+ updateItem(item, percent);
model->completeItem();
- if (currentIndex == index)
+ if (currentIndex == index) {
item->setFocus(true);
+ if (QDeclarativePathViewAttached *att = attached(item))
+ att->setIsCurrentItem(true);
+ }
}
- q->refill();
+ if (pathItems != -1)
+ q->refill();
}
void QDeclarativePathViewPrivate::updateItem(QDeclarativeItem *item, qreal percent)
{
- if (QObject *obj = QDeclarativePathView::qmlAttachedProperties(item)) {
+ if (QDeclarativePathViewAttached *att = attached(item)) {
foreach(const QString &attr, path->attributes())
- static_cast<QDeclarativePathViewAttached *>(obj)->setValue(attr.toUtf8(), path->attributeAt(attr, percent));
+ att->setValue(attr.toUtf8(), path->attributeAt(attr, percent));
}
QPointF pf = path->pointAt(percent);
item->setX(pf.x() - item->width()*item->scale()/2);
@@ -735,8 +781,11 @@ void QDeclarativePathView::refill()
QDeclarativeItem *item = d->getItem(index);
item->setZValue(wrapIndex);
d->model->completeItem();
- if (d->currentIndex == index)
+ if (d->currentIndex == index) {
item->setFocus(true);
+ if (QDeclarativePathViewAttached *att = d->attached(item))
+ att->setIsCurrentItem(true);
+ }
d->items << item;
d->pathOffset++;
d->pathOffset=d->pathOffset % d->items.count();
@@ -752,8 +801,11 @@ void QDeclarativePathView::refill()
QDeclarativeItem *item = d->getItem(d->firstIndex);
item->setZValue(d->firstIndex);
d->model->completeItem();
- if (d->currentIndex == d->firstIndex)
+ if (d->currentIndex == d->firstIndex) {
item->setFocus(true);
+ if (QDeclarativePathViewAttached *att = d->attached(item))
+ att->setIsCurrentItem(true);
+ }
d->items.prepend(item);
d->pathOffset--;
if (d->pathOffset < 0)
@@ -909,10 +961,21 @@ void QDeclarativePathViewPrivate::updateCurrent()
return;
int idx = calcCurrentIndex();
if (model && idx != currentIndex) {
+ int itemIndex = (currentIndex - firstIndex + model->count()) % model->count();
+ if (itemIndex < items.count()) {
+ if (QDeclarativeItem *item = items.at(itemIndex)) {
+ if (QDeclarativePathViewAttached *att = attached(item))
+ att->setIsCurrentItem(false);
+ }
+ }
currentIndex = idx;
- int itemIndex = (idx - firstIndex + model->count()) % model->count();
- if (itemIndex < items.count())
- items.at(itemIndex)->setFocus(true);
+ itemIndex = (idx - firstIndex + model->count()) % model->count();
+ if (itemIndex < items.count()) {
+ QDeclarativeItem *item = items.at(itemIndex);
+ item->setFocus(true);
+ if (QDeclarativePathViewAttached *att = attached(item))
+ att->setIsCurrentItem(true);
+ }
emit q->currentIndexChanged();
}
}
@@ -993,17 +1056,10 @@ void QDeclarativePathViewPrivate::snapToCurrent()
}
}
-QHash<QObject*, QObject*> QDeclarativePathView::attachedProperties;
-QObject *QDeclarativePathView::qmlAttachedProperties(QObject *obj)
+QDeclarativePathViewAttached *QDeclarativePathView::qmlAttachedProperties(QObject *obj)
{
- QObject *rv = attachedProperties.value(obj);
- if (!rv) {
- rv = new QDeclarativePathViewAttached(obj);
- attachedProperties.insert(obj, rv);
- }
- return rv;
+ return new QDeclarativePathViewAttached(obj);
}
QT_END_NAMESPACE
-#include <qdeclarativepathview.moc>