1 /****************************************************************************
3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
4 ** All rights reserved.
5 ** Contact: Nokia Corporation (qt-info@nokia.com)
7 ** This file is part of the QtDeclarative module of the Qt Toolkit.
9 ** $QT_BEGIN_LICENSE:LGPL$
10 ** No Commercial Usage
11 ** This file contains pre-release code and may not be distributed.
12 ** You may use this file in accordance with the terms and conditions
13 ** contained in the Technology Preview License Agreement accompanying
16 ** GNU Lesser General Public License Usage
17 ** Alternatively, this file may be used under the terms of the GNU Lesser
18 ** General Public License version 2.1 as published by the Free Software
19 ** Foundation and appearing in the file LICENSE.LGPL included in the
20 ** packaging of this file. Please review the following information to
21 ** ensure the GNU Lesser General Public License version 2.1 requirements
22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
24 ** In addition, as a special exception, Nokia gives you certain additional
25 ** rights. These rights are described in the Nokia Qt LGPL Exception
26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
28 ** If you have questions regarding the use of this file, please contact
29 ** Nokia at qt-info@nokia.com.
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/qdeclarativeitem_p.h>
51 #include <QtCore/qdebug.h>
52 #include <QtCore/qstringlist.h>
54 #include <QtGui/qevent.h>
56 #include <private/qobject_p.h>
58 #ifndef QT_NO_GESTURES
62 class QDeclarativeGestureAreaPrivate : public QDeclarativeItemPrivate
64 Q_DECLARE_PUBLIC(QDeclarativeGestureArea)
66 QDeclarativeGestureAreaPrivate() : componentcomplete(false), gesture(0) {}
68 typedef QMap<Qt::GestureType,QDeclarativeExpression*> Bindings;
71 bool componentcomplete;
77 bool gestureEvent(QGestureEvent *event);
81 \qmlclass GestureArea QDeclarativeGestureArea
82 \ingroup qml-basic-interaction-elements
84 \brief The GestureArea item enables simple gesture handling.
87 A GestureArea is like a MouseArea, but it has signals for gesture events.
89 \warning Elements in the Qt.labs module are not guaranteed to remain compatible
92 \warning GestureArea is an experimental element whose development has
93 been discontinued. PinchArea is available in QtQuick 1.1 and handles
94 two finger gesture input.
96 \note This element is only functional on devices with touch input.
99 import Qt.labs.gestures 1.0
103 // onPan: ... gesture.acceleration ...
104 // onPinch: ... gesture.rotationAngle ...
112 Each signal has a \e gesture parameter that has the
113 properties of the gesture.
116 \header \o Signal \o Type \o Property \o Description
117 \row \o onTap \o point \o position \o the position of the tap
118 \row \o onTapAndHold \o point \o position \o the position of the tap
119 \row \o onPan \o real \o acceleration \o the acceleration of the pan
120 \row \o onPan \o point \o delta \o the offset from the previous input position to the current input
121 \row \o onPan \o point \o offset \o the total offset from the first input position to the current input position
122 \row \o onPan \o point \o lastOffset \o the previous value of offset
123 \row \o onPinch \o point \o centerPoint \o the midpoint between the two input points
124 \row \o onPinch \o point \o lastCenterPoint \o the previous value of centerPoint
125 \row \o onPinch \o point \o startCenterPoint \o the first value of centerPoint
126 \row \o onPinch \o real \o rotationAngle \o the angle covered by the gesture motion
127 \row \o onPinch \o real \o lastRotationAngle \o the previous value of rotationAngle
128 \row \o onPinch \o real \o totalRotationAngle \o the complete angle covered by the gesture
129 \row \o onPinch \o real \o scaleFactor \o the change in distance between the two input points
130 \row \o onPinch \o real \o lastScaleFactor \o the previous value of scaleFactor
131 \row \o onPinch \o real \o totalScaleFactor \o the complete scale factor of the gesture
132 \row \o onSwipe \o real \o swipeAngle \o the angle of the swipe
135 Custom gestures, handled by onGesture, will have custom properties.
137 GestureArea is an invisible item: it is never painted.
144 \class QDeclarativeGestureArea
145 \brief The QDeclarativeGestureArea class provides simple gesture handling.
148 QDeclarativeGestureArea::QDeclarativeGestureArea(QDeclarativeItem *parent) :
149 QDeclarativeItem(*(new QDeclarativeGestureAreaPrivate), parent)
151 setAcceptedMouseButtons(Qt::LeftButton);
152 setAcceptTouchEvents(true);
155 QDeclarativeGestureArea::~QDeclarativeGestureArea()
160 QDeclarativeGestureAreaParser::compile(const QList<QDeclarativeCustomParserProperty> &props)
163 QDataStream ds(&rv, QIODevice::WriteOnly);
165 for(int ii = 0; ii < props.count(); ++ii)
167 QString propName = QString::fromUtf8(props.at(ii).name());
168 Qt::GestureType type;
170 if (propName == QLatin1String("onTap")) {
171 type = Qt::TapGesture;
172 } else if (propName == QLatin1String("onTapAndHold")) {
173 type = Qt::TapAndHoldGesture;
174 } else if (propName == QLatin1String("onPan")) {
175 type = Qt::PanGesture;
176 } else if (propName == QLatin1String("onPinch")) {
177 type = Qt::PinchGesture;
178 } else if (propName == QLatin1String("onSwipe")) {
179 type = Qt::SwipeGesture;
180 } else if (propName == QLatin1String("onGesture")) {
181 type = Qt::CustomGesture;
183 error(props.at(ii), QDeclarativeGestureArea::tr("Cannot assign to non-existent property \"%1\"").arg(propName));
187 QList<QVariant> values = props.at(ii).assignedValues();
189 for (int i = 0; i < values.count(); ++i) {
190 const QVariant &value = values.at(i);
192 if (value.userType() == qMetaTypeId<QDeclarativeCustomParserNode>()) {
193 error(props.at(ii), QDeclarativeGestureArea::tr("GestureArea: nested objects not allowed"));
195 } else if (value.userType() == qMetaTypeId<QDeclarativeCustomParserProperty>()) {
196 error(props.at(ii), QDeclarativeGestureArea::tr("GestureArea: syntax error"));
199 QDeclarativeParser::Variant v = qvariant_cast<QDeclarativeParser::Variant>(value);
205 error(props.at(ii), QDeclarativeGestureArea::tr("GestureArea: script expected"));
215 void QDeclarativeGestureAreaParser::setCustomData(QObject *object,
216 const QByteArray &data)
218 QDeclarativeGestureArea *ga = static_cast<QDeclarativeGestureArea*>(object);
219 ga->d_func()->data = data;
223 void QDeclarativeGestureArea::connectSignals()
225 Q_D(QDeclarativeGestureArea);
226 if (!d->componentcomplete)
229 QDataStream ds(d->data);
230 while (!ds.atEnd()) {
237 QDeclarativeExpression *exp = new QDeclarativeExpression(qmlContext(this), this, script);
238 d->bindings.insert(Qt::GestureType(gesturetype),exp);
239 grabGesture(Qt::GestureType(gesturetype));
243 void QDeclarativeGestureArea::componentComplete()
245 QDeclarativeItem::componentComplete();
246 Q_D(QDeclarativeGestureArea);
247 d->componentcomplete=true;
251 QGesture *QDeclarativeGestureArea::gesture() const
253 Q_D(const QDeclarativeGestureArea);
257 bool QDeclarativeGestureArea::sceneEvent(QEvent *event)
259 Q_D(QDeclarativeGestureArea);
260 if (event->type() == QEvent::Gesture)
261 return d->gestureEvent(static_cast<QGestureEvent*>(event));
262 return QDeclarativeItem::sceneEvent(event);
265 bool QDeclarativeGestureAreaPrivate::gestureEvent(QGestureEvent *event)
268 for (Bindings::Iterator it = bindings.begin(); it != bindings.end(); ++it) {
269 if ((gesture = event->gesture(it.key()))) {
270 QDeclarativeExpression *expr = it.value();
272 if (expr->hasError())
273 qmlInfo(q_func()) << expr->error();
274 event->setAccepted(true); // XXX only if value returns true?
282 #endif // QT_NO_GESTURES