Fixed crash in GL 2 paint engine on Intel Atom.
[profile/ivi/qtbase.git] / src / widgets / platforms / mac / qmacgesturerecognizer_mac.mm
1 /****************************************************************************
2 **
3 ** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
4 ** All rights reserved.
5 ** Contact: Nokia Corporation (qt-info@nokia.com)
6 **
7 ** This file is part of the QtGui module of the Qt Toolkit.
8 **
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.
17 **
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.
21 **
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.
29 **
30 ** Other Usage
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.
33 **
34 **
35 **
36 **
37 **
38 ** $QT_END_LICENSE$
39 **
40 ****************************************************************************/
41
42 #include "qmacgesturerecognizer_mac_p.h"
43 #include "qgesture.h"
44 #include "qgesture_p.h"
45 #include "qevent.h"
46 #include "qevent_p.h"
47 #include "qwidget.h"
48 #include "qdebug.h"
49
50 #ifndef QT_NO_GESTURES
51
52 QT_BEGIN_NAMESPACE
53
54 QMacSwipeGestureRecognizer::QMacSwipeGestureRecognizer()
55 {
56 }
57
58 QGesture *QMacSwipeGestureRecognizer::create(QObject * /*target*/)
59 {
60     return new QSwipeGesture;
61 }
62
63 QGestureRecognizer::Result
64 QMacSwipeGestureRecognizer::recognize(QGesture *gesture, QObject *obj, QEvent *event)
65 {
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;
74                 break; }
75             default:
76                 break;
77         }
78     }
79
80     return QGestureRecognizer::Ignore;
81 }
82
83 void QMacSwipeGestureRecognizer::reset(QGesture *gesture)
84 {
85     QSwipeGesture *g = static_cast<QSwipeGesture *>(gesture);
86     g->setSwipeAngle(0);
87     QGestureRecognizer::reset(gesture);
88 }
89
90 ////////////////////////////////////////////////////////////////////////
91
92 QMacPinchGestureRecognizer::QMacPinchGestureRecognizer()
93 {
94 }
95
96 QGesture *QMacPinchGestureRecognizer::create(QObject * /*target*/)
97 {
98     return new QPinchGesture;
99 }
100
101 QGestureRecognizer::Result
102 QMacPinchGestureRecognizer::recognize(QGesture *gesture, QObject *obj, QEvent *event)
103 {
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:
109             reset(gesture);
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;
124         }
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;
135         default:
136             break;
137         }
138     }
139
140     return QGestureRecognizer::Ignore;
141 }
142
143 void QMacPinchGestureRecognizer::reset(QGesture *gesture)
144 {
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);
158 }
159
160 ////////////////////////////////////////////////////////////////////////
161
162
163 QMacPanGestureRecognizer::QMacPanGestureRecognizer() : _panCanceled(true)
164 {
165 }
166
167 QGesture *QMacPanGestureRecognizer::create(QObject *target)
168 {
169     if (!target)
170         return new QPanGesture;
171
172     if (QWidget *w = qobject_cast<QWidget *>(target)) {
173         w->setAttribute(Qt::WA_AcceptTouchEvents);
174         w->setAttribute(Qt::WA_TouchPadAcceptSingleTouchEvents);
175         return new QPanGesture;
176     }
177     return 0;
178 }
179
180 QGestureRecognizer::Result
181 QMacPanGestureRecognizer::recognize(QGesture *gesture, QObject *target, QEvent *event)
182 {
183     const int panBeginDelay = 300;
184     const int panBeginRadius = 3;
185
186     QPanGesture *g = static_cast<QPanGesture *>(gesture);
187
188     switch (event->type()) {
189     case QEvent::TouchBegin: {
190         const QTouchEvent *ev = static_cast<const QTouchEvent*>(event);
191         if (ev->touchPoints().size() == 1) {
192             reset(gesture);
193             _startPos = QCursor::pos();
194             _panTimer.start(panBeginDelay, target);
195             _panCanceled = false;
196             return QGestureRecognizer::MayBeGesture;
197         }
198         break;}
199     case QEvent::TouchEnd: {
200         if (_panCanceled)
201             break;
202
203         const QTouchEvent *ev = static_cast<const QTouchEvent*>(event);
204         if (ev->touchPoints().size() == 1)
205             return QGestureRecognizer::FinishGesture;
206         break;}
207     case QEvent::TouchUpdate: {
208         if (_panCanceled)
209             break;
210
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) {
218                     _panCanceled = true;
219                     _panTimer.stop();
220                     return QGestureRecognizer::CancelGesture;
221                 }
222             } else {
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;
229             }
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:
233             _panCanceled = true;
234             _panTimer.stop();
235             return QGestureRecognizer::CancelGesture;
236         }
237         break;}
238     case QEvent::Timer: {
239         QTimerEvent *ev = static_cast<QTimerEvent *>(event);
240         if (ev->timerId() == _panTimer.timerId()) {
241             _panTimer.stop();
242             if (_panCanceled)
243                 break;
244             // Begin new pan session!
245             _startPos = QCursor::pos();
246             g->setHotSpot(_startPos);
247             return QGestureRecognizer::TriggerGesture | QGestureRecognizer::ConsumeEventHint;
248         }
249         break; }
250     default:
251         break;
252     }
253
254     return QGestureRecognizer::Ignore;
255 }
256
257 void QMacPanGestureRecognizer::reset(QGesture *gesture)
258 {
259     QPanGesture *g = static_cast<QPanGesture *>(gesture);
260     _startPos = QPointF();
261     _panCanceled = true;
262     g->setOffset(QPointF(0, 0));
263     g->setLastOffset(QPointF(0, 0));
264     g->setAcceleration(qreal(1));
265     QGestureRecognizer::reset(gesture);
266 }
267
268 QT_END_NAMESPACE
269
270 #endif // QT_NO_GESTURES