summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorZeno Albisser <zeno.albisser@nokia.com>2010-09-07 08:14:45 -0400
committerZeno Albisser <zeno.albisser@nokia.com>2010-09-08 09:02:33 -0400
commit4a9a0c09f3cfb9262f929620fd86609a9b1b3a76 (patch)
tree1f7dc0864578addf117a94ef5144a91ea4aaf98a
initial import of GestureArea sources including Recognizers
These sources have been extracted from a previous repository of the QMLEnablers project. The purpose of these files is to provide GestureRecognizers loadable as a module in QML. Reviewed-by: Denis Dzyubenko
-rw-r--r--gestureareaplugin_p.h71
-rw-r--r--gestures.pro34
-rw-r--r--plugin.cpp91
-rw-r--r--qdeclarativegesturearea.cpp294
-rw-r--r--qdeclarativegesturearea_p.h95
-rw-r--r--qdeclarativegesturehandler.cpp170
-rw-r--r--qdeclarativegesturehandler_p.h208
-rw-r--r--qdeclarativegesturerecognizers.cpp874
-rw-r--r--qdeclarativegesturerecognizers_p.h117
-rw-r--r--qmldir1
10 files changed, 1955 insertions, 0 deletions
diff --git a/gestureareaplugin_p.h b/gestureareaplugin_p.h
new file mode 100644
index 0000000..95ed762
--- /dev/null
+++ b/gestureareaplugin_p.h
@@ -0,0 +1,71 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QML Gesture Area plugin of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef GESTUREAREAPLUGIN_P_H
+#define GESTUREAREAPLUGIN_P_H
+
+#include <QtDeclarative/qdeclarativeextensionplugin.h>
+#include <QtCore/QSet>
+#include <QtCore/QList>
+#include <QtCore/QWeakPointer>
+
+QT_BEGIN_NAMESPACE
+
+class QDeclarativeGestureArea;
+class GestureAreaQmlPlugin : public QDeclarativeExtensionPlugin
+{
+ Q_OBJECT
+public:
+ GestureAreaQmlPlugin(QObject *parent = 0) : QDeclarativeExtensionPlugin(parent) { self = this; }
+ ~GestureAreaQmlPlugin() { self = 0; }
+
+ virtual void registerTypes(const char *uri);
+
+ static GestureAreaQmlPlugin *self;
+
+ QSet<Qt::GestureType> allGestures;
+ // all gesture areas with default handlers
+ QList<QWeakPointer<QDeclarativeGestureArea> > allDefaultAreas;
+};
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/gestures.pro b/gestures.pro
new file mode 100644
index 0000000..2da157d
--- /dev/null
+++ b/gestures.pro
@@ -0,0 +1,34 @@
+TARGET = qmlgestureareaplugin
+TARGETPATH = Qt/labs/gestures
+
+TEMPLATE = lib
+CONFIG += qt plugin
+QT += declarative
+
+SOURCES += qdeclarativegesturearea.cpp \
+ qdeclarativegesturehandler.cpp \
+ qdeclarativegesturerecognizers.cpp \
+ plugin.cpp
+HEADERS += qdeclarativegesturearea_p.h \
+ gestureareaplugin_p.h \
+ qdeclarativegesturehandler_p.h \
+ qdeclarativegesturerecognizers_p.h
+
+QTDIR_build:DESTDIR = $$QT_BUILD_TREE/imports/$$TARGETPATH
+else:DESTDIR = .
+target.path = $$[QT_INSTALL_IMPORTS]/$$TARGETPATH
+
+qmldir.files += $$PWD/qmldir
+qmldir.path += $$[QT_INSTALL_IMPORTS]/$$TARGETPATH
+
+symbian:{
+ TARGET.UID3 = 0x2002131F
+ include($$QT_SOURCE_TREE/demos/symbianpkgrules.pri)
+
+ importFiles.sources = $$DESTDIR/qmlgestureareaplugin$${QT_LIBINFIX}.dll qmldir
+ importFiles.path = $$QT_IMPORTS_BASE_DIR/$$TARGETPATH
+
+ DEPLOYMENT = importFiles
+}
+
+INSTALLS += target qmldir
diff --git a/plugin.cpp b/plugin.cpp
new file mode 100644
index 0000000..e848868
--- /dev/null
+++ b/plugin.cpp
@@ -0,0 +1,91 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QML Gesture Area plugin of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtDeclarative/qdeclarative.h>
+
+#include "gestureareaplugin_p.h"
+#include "qdeclarativegesturearea_p.h"
+#include "qdeclarativegesturerecognizers_p.h"
+
+QT_BEGIN_NAMESPACE
+
+void GestureAreaQmlPlugin::registerTypes(const char *uri)
+{
+ Q_ASSERT(QLatin1String(uri) == QLatin1String("Qt.labs.gestures"));
+#ifndef QT_NO_GESTURES
+ qmlRegisterType<QDeclarativeGestureArea>(uri, 2, 0, "GestureArea");
+
+ qmlRegisterUncreatableType<QDeclarativeGestureHandler>(uri, 2, 0, "GestureHandler", QLatin1String("Do not create objects of this type."));
+
+ qmlRegisterUncreatableType<QGesture>(uri, 2, 0, "Gesture", QLatin1String("Do not create objects of this type."));
+ qmlRegisterUncreatableType<QPanGesture>(uri, 2, 0, "PanGesture", QLatin1String("Do not create objects of this type."));
+ qmlRegisterUncreatableType<QTapGesture>(uri, 2, 0, "TapGesture", QLatin1String("Do not create objects of this type."));
+ qmlRegisterUncreatableType<QTapAndHoldGesture>(uri, 2, 0, "TapAndHoldGesture", QLatin1String("Do not create objects of this type."));
+ qmlRegisterUncreatableType<QPinchGesture>(uri, 2, 0, "PinchGesture", QLatin1String("Do not create objects of this type."));
+ qmlRegisterUncreatableType<QSwipeGesture>(uri, 2, 0, "SwipeGesture", QLatin1String("Do not create objects of this type."));
+
+ qmlRegisterType<QDeclarativeDefaultGestureHandler>(uri, 2, 0, "Default");
+ qmlRegisterType<QDeclarativePanGestureHandler>(uri, 2, 0, "Pan");
+ qmlRegisterType<QDeclarativeTapGestureHandler>(uri, 2, 0, "Tap");
+ qmlRegisterType<QDeclarativeTapAndHoldGestureHandler>(uri, 2, 0, "TapAndHold");
+ qmlRegisterType<QDeclarativePinchGestureHandler>(uri, 2, 0, "Pinch");
+ qmlRegisterType<QDeclarativeSwipeGestureHandler>(uri, 2, 0, "Swipe");
+
+ QGestureRecognizer::unregisterRecognizer(Qt::TapGesture);
+ QGestureRecognizer::unregisterRecognizer(Qt::TapAndHoldGesture);
+ QGestureRecognizer::unregisterRecognizer(Qt::PanGesture);
+ QGestureRecognizer::unregisterRecognizer(Qt::PinchGesture);
+ QGestureRecognizer::unregisterRecognizer(Qt::SwipeGesture);
+
+ QGestureRecognizer::registerRecognizer(new QTapGestureRecognizer());
+ QGestureRecognizer::registerRecognizer(new QTapAndHoldGestureRecognizer());
+ QGestureRecognizer::registerRecognizer(new QPanGestureRecognizer());
+ QGestureRecognizer::registerRecognizer(new QPinchGestureRecognizer());
+ QGestureRecognizer::registerRecognizer(new QSwipeGestureRecognizer());
+#endif
+}
+
+GestureAreaQmlPlugin *GestureAreaQmlPlugin::self = 0;
+
+QT_END_NAMESPACE
+
+
+Q_EXPORT_PLUGIN2(qmlgestureareaplugin, QT_PREPEND_NAMESPACE(GestureAreaQmlPlugin));
diff --git a/qdeclarativegesturearea.cpp b/qdeclarativegesturearea.cpp
new file mode 100644
index 0000000..c5f621f
--- /dev/null
+++ b/qdeclarativegesturearea.cpp
@@ -0,0 +1,294 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QML Gesture Area plugin of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qdeclarativegesturearea_p.h"
+
+#include <qdeclarativeexpression.h>
+#include <qdeclarativecontext.h>
+#include <qdeclarativeinfo.h>
+
+#include <private/qdeclarativeproperty_p.h>
+#include <private/qdeclarativeitem_p.h>
+#include <private/qdeclarativebinding_p.h>
+
+#include <QtCore/qdebug.h>
+#include <QtCore/qstringlist.h>
+
+#include <QtGui/qevent.h>
+#include <QtGui/qgesture.h>
+
+#include <private/qobject_p.h>
+
+#include "qdeclarativegesturehandler_p.h"
+#include "gestureareaplugin_p.h"
+
+#ifndef QT_NO_GESTURES
+
+QT_BEGIN_NAMESPACE
+
+class QDeclarativeGestureAreaPrivate : public QDeclarativeItemPrivate
+{
+ Q_DECLARE_PUBLIC(QDeclarativeGestureArea)
+public:
+ QDeclarativeGestureAreaPrivate() : defaultHandler(0) { }
+
+ typedef QMap<Qt::GestureType, QObject *> Handlers;
+ Handlers handlers;
+ QObject *defaultHandler;
+
+ static void handlers_append(QDeclarativeListProperty<QObject> *prop, QObject *handler) {
+ QDeclarativeGestureAreaPrivate *d = static_cast<QDeclarativeGestureAreaPrivate *>(prop->data);
+ QDeclarativeGestureArea *q = d->q_func();
+ handler->setParent(q);
+ int type = handler->property("gestureType").toInt();
+ // check that all needed properties exist
+ if (!handler->property("gestureType").isValid() || !handler->property("gesture").isValid()
+ || !handler->property("onStarted").isValid() || !handler->property("onUpdated").isValid()
+ || !handler->property("onCanceled").isValid() || !handler->property("onFinished").isValid()) {
+ qmlInfo(handler) << "Invalid GestureArea handler.\n"
+ << "A GestureArea handler should provide the following properties: "
+ "'gestureType', 'onStarted', 'onUpdated', 'onCanceled', 'onFinished' and 'gesture'";
+ return;
+ }
+ Qt::GestureType gestureType = Qt::GestureType(type);
+ if (d->handlers.contains(gestureType)) {
+ qmlInfo(handler) << "Duplicate gesture found, ignoring.";
+ return;
+ }
+ d->handlers.insert(gestureType, handler);
+ if (GestureAreaQmlPlugin::self)
+ GestureAreaQmlPlugin::self->allGestures << gestureType;
+ if (type == 0 && GestureAreaQmlPlugin::self) {
+ d->defaultHandler = handler;
+ GestureAreaQmlPlugin::self->allDefaultAreas << QWeakPointer<QDeclarativeGestureArea>(q);
+ foreach (Qt::GestureType gestureType, GestureAreaQmlPlugin::self->allGestures) {
+ foreach (QWeakPointer<QDeclarativeGestureArea> area, GestureAreaQmlPlugin::self->allDefaultAreas) {
+ if (area)
+ area.data()->grabGesture(gestureType);
+ }
+ }
+ } else {
+ q->grabGesture(gestureType);
+ }
+ }
+ static void handlers_clear(QDeclarativeListProperty<QObject> *prop) {
+ QDeclarativeGestureAreaPrivate *d = static_cast<QDeclarativeGestureAreaPrivate *>(prop->data);
+ d->handlers.clear();
+ }
+ static int handlers_count(QDeclarativeListProperty<QObject> *prop) {
+ QDeclarativeGestureAreaPrivate *d = static_cast<QDeclarativeGestureAreaPrivate *>(prop->data);
+ return d->handlers.count();
+ }
+ static QObject *handlers_at(QDeclarativeListProperty<QObject> *prop, int index) {
+ QDeclarativeGestureAreaPrivate *d = static_cast<QDeclarativeGestureAreaPrivate *>(prop->data);
+ return d->handlers.value(d->handlers.keys().at(index));
+ }
+
+ void evaluate(QGestureEvent *event, QGesture *gesture, QObject *handler);
+ bool gestureEvent(QGestureEvent *event);
+};
+
+/*!
+ \qmlclass GestureArea QDeclarativeGestureArea
+ \ingroup qml-basic-interaction-elements
+
+ \brief The GestureArea item enables simple gesture handling.
+ \inherits Item
+
+ A GestureArea is like a MouseArea, but it has signals for gesture events.
+
+ \e {Elements in the Qt.labs module are not guaranteed to remain compatible
+ in future versions.}
+
+ \qml
+ import Qt.labs.gestures 0.1
+
+ GestureArea {
+ anchors.fill: parent
+
+ Pan {
+ when: Math.abs(gesture.delta.y) < Math.abs(gesture.delta.x)
+ onUpdated: {
+ // use gesture.delta
+ }
+ }
+ TapAndHold {
+ onFinished: {
+ // do something
+ }
+ }
+ }
+ \endqml
+
+ Each gesture object has a \e when clause that will be evaluated on start of the
+ gesture. If the when clause evaluates to true the gesture is accepted and the
+ \e onStarted script is handled. If there is no \e when clause then it will
+ automatically be accepted. Notice that a gesture that is not accepted will be
+ offered to another gesture area that is also covering the area where the gesture
+ happened.
+
+ After acceptance of a gesture updates in movement call \e unOpdated and finally either
+ the script from \e onCanceled or \e onFinished is handled when the gesture is canceled
+ or finished.
+ Each gesture object has a \e gesture parameter that has the properties of the gesture
+ which can be used in all of the script properties.
+
+ The full list of supported gesture-types handled by a GestureArea is listed in the table
+ below.
+ \table
+ \header \o Type \o Description
+ \row \o Pan \o a movement of pressing and holding while moving the pointing device on the gesture area
+ \row \o Tap \o a touch and release without moving
+ \row \o TapAndHold \o a touch without releasing or moving for a longer time
+ \row \o Pinch \o is used to handle the moving using more than one finger
+ \endtable
+
+ GestureArea is an invisible item: it is never painted.
+
+ \sa MouseArea, {declarative/touchinteraction/gestures}{Gestures example}
+*/
+
+/*!
+ \internal
+ \class QDeclarativeGestureArea
+ \brief The QDeclarativeGestureArea class provides simple gesture handling.
+
+*/
+QDeclarativeGestureArea::QDeclarativeGestureArea(QDeclarativeItem *parent) :
+ QDeclarativeItem(*(new QDeclarativeGestureAreaPrivate), parent)
+{
+ setAcceptedMouseButtons(Qt::LeftButton);
+ setAcceptTouchEvents(true);
+}
+
+QDeclarativeGestureArea::~QDeclarativeGestureArea()
+{
+}
+
+QDeclarativeListProperty<QObject> QDeclarativeGestureArea::handlers()
+{
+ Q_D(QDeclarativeGestureArea);
+ return QDeclarativeListProperty<QObject>(this, d, QDeclarativeGestureAreaPrivate::handlers_append,
+ QDeclarativeGestureAreaPrivate::handlers_count, QDeclarativeGestureAreaPrivate::handlers_at,
+ QDeclarativeGestureAreaPrivate::handlers_clear);
+}
+
+bool QDeclarativeGestureArea::sceneEvent(QEvent *event)
+{
+ Q_D(QDeclarativeGestureArea);
+ switch (event->type()) {
+ case QEvent::GraphicsSceneMousePress:
+ case QEvent::MouseButtonPress:
+ case QEvent::TouchBegin:
+ event->accept();
+ return true;
+ case QEvent::Gesture:
+ return d->gestureEvent(static_cast<QGestureEvent *>(event));
+ default:
+ break;
+ }
+ return QDeclarativeItem::sceneEvent(event);
+}
+
+void QDeclarativeGestureAreaPrivate::evaluate(QGestureEvent *event, QGesture *gesture, QObject *handler)
+{
+ handler->setProperty("gesture", QVariant::fromValue<QObject *>(gesture));
+ QDeclarativeScriptString when = handler->property("when").value<QDeclarativeScriptString>();
+ if (!when.script().isEmpty()) {
+ QDeclarativeExpression expr(when.context(), when.scopeObject(), when.script());
+ QVariant result = expr.evaluate();
+ if (expr.hasError()) {
+ qmlInfo(q_func()) << expr.error();
+ return;
+ }
+ if (!result.toBool())
+ return;
+ }
+
+ // those names map to the enum Qt::GestureState
+ static const char * scriptPropertyNames[] = { "0", "onStarted", "onUpdated", "onFinished", "onCanceled", "__ERROR" };
+ QDeclarativeScriptString script = handler->property(scriptPropertyNames[gesture->state()]).value<QDeclarativeScriptString>();
+ if (!script.script().isEmpty()) {
+ QDeclarativeExpression expr(script.context(), script.scopeObject(), script.script());
+ expr.evaluate();
+ if (expr.hasError())
+ qmlInfo(q_func()) << expr.error();
+ }
+ event->accept(gesture);
+ handler->setProperty("gesture", QVariant());
+}
+
+bool QDeclarativeGestureAreaPrivate::gestureEvent(QGestureEvent *event)
+{
+ event->accept();
+ foreach(Qt::GestureType type, handlers.keys())
+ event->ignore(type);
+
+ if (handlers.isEmpty())
+ return false;
+
+ QSet<Qt::GestureType> handledGestures;
+ Handlers::Iterator it = handlers.end();
+ do {
+ --it;
+ Qt::GestureType gestureType = it.key();
+ if (!gestureType)
+ continue;
+ if (QGesture *gesture = event->gesture(gestureType)) {
+ handledGestures << gestureType;
+ QObject *handler = it.value();
+ evaluate(event, gesture, handler);
+ }
+ } while (it != handlers.begin());
+
+ if (defaultHandler) {
+ // filter all gestures through the default handler
+ foreach (QGesture *gesture, event->gestures()) {
+ if (!handledGestures.contains(gesture->gestureType()))
+ evaluate(event, gesture, defaultHandler);
+ }
+ }
+ return false;
+}
+
+QT_END_NAMESPACE
+
+#endif // QT_NO_GESTURES
diff --git a/qdeclarativegesturearea_p.h b/qdeclarativegesturearea_p.h
new file mode 100644
index 0000000..d91d695
--- /dev/null
+++ b/qdeclarativegesturearea_p.h
@@ -0,0 +1,95 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QML Gesture Area plugin of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QDECLARATIVEGESTUREAREA_H
+#define QDECLARATIVEGESTUREAREA_H
+
+#include <qdeclarativeitem.h>
+#include <qdeclarativescriptstring.h>
+#include <private/qdeclarativecustomparser_p.h>
+
+#include <QtCore/qobject.h>
+#include <QtCore/qstring.h>
+#include <QtGui/qgesture.h>
+
+#include "qdeclarativegesturehandler_p.h"
+
+#ifndef QT_NO_GESTURES
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Declarative)
+
+class QDeclarativeBoundSignal;
+class QDeclarativeContext;
+class QDeclarativeGestureAreaPrivate;
+class QDeclarativeGestureArea : public QDeclarativeItem
+{
+ Q_OBJECT
+
+ Q_PROPERTY(QDeclarativeListProperty<QObject> handlers READ handlers)
+ Q_CLASSINFO("DefaultProperty", "handlers")
+
+public:
+ QDeclarativeGestureArea(QDeclarativeItem *parent=0);
+ ~QDeclarativeGestureArea();
+
+ QDeclarativeListProperty<QObject> handlers();
+
+protected:
+ bool sceneEvent(QEvent *event);
+
+private:
+ Q_DISABLE_COPY(QDeclarativeGestureArea)
+ Q_DECLARE_PRIVATE_D(QGraphicsItem::d_ptr.data(), QDeclarativeGestureArea)
+};
+
+QT_END_NAMESPACE
+
+QML_DECLARE_TYPE(QDeclarativeGestureArea)
+
+QT_END_HEADER
+
+#endif // QT_NO_GESTURES
+
+#endif
diff --git a/qdeclarativegesturehandler.cpp b/qdeclarativegesturehandler.cpp
new file mode 100644
index 0000000..05e13d7
--- /dev/null
+++ b/qdeclarativegesturehandler.cpp
@@ -0,0 +1,170 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QML Gesture Area plugin of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qdeclarativegesturehandler_p.h"
+
+#include <QtCore/qdebug.h>
+#include <QtCore/qstringlist.h>
+
+#include <QtGui/qevent.h>
+
+#include <private/qobject_p.h>
+#include <private/qdeclarativebinding_p.h>
+
+#ifndef QT_NO_GESTURES
+
+QT_BEGIN_NAMESPACE
+
+class QDeclarativeGestureHandlerPrivate : public QObjectPrivate
+{
+public:
+ QDeclarativeGestureHandlerPrivate()
+ : gestureType((Qt::GestureType)0), gesture(0) { }
+
+ int gestureType;
+ QDeclarativeScriptString when;
+ QDeclarativeScriptString onStarted;
+ QDeclarativeScriptString onUpdated;
+ QDeclarativeScriptString onCanceled;
+ QDeclarativeScriptString onFinished;
+ QObject *gesture;
+};
+
+QDeclarativeGestureHandler::QDeclarativeGestureHandler(QObject *parent)
+ : QObject(*new QDeclarativeGestureHandlerPrivate, parent)
+{
+}
+
+QDeclarativeGestureHandler::QDeclarativeGestureHandler(QDeclarativeGestureHandlerPrivate &dd, QObject *parent)
+ : QObject(dd, parent)
+{
+}
+
+bool QDeclarativeGestureHandler::isWhenKnown() const
+{
+ Q_D(const QDeclarativeGestureHandler);
+ return !d->when.script().isEmpty();
+}
+
+QDeclarativeScriptString QDeclarativeGestureHandler::when() const
+{
+ Q_D(const QDeclarativeGestureHandler);
+ return d->when;
+}
+
+void QDeclarativeGestureHandler::setWhen(const QDeclarativeScriptString &when)
+{
+ Q_D(QDeclarativeGestureHandler);
+ d->when = when;
+}
+
+QDeclarativeScriptString QDeclarativeGestureHandler::onStarted() const
+{
+ Q_D(const QDeclarativeGestureHandler);
+ return d->onStarted;
+}
+
+void QDeclarativeGestureHandler::setOnStarted(const QDeclarativeScriptString &script)
+{
+ Q_D(QDeclarativeGestureHandler);
+ d->onStarted = script;
+}
+
+QDeclarativeScriptString QDeclarativeGestureHandler::onUpdated() const
+{
+ Q_D(const QDeclarativeGestureHandler);
+ return d->onUpdated;
+}
+
+void QDeclarativeGestureHandler::setOnUpdated(const QDeclarativeScriptString &script)
+{
+ Q_D(QDeclarativeGestureHandler);
+ d->onUpdated = script;
+}
+
+QDeclarativeScriptString QDeclarativeGestureHandler::onFinished() const
+{
+ Q_D(const QDeclarativeGestureHandler);
+ return d->onFinished;
+}
+
+void QDeclarativeGestureHandler::setOnFinished(const QDeclarativeScriptString &script)
+{
+ Q_D(QDeclarativeGestureHandler);
+ d->onFinished = script;
+}
+
+QDeclarativeScriptString QDeclarativeGestureHandler::onCanceled() const
+{
+ Q_D(const QDeclarativeGestureHandler);
+ return d->onCanceled;
+}
+
+void QDeclarativeGestureHandler::setOnCanceled(const QDeclarativeScriptString &script)
+{
+ Q_D(QDeclarativeGestureHandler);
+ d->onCanceled = script;
+}
+
+QObject *QDeclarativeGestureHandler::gesture() const
+{
+ return d_func()->gesture;
+}
+
+void QDeclarativeGestureHandler::setGesture(QObject *gesture)
+{
+ d_func()->gesture = gesture;
+}
+
+int QDeclarativeGestureHandler::gestureType() const
+{
+ return d_func()->gestureType;
+}
+
+void QDeclarativeGestureHandler::setGestureType(int gestureType)
+{
+ d_func()->gestureType = gestureType;
+}
+
+
+QT_END_NAMESPACE
+
+#endif // QT_NO_GESTURES
diff --git a/qdeclarativegesturehandler_p.h b/qdeclarativegesturehandler_p.h
new file mode 100644
index 0000000..0e9aa38
--- /dev/null
+++ b/qdeclarativegesturehandler_p.h
@@ -0,0 +1,208 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QML Gesture Area plugin of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QDECLARATIVEGESTUREHANDLER_H
+#define QDECLARATIVEGESTUREHANDLER_H
+
+#include <QtDeclarative/qdeclarative.h>
+#include <QtDeclarative/qdeclarativescriptstring.h>
+#include <QtCore/qobject.h>
+#include <QtCore/qstringlist.h>
+#include <QtGui/qgesture.h>
+
+#ifndef QT_NO_GESTURES
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Declarative)
+
+class QGesture;
+class QDeclarativeBinding;
+class QDeclarativeGestureHandlerPrivate;
+class QDeclarativeGestureHandler : public QObject
+{
+ Q_OBJECT
+ Q_PROPERTY(int gestureType READ gestureType WRITE setGestureType)
+ Q_PROPERTY(QObject *parent READ parent DESIGNABLE false FINAL)
+ Q_PROPERTY(QDeclarativeScriptString when READ when WRITE setWhen)
+ Q_PROPERTY(QDeclarativeScriptString onStarted READ onStarted WRITE setOnStarted)
+ Q_PROPERTY(QDeclarativeScriptString onUpdated READ onUpdated WRITE setOnUpdated)
+ Q_PROPERTY(QDeclarativeScriptString onCanceled READ onCanceled WRITE setOnCanceled)
+ Q_PROPERTY(QDeclarativeScriptString onFinished READ onFinished WRITE setOnFinished)
+ Q_PROPERTY(QObject *gesture READ gesture WRITE setGesture NOTIFY gestureChanged)
+
+public:
+ bool isWhenKnown() const;
+ QDeclarativeScriptString when() const;
+ void setWhen(const QDeclarativeScriptString &script);
+
+ QDeclarativeScriptString onStarted() const;
+ void setOnStarted(const QDeclarativeScriptString &script);
+
+ QDeclarativeScriptString onUpdated() const;
+ void setOnUpdated(const QDeclarativeScriptString &script);
+
+ QDeclarativeScriptString onCanceled() const;
+ void setOnCanceled(const QDeclarativeScriptString &script);
+
+ QDeclarativeScriptString onFinished() const;
+ void setOnFinished(const QDeclarativeScriptString &script);
+
+ QObject *gesture() const;
+ void setGesture(QObject *gesture);
+
+ int gestureType() const;
+
+Q_SIGNALS:
+ void gestureChanged();
+
+protected:
+ QDeclarativeGestureHandler(QObject *parent = 0);
+ QDeclarativeGestureHandler(QDeclarativeGestureHandlerPrivate &dd, QObject *parent = 0);
+
+ void setGestureType(int type);
+
+private:
+ friend class QDeclarativeGestureArea;
+ Q_DISABLE_COPY(QDeclarativeGestureHandler)
+ Q_DECLARE_PRIVATE(QDeclarativeGestureHandler)
+};
+
+class QDeclarativePanGestureHandler : public QDeclarativeGestureHandler
+{
+ Q_OBJECT
+public:
+ QDeclarativePanGestureHandler(QObject *parent = 0)
+ : QDeclarativeGestureHandler(parent)
+ {
+ setGestureType(Qt::PanGesture);
+ }
+
+private:
+ Q_DISABLE_COPY(QDeclarativePanGestureHandler)
+};
+
+class QDeclarativeDefaultGestureHandler : public QDeclarativeGestureHandler
+{
+ Q_OBJECT
+public:
+ QDeclarativeDefaultGestureHandler(QObject *parent = 0)
+ : QDeclarativeGestureHandler(parent)
+ {
+ }
+
+private:
+ Q_DISABLE_COPY(QDeclarativeDefaultGestureHandler)
+};
+
+class QDeclarativePinchGestureHandler : public QDeclarativeGestureHandler
+{
+ Q_OBJECT
+public:
+ QDeclarativePinchGestureHandler(QObject *parent = 0)
+ : QDeclarativeGestureHandler(parent)
+ {
+ setGestureType(Qt::PinchGesture);
+ }
+
+private:
+ Q_DISABLE_COPY(QDeclarativePinchGestureHandler)
+};
+
+class QDeclarativeTapGestureHandler : public QDeclarativeGestureHandler
+{
+ Q_OBJECT
+public:
+ QDeclarativeTapGestureHandler(QObject *parent = 0)
+ : QDeclarativeGestureHandler(parent)
+ {
+ setGestureType(Qt::TapGesture);
+ }
+
+private:
+ Q_DISABLE_COPY(QDeclarativeTapGestureHandler)
+};
+
+class QDeclarativeTapAndHoldGestureHandler : public QDeclarativeGestureHandler
+{
+ Q_OBJECT
+public:
+ QDeclarativeTapAndHoldGestureHandler(QObject *parent = 0)
+ : QDeclarativeGestureHandler(parent)
+ {
+ setGestureType(Qt::TapAndHoldGesture);
+ }
+
+private:
+ Q_DISABLE_COPY(QDeclarativeTapAndHoldGestureHandler)
+};
+
+class QDeclarativeSwipeGestureHandler : public QDeclarativeGestureHandler
+{
+ Q_OBJECT
+public:
+ QDeclarativeSwipeGestureHandler(QObject *parent = 0)
+ : QDeclarativeGestureHandler(parent)
+ {
+ setGestureType(Qt::SwipeGesture);
+ }
+
+private:
+ Q_DISABLE_COPY(QDeclarativeSwipeGestureHandler)
+};
+
+QT_END_NAMESPACE
+
+QML_DECLARE_TYPE(QDeclarativeGestureHandler)
+QML_DECLARE_TYPE(QDeclarativeDefaultGestureHandler)
+QML_DECLARE_TYPE(QDeclarativePanGestureHandler)
+QML_DECLARE_TYPE(QDeclarativePinchGestureHandler)
+QML_DECLARE_TYPE(QDeclarativeTapGestureHandler)
+QML_DECLARE_TYPE(QDeclarativeTapAndHoldGestureHandler)
+QML_DECLARE_TYPE(QDeclarativeSwipeGestureHandler)
+
+QT_END_HEADER
+
+#endif // QT_NO_GESTURES
+
+#endif
diff --git a/qdeclarativegesturerecognizers.cpp b/qdeclarativegesturerecognizers.cpp
new file mode 100644
index 0000000..a7d260a
--- /dev/null
+++ b/qdeclarativegesturerecognizers.cpp
@@ -0,0 +1,874 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QML Gesture Area plugin of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qdeclarativegesturerecognizers_p.h"
+#include "qgesture.h"
+#include "qevent.h"
+#include "qwidget.h"
+#include "qabstractscrollarea.h"
+#include <qgraphicssceneevent.h>
+#include "qdebug.h"
+
+#include "qmath.h"
+
+#ifndef QT_NO_GESTURES
+
+QT_BEGIN_NAMESPACE
+
+static const int PanGestureMovementThreshold = 30;
+
+QPanGestureRecognizer::QPanGestureRecognizer()
+{
+}
+
+QGesture *QPanGestureRecognizer::create(QObject *target)
+{
+ if (target && target->isWidgetType()) {
+#if defined(Q_OS_WIN) && !defined(QT_NO_NATIVE_GESTURES)
+ // for scroll areas on Windows we want to use native gestures instead
+ if (!qobject_cast<QAbstractScrollArea *>(target->parent()))
+ static_cast<QWidget *>(target)->setAttribute(Qt::WA_AcceptTouchEvents);
+#else
+ static_cast<QWidget *>(target)->setAttribute(Qt::WA_AcceptTouchEvents);
+#endif
+ } else if (target) {
+ return 0;
+ }
+ return new QPanGesture;
+}
+
+QGestureRecognizer::Result QPanGestureRecognizer::recognize(QGesture *state,
+ QObject *,
+ QEvent *event)
+{
+ QPanGesture *q = static_cast<QPanGesture *>(state);
+ QPanGesturePrivate *d = q->d_func();
+
+ QGestureRecognizer::Result result;
+ switch (event->type()) {
+ case QEvent::TouchBegin: {
+ const QTouchEvent *ev = static_cast<const QTouchEvent *>(event);
+ d->gotTouched = true;
+ QTouchEvent::TouchPoint p = ev->touchPoints().at(0);
+ d->lastOffset = d->offset = QPointF();
+ d->pressTime.start();
+ result = QGestureRecognizer::MayBeGesture;
+ break;
+ }
+ case QEvent::TouchEnd: {
+ const QTouchEvent *ev = static_cast<const QTouchEvent *>(event);
+ if (q->state() != Qt::NoGesture) {
+ if (ev->deviceType() == QTouchEvent::TouchScreen && ev->touchPoints().size() == 1) {
+ QTouchEvent::TouchPoint p1 = ev->touchPoints().at(0);
+ d->lastOffset = d->offset;
+ d->offset = QPointF(p1.pos().x() - p1.startPos().x(), p1.pos().y() - p1.startPos().y());
+ } else if (ev->deviceType() == QTouchEvent::TouchPad && ev->touchPoints().size() == 2) {
+ QTouchEvent::TouchPoint p1 = ev->touchPoints().at(0);
+ QTouchEvent::TouchPoint p2 = ev->touchPoints().at(1);
+ d->lastOffset = d->offset;
+ d->offset =
+ QPointF(p1.pos().x() - p1.startPos().x() + p2.pos().x() - p2.startPos().x(),
+ p1.pos().y() - p1.startPos().y() + p2.pos().y() - p2.startPos().y()) / 2;
+ }
+ result = QGestureRecognizer::FinishGesture;
+ } else {
+ result = QGestureRecognizer::CancelGesture;
+ }
+ break;
+ }
+ case QEvent::TouchUpdate: {
+ bool deviceAndTouchPointsOK = false;
+ const QTouchEvent *ev = static_cast<const QTouchEvent *>(event);
+ QTouchEvent::TouchPoint p1;
+ if (ev->deviceType() == QTouchEvent::TouchScreen && ev->touchPoints().size() == 1) {
+ deviceAndTouchPointsOK = true;
+ p1 = ev->touchPoints().at(0);
+ d->lastOffset = d->offset;
+ d->offset = QPointF(p1.pos().x() - p1.startPos().x(), p1.pos().y() - p1.startPos().y());
+ } else if (ev->deviceType() == QTouchEvent::TouchPad && ev->touchPoints().size() >= 2) {
+ deviceAndTouchPointsOK = true;
+ p1 = ev->touchPoints().at(0);
+ QTouchEvent::TouchPoint p2 = ev->touchPoints().at(1);
+ d->lastOffset = d->offset;
+ d->offset =
+ QPointF(p1.pos().x() - p1.startPos().x() + p2.pos().x() - p2.startPos().x(),
+ p1.pos().y() - p1.startPos().y() + p2.pos().y() - p2.startPos().y()) / 2;
+ }
+ if (deviceAndTouchPointsOK &&
+ (d->offset.x() > 10 || d->offset.y() > 10 ||
+ d->offset.x() < -10 || d->offset.y() < -10)) {
+ q->setHotSpot(p1.startScreenPos());
+ result = QGestureRecognizer::TriggerGesture;
+ } else {
+ result = QGestureRecognizer::MayBeGesture;
+ }
+ break;
+ }
+
+ case QEvent::MouseButtonPress:
+ if (!d->gotTouched) {
+ QMouseEvent *ev = static_cast<QMouseEvent *>(event);
+ if (ev->buttons() == Qt::LeftButton && !(ev->modifiers() & Qt::ControlModifier)) {
+ d->startPosition = d->lastPos = ev->globalPos();
+ state->setHotSpot(d->startPosition);
+ state->setHandled(false);
+ d->pressTime.start();
+ d->lastPosTime.start();
+ ev->accept();
+ }
+ }
+ return QGestureRecognizer::MayBeGesture;
+
+ case QEvent::MouseMove:
+ if (!d->gotTouched) {
+ QMouseEvent *ev = static_cast<QMouseEvent *>(event);
+ if (!d->startPosition.isNull()) {
+ QPoint delta = ev->globalPos() - d->startPosition;
+ if (state->state() != Qt::GestureStarted || state->state() != Qt::GestureUpdated) {
+ if (delta.manhattanLength() > PanGestureMovementThreshold || d->pressTime.elapsed() > 200) {
+ q->setLastOffset(q->offset());
+ q->setOffset(delta);
+
+ qreal elapsed = qreal(d->lastPosTime.restart()) / 1000.;
+ if (elapsed <= 0)
+ elapsed = 1;
+ int dx = ev->globalPos().x() - d->lastPos.x();
+ d->xVelocity += dx / elapsed;
+ d->xVelocity /= 2;
+ int dy = ev->globalPos().y() - d->lastPos.y();
+ d->yVelocity += dy / elapsed;
+ d->yVelocity /= 2;
+
+ d->lastPos = ev->globalPos();
+ return QGestureRecognizer::TriggerGesture;
+ }
+ }
+ }
+ }
+ return QGestureRecognizer::Ignore;
+
+ case QEvent::MouseButtonRelease:
+ if (!d->gotTouched) {
+ if(q->state() != Qt::NoGesture) {
+ QMouseEvent *ev = static_cast<QMouseEvent *>(event);
+ if (d->lastPosTime.elapsed() > 100) {
+ // if we drag then pause before release we should not cause a flick.
+ d->xVelocity = d->yVelocity = 0;
+ } else {
+ // FlickThreshold determines how far the "mouse" must have moved
+ // before we perform a flick.
+ static const int FlickThreshold = 20;
+
+ // Really slow flicks can be annoying.
+ static const int minimumFlickVelocity = 200;
+
+ if (qAbs(d->xVelocity) > 10 && qAbs(ev->globalPos().x() - d->startPosition.x()) > FlickThreshold) {
+ if (qAbs(d->xVelocity) < minimumFlickVelocity)
+ d->xVelocity = d->xVelocity < 0 ? -minimumFlickVelocity : minimumFlickVelocity;
+ }
+ if (qAbs(d->yVelocity) > 10 && qAbs(ev->globalPos().y() - d->startPosition.y()) > FlickThreshold) {
+ if (qAbs(d->yVelocity) < minimumFlickVelocity)
+ d->yVelocity = d->yVelocity < 0 ? -minimumFlickVelocity : minimumFlickVelocity;
+ }
+ }
+ if (!d->startPosition.isNull() && !q->lastOffset().isNull()) {
+ return QGestureRecognizer::FinishGesture;
+ }
+ }
+ }
+ return QGestureRecognizer::CancelGesture;
+
+ default:
+ result = QGestureRecognizer::Ignore;
+ break;
+ }
+ return result;
+}
+
+void QPanGestureRecognizer::reset(QGesture *state)
+{
+ if (!state)
+ return;
+ QPanGesture *pan = static_cast<QPanGesture*>(state);
+ QPanGesturePrivate *d = pan->d_func();
+
+ d->startPosition = QPoint();
+ d->lastOffset = d->offset = QPointF();
+ d->acceleration = 0;
+ d->gotTouched = false;
+ d->pressTime.invalidate();
+ d->lastPosTime.invalidate();
+ d->lastPos = QPoint();
+ d->xVelocity = d->yVelocity = 0;
+
+ QGestureRecognizer::reset(state);
+}
+
+
+//
+// QPinchGestureRecognizer
+//
+
+QPinchGestureRecognizer::QPinchGestureRecognizer()
+{
+}
+
+QGesture *QPinchGestureRecognizer::create(QObject *target)
+{
+ if (target) {
+ if (target->isWidgetType())
+ static_cast<QWidget *>(target)->setAttribute(Qt::WA_AcceptTouchEvents);
+ else
+ return 0;
+ }
+ return new QPinchGesture;
+}
+
+QGestureRecognizer::Result QPinchGestureRecognizer::recognize(QGesture *state,
+ QObject *obj,
+ QEvent *event)
+{
+ QPinchGesture *q = static_cast<QPinchGesture *>(state);
+ QPinchGesturePrivate *d = q->d_func();
+
+ QGestureRecognizer::Result result;
+
+ switch (event->type()) {
+ case QEvent::TouchBegin: {
+ d->gotTouched = true;
+ result = QGestureRecognizer::MayBeGesture;
+ break;
+ }
+ case QEvent::TouchEnd: {
+ if (q->state() != Qt::NoGesture) {
+ result = QGestureRecognizer::FinishGesture;
+ } else {
+ result = QGestureRecognizer::CancelGesture;
+ }
+ break;
+ }
+ case QEvent::TouchUpdate: {
+ const QTouchEvent *ev = static_cast<const QTouchEvent *>(event);
+ d->changeFlags = 0;
+ if (ev->touchPoints().size() == 2) {
+ QTouchEvent::TouchPoint p1 = ev->touchPoints().at(0);
+ QTouchEvent::TouchPoint p2 = ev->touchPoints().at(1);
+
+ d->hotSpot = p1.screenPos();
+ d->isHotSpotSet = true;
+
+ if (d->isNewSequence) {
+ d->startPosition[0] = p1.screenPos();
+ d->startPosition[1] = p2.screenPos();
+ }
+ QLineF line(p1.screenPos(), p2.screenPos());
+ QLineF lastLine(p1.lastScreenPos(), p2.lastScreenPos());
+ QLineF tmp(line);
+ tmp.setLength(line.length() / 2.);
+ QPointF centerPoint = tmp.p2();
+
+ d->lastCenterPoint = d->centerPoint;
+ d->centerPoint = centerPoint;
+ d->changeFlags |= QPinchGesture::CenterPointChanged;
+
+ const qreal scaleFactor = line.length() / lastLine.length();
+
+ if (d->isNewSequence) {
+ d->lastScaleFactor = scaleFactor;
+ d->lastCenterPoint = centerPoint;
+ } else {
+ d->lastScaleFactor = d->scaleFactor;
+ }
+ d->scaleFactor = scaleFactor;
+ d->totalScaleFactor = d->totalScaleFactor * scaleFactor;
+ d->changeFlags |= QPinchGesture::ScaleFactorChanged;
+
+ qreal angle = QLineF(p1.screenPos(), p2.screenPos()).angle();
+ if (angle > 180)
+ angle -= 360;
+ qreal startAngle = QLineF(p1.startScreenPos(), p2.startScreenPos()).angle();
+ if (startAngle > 180)
+ startAngle -= 360;
+ const qreal rotationAngle = startAngle - angle;
+ if (d->isNewSequence)
+ d->lastRotationAngle = rotationAngle;
+ else
+ d->lastRotationAngle = d->rotationAngle;
+ d->rotationAngle = rotationAngle;
+ d->totalRotationAngle += d->rotationAngle - d->lastRotationAngle;
+ d->changeFlags |= QPinchGesture::RotationAngleChanged;
+
+ d->totalChangeFlags |= d->changeFlags;
+ if(p1.state() == Qt::TouchPointReleased || p2.state() == Qt::TouchPointReleased)
+ d->isNewSequence = true;
+ else
+ d->isNewSequence = false;
+ result = QGestureRecognizer::TriggerGesture;
+ } else {
+ d->isNewSequence = true;
+ if (q->state() != Qt::NoGesture)
+ result = QGestureRecognizer::Ignore;
+ else
+ result = QGestureRecognizer::FinishGesture;
+ }
+ break;
+ }
+
+ case QEvent::Wheel: {
+ QWheelEvent *ev = static_cast<QWheelEvent *>(event);
+ const Qt::KeyboardModifiers ctrlShiftMask = Qt::ControlModifier | Qt::ShiftModifier;
+ if (ev->modifiers() & (Qt::ControlModifier | Qt::ShiftModifier)) {
+ q->setHotSpot(ev->globalPos());
+
+ bool isNewSequence = q->state() == Qt::NoGesture;
+
+ d->lastCenterPoint = d->centerPoint;
+ d->centerPoint = ev->globalPos();
+
+ d->changeFlags = 0;
+
+ if (ev->modifiers() & Qt::ControlModifier) {
+ d->lastScaleFactor = d->scaleFactor;
+ if (ev->delta() > 0)
+ d->scaleFactor = 1.1 * qAbs(ev->delta()) / 8. / 15.;
+ else
+ d->scaleFactor = 0.9 / qAbs(ev->delta() / 8. / 15.);
+ d->changeFlags |= QPinchGesture::ScaleFactorChanged;
+ } else if (ev->modifiers() & Qt::ShiftModifier) {
+ d->lastRotationAngle = d->rotationAngle;
+ d->rotationAngle += ev->delta() / 8. / 15.;
+ d->changeFlags |= QPinchGesture::RotationAngleChanged;
+ }
+
+ if (isNewSequence) {
+ d->lastCenterPoint = d->centerPoint;
+ d->lastScaleFactor = d->scaleFactor;
+ d->lastRotationAngle = d->rotationAngle;
+ }
+
+ int timerId = q->property("timerid").toInt();
+ if (timerId)
+ q->killTimer(timerId);
+ q->setProperty("timerid", q->startTimer(400));
+ return QGestureRecognizer::TriggerGesture | QGestureRecognizer::ConsumeEventHint;
+ }
+ return QGestureRecognizer::Ignore;
+ }
+ case QEvent::MouseButtonPress:
+ if (q->property("timerid").toInt()) {
+ return QGestureRecognizer::FinishGesture;
+ }
+ return QGestureRecognizer::Ignore;
+
+ case QEvent::Timer: {
+ int timerId = state->property("timerid").toInt();
+ if (obj == state && timerId) {
+ state->killTimer(timerId);
+ d->changeFlags = 0;
+ return QGestureRecognizer::FinishGesture | QGestureRecognizer::ConsumeEventHint;
+ }
+ }
+
+ default:
+ result = QGestureRecognizer::Ignore;
+ break;
+ }
+ return result;
+}
+
+void QPinchGestureRecognizer::reset(QGesture *state)
+{
+ if (!state)
+ return;
+ QPinchGesture *pinch = static_cast<QPinchGesture *>(state);
+ QPinchGesturePrivate *d = pinch->d_func();
+
+ d->totalChangeFlags = d->changeFlags = 0;
+
+ d->startCenterPoint = d->lastCenterPoint = d->centerPoint = QPointF();
+ d->totalScaleFactor = d->lastScaleFactor = d->scaleFactor = 1;
+ d->totalRotationAngle = d->lastRotationAngle = d->rotationAngle = 0;
+
+ d->isNewSequence = true;
+ d->startPosition[0] = d->startPosition[1] = QPointF();
+
+ d->gotTouched = false;
+
+ int timerId = state->property("timerid").toInt();
+ if (timerId) {
+ state->killTimer(timerId);
+ state->setProperty("timerid", QVariant());
+ }
+ QGestureRecognizer::reset(state);
+}
+
+//
+// QSwipeGestureRecognizer
+//
+
+QSwipeGestureRecognizer::QSwipeGestureRecognizer()
+{
+}
+
+QGesture *QSwipeGestureRecognizer::create(QObject *target)
+{
+ if (target) {
+ if (target->isWidgetType())
+ static_cast<QWidget *>(target)->setAttribute(Qt::WA_AcceptTouchEvents);
+ else
+ return 0;
+ }
+ return new QSwipeGesture;
+}
+
+QGestureRecognizer::Result QSwipeGestureRecognizer::recognize(QGesture *state,
+ QObject *,
+ QEvent *event)
+{
+ QSwipeGesture *q = static_cast<QSwipeGesture *>(state);
+ QSwipeGesturePrivate *d = q->d_func();
+
+ QGestureRecognizer::Result result;
+
+ switch (event->type()) {
+ case QEvent::TouchBegin: {
+ d->gotTouched = true;
+ d->velocityValue = 1;
+ d->time.start();
+ d->started = true;
+ result = QGestureRecognizer::MayBeGesture;
+ break;
+ }
+ case QEvent::TouchEnd: {
+ if (q->state() != Qt::NoGesture) {
+ result = QGestureRecognizer::FinishGesture;
+ } else {
+ result = QGestureRecognizer::CancelGesture;
+ }
+ break;
+ }
+ case QEvent::TouchUpdate: {
+ const QTouchEvent *ev = static_cast<const QTouchEvent *>(event);
+ if (!d->started)
+ result = QGestureRecognizer::CancelGesture;
+ else if (ev->touchPoints().size() == 2) {
+ QTouchEvent::TouchPoint p1 = ev->touchPoints().at(0);
+ QTouchEvent::TouchPoint p2 = ev->touchPoints().at(1);
+
+ if (d->lastPositions[0].isNull()) {
+ d->lastPositions[0] = p1.startScreenPos().toPoint();
+ d->lastPositions[1] = p2.startScreenPos().toPoint();
+ }
+ d->hotSpot = p1.screenPos();
+ d->isHotSpotSet = true;
+
+ int xDistance = (p1.screenPos().x() - d->lastPositions[0].x() +
+ p2.screenPos().x() - d->lastPositions[1].x()) / 2;
+ int yDistance = (p1.screenPos().y() - d->lastPositions[0].y() +
+ p2.screenPos().y() - d->lastPositions[1].y()) / 2;
+ int absXDistance = qAbs(xDistance);
+ int absYDistance = qAbs(yDistance);
+
+ const int distance = absXDistance >= absYDistance ? absXDistance : absYDistance;
+ int elapsedTime = d->time.restart();
+ if (!elapsedTime)
+ elapsedTime = 1;
+ d->velocityValue = 0.9 * d->velocityValue + distance / elapsedTime;
+ d->swipeAngle = QLineF(p1.startScreenPos(), p1.screenPos()).angle();
+
+ static const int MoveThreshold = 50;
+ if (absXDistance > MoveThreshold || absYDistance > MoveThreshold) {
+ // measure the distance to check if the direction changed
+ d->lastPositions[0] = p1.screenPos().toPoint();
+ d->lastPositions[1] = p2.screenPos().toPoint();
+ QSwipeGesture::SwipeDirection horizontal =
+ xDistance > 0 ? QSwipeGesture::Right : QSwipeGesture::Left;
+ QSwipeGesture::SwipeDirection vertical =
+ yDistance > 0 ? QSwipeGesture::Down : QSwipeGesture::Up;
+ if (d->verticalDirection == QSwipeGesture::NoDirection)
+ d->verticalDirection = vertical;
+ if (d->horizontalDirection == QSwipeGesture::NoDirection)
+ d->horizontalDirection = horizontal;
+ if (d->verticalDirection != vertical || d->horizontalDirection != horizontal) {
+ // the user has changed the direction!
+ result = QGestureRecognizer::CancelGesture;
+ }
+ result = QGestureRecognizer::TriggerGesture;
+ } else {
+ if (q->state() != Qt::NoGesture)
+ result = QGestureRecognizer::TriggerGesture;
+ else
+ result = QGestureRecognizer::MayBeGesture;
+ }
+ } else if (ev->touchPoints().size() > 2) {
+ result = QGestureRecognizer::CancelGesture;
+ } else { // less than 2 touch points
+ if (d->started && (ev->touchPointStates() & Qt::TouchPointPressed))
+ result = QGestureRecognizer::CancelGesture;
+ else if (d->started)
+ result = QGestureRecognizer::Ignore;
+ else
+ result = QGestureRecognizer::MayBeGesture;
+ }
+ break;
+ }
+
+ case QEvent::MouseButtonPress: {
+ if(!d->gotTouched) {
+ const QMouseEvent *ev = static_cast<const QMouseEvent *>(event);
+ d->velocityValue = 1;
+ d->time.start();
+ d->started = true;
+ state->setHotSpot(ev->globalPos());
+ return QGestureRecognizer::MayBeGesture;
+ }
+ return QGestureRecognizer::Ignore;
+ }
+ case QEvent::MouseButtonRelease: {
+ if(!d->gotTouched) {
+ if (q->state() != Qt::NoGesture) {
+ result = QGestureRecognizer::FinishGesture;
+ } else {
+ result = QGestureRecognizer::CancelGesture;
+ }
+ } else
+ result = QGestureRecognizer::Ignore;
+ break;
+ }
+
+ case QEvent::MouseMove: {
+ if(!d->gotTouched) {
+ const QMouseEvent *ev = static_cast<const QMouseEvent *>(event);
+ if (!d->started)
+ result = QGestureRecognizer::CancelGesture;
+ else {
+ if (d->lastPositions[0].isNull()) {
+ d->lastPositions[0] = ev->pos();
+ }
+
+ int xDistance = (ev->x() - d->lastPositions[0].x());
+ int yDistance = (ev->y() - d->lastPositions[0].y());
+ int absXDistance = qAbs(xDistance);
+ int absYDistance = qAbs(yDistance);
+
+ const int distance = absXDistance >= absYDistance ? absXDistance : absYDistance;
+ int elapsedTime = d->time.restart();
+ if (!elapsedTime)
+ elapsedTime = 1;
+ d->velocityValue = 0.9 * d->velocityValue + distance / elapsedTime;
+ d->swipeAngle = QLineF(d->lastPositions[0], ev->pos()).angle();
+
+ static const int MoveThreshold = 50;
+ if (absXDistance > MoveThreshold || absYDistance > MoveThreshold) {
+ // measure the distance to check if the direction changed
+ d->lastPositions[0] = ev->pos();
+ QSwipeGesture::SwipeDirection horizontal =
+ xDistance > 0 ? QSwipeGesture::Right : QSwipeGesture::Left;
+ QSwipeGesture::SwipeDirection vertical =
+ yDistance > 0 ? QSwipeGesture::Down : QSwipeGesture::Up;
+ if (d->verticalDirection == QSwipeGesture::NoDirection)
+ d->verticalDirection = vertical;
+ if (d->horizontalDirection == QSwipeGesture::NoDirection)
+ d->horizontalDirection = horizontal;
+ if (d->verticalDirection != vertical || d->horizontalDirection != horizontal) {
+ // the user has changed the direction!
+ result = QGestureRecognizer::CancelGesture;
+ }
+ result = QGestureRecognizer::TriggerGesture;
+ } else {
+ if (q->state() != Qt::NoGesture)
+ result = QGestureRecognizer::TriggerGesture;
+ else
+ result = QGestureRecognizer::MayBeGesture;
+ }
+ }
+ } else
+ result = QGestureRecognizer::Ignore;
+ break;
+ }
+ default:
+ result = QGestureRecognizer::Ignore;
+ break;
+ }
+ return result;
+}
+
+void QSwipeGestureRecognizer::reset(QGesture *state)
+{
+ if (!state)
+ return;
+ QSwipeGesture *q = static_cast<QSwipeGesture *>(state);
+ QSwipeGesturePrivate *d = q->d_func();
+
+ d->verticalDirection = d->horizontalDirection = QSwipeGesture::NoDirection;
+ d->swipeAngle = 0;
+ d->gotTouched = false;
+
+ d->lastPositions[0] = d->lastPositions[1] = d->lastPositions[2] = QPoint();
+ d->started = false;
+ d->velocityValue = 0;
+ d->time.invalidate();
+
+ QGestureRecognizer::reset(state);
+}
+
+//
+// QTapGestureRecognizer
+//
+
+QTapGestureRecognizer::QTapGestureRecognizer()
+{
+}
+
+QGesture *QTapGestureRecognizer::create(QObject *target)
+{
+ if (target) {
+ if (target->isWidgetType())
+ static_cast<QWidget *>(target)->setAttribute(Qt::WA_AcceptTouchEvents);
+ else
+ return 0;
+ }
+ return new QTapGesture;
+}
+
+QGestureRecognizer::Result QTapGestureRecognizer::recognize(QGesture *state,
+ QObject *,
+ QEvent *event)
+{
+ QTapGesture *q = static_cast<QTapGesture *>(state);
+ QTapGesturePrivate *d = q->d_func();
+
+ QGestureRecognizer::Result result = QGestureRecognizer::CancelGesture;
+
+ switch (event->type()) {
+ case QEvent::TouchBegin: {
+ d->gotTouched = true;
+ const QTouchEvent *ev = static_cast<const QTouchEvent *>(event);
+ d->position = ev->touchPoints().at(0).pos();
+ q->setHotSpot(ev->touchPoints().at(0).screenPos());
+ result = QGestureRecognizer::TriggerGesture;
+ break;
+ }
+ case QEvent::TouchUpdate:
+ case QEvent::TouchEnd: {
+ const QTouchEvent *ev = static_cast<const QTouchEvent *>(event);
+ if (q->state() != Qt::NoGesture && ev->touchPoints().size() == 1) {
+ QTouchEvent::TouchPoint p = ev->touchPoints().at(0);
+ QPoint delta = p.pos().toPoint() - p.startPos().toPoint();
+ enum { TapRadius = 40 };
+ if (delta.manhattanLength() <= TapRadius) {
+ if (event->type() == QEvent::TouchEnd)
+ result = QGestureRecognizer::FinishGesture;
+ else
+ result = QGestureRecognizer::TriggerGesture;
+ }
+ }
+ break;
+ }
+
+ case QEvent::MouseButtonPress:
+ if (!d->gotTouched) {
+ QMouseEvent *ev = static_cast<QMouseEvent *>(event);
+ if (!(ev->modifiers() & Qt::ControlModifier)) {
+ state->setProperty("position", ev->globalPos());
+ state->setHotSpot(ev->globalPos());
+ state->setHandled(false);
+ event->accept();
+ return QGestureRecognizer::TriggerGesture | QGestureRecognizer::ConsumeEventHint;
+ }
+ }
+ return QGestureRecognizer::Ignore;
+
+ case QEvent::MouseMove:
+ return QGestureRecognizer::Ignore;
+
+ case QEvent::MouseButtonRelease:
+ if (!d->gotTouched) {
+ if (state->state() == Qt::GestureStarted) {
+ return QGestureRecognizer::FinishGesture;
+ }
+ }
+ return QGestureRecognizer::Ignore;
+
+ case QEvent::Gesture: {
+ // We check for other gesture events: TapAndHold and Pan both cancel the simple Tap
+ QGestureEvent *ge = static_cast<QGestureEvent *>(event);
+ if (ge->gesture(Qt::PanGesture) || ge->gesture(Qt::TapAndHoldGesture)) {
+ if (state->state() == Qt::GestureStarted || state->state() == Qt::GestureUpdated)
+ return QGestureRecognizer::CancelGesture;
+ }
+ return QGestureRecognizer::Ignore;
+ }
+
+ default:
+ result = QGestureRecognizer::Ignore;
+ break;
+ }
+ return result;
+}
+
+void QTapGestureRecognizer::reset(QGesture *state)
+{
+ if (!state)
+ return;
+ QTapGesture *q = static_cast<QTapGesture *>(state);
+ QTapGesturePrivate *d = q->d_func();
+
+ d->position = QPointF();
+
+ QGestureRecognizer::reset(state);
+}
+
+//
+// QTapAndHoldGestureRecognizer
+//
+
+QTapAndHoldGestureRecognizer::QTapAndHoldGestureRecognizer()
+{
+}
+
+QGesture *QTapAndHoldGestureRecognizer::create(QObject *target)
+{
+ if (target) {
+ if (target->isWidgetType())
+ static_cast<QWidget *>(target)->setAttribute(Qt::WA_AcceptTouchEvents);
+ else
+ return 0;
+ }
+ return new QTapAndHoldGesture;
+}
+
+QGestureRecognizer::Result
+QTapAndHoldGestureRecognizer::recognize(QGesture *state, QObject *object,
+ QEvent *event)
+{
+ QTapAndHoldGesture *q = static_cast<QTapAndHoldGesture *>(state);
+ QTapAndHoldGesturePrivate *d = q->d_func();
+
+ if (object == state && event->type() == QEvent::Timer) {
+ q->killTimer(d->timerId);
+ d->timerId = 0;
+ return QGestureRecognizer::FinishGesture | QGestureRecognizer::ConsumeEventHint;
+ }
+
+ const QTouchEvent *ev = static_cast<const QTouchEvent *>(event);
+// const QMouseEvent *me = static_cast<const QMouseEvent *>(event);
+#ifndef QT_NO_GRAPHICSVIEW
+ const QMouseEvent *gsme = static_cast<const QMouseEvent *>(event);
+#endif
+
+ enum { TapRadius = 40 };
+
+ switch (event->type()) {
+#ifndef QT_NO_GRAPHICSVIEW
+ case QEvent::MouseButtonPress:
+ d->position = gsme->globalPos();
+ q->setHotSpot(d->position);
+ if (d->timerId)
+ q->killTimer(d->timerId);
+ d->timerId = q->startTimer(QTapAndHoldGesturePrivate::Timeout);
+ return QGestureRecognizer::MayBeGesture; // we don't show a sign of life until the timeout
+#endif
+// case QEvent::MouseButtonPress:
+// d->position = me->globalPos();
+// q->setHotSpot(d->position);
+// if (d->timerId)
+// q->killTimer(d->timerId);
+// d->timerId = q->startTimer(QTapAndHoldGesturePrivate::Timeout);
+// return QGestureRecognizer::MayBeGesture; // we don't show a sign of life until the timeout
+ case QEvent::TouchBegin:
+ d->position = ev->touchPoints().at(0).startScreenPos();
+ q->setHotSpot(d->position);
+ if (d->timerId)
+ q->killTimer(d->timerId);
+ d->timerId = q->startTimer(QTapAndHoldGesturePrivate::Timeout);
+ return QGestureRecognizer::MayBeGesture; // we don't show a sign of life until the timeout
+#ifndef QT_NO_GRAPHICSVIEW
+ case QEvent::MouseButtonRelease:
+#endif
+// case QEvent::MouseButtonRelease:
+ case QEvent::TouchEnd:
+ return QGestureRecognizer::CancelGesture; // get out of the MayBeGesture state
+ case QEvent::TouchUpdate:
+ if (d->timerId && ev->touchPoints().size() == 1) {
+ QTouchEvent::TouchPoint p = ev->touchPoints().at(0);
+ QPoint delta = p.pos().toPoint() - p.startPos().toPoint();
+ if (delta.manhattanLength() <= TapRadius)
+ return QGestureRecognizer::MayBeGesture;
+ }
+ return QGestureRecognizer::CancelGesture;
+// case QEvent::MouseMove: {
+// QPoint delta = me->globalPos() - d->position.toPoint();
+// if (d->timerId && delta.manhattanLength() <= TapRadius)
+// return QGestureRecognizer::MayBeGesture;
+// return QGestureRecognizer::CancelGesture;
+// }
+#ifndef QT_NO_GRAPHICSVIEW
+ case QEvent::MouseMove: {
+ QPoint delta = gsme->globalPos() - d->position.toPoint();
+ if (d->timerId && delta.manhattanLength() <= TapRadius)
+ return QGestureRecognizer::MayBeGesture;
+ return QGestureRecognizer::CancelGesture;
+ }
+#endif
+ default:
+ return QGestureRecognizer::Ignore;
+ }
+}
+
+void QTapAndHoldGestureRecognizer::reset(QGesture *state)
+{
+ if (!state)
+ return;
+ QTapAndHoldGesture *q = static_cast<QTapAndHoldGesture *>(state);
+ QTapAndHoldGesturePrivate *d = q->d_func();
+
+ d->position = QPointF();
+ if (d->timerId)
+ q->killTimer(d->timerId);
+ d->timerId = 0;
+
+ QGestureRecognizer::reset(state);
+}
+
+QT_END_NAMESPACE
+
+#endif // QT_NO_GESTURES
diff --git a/qdeclarativegesturerecognizers_p.h b/qdeclarativegesturerecognizers_p.h
new file mode 100644
index 0000000..6ad7e4b
--- /dev/null
+++ b/qdeclarativegesturerecognizers_p.h
@@ -0,0 +1,117 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QML Gesture Area plugin of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QDECLARATIVEGESTURERECOGNIZERS_P_H
+#define QDECLARATIVEGESTURERECOGNIZERS_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists for the convenience
+// of other Qt classes. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include "qgesturerecognizer.h"
+//#include "private/qgesture_p.h"
+
+#ifndef QT_NO_GESTURES
+
+QT_BEGIN_NAMESPACE
+
+class QPanGestureRecognizer : public QGestureRecognizer
+{
+public:
+ QPanGestureRecognizer();
+
+ QGesture *create(QObject *target);
+ QGestureRecognizer::Result recognize(QGesture *state, QObject *watched, QEvent *event);
+ void reset(QGesture *state);
+};
+
+class QPinchGestureRecognizer : public QGestureRecognizer
+{
+public:
+ QPinchGestureRecognizer();
+
+ QGesture *create(QObject *target);
+ QGestureRecognizer::Result recognize(QGesture *state, QObject *watched, QEvent *event);
+ void reset(QGesture *state);
+};
+
+class QSwipeGestureRecognizer : public QGestureRecognizer
+{
+public:
+ QSwipeGestureRecognizer();
+
+ QGesture *create(QObject *target);
+ QGestureRecognizer::Result recognize(QGesture *state, QObject *watched, QEvent *event);
+ void reset(QGesture *state);
+};
+
+class QTapGestureRecognizer : public QGestureRecognizer
+{
+public:
+ QTapGestureRecognizer();
+
+ QGesture *create(QObject *target);
+ QGestureRecognizer::Result recognize(QGesture *state, QObject *watched, QEvent *event);
+ void reset(QGesture *state);
+};
+
+class QTapAndHoldGestureRecognizer : public QGestureRecognizer
+{
+public:
+ QTapAndHoldGestureRecognizer();
+
+ QGesture *create(QObject *target);
+ QGestureRecognizer::Result recognize(QGesture *state, QObject *watched, QEvent *event);
+ void reset(QGesture *state);
+};
+
+QT_END_NAMESPACE
+
+#endif // QT_NO_GESTURES
+
+#endif // QDECLARATIVEGESTURERECOGNIZERS_P_H
diff --git a/qmldir b/qmldir
new file mode 100644
index 0000000..c5a2804
--- /dev/null
+++ b/qmldir
@@ -0,0 +1 @@
+plugin qmlgestureareaplugin