summaryrefslogtreecommitdiffstats
path: root/src/declarative/fx/qfxitem.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/declarative/fx/qfxitem.cpp')
-rw-r--r--src/declarative/fx/qfxitem.cpp576
1 files changed, 533 insertions, 43 deletions
diff --git a/src/declarative/fx/qfxitem.cpp b/src/declarative/fx/qfxitem.cpp
index b36e994..cae5c72 100644
--- a/src/declarative/fx/qfxitem.cpp
+++ b/src/declarative/fx/qfxitem.cpp
@@ -51,6 +51,7 @@
#include <QtGui/qgraphicstransform.h>
#include <QtDeclarative/qmlengine.h>
+#include <QtDeclarative/qmlopenmetaobject.h>
#include "qmlstate.h"
#include "qlistmodelinterface.h"
@@ -219,6 +220,517 @@ void QFxContents::setItem(QFxItem *item)
}
/*!
+ \qmlclass Keys
+ \brief The Keys attached property provides key handling to Items.
+
+ All visual primitives support key handling via the \e Keys
+ attached property. Keys can be handled via the \e onPressed
+ and \e onReleased signal properties.
+
+ The signal properties have a \l KeyEvent parameter, named
+ \e event which contains details of the event. If a key is
+ handled \e event.accepted should be set to true to prevent the
+ event from propagating up the item heirarchy.
+
+ \code
+ Item {
+ focus: true
+ Keys.onPressed: {
+ if (event.key == Qt.Key_Left) {
+ print("move left");
+ event.accepted = true;
+ }
+ }
+ }
+ \endcode
+
+ Some keys may alternatively be handled via specific signal properties,
+ for example \e onSelectPressed. These handlers automatically set
+ \e event.accepted to true.
+
+ \code
+ Item {
+ focus: true
+ key.onLeftPressed: print("move left")
+ }
+ \endcode
+
+ See \l {Qt::Key}{Qt.Key} for the list of keyboard codes.
+
+ \sa KeyEvent
+*/
+
+/*!
+ \qmlproperty bool Keys::enabled
+
+ This flags enables key handling if true (default); otherwise
+ no key handlers will be called.
+*/
+
+/*!
+ \qmlsignal Keys::onPressed(event)
+
+ This handler is called when a key has been pressed. The \a event
+ parameter provides information about the event.
+*/
+
+/*!
+ \qmlsignal Keys::onReleased(event)
+
+ This handler is called when a key has been released. The \a event
+ parameter provides information about the event.
+*/
+
+/*!
+ \qmlsignal Keys::onDigit0Pressed(event)
+
+ This handler is called when the digit '0' has been pressed. The \a event
+ parameter provides information about the event.
+*/
+
+/*!
+ \qmlsignal Keys::onDigit1Pressed(event)
+
+ This handler is called when the digit '1' has been pressed. The \a event
+ parameter provides information about the event.
+*/
+
+/*!
+ \qmlsignal Keys::onDigit2Pressed(event)
+
+ This handler is called when the digit '2' has been pressed. The \a event
+ parameter provides information about the event.
+*/
+
+/*!
+ \qmlsignal Keys::onDigit3Pressed(event)
+
+ This handler is called when the digit '3' has been pressed. The \a event
+ parameter provides information about the event.
+*/
+
+/*!
+ \qmlsignal Keys::onDigit4Pressed(event)
+
+ This handler is called when the digit '4' has been pressed. The \a event
+ parameter provides information about the event.
+*/
+
+/*!
+ \qmlsignal Keys::onDigit5Pressed(event)
+
+ This handler is called when the digit '5' has been pressed. The \a event
+ parameter provides information about the event.
+*/
+
+/*!
+ \qmlsignal Keys::onDigit6Pressed(event)
+
+ This handler is called when the digit '6' has been pressed. The \a event
+ parameter provides information about the event.
+*/
+
+/*!
+ \qmlsignal Keys::onDigit7Pressed(event)
+
+ This handler is called when the digit '7' has been pressed. The \a event
+ parameter provides information about the event.
+*/
+
+/*!
+ \qmlsignal Keys::onDigit8Pressed(event)
+
+ This handler is called when the digit '8' has been pressed. The \a event
+ parameter provides information about the event.
+*/
+
+/*!
+ \qmlsignal Keys::onDigit9Pressed(event)
+
+ This handler is called when the digit '9' has been pressed. The \a event
+ parameter provides information about the event.
+*/
+
+/*!
+ \qmlsignal Keys::onLeftPressed(event)
+
+ This handler is called when the Left arrow has been pressed. The \a event
+ parameter provides information about the event.
+*/
+
+/*!
+ \qmlsignal Keys::onRightPressed(event)
+
+ This handler is called when the Right arrow has been pressed. The \a event
+ parameter provides information about the event.
+*/
+
+/*!
+ \qmlsignal Keys::onUpPressed(event)
+
+ This handler is called when the Up arrow has been pressed. The \a event
+ parameter provides information about the event.
+*/
+
+/*!
+ \qmlsignal Keys::onDownPressed(event)
+
+ This handler is called when the Down arrow has been pressed. The \a event
+ parameter provides information about the event.
+*/
+
+/*!
+ \qmlsignal Keys::onAsteriskPressed(event)
+
+ This handler is called when the Asterisk '*' has been pressed. The \a event
+ parameter provides information about the event.
+*/
+
+/*!
+ \qmlsignal Keys::onEscapePressed(event)
+
+ This handler is called when the Escape key has been pressed. The \a event
+ parameter provides information about the event.
+*/
+
+/*!
+ \qmlsignal Keys::onReturnPressed(event)
+
+ This handler is called when the Return key has been pressed. The \a event
+ parameter provides information about the event.
+*/
+
+/*!
+ \qmlsignal Keys::onEnterPressed(event)
+
+ This handler is called when the Enter key has been pressed. The \a event
+ parameter provides information about the event.
+*/
+
+/*!
+ \qmlsignal Keys::onDeletePressed(event)
+
+ This handler is called when the Delete key has been pressed. The \a event
+ parameter provides information about the event.
+*/
+
+/*!
+ \qmlsignal Keys::onSpacePressed(event)
+
+ This handler is called when the Space key has been pressed. The \a event
+ parameter provides information about the event.
+*/
+
+/*!
+ \qmlsignal Keys::onBackPressed(event)
+
+ This handler is called when the Back key has been pressed. The \a event
+ parameter provides information about the event.
+*/
+
+/*!
+ \qmlsignal Keys::onCancelPressed(event)
+
+ This handler is called when the Cancel key has been pressed. The \a event
+ parameter provides information about the event.
+*/
+
+/*!
+ \qmlsignal Keys::onSelectPressed(event)
+
+ This handler is called when the Select key has been pressed. The \a event
+ parameter provides information about the event.
+*/
+
+/*!
+ \qmlsignal Keys::onYesPressed(event)
+
+ This handler is called when the Yes key has been pressed. The \a event
+ parameter provides information about the event.
+*/
+
+/*!
+ \qmlsignal Keys::onNoPressed(event)
+
+ This handler is called when the No key has been pressed. The \a event
+ parameter provides information about the event.
+*/
+
+/*!
+ \qmlsignal Keys::onContext1Pressed(event)
+
+ This handler is called when the Context1 key has been pressed. The \a event
+ parameter provides information about the event.
+*/
+
+/*!
+ \qmlsignal Keys::onContext2Pressed(event)
+
+ This handler is called when the Context2 key has been pressed. The \a event
+ parameter provides information about the event.
+*/
+
+/*!
+ \qmlsignal Keys::onContext3Pressed(event)
+
+ This handler is called when the Context3 key has been pressed. The \a event
+ parameter provides information about the event.
+*/
+
+/*!
+ \qmlsignal Keys::onContext4Pressed(event)
+
+ This handler is called when the Context4 key has been pressed. The \a event
+ parameter provides information about the event.
+*/
+
+/*!
+ \qmlsignal Keys::onCallPressed(event)
+
+ This handler is called when the Call key has been pressed. The \a event
+ parameter provides information about the event.
+*/
+
+/*!
+ \qmlsignal Keys::onHangupPressed(event)
+
+ This handler is called when the Hangup key has been pressed. The \a event
+ parameter provides information about the event.
+*/
+
+/*!
+ \qmlsignal Keys::onFlipPressed(event)
+
+ This handler is called when the Flip key has been pressed. The \a event
+ parameter provides information about the event.
+*/
+
+/*!
+ \qmlsignal Keys::onMenuPressed(event)
+
+ This handler is called when the Menu key has been pressed. The \a event
+ parameter provides information about the event.
+*/
+
+/*!
+ \qmlsignal Keys::onVolumeUpPressed(event)
+
+ This handler is called when the VolumeUp key has been pressed. The \a event
+ parameter provides information about the event.
+*/
+
+/*!
+ \qmlsignal Keys::onVolumeDownPressed(event)
+
+ This handler is called when the VolumeDown key has been pressed. The \a event
+ parameter provides information about the event.
+*/
+
+class QFxKeysAttachedPrivate : public QObjectPrivate
+{
+public:
+ QFxKeysAttachedPrivate() : QObjectPrivate(), enabled(true) {}
+
+ bool isConnected(int idx);
+
+ bool enabled;
+};
+
+class QFxKeysAttached : public QObject
+{
+ Q_OBJECT
+ Q_DECLARE_PRIVATE(QFxKeysAttached);
+
+ Q_PROPERTY(bool enabled READ enabled WRITE setEnabled NOTIFY enabledChanged)
+public:
+ QFxKeysAttached(QObject *parent=0);
+ ~QFxKeysAttached();
+
+ bool enabled() const { Q_D(const QFxKeysAttached); return d->enabled; }
+ void setEnabled(bool enabled) {
+ Q_D(QFxKeysAttached);
+ if (enabled != d->enabled) {
+ d->enabled = enabled;
+ emit enabledChanged();
+ }
+ }
+
+ static QFxKeysAttached *qmlAttachedProperties(QObject *);
+
+signals:
+ void enabledChanged();
+ void pressed(QFxKeyEvent *event);
+ void released(QFxKeyEvent *event);
+ void digit0Pressed(QFxKeyEvent *event);
+ void digit1Pressed(QFxKeyEvent *event);
+ void digit2Pressed(QFxKeyEvent *event);
+ void digit3Pressed(QFxKeyEvent *event);
+ void digit4Pressed(QFxKeyEvent *event);
+ void digit5Pressed(QFxKeyEvent *event);
+ void digit6Pressed(QFxKeyEvent *event);
+ void digit7Pressed(QFxKeyEvent *event);
+ void digit8Pressed(QFxKeyEvent *event);
+ void digit9Pressed(QFxKeyEvent *event);
+
+ void leftPressed(QFxKeyEvent *event);
+ void rightPressed(QFxKeyEvent *event);
+ void upPressed(QFxKeyEvent *event);
+ void downPressed(QFxKeyEvent *event);
+
+ void asteriskPressed(QFxKeyEvent *event);
+ void escapePressed(QFxKeyEvent *event);
+ void returnPressed(QFxKeyEvent *event);
+ void enterPressed(QFxKeyEvent *event);
+ void deletePressed(QFxKeyEvent *event);
+ void spacePressed(QFxKeyEvent *event);
+ void backPressed(QFxKeyEvent *event);
+ void cancelPressed(QFxKeyEvent *event);
+ void selectPressed(QFxKeyEvent *event);
+ void yesPressed(QFxKeyEvent *event);
+ void noPressed(QFxKeyEvent *event);
+ void context1Pressed(QFxKeyEvent *event);
+ void context2Pressed(QFxKeyEvent *event);
+ void context3Pressed(QFxKeyEvent *event);
+ void context4Pressed(QFxKeyEvent *event);
+ void callPressed(QFxKeyEvent *event);
+ void hangupPressed(QFxKeyEvent *event);
+ void flipPressed(QFxKeyEvent *event);
+ void menuPressed(QFxKeyEvent *event);
+ void volumeUpPressed(QFxKeyEvent *event);
+ void volumeDownPressed(QFxKeyEvent *event);
+
+private:
+ void keyPressed(QKeyEvent *event);
+ void keyReleased(QKeyEvent *event);
+
+ const char *keyToSignal(int key) {
+ QByteArray keySignal;
+ if (key >= Qt::Key_0 && key <= Qt::Key_9) {
+ keySignal = "digit0Pressed";
+ keySignal[5] = '0' + (key - Qt::Key_0);
+ } else {
+ int i = 0;
+ while (sigMap[i].key && sigMap[i].key != key)
+ ++i;
+ keySignal = sigMap[i].sig;
+ }
+ return keySignal;
+ }
+
+ struct SigMap {
+ int key;
+ const char *sig;
+ };
+
+ static const SigMap sigMap[];
+ static QHash<QObject*, QFxKeysAttached*> attachedProperties;
+ friend class QFxItem;
+};
+
+const QFxKeysAttached::SigMap QFxKeysAttached::sigMap[] = {
+ { Qt::Key_Left, "leftPressed" },
+ { Qt::Key_Right, "rightPressed" },
+ { Qt::Key_Up, "upPressed" },
+ { Qt::Key_Down, "downPressed" },
+ { Qt::Key_Asterisk, "asteriskPressed" },
+ { Qt::Key_Escape, "escapePressed" },
+ { Qt::Key_Return, "returnPressed" },
+ { Qt::Key_Enter, "enterPressed" },
+ { Qt::Key_Delete, "deletePressed" },
+ { Qt::Key_Space, "spacePressed" },
+ { Qt::Key_Back, "backPressed" },
+ { Qt::Key_Cancel, "cancelPressed" },
+ { Qt::Key_Select, "selectPressed" },
+ { Qt::Key_Yes, "yesPressed" },
+ { Qt::Key_No, "noPressed" },
+ { Qt::Key_Context1, "context1Pressed" },
+ { Qt::Key_Context2, "context2Pressed" },
+ { Qt::Key_Context3, "context3Pressed" },
+ { Qt::Key_Context4, "context4Pressed" },
+ { Qt::Key_Call, "callPressed" },
+ { Qt::Key_Hangup, "hangupPressed" },
+ { Qt::Key_Flip, "flipPressed" },
+ { Qt::Key_Menu, "menuPressed" },
+ { Qt::Key_VolumeUp, "volumeUpPressed" },
+ { Qt::Key_VolumeDown, "volumeDownPressed" },
+ { 0, 0 }
+};
+
+QHash<QObject*, QFxKeysAttached*> QFxKeysAttached::attachedProperties;
+
+bool QFxKeysAttachedPrivate::isConnected(int idx)
+{
+ if (idx < 32) {
+ quint32 mask = 1 << idx;
+ return connectedSignals[0] & mask;
+ } else if (idx < 64) {
+ quint32 mask = 1 << (idx-32);
+ return connectedSignals[1] & mask;
+ }
+ return false;
+}
+
+QFxKeysAttached::QFxKeysAttached(QObject *parent)
+ : QObject(*(new QFxKeysAttachedPrivate), 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)
+{
+ Q_D(QFxKeysAttached);
+ if (!d->enabled) {
+ event->ignore();
+ return;
+ }
+
+ QFxKeyEvent ke(*event);
+ QByteArray keySignal = keyToSignal(event->key());
+ if (!keySignal.isEmpty()) {
+ keySignal += "(QFxKeyEvent*)";
+ int idx = QFxKeysAttached::staticMetaObject.indexOfSignal(keySignal);
+ if (d->isConnected(idx)) {
+ // If we specifically handle a key then default to accepted
+ ke.setAccepted(true);
+ metaObject()->method(idx).invoke(this, Q_ARG(QFxKeysAttached, &ke));
+ }
+ }
+ if (!ke.isAccepted())
+ emit pressed(&ke);
+ event->setAccepted(ke.isAccepted());
+}
+
+void QFxKeysAttached::keyReleased(QKeyEvent *event)
+{
+ Q_D(QFxKeysAttached);
+ if (!d->enabled) {
+ event->ignore();
+ return;
+ }
+ QFxKeyEvent ke(*event);
+ emit released(&ke);
+ event->setAccepted(ke.isAccepted());
+}
+
+QFxKeysAttached *QFxKeysAttached::qmlAttachedProperties(QObject *obj)
+{
+ QFxKeysAttached *rv = attachedProperties.value(obj);
+ if (!rv) {
+ rv = new QFxKeysAttached(obj);
+ attachedProperties.insert(obj, rv);
+ }
+ return rv;
+}
+
+
+/*!
\qmlclass Item QFxItem
\brief The Item is the most basic of all visual items in QML.
*/
@@ -231,7 +743,7 @@ void QFxContents::setItem(QFxItem *item)
All visual items in Qt Declarative inherit from QFxItem. Although QFxItem
has no visual appearance, it defines all the properties that are
common across visual items - like the x and y position, and the
- width and height.
+ width and height. \l {Keys}{Key handling} is also provided by Item.
QFxItem is also useful for grouping items together.
@@ -255,6 +767,7 @@ void QFxContents::setItem(QFxItem *item)
}
}
\endqml
+
\endqmltext
\ingroup group_coreitems
@@ -318,34 +831,6 @@ void QFxContents::setItem(QFxItem *item)
*/
/*!
- \qmlsignal Item::onKeyPress(event)
-
- This handler is called when a key is pressed.
-
- The key event is available via the KeyEvent \a event.
-
- \qml
- Item {
- onKeyPress: { if (event.key == Qt.Key_Enter) state='Enter' }
- }
- \endqml
-*/
-
-/*!
- \qmlsignal Item::onKeyRelease(event)
-
- This handler is called when a key is released.
-
- The key event is available in via the KeyEvent \a event.
-
- \qml
- Item {
- onKeyRelease: { if (event.key == Qt.Key_Enter) state='Enter' }
- }
- \endqml
-*/
-
-/*!
\fn void QFxItem::parentChanged()
This signal is emitted when the parent of the item changes.
@@ -904,22 +1389,22 @@ void QFxItem::geometryChanged(const QRectF &newGeometry,
}
}
-/*! \fn void QFxItem::keyPress(QFxKeyEvent *event)
- This signal is emitted by keyPressEvent() for the \a event.
- */
-
-/*! \fn void QFxItem::keyRelease(QFxKeyEvent *event)
- This signal is emitted by keyReleaseEvent() for the \a event.
- */
+void QFxItem::setKeyHandler(QFxKeysAttached *handler)
+{
+ Q_D(QFxItem);
+ d->keyHandler = handler;
+}
/*!
\reimp
*/
void QFxItem::keyPressEvent(QKeyEvent *event)
{
- QFxKeyEvent ke(*event);
- emit keyPress(&ke);
- event->setAccepted(ke.isAccepted());
+ Q_D(QFxItem);
+ if (d->keyHandler)
+ d->keyHandler->keyPressed(event);
+ else
+ event->ignore();
}
/*!
@@ -927,9 +1412,11 @@ void QFxItem::keyPressEvent(QKeyEvent *event)
*/
void QFxItem::keyReleaseEvent(QKeyEvent *event)
{
- QFxKeyEvent ke(*event);
- emit keyRelease(&ke);
- event->setAccepted(ke.isAccepted());
+ Q_D(QFxItem);
+ if (d->keyHandler)
+ d->keyHandler->keyReleased(event);
+ else
+ event->ignore();
}
/*!
@@ -1917,5 +2404,8 @@ QDebug operator<<(QDebug debug, QFxItem *item)
QT_END_NAMESPACE
-#include "moc_qfxitem.cpp"
+QML_DECLARE_TYPE(QFxKeysAttached)
+QML_DEFINE_TYPE(Qt,4,6,(QT_VERSION&0x00ff00)>>8,Keys,QFxKeysAttached)
+#include "moc_qfxitem.cpp"
+#include "qfxitem.moc"