diff options
author | Martin Jones <martin.jones@nokia.com> | 2010-03-08 02:38:17 (GMT) |
---|---|---|
committer | Martin Jones <martin.jones@nokia.com> | 2010-03-08 02:38:17 (GMT) |
commit | 2d3323d239c9d20c98e09c9398931e60bb799cca (patch) | |
tree | b5484d2eb06cfc60759e45f7b8fc82176ab09b07 /src | |
parent | 9bc81769eb6ebc9bd62fe3c1d86e67ddccbed8b6 (diff) | |
download | Qt-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')
3 files changed, 181 insertions, 73 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> diff --git a/src/declarative/graphicsitems/qdeclarativepathview_p.h b/src/declarative/graphicsitems/qdeclarativepathview_p.h index df9c6ae..6dbd044 100644 --- a/src/declarative/graphicsitems/qdeclarativepathview_p.h +++ b/src/declarative/graphicsitems/qdeclarativepathview_p.h @@ -52,6 +52,7 @@ QT_BEGIN_NAMESPACE QT_MODULE(Declarative) class QDeclarativePathViewPrivate; +class QDeclarativePathViewAttached; class Q_DECLARATIVE_EXPORT QDeclarativePathView : public QDeclarativeItem { Q_OBJECT @@ -96,7 +97,7 @@ public: int pathItemCount() const; void setPathItemCount(int); - static QObject *qmlAttachedProperties(QObject *); + static QDeclarativePathViewAttached *qmlAttachedProperties(QObject *); Q_SIGNALS: void currentIndexChanged(); @@ -127,11 +128,57 @@ private Q_SLOTS: private: friend class QDeclarativePathViewAttached; - static QHash<QObject*, QObject*> attachedProperties; Q_DISABLE_COPY(QDeclarativePathView) Q_DECLARE_PRIVATE_D(QGraphicsItem::d_ptr.data(), QDeclarativePathView) }; +class QDeclarativeOpenMetaObject; +class QDeclarativePathViewAttached : public QObject +{ + Q_OBJECT + + Q_PROPERTY(QDeclarativePathView *view READ view CONSTANT) + Q_PROPERTY(bool isCurrentItem READ isCurrentItem NOTIFY currentItemChanged) + Q_PROPERTY(bool onPath READ isOnPath NOTIFY pathChanged) + +public: + QDeclarativePathViewAttached(QObject *parent); + ~QDeclarativePathViewAttached(); + + QDeclarativePathView *view() { return m_view; } + + bool isCurrentItem() const { return m_isCurrent; } + void setIsCurrentItem(bool c) { + if (m_isCurrent != c) { + m_isCurrent = c; + emit currentItemChanged(); + } + } + + QVariant value(const QByteArray &name) const; + void setValue(const QByteArray &name, const QVariant &val); + + bool isOnPath() const { return m_onPath; } + void setOnPath(bool on) { + if (on != m_onPath) { + m_onPath = on; + emit pathChanged(); + } + } + +Q_SIGNALS: + void currentItemChanged(); + void pathChanged(); + +private: + friend class QDeclarativePathViewPrivate; + QDeclarativePathView *m_view; + QDeclarativeOpenMetaObject *m_metaobject; + bool m_onPath : 1; + bool m_isCurrent : 1; +}; + + QT_END_NAMESPACE QML_DECLARE_TYPE(QDeclarativePathView) diff --git a/src/declarative/graphicsitems/qdeclarativepathview_p_p.h b/src/declarative/graphicsitems/qdeclarativepathview_p_p.h index 6344a8a..4083ab5 100644 --- a/src/declarative/graphicsitems/qdeclarativepathview_p_p.h +++ b/src/declarative/graphicsitems/qdeclarativepathview_p_p.h @@ -71,6 +71,8 @@ typedef struct PathViewItem{ QDeclarativeItem* item; }PathViewItem; +class QDeclarativeOpenMetaObjectType; +class QDeclarativePathViewAttached; class QDeclarativePathViewPrivate : public QDeclarativeItemPrivate { Q_DECLARE_PUBLIC(QDeclarativePathView) @@ -81,7 +83,7 @@ public: , lastElapsed(0), stealMouse(false), ownModel(false), activeItem(0) , snapPos(0), dragMargin(0), moveOffset(this, &QDeclarativePathViewPrivate::setOffset) , firstIndex(0), pathItems(-1), pathOffset(0), requestedIndex(-1) - , moveReason(Other) + , moveReason(Other), attType(0) { } @@ -97,6 +99,8 @@ public: QDeclarativeItem *getItem(int modelIndex); void releaseItem(QDeclarativeItem *item); + QDeclarativePathViewAttached *attached(QDeclarativeItem *item); + void clear(); bool isValid() const { return model && model->count() > 0 && model->isValid() && path; @@ -137,6 +141,7 @@ public: QVariant modelVariant; enum MovementReason { Other, Key, Mouse }; MovementReason moveReason; + QDeclarativeOpenMetaObjectType *attType; }; QT_END_NAMESPACE |