1 /****************************************************************************
3 ** Copyright (C) 2012 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 QtGui 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 "qmacgesturerecognizer_mac_p.h"
44 #include "qgesture_p.h"
50 #ifndef QT_NO_GESTURES
54 QMacSwipeGestureRecognizer::QMacSwipeGestureRecognizer()
58 QGesture *QMacSwipeGestureRecognizer::create(QObject * /*target*/)
60 return new QSwipeGesture;
63 QGestureRecognizer::Result
64 QMacSwipeGestureRecognizer::recognize(QGesture *gesture, QObject *obj, QEvent *event)
66 if (event->type() == QEvent::NativeGesture && obj->isWidgetType()) {
67 QNativeGestureEvent *ev = static_cast<QNativeGestureEvent*>(event);
68 switch (ev->gestureType) {
69 case QNativeGestureEvent::Swipe: {
70 QSwipeGesture *g = static_cast<QSwipeGesture *>(gesture);
71 g->setSwipeAngle(ev->angle);
72 g->setHotSpot(ev->position);
73 return QGestureRecognizer::FinishGesture | QGestureRecognizer::ConsumeEventHint;
80 return QGestureRecognizer::Ignore;
83 void QMacSwipeGestureRecognizer::reset(QGesture *gesture)
85 QSwipeGesture *g = static_cast<QSwipeGesture *>(gesture);
87 QGestureRecognizer::reset(gesture);
90 ////////////////////////////////////////////////////////////////////////
92 QMacPinchGestureRecognizer::QMacPinchGestureRecognizer()
96 QGesture *QMacPinchGestureRecognizer::create(QObject * /*target*/)
98 return new QPinchGesture;
101 QGestureRecognizer::Result
102 QMacPinchGestureRecognizer::recognize(QGesture *gesture, QObject *obj, QEvent *event)
104 if (event->type() == QEvent::NativeGesture && obj->isWidgetType()) {
105 QPinchGesture *g = static_cast<QPinchGesture *>(gesture);
106 QNativeGestureEvent *ev = static_cast<QNativeGestureEvent*>(event);
107 switch(ev->gestureType) {
108 case QNativeGestureEvent::GestureBegin:
110 g->setStartCenterPoint(static_cast<QWidget*>(obj)->mapFromGlobal(ev->position));
111 g->setCenterPoint(g->startCenterPoint());
112 g->setChangeFlags(QPinchGesture::CenterPointChanged);
113 g->setTotalChangeFlags(g->totalChangeFlags() | g->changeFlags());
114 g->setHotSpot(ev->position);
115 return QGestureRecognizer::MayBeGesture | QGestureRecognizer::ConsumeEventHint;
116 case QNativeGestureEvent::Rotate: {
117 g->setLastScaleFactor(g->scaleFactor());
118 g->setLastRotationAngle(g->rotationAngle());
119 g->setRotationAngle(g->rotationAngle() + ev->percentage);
120 g->setChangeFlags(QPinchGesture::RotationAngleChanged);
121 g->setTotalChangeFlags(g->totalChangeFlags() | g->changeFlags());
122 g->setHotSpot(ev->position);
123 return QGestureRecognizer::TriggerGesture | QGestureRecognizer::ConsumeEventHint;
125 case QNativeGestureEvent::Zoom:
126 g->setLastScaleFactor(g->scaleFactor());
127 g->setLastRotationAngle(g->rotationAngle());
128 g->setScaleFactor(g->scaleFactor() * (1 + ev->percentage));
129 g->setChangeFlags(QPinchGesture::ScaleFactorChanged);
130 g->setTotalChangeFlags(g->totalChangeFlags() | g->changeFlags());
131 g->setHotSpot(ev->position);
132 return QGestureRecognizer::TriggerGesture | QGestureRecognizer::ConsumeEventHint;
133 case QNativeGestureEvent::GestureEnd:
134 return QGestureRecognizer::FinishGesture | QGestureRecognizer::ConsumeEventHint;
140 return QGestureRecognizer::Ignore;
143 void QMacPinchGestureRecognizer::reset(QGesture *gesture)
145 QPinchGesture *g = static_cast<QPinchGesture *>(gesture);
146 g->setChangeFlags(0);
147 g->setTotalChangeFlags(0);
148 g->setScaleFactor(1.0f);
149 g->setTotalScaleFactor(1.0f);
150 g->setLastScaleFactor(1.0f);
151 g->setRotationAngle(0.0f);
152 g->setTotalRotationAngle(0.0f);
153 g->setLastRotationAngle(0.0f);
154 g->setCenterPoint(QPointF());
155 g->setStartCenterPoint(QPointF());
156 g->setLastCenterPoint(QPointF());
157 QGestureRecognizer::reset(gesture);
160 ////////////////////////////////////////////////////////////////////////
163 QMacPanGestureRecognizer::QMacPanGestureRecognizer() : _panCanceled(true)
167 QGesture *QMacPanGestureRecognizer::create(QObject *target)
170 return new QPanGesture;
172 if (QWidget *w = qobject_cast<QWidget *>(target)) {
173 w->setAttribute(Qt::WA_AcceptTouchEvents);
174 w->setAttribute(Qt::WA_TouchPadAcceptSingleTouchEvents);
175 return new QPanGesture;
180 QGestureRecognizer::Result
181 QMacPanGestureRecognizer::recognize(QGesture *gesture, QObject *target, QEvent *event)
183 const int panBeginDelay = 300;
184 const int panBeginRadius = 3;
186 QPanGesture *g = static_cast<QPanGesture *>(gesture);
188 switch (event->type()) {
189 case QEvent::TouchBegin: {
190 const QTouchEvent *ev = static_cast<const QTouchEvent*>(event);
191 if (ev->touchPoints().size() == 1) {
193 _startPos = QCursor::pos();
194 _panTimer.start(panBeginDelay, target);
195 _panCanceled = false;
196 return QGestureRecognizer::MayBeGesture;
199 case QEvent::TouchEnd: {
203 const QTouchEvent *ev = static_cast<const QTouchEvent*>(event);
204 if (ev->touchPoints().size() == 1)
205 return QGestureRecognizer::FinishGesture;
207 case QEvent::TouchUpdate: {
211 const QTouchEvent *ev = static_cast<const QTouchEvent*>(event);
212 if (ev->touchPoints().size() == 1) {
213 if (_panTimer.isActive()) {
214 // INVARIANT: Still in maybeGesture. Check if the user
215 // moved his finger so much that it makes sense to cancel the pan:
216 const QPointF p = QCursor::pos();
217 if ((p - _startPos).manhattanLength() > panBeginRadius) {
220 return QGestureRecognizer::CancelGesture;
223 const QPointF p = QCursor::pos();
224 const QPointF posOffset = p - _startPos;
225 g->setLastOffset(g->offset());
226 g->setOffset(QPointF(posOffset.x(), posOffset.y()));
227 g->setHotSpot(_startPos);
228 return QGestureRecognizer::TriggerGesture;
230 } else if (_panTimer.isActive()) {
231 // I only want to cancel the pan if the user is pressing
232 // more than one finger, and the pan hasn't started yet:
235 return QGestureRecognizer::CancelGesture;
238 case QEvent::Timer: {
239 QTimerEvent *ev = static_cast<QTimerEvent *>(event);
240 if (ev->timerId() == _panTimer.timerId()) {
244 // Begin new pan session!
245 _startPos = QCursor::pos();
246 g->setHotSpot(_startPos);
247 return QGestureRecognizer::TriggerGesture | QGestureRecognizer::ConsumeEventHint;
254 return QGestureRecognizer::Ignore;
257 void QMacPanGestureRecognizer::reset(QGesture *gesture)
259 QPanGesture *g = static_cast<QPanGesture *>(gesture);
260 _startPos = QPointF();
262 g->setOffset(QPointF(0, 0));
263 g->setLastOffset(QPointF(0, 0));
264 g->setAcceleration(qreal(1));
265 QGestureRecognizer::reset(gesture);
270 #endif // QT_NO_GESTURES