1 /****************************************************************************
3 ** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
4 ** All rights reserved.
5 ** Contact: http://www.qt-project.org/
7 ** This file is part of the QtDeclarative module of the Qt Toolkit.
9 ** $QT_BEGIN_LICENSE:LGPL$
10 ** GNU Lesser General Public License Usage
11 ** This file may be used under the terms of the GNU Lesser General Public
12 ** License version 2.1 as published by the Free Software Foundation and
13 ** appearing in the file LICENSE.LGPL included in the packaging of this
14 ** file. Please review the following information to ensure the GNU Lesser
15 ** General Public License version 2.1 requirements will be met:
16 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
18 ** In addition, as a special exception, Nokia gives you certain additional
19 ** rights. These rights are described in the Nokia Qt LGPL Exception
20 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
22 ** GNU General Public License Usage
23 ** Alternatively, this file may be used under the terms of the GNU General
24 ** Public License version 3.0 as published by the Free Software Foundation
25 ** and appearing in the file LICENSE.GPL included in the packaging of this
26 ** file. Please review the following information to ensure the GNU General
27 ** Public License version 3.0 requirements will be met:
28 ** http://www.gnu.org/copyleft/gpl.html.
31 ** Alternatively, this file may be used in accordance with the terms and
32 ** conditions contained in a signed written agreement between you and Nokia.
40 ****************************************************************************/
42 #include "qdeclarativegesturearea_p.h"
44 #include <qdeclarativeexpression.h>
45 #include <qdeclarativecontext.h>
46 #include <qdeclarativeinfo.h>
48 #include <private/qdeclarativeproperty_p.h>
49 #include <private/qdeclarativescript_p.h>
50 #include <QtQuick1/private/qdeclarativeitem_p.h>
52 #include <QtCore/qdebug.h>
53 #include <QtCore/qstringlist.h>
55 #include <QtGui/qevent.h>
57 #include <private/qobject_p.h>
59 #ifndef QT_NO_GESTURES
63 class QDeclarativeGestureAreaPrivate : public QDeclarativeItemPrivate
65 Q_DECLARE_PUBLIC(QDeclarativeGestureArea)
67 QDeclarativeGestureAreaPrivate() : componentcomplete(false), gesture(0) {}
69 typedef QMap<Qt::GestureType,QDeclarativeExpression*> Bindings;
72 bool componentcomplete;
78 bool gestureEvent(QGestureEvent *event);
82 \qmlclass GestureArea QDeclarativeGestureArea
83 \ingroup qml-basic-interaction-elements
85 \brief The GestureArea item enables simple gesture handling.
88 A GestureArea is like a MouseArea, but it has signals for gesture events.
90 \warning Elements in the Qt.labs module are not guaranteed to remain compatible
93 \warning GestureArea is an experimental element whose development has
94 been discontinued. PinchArea is available in QtQuick 1.1 and handles
95 two finger gesture input.
97 \note This element is only functional on devices with touch input.
100 import Qt.labs.gestures 1.0
104 // onPan: ... gesture.acceleration ...
105 // onPinch: ... gesture.rotationAngle ...
113 Each signal has a \e gesture parameter that has the
114 properties of the gesture.
117 \header \o Signal \o Type \o Property \o Description
118 \row \o onTap \o point \o position \o the position of the tap
119 \row \o onTapAndHold \o point \o position \o the position of the tap
120 \row \o onPan \o real \o acceleration \o the acceleration of the pan
121 \row \o onPan \o point \o delta \o the offset from the previous input position to the current input
122 \row \o onPan \o point \o offset \o the total offset from the first input position to the current input position
123 \row \o onPan \o point \o lastOffset \o the previous value of offset
124 \row \o onPinch \o point \o centerPoint \o the midpoint between the two input points
125 \row \o onPinch \o point \o lastCenterPoint \o the previous value of centerPoint
126 \row \o onPinch \o point \o startCenterPoint \o the first value of centerPoint
127 \row \o onPinch \o real \o rotationAngle \o the angle covered by the gesture motion
128 \row \o onPinch \o real \o lastRotationAngle \o the previous value of rotationAngle
129 \row \o onPinch \o real \o totalRotationAngle \o the complete angle covered by the gesture
130 \row \o onPinch \o real \o scaleFactor \o the change in distance between the two input points
131 \row \o onPinch \o real \o lastScaleFactor \o the previous value of scaleFactor
132 \row \o onPinch \o real \o totalScaleFactor \o the complete scale factor of the gesture
133 \row \o onSwipe \o real \o swipeAngle \o the angle of the swipe
136 Custom gestures, handled by onGesture, will have custom properties.
138 GestureArea is an invisible item: it is never painted.
145 \class QDeclarativeGestureArea
146 \brief The QDeclarativeGestureArea class provides simple gesture handling.
149 QDeclarativeGestureArea::QDeclarativeGestureArea(QDeclarativeItem *parent) :
150 QDeclarativeItem(*(new QDeclarativeGestureAreaPrivate), parent)
152 setAcceptedMouseButtons(Qt::LeftButton);
153 setAcceptTouchEvents(true);
156 QDeclarativeGestureArea::~QDeclarativeGestureArea()
161 QDeclarativeGestureAreaParser::compile(const QList<QDeclarativeCustomParserProperty> &props)
164 QDataStream ds(&rv, QIODevice::WriteOnly);
166 for(int ii = 0; ii < props.count(); ++ii)
168 QString propName = props.at(ii).name();
169 Qt::GestureType type;
171 if (propName == QLatin1String("onTap")) {
172 type = Qt::TapGesture;
173 } else if (propName == QLatin1String("onTapAndHold")) {
174 type = Qt::TapAndHoldGesture;
175 } else if (propName == QLatin1String("onPan")) {
176 type = Qt::PanGesture;
177 } else if (propName == QLatin1String("onPinch")) {
178 type = Qt::PinchGesture;
179 } else if (propName == QLatin1String("onSwipe")) {
180 type = Qt::SwipeGesture;
181 } else if (propName == QLatin1String("onGesture")) {
182 type = Qt::CustomGesture;
184 error(props.at(ii), QDeclarativeGestureArea::tr("Cannot assign to non-existent property \"%1\"").arg(propName));
188 QList<QVariant> values = props.at(ii).assignedValues();
190 for (int i = 0; i < values.count(); ++i) {
191 const QVariant &value = values.at(i);
193 if (value.userType() == qMetaTypeId<QDeclarativeCustomParserNode>()) {
194 error(props.at(ii), QDeclarativeGestureArea::tr("GestureArea: nested objects not allowed"));
196 } else if (value.userType() == qMetaTypeId<QDeclarativeCustomParserProperty>()) {
197 error(props.at(ii), QDeclarativeGestureArea::tr("GestureArea: syntax error"));
200 QDeclarativeScript::Variant v = qvariant_cast<QDeclarativeScript::Variant>(value);
206 error(props.at(ii), QDeclarativeGestureArea::tr("GestureArea: script expected"));
216 void QDeclarativeGestureAreaParser::setCustomData(QObject *object,
217 const QByteArray &data)
219 QDeclarativeGestureArea *ga = static_cast<QDeclarativeGestureArea*>(object);
220 ga->d_func()->data = data;
224 void QDeclarativeGestureArea::connectSignals()
226 Q_D(QDeclarativeGestureArea);
227 if (!d->componentcomplete)
230 QDataStream ds(d->data);
231 while (!ds.atEnd()) {
238 QDeclarativeExpression *exp = new QDeclarativeExpression(qmlContext(this), this, script);
239 d->bindings.insert(Qt::GestureType(gesturetype),exp);
240 grabGesture(Qt::GestureType(gesturetype));
244 void QDeclarativeGestureArea::componentComplete()
246 QDeclarativeItem::componentComplete();
247 Q_D(QDeclarativeGestureArea);
248 d->componentcomplete=true;
252 QGesture *QDeclarativeGestureArea::gesture() const
254 Q_D(const QDeclarativeGestureArea);
258 bool QDeclarativeGestureArea::sceneEvent(QEvent *event)
260 Q_D(QDeclarativeGestureArea);
261 if (event->type() == QEvent::Gesture)
262 return d->gestureEvent(static_cast<QGestureEvent*>(event));
263 return QDeclarativeItem::sceneEvent(event);
266 bool QDeclarativeGestureAreaPrivate::gestureEvent(QGestureEvent *event)
269 for (Bindings::Iterator it = bindings.begin(); it != bindings.end(); ++it) {
270 if ((gesture = event->gesture(it.key()))) {
271 QDeclarativeExpression *expr = it.value();
273 if (expr->hasError())
274 qmlInfo(q_func()) << expr->error();
275 event->setAccepted(true); // XXX only if value returns true?
283 #endif // QT_NO_GESTURES