diff options
Diffstat (limited to 'src/declarative/fx/qfxitem.cpp')
-rw-r--r-- | src/declarative/fx/qfxitem.cpp | 172 |
1 files changed, 140 insertions, 32 deletions
diff --git a/src/declarative/fx/qfxitem.cpp b/src/declarative/fx/qfxitem.cpp index 772449e..7938dc9 100644 --- a/src/declarative/fx/qfxitem.cpp +++ b/src/declarative/fx/qfxitem.cpp @@ -299,6 +299,50 @@ void QFxContents::setItem(QFxItem *item) calcWidth(); } +/* + Key filters can be installed on a QFxItem, but not removed. Currently they + are only used by attached objects (which are only destroyed on Item + destruction), so this isn't a problem. If in future this becomes any form + of public API, they will have to support removal too. +*/ +class QFxItemKeyFilter +{ +public: + QFxItemKeyFilter(QFxItem * = 0); + virtual ~QFxItemKeyFilter(); + + virtual void keyPressed(QKeyEvent *event); + virtual void keyReleased(QKeyEvent *event); + +private: + QFxItemKeyFilter *m_next; +}; + +QFxItemKeyFilter::QFxItemKeyFilter(QFxItem *item) +: m_next(0) +{ + QFxItemPrivate *p = + item?static_cast<QFxItemPrivate *>(QGraphicsItemPrivate::get(item)):0; + if (p) { + m_next = p->keyHandler; + p->keyHandler = this; + } +} + +QFxItemKeyFilter::~QFxItemKeyFilter() +{ +} + +void QFxItemKeyFilter::keyPressed(QKeyEvent *event) +{ + if (m_next) m_next->keyPressed(event); +} + +void QFxItemKeyFilter::keyReleased(QKeyEvent *event) +{ + if (m_next) m_next->keyReleased(event); +} + class QFxKeyNavigationAttachedPrivate : public QObjectPrivate { public: @@ -311,7 +355,7 @@ public: QFxItem *down; }; -class QFxKeyNavigationAttached : public QObject +class QFxKeyNavigationAttached : public QObject, public QFxItemKeyFilter { Q_OBJECT Q_DECLARE_PRIVATE(QFxKeyNavigationAttached); @@ -333,10 +377,18 @@ public: void setDown(QFxItem *); static QFxKeyNavigationAttached *qmlAttachedProperties(QObject *); + +signals: + void changed(); + +private: + virtual void keyPressed(QKeyEvent *event); + virtual void keyReleased(QKeyEvent *event); }; QFxKeyNavigationAttached::QFxKeyNavigationAttached(QObject *parent) -: QObject(*(new QFxKeyNavigationAttachedPrivate), parent) +: QObject(*(new QFxKeyNavigationAttachedPrivate), parent), + QFxItemKeyFilter(qobject_cast<QFxItem*>(parent)) { } @@ -356,6 +408,7 @@ void QFxKeyNavigationAttached::setLeft(QFxItem *i) { Q_D(QFxKeyNavigationAttached); d->left = i; + emit changed(); } QFxItem *QFxKeyNavigationAttached::right() const @@ -368,6 +421,7 @@ void QFxKeyNavigationAttached::setRight(QFxItem *i) { Q_D(QFxKeyNavigationAttached); d->right = i; + emit changed(); } QFxItem *QFxKeyNavigationAttached::up() const @@ -380,6 +434,7 @@ void QFxKeyNavigationAttached::setUp(QFxItem *i) { Q_D(QFxKeyNavigationAttached); d->up = i; + emit changed(); } QFxItem *QFxKeyNavigationAttached::down() const @@ -392,6 +447,79 @@ void QFxKeyNavigationAttached::setDown(QFxItem *i) { Q_D(QFxKeyNavigationAttached); d->down = i; + emit changed(); +} + +void QFxKeyNavigationAttached::keyPressed(QKeyEvent *event) +{ + Q_D(QFxKeyNavigationAttached); + + event->ignore(); + + switch(event->key()) { + case Qt::Key_Left: + if (d->left) { + d->left->setFocus(true); + event->accept(); + } + break; + case Qt::Key_Right: + if (d->right) { + d->right->setFocus(true); + event->accept(); + } + break; + case Qt::Key_Up: + if (d->up) { + d->up->setFocus(true); + event->accept(); + } + break; + case Qt::Key_Down: + if (d->down) { + d->down->setFocus(true); + event->accept(); + } + break; + default: + break; + } + + if (!event->isAccepted()) QFxItemKeyFilter::keyPressed(event); +} + +void QFxKeyNavigationAttached::keyReleased(QKeyEvent *event) +{ + Q_D(QFxKeyNavigationAttached); + + event->ignore(); + + switch(event->key()) { + case Qt::Key_Left: + if (d->left) { + event->accept(); + } + break; + case Qt::Key_Right: + if (d->right) { + event->accept(); + } + break; + case Qt::Key_Up: + if (d->up) { + event->accept(); + } + break; + case Qt::Key_Down: + if (d->down) { + event->accept(); + } + break; + default: + break; + } + + if (!event->isAccepted()) QFxItemKeyFilter::keyReleased(event); } /*! @@ -711,7 +839,7 @@ public: bool enabled; }; -class QFxKeysAttached : public QObject +class QFxKeysAttached : public QObject, public QFxItemKeyFilter { Q_OBJECT Q_DECLARE_PRIVATE(QFxKeysAttached); @@ -776,8 +904,8 @@ signals: void volumeDownPressed(QFxKeyEvent *event); private: - void keyPressed(QKeyEvent *event); - void keyReleased(QKeyEvent *event); + virtual void keyPressed(QKeyEvent *event); + virtual void keyReleased(QKeyEvent *event); const char *keyToSignal(int key) { QByteArray keySignal; @@ -799,7 +927,6 @@ private: }; static const SigMap sigMap[]; - friend class QFxItem; }; const QFxKeysAttached::SigMap QFxKeysAttached::sigMap[] = { @@ -838,16 +965,13 @@ bool QFxKeysAttachedPrivate::isConnected(const char *signalName) } QFxKeysAttached::QFxKeysAttached(QObject *parent) -: QObject(*(new QFxKeysAttachedPrivate), parent) +: QObject(*(new QFxKeysAttachedPrivate), parent), + QFxItemKeyFilter(qobject_cast<QFxItem*>(parent)) { - if (QFxItem *item = qobject_cast<QFxItem*>(parent)) - item->setKeyHandler(this); } QFxKeysAttached::~QFxKeysAttached() { - if (QFxItem *item = qobject_cast<QFxItem*>(parent())) - item->setKeyHandler(0); } void QFxKeysAttached::keyPressed(QKeyEvent *event) @@ -872,6 +996,8 @@ void QFxKeysAttached::keyPressed(QKeyEvent *event) if (!ke.isAccepted()) emit pressed(&ke); event->setAccepted(ke.isAccepted()); + + if (!event->isAccepted()) QFxItemKeyFilter::keyPressed(event); } void QFxKeysAttached::keyReleased(QKeyEvent *event) @@ -884,21 +1010,15 @@ void QFxKeysAttached::keyReleased(QKeyEvent *event) QFxKeyEvent ke(*event); emit released(&ke); event->setAccepted(ke.isAccepted()); + + if (!event->isAccepted()) QFxItemKeyFilter::keyReleased(event); } QFxKeysAttached *QFxKeysAttached::qmlAttachedProperties(QObject *obj) { - QFxKeysAttached *rv = 0; - QFxItem *item = qobject_cast<QFxItem*>(obj); - if (item) { - rv = item->keyHandler(); - if (!rv) - rv = new QFxKeysAttached(obj); - } - return rv; + return new QFxKeysAttached(obj); } - /*! \qmlclass Item QFxItem \brief The Item is the most basic of all visual items in QML. @@ -1517,18 +1637,6 @@ void QFxItem::geometryChanged(const QRectF &newGeometry, } } -QFxKeysAttached *QFxItem::keyHandler() -{ - Q_D(QFxItem); - return d->keyHandler; -} - -void QFxItem::setKeyHandler(QFxKeysAttached *handler) -{ - Q_D(QFxItem); - d->keyHandler = handler; -} - /*! \reimp */ |