0
|
1 |
/****************************************************************************
|
|
2 |
**
|
|
3 |
** Copyright (C) 2009 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 |
** 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
|
|
14 |
** this package.
|
|
15 |
**
|
|
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.
|
|
23 |
**
|
|
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.
|
|
27 |
**
|
|
28 |
** If you have questions regarding the use of this file, please contact
|
|
29 |
** Nokia at qt-info@nokia.com.
|
|
30 |
**
|
|
31 |
**
|
|
32 |
**
|
|
33 |
**
|
|
34 |
**
|
|
35 |
**
|
|
36 |
**
|
|
37 |
**
|
|
38 |
** $QT_END_LICENSE$
|
|
39 |
**
|
|
40 |
****************************************************************************/
|
|
41 |
|
|
42 |
#include "private/qgesturemanager_p.h"
|
|
43 |
#include "private/qstandardgestures_p.h"
|
|
44 |
#include "private/qwidget_p.h"
|
|
45 |
#include "private/qgesture_p.h"
|
|
46 |
#include "private/qgraphicsitem_p.h"
|
|
47 |
#include "private/qevent_p.h"
|
|
48 |
#include "qgesture.h"
|
|
49 |
#include "qevent.h"
|
|
50 |
#include "qgraphicsitem.h"
|
|
51 |
|
|
52 |
#ifdef Q_WS_MAC
|
|
53 |
#include "qmacgesturerecognizer_mac_p.h"
|
|
54 |
#endif
|
|
55 |
|
|
56 |
#include "qdebug.h"
|
|
57 |
|
|
58 |
// #define GESTURE_DEBUG
|
|
59 |
#ifndef GESTURE_DEBUG
|
|
60 |
# define DEBUG if (0) qDebug
|
|
61 |
#else
|
|
62 |
# define DEBUG qDebug
|
|
63 |
#endif
|
|
64 |
|
|
65 |
QT_BEGIN_NAMESPACE
|
|
66 |
|
|
67 |
QGestureManager::QGestureManager(QObject *parent)
|
|
68 |
: QObject(parent), state(NotGesture), lastCustomGestureId(0)
|
|
69 |
{
|
|
70 |
qRegisterMetaType<Qt::GestureState>();
|
|
71 |
|
|
72 |
#if defined(Q_WS_MAC)
|
|
73 |
registerGestureRecognizer(new QMacSwipeGestureRecognizer);
|
|
74 |
registerGestureRecognizer(new QMacPinchGestureRecognizer);
|
|
75 |
#if defined(QT_MAC_USE_COCOA)
|
|
76 |
registerGestureRecognizer(new QMacPanGestureRecognizer);
|
|
77 |
#endif
|
|
78 |
#else
|
|
79 |
registerGestureRecognizer(new QPanGestureRecognizer);
|
|
80 |
#endif
|
|
81 |
}
|
|
82 |
|
|
83 |
QGestureManager::~QGestureManager()
|
|
84 |
{
|
|
85 |
|
|
86 |
}
|
|
87 |
|
|
88 |
Qt::GestureType QGestureManager::registerGestureRecognizer(QGestureRecognizer *recognizer)
|
|
89 |
{
|
|
90 |
QGesture *dummy = recognizer->createGesture(0);
|
|
91 |
if (!dummy) {
|
|
92 |
qWarning("QGestureManager::registerGestureRecognizer: "
|
|
93 |
"the recognizer fails to create a gesture object, skipping registration.");
|
|
94 |
return Qt::GestureType(0);
|
|
95 |
}
|
|
96 |
Qt::GestureType type = dummy->gestureType();
|
|
97 |
if (type == Qt::CustomGesture) {
|
|
98 |
// generate a new custom gesture id
|
|
99 |
++lastCustomGestureId;
|
|
100 |
type = Qt::GestureType(Qt::CustomGesture + lastCustomGestureId);
|
|
101 |
}
|
|
102 |
recognizers.insertMulti(type, recognizer);
|
|
103 |
delete dummy;
|
|
104 |
return type;
|
|
105 |
}
|
|
106 |
|
|
107 |
void QGestureManager::unregisterGestureRecognizer(Qt::GestureType)
|
|
108 |
{
|
|
109 |
|
|
110 |
}
|
|
111 |
|
|
112 |
QGesture *QGestureManager::getState(QObject *object, Qt::GestureType type)
|
|
113 |
{
|
|
114 |
// if the widget is being deleted we should be carefull and not to
|
|
115 |
// create a new state, as it will create QWeakPointer which doesnt work
|
|
116 |
// from the destructor.
|
|
117 |
if (object->isWidgetType()) {
|
|
118 |
if (static_cast<QWidget *>(object)->d_func()->data.in_destructor)
|
|
119 |
return 0;
|
|
120 |
} else if (QGesture *g = qobject_cast<QGesture *>(object)) {
|
|
121 |
return g;
|
|
122 |
} else {
|
|
123 |
Q_ASSERT(qobject_cast<QGraphicsObject *>(object));
|
|
124 |
}
|
|
125 |
|
|
126 |
QGesture *state =
|
|
127 |
objectGestures.value(QGestureManager::ObjectGesture(object, type));
|
|
128 |
if (!state) {
|
|
129 |
QGestureRecognizer *recognizer = recognizers.value(type);
|
|
130 |
if (recognizer) {
|
|
131 |
state = recognizer->createGesture(object);
|
|
132 |
if (!state)
|
|
133 |
return 0;
|
|
134 |
if (state->gestureType() == Qt::CustomGesture) {
|
|
135 |
// if the recognizer didn't fill in the gesture type, then this
|
|
136 |
// is a custom gesture with autogenerated it and we fill it.
|
|
137 |
state->d_func()->gestureType = type;
|
|
138 |
#if defined(GESTURE_DEBUG)
|
|
139 |
state->setObjectName(QString::number((int)type));
|
|
140 |
#endif
|
|
141 |
}
|
|
142 |
objectGestures.insert(QGestureManager::ObjectGesture(object, type), state);
|
|
143 |
gestureToRecognizer[state] = recognizer;
|
|
144 |
gestureOwners[state] = object;
|
|
145 |
}
|
|
146 |
}
|
|
147 |
return state;
|
|
148 |
}
|
|
149 |
|
|
150 |
bool QGestureManager::filterEventThroughContexts(const QMap<QObject *,
|
|
151 |
Qt::GestureType> &contexts,
|
|
152 |
QEvent *event)
|
|
153 |
{
|
|
154 |
QSet<QGesture *> triggeredGestures;
|
|
155 |
QSet<QGesture *> finishedGestures;
|
|
156 |
QSet<QGesture *> newMaybeGestures;
|
|
157 |
QSet<QGesture *> canceledGestures;
|
|
158 |
QSet<QGesture *> notGestures;
|
|
159 |
|
|
160 |
// TODO: sort contexts by the gesture type and check if one of the contexts
|
|
161 |
// is already active.
|
|
162 |
|
|
163 |
// filter the event through recognizers
|
|
164 |
typedef QMap<QObject *, Qt::GestureType>::const_iterator ContextIterator;
|
|
165 |
for (ContextIterator cit = contexts.begin(), ce = contexts.end(); cit != ce; ++cit) {
|
|
166 |
Qt::GestureType gestureType = cit.value();
|
|
167 |
QMap<Qt::GestureType, QGestureRecognizer *>::const_iterator
|
|
168 |
rit = recognizers.lowerBound(gestureType),
|
|
169 |
re = recognizers.upperBound(gestureType);
|
|
170 |
for (; rit != re; ++rit) {
|
|
171 |
QGestureRecognizer *recognizer = rit.value();
|
|
172 |
QObject *target = cit.key();
|
|
173 |
QGesture *state = getState(target, gestureType);
|
|
174 |
if (!state)
|
|
175 |
continue;
|
|
176 |
QGestureRecognizer::Result result = recognizer->filterEvent(state, target, event);
|
|
177 |
QGestureRecognizer::Result type = result & QGestureRecognizer::ResultState_Mask;
|
|
178 |
if (type == QGestureRecognizer::GestureTriggered) {
|
|
179 |
DEBUG() << "QGestureManager: gesture triggered: " << state;
|
|
180 |
triggeredGestures << state;
|
|
181 |
} else if (type == QGestureRecognizer::GestureFinished) {
|
|
182 |
DEBUG() << "QGestureManager: gesture finished: " << state;
|
|
183 |
finishedGestures << state;
|
|
184 |
} else if (type == QGestureRecognizer::MaybeGesture) {
|
|
185 |
DEBUG() << "QGestureManager: maybe gesture: " << state;
|
|
186 |
newMaybeGestures << state;
|
|
187 |
} else if (type == QGestureRecognizer::NotGesture) {
|
|
188 |
DEBUG() << "QGestureManager: not gesture: " << state;
|
|
189 |
notGestures << state;
|
|
190 |
} else if (type == QGestureRecognizer::Ignore) {
|
|
191 |
DEBUG() << "QGestureManager: gesture ignored the event: " << state;
|
|
192 |
} else {
|
|
193 |
DEBUG() << "QGestureManager: hm, lets assume the recognizer"
|
|
194 |
<< "ignored the event: " << state;
|
|
195 |
}
|
|
196 |
if (result & QGestureRecognizer::ConsumeEventHint) {
|
|
197 |
DEBUG() << "QGestureManager: we were asked to consume the event: "
|
|
198 |
<< state;
|
|
199 |
//TODO: consume events if asked
|
|
200 |
}
|
|
201 |
}
|
|
202 |
}
|
|
203 |
|
|
204 |
QSet<QGesture *> startedGestures = triggeredGestures - activeGestures;
|
|
205 |
triggeredGestures &= activeGestures;
|
|
206 |
|
|
207 |
// check if a running gesture switched back to maybe state
|
|
208 |
QSet<QGesture *> activeToMaybeGestures = activeGestures & newMaybeGestures;
|
|
209 |
|
|
210 |
// check if a running gesture switched back to not gesture state,
|
|
211 |
// i.e. were canceled
|
|
212 |
QSet<QGesture *> activeToCancelGestures = activeGestures & notGestures;
|
|
213 |
canceledGestures += activeToCancelGestures;
|
|
214 |
|
|
215 |
// start timers for new gestures in maybe state
|
|
216 |
foreach (QGesture *state, newMaybeGestures) {
|
|
217 |
QBasicTimer &timer = maybeGestures[state];
|
|
218 |
if (!timer.isActive())
|
|
219 |
timer.start(3000, this);
|
|
220 |
}
|
|
221 |
// kill timers for gestures that were in maybe state
|
|
222 |
QSet<QGesture *> notMaybeGestures = (startedGestures | triggeredGestures
|
|
223 |
| finishedGestures | canceledGestures
|
|
224 |
| notGestures);
|
|
225 |
foreach(QGesture *gesture, notMaybeGestures) {
|
|
226 |
QMap<QGesture *, QBasicTimer>::iterator it =
|
|
227 |
maybeGestures.find(gesture);
|
|
228 |
if (it != maybeGestures.end()) {
|
|
229 |
it.value().stop();
|
|
230 |
maybeGestures.erase(it);
|
|
231 |
}
|
|
232 |
}
|
|
233 |
|
|
234 |
Q_ASSERT((startedGestures & finishedGestures).isEmpty());
|
|
235 |
Q_ASSERT((startedGestures & newMaybeGestures).isEmpty());
|
|
236 |
Q_ASSERT((startedGestures & canceledGestures).isEmpty());
|
|
237 |
Q_ASSERT((finishedGestures & newMaybeGestures).isEmpty());
|
|
238 |
Q_ASSERT((finishedGestures & canceledGestures).isEmpty());
|
|
239 |
Q_ASSERT((canceledGestures & newMaybeGestures).isEmpty());
|
|
240 |
|
|
241 |
QSet<QGesture *> notStarted = finishedGestures - activeGestures;
|
|
242 |
if (!notStarted.isEmpty()) {
|
|
243 |
// there are some gestures that claim to be finished, but never started.
|
|
244 |
// probably those are "singleshot" gestures so we'll fake the started state.
|
|
245 |
foreach (QGesture *gesture, notStarted)
|
|
246 |
gesture->d_func()->state = Qt::GestureStarted;
|
|
247 |
QSet<QGesture *> undeliveredGestures;
|
|
248 |
deliverEvents(notStarted, &undeliveredGestures);
|
|
249 |
finishedGestures -= undeliveredGestures;
|
|
250 |
}
|
|
251 |
|
|
252 |
activeGestures += startedGestures;
|
|
253 |
// sanity check: all triggered gestures should already be in active gestures list
|
|
254 |
Q_ASSERT((activeGestures & triggeredGestures).size() == triggeredGestures.size());
|
|
255 |
activeGestures -= finishedGestures;
|
|
256 |
activeGestures -= activeToMaybeGestures;
|
|
257 |
activeGestures -= canceledGestures;
|
|
258 |
|
|
259 |
// set the proper gesture state on each gesture
|
|
260 |
foreach (QGesture *gesture, startedGestures)
|
|
261 |
gesture->d_func()->state = Qt::GestureStarted;
|
|
262 |
foreach (QGesture *gesture, triggeredGestures)
|
|
263 |
gesture->d_func()->state = Qt::GestureUpdated;
|
|
264 |
foreach (QGesture *gesture, finishedGestures)
|
|
265 |
gesture->d_func()->state = Qt::GestureFinished;
|
|
266 |
foreach (QGesture *gesture, canceledGestures)
|
|
267 |
gesture->d_func()->state = Qt::GestureCanceled;
|
|
268 |
foreach (QGesture *gesture, activeToMaybeGestures)
|
|
269 |
gesture->d_func()->state = Qt::GestureFinished;
|
|
270 |
|
|
271 |
if (!activeGestures.isEmpty() || !maybeGestures.isEmpty() ||
|
|
272 |
!startedGestures.isEmpty() || !triggeredGestures.isEmpty() ||
|
|
273 |
!finishedGestures.isEmpty() || !canceledGestures.isEmpty()) {
|
|
274 |
DEBUG() << "QGestureManager::filterEvent:"
|
|
275 |
<< "\n\tactiveGestures:" << activeGestures
|
|
276 |
<< "\n\tmaybeGestures:" << maybeGestures.keys()
|
|
277 |
<< "\n\tstarted:" << startedGestures
|
|
278 |
<< "\n\ttriggered:" << triggeredGestures
|
|
279 |
<< "\n\tfinished:" << finishedGestures
|
|
280 |
<< "\n\tcanceled:" << canceledGestures;
|
|
281 |
}
|
|
282 |
|
|
283 |
QSet<QGesture *> undeliveredGestures;
|
|
284 |
deliverEvents(startedGestures+triggeredGestures+finishedGestures+canceledGestures,
|
|
285 |
&undeliveredGestures);
|
|
286 |
|
|
287 |
activeGestures -= undeliveredGestures;
|
|
288 |
|
|
289 |
// reset gestures that ended
|
|
290 |
QSet<QGesture *> endedGestures =
|
|
291 |
finishedGestures + canceledGestures + undeliveredGestures;
|
|
292 |
foreach (QGesture *gesture, endedGestures) {
|
|
293 |
if (QGestureRecognizer *recognizer = gestureToRecognizer.value(gesture, 0)) {
|
|
294 |
recognizer->reset(gesture);
|
|
295 |
}
|
|
296 |
gestureTargets.remove(gesture);
|
|
297 |
}
|
|
298 |
return false;
|
|
299 |
}
|
|
300 |
|
|
301 |
bool QGestureManager::filterEvent(QWidget *receiver, QEvent *event)
|
|
302 |
{
|
|
303 |
QSet<Qt::GestureType> types;
|
|
304 |
QMap<QObject *, Qt::GestureType> contexts;
|
|
305 |
QWidget *w = receiver;
|
|
306 |
typedef QMap<Qt::GestureType, Qt::GestureContext>::const_iterator ContextIterator;
|
|
307 |
if (!w->d_func()->gestureContext.isEmpty()) {
|
|
308 |
for(ContextIterator it = w->d_func()->gestureContext.begin(),
|
|
309 |
e = w->d_func()->gestureContext.end(); it != e; ++it) {
|
|
310 |
types.insert(it.key());
|
|
311 |
contexts.insertMulti(w, it.key());
|
|
312 |
}
|
|
313 |
}
|
|
314 |
// find all gesture contexts for the widget tree
|
|
315 |
w = w->isWindow() ? 0 : w->parentWidget();
|
|
316 |
while (w)
|
|
317 |
{
|
|
318 |
for (ContextIterator it = w->d_func()->gestureContext.begin(),
|
|
319 |
e = w->d_func()->gestureContext.end(); it != e; ++it) {
|
|
320 |
if (it.value() == Qt::WidgetWithChildrenGesture) {
|
|
321 |
if (!types.contains(it.key())) {
|
|
322 |
types.insert(it.key());
|
|
323 |
contexts.insertMulti(w, it.key());
|
|
324 |
}
|
|
325 |
}
|
|
326 |
}
|
|
327 |
if (w->isWindow())
|
|
328 |
break;
|
|
329 |
w = w->parentWidget();
|
|
330 |
}
|
|
331 |
return filterEventThroughContexts(contexts, event);
|
|
332 |
}
|
|
333 |
|
|
334 |
bool QGestureManager::filterEvent(QGraphicsObject *receiver, QEvent *event)
|
|
335 |
{
|
|
336 |
QSet<Qt::GestureType> types;
|
|
337 |
QMap<QObject *, Qt::GestureType> contexts;
|
|
338 |
QGraphicsObject *item = receiver;
|
|
339 |
if (!item->QGraphicsItem::d_func()->gestureContext.isEmpty()) {
|
|
340 |
typedef QMap<Qt::GestureType, Qt::GestureContext>::const_iterator ContextIterator;
|
|
341 |
for(ContextIterator it = item->QGraphicsItem::d_func()->gestureContext.begin(),
|
|
342 |
e = item->QGraphicsItem::d_func()->gestureContext.end(); it != e; ++it) {
|
|
343 |
types.insert(it.key());
|
|
344 |
contexts.insertMulti(item, it.key());
|
|
345 |
}
|
|
346 |
}
|
|
347 |
// find all gesture contexts for the graphics object tree
|
|
348 |
item = item->parentObject();
|
|
349 |
while (item)
|
|
350 |
{
|
|
351 |
typedef QMap<Qt::GestureType, Qt::GestureContext>::const_iterator ContextIterator;
|
|
352 |
for (ContextIterator it = item->QGraphicsItem::d_func()->gestureContext.begin(),
|
|
353 |
e = item->QGraphicsItem::d_func()->gestureContext.end(); it != e; ++it) {
|
|
354 |
if (it.value() == Qt::ItemWithChildrenGesture) {
|
|
355 |
if (!types.contains(it.key()))
|
|
356 |
contexts.insertMulti(item, it.key());
|
|
357 |
}
|
|
358 |
}
|
|
359 |
item = item->parentObject();
|
|
360 |
}
|
|
361 |
return filterEventThroughContexts(contexts, event);
|
|
362 |
}
|
|
363 |
|
|
364 |
bool QGestureManager::filterEvent(QGesture *state, QEvent *event)
|
|
365 |
{
|
|
366 |
QMap<QObject *, Qt::GestureType> contexts;
|
|
367 |
contexts.insert(state, state->gestureType());
|
|
368 |
return filterEventThroughContexts(contexts, event);
|
|
369 |
}
|
|
370 |
|
|
371 |
void QGestureManager::getGestureTargets(const QSet<QGesture*> &gestures,
|
|
372 |
QMap<QWidget *, QList<QGesture *> > *conflicts,
|
|
373 |
QMap<QWidget *, QList<QGesture *> > *normal)
|
|
374 |
{
|
|
375 |
typedef QHash<Qt::GestureType, QHash<QWidget *, QGesture *> > GestureByTypes;
|
|
376 |
GestureByTypes gestureByTypes;
|
|
377 |
|
|
378 |
// sort gestures by types
|
|
379 |
foreach (QGesture *gesture, gestures) {
|
|
380 |
QWidget *receiver = gestureTargets.value(gesture, 0);
|
|
381 |
Q_ASSERT(receiver);
|
|
382 |
gestureByTypes[gesture->gestureType()].insert(receiver, gesture);
|
|
383 |
}
|
|
384 |
|
|
385 |
// for each gesture type
|
|
386 |
foreach (Qt::GestureType type, gestureByTypes.keys()) {
|
|
387 |
QHash<QWidget *, QGesture *> gestures = gestureByTypes.value(type);
|
|
388 |
foreach (QWidget *widget, gestures.keys()) {
|
|
389 |
QWidget *w = widget->parentWidget();
|
|
390 |
while (w) {
|
|
391 |
QMap<Qt::GestureType, Qt::GestureContext>::const_iterator it
|
|
392 |
= w->d_func()->gestureContext.find(type);
|
|
393 |
if (it != w->d_func()->gestureContext.end()) {
|
|
394 |
// i.e. 'w' listens to gesture 'type'
|
|
395 |
Qt::GestureContext context = it.value();
|
|
396 |
if (context == Qt::WidgetWithChildrenGesture && w != widget) {
|
|
397 |
// conflicting gesture!
|
|
398 |
(*conflicts)[widget].append(gestures[widget]);
|
|
399 |
break;
|
|
400 |
}
|
|
401 |
}
|
|
402 |
if (w->isWindow()) {
|
|
403 |
w = 0;
|
|
404 |
break;
|
|
405 |
}
|
|
406 |
w = w->parentWidget();
|
|
407 |
}
|
|
408 |
if (!w)
|
|
409 |
(*normal)[widget].append(gestures[widget]);
|
|
410 |
}
|
|
411 |
}
|
|
412 |
}
|
|
413 |
|
|
414 |
void QGestureManager::deliverEvents(const QSet<QGesture *> &gestures,
|
|
415 |
QSet<QGesture *> *undeliveredGestures)
|
|
416 |
{
|
|
417 |
if (gestures.isEmpty())
|
|
418 |
return;
|
|
419 |
|
|
420 |
typedef QMap<QWidget *, QList<QGesture *> > GesturesPerWidget;
|
|
421 |
GesturesPerWidget conflictedGestures;
|
|
422 |
GesturesPerWidget normalStartedGestures;
|
|
423 |
|
|
424 |
QSet<QGesture *> startedGestures;
|
|
425 |
// first figure out the initial receivers of gestures
|
|
426 |
for (QSet<QGesture *>::const_iterator it = gestures.begin(),
|
|
427 |
e = gestures.end(); it != e; ++it) {
|
|
428 |
QGesture *gesture = *it;
|
|
429 |
QWidget *target = gestureTargets.value(gesture, 0);
|
|
430 |
if (!target) {
|
|
431 |
// the gesture has just started and doesn't have a target yet.
|
|
432 |
Q_ASSERT(gesture->state() == Qt::GestureStarted);
|
|
433 |
if (gesture->hasHotSpot()) {
|
|
434 |
// guess the target widget using the hotspot of the gesture
|
|
435 |
QPoint pt = gesture->hotSpot().toPoint();
|
|
436 |
if (QWidget *w = qApp->topLevelAt(pt)) {
|
|
437 |
target = w->childAt(w->mapFromGlobal(pt));
|
|
438 |
}
|
|
439 |
} else {
|
|
440 |
// or use the context of the gesture
|
|
441 |
QObject *context = gestureOwners.value(gesture, 0);
|
|
442 |
if (context->isWidgetType())
|
|
443 |
target = static_cast<QWidget *>(context);
|
|
444 |
}
|
|
445 |
if (target)
|
|
446 |
gestureTargets.insert(gesture, target);
|
|
447 |
}
|
|
448 |
|
|
449 |
Qt::GestureType gestureType = gesture->gestureType();
|
|
450 |
Q_ASSERT(gestureType != Qt::CustomGesture);
|
|
451 |
|
|
452 |
if (target) {
|
|
453 |
if (gesture->state() == Qt::GestureStarted) {
|
|
454 |
startedGestures.insert(gesture);
|
|
455 |
} else {
|
|
456 |
normalStartedGestures[target].append(gesture);
|
|
457 |
}
|
|
458 |
} else {
|
|
459 |
DEBUG() << "QGestureManager::deliverEvent: could not find the target for gesture"
|
|
460 |
<< gesture->gestureType();
|
|
461 |
qWarning("QGestureManager::deliverEvent: could not find the target for gesture");
|
|
462 |
undeliveredGestures->insert(gesture);
|
|
463 |
}
|
|
464 |
}
|
|
465 |
|
|
466 |
getGestureTargets(startedGestures, &conflictedGestures, &normalStartedGestures);
|
|
467 |
DEBUG() << "QGestureManager::deliverEvents:"
|
|
468 |
<< "\nstarted: " << startedGestures
|
|
469 |
<< "\nconflicted: " << conflictedGestures
|
|
470 |
<< "\nnormal: " << normalStartedGestures
|
|
471 |
<< "\n";
|
|
472 |
|
|
473 |
// if there are conflicting gestures, send the GestureOverride event
|
|
474 |
for (GesturesPerWidget::const_iterator it = conflictedGestures.begin(),
|
|
475 |
e = conflictedGestures.end(); it != e; ++it) {
|
|
476 |
QWidget *receiver = it.key();
|
|
477 |
QList<QGesture *> gestures = it.value();
|
|
478 |
DEBUG() << "QGestureManager::deliverEvents: sending GestureOverride to"
|
|
479 |
<< receiver
|
|
480 |
<< "gestures:" << gestures;
|
|
481 |
QGestureEvent event(gestures);
|
|
482 |
event.t = QEvent::GestureOverride;
|
|
483 |
// mark event and individual gestures as ignored
|
|
484 |
event.ignore();
|
|
485 |
foreach(QGesture *g, gestures)
|
|
486 |
event.setAccepted(g, false);
|
|
487 |
|
|
488 |
QApplication::sendEvent(receiver, &event);
|
|
489 |
bool eventAccepted = event.isAccepted();
|
|
490 |
foreach(QGesture *gesture, event.allGestures()) {
|
|
491 |
if (eventAccepted || event.isAccepted(gesture)) {
|
|
492 |
QWidget *w = event.d_func()->targetWidgets.value(gesture->gestureType(), 0);
|
|
493 |
Q_ASSERT(w);
|
|
494 |
DEBUG() << "override event: gesture was accepted:" << gesture << w;
|
|
495 |
QList<QGesture *> &gestures = normalStartedGestures[w];
|
|
496 |
gestures.append(gesture);
|
|
497 |
// override the target
|
|
498 |
gestureTargets[gesture] = w;
|
|
499 |
} else {
|
|
500 |
DEBUG() << "override event: gesture wasn't accepted. putting back:" << gesture;
|
|
501 |
QList<QGesture *> &gestures = normalStartedGestures[receiver];
|
|
502 |
gestures.append(gesture);
|
|
503 |
}
|
|
504 |
}
|
|
505 |
}
|
|
506 |
|
|
507 |
// delivering gestures that are not in conflicted state
|
|
508 |
for (GesturesPerWidget::const_iterator it = normalStartedGestures.begin(),
|
|
509 |
e = normalStartedGestures.end(); it != e; ++it) {
|
|
510 |
if (!it.value().isEmpty()) {
|
|
511 |
DEBUG() << "QGestureManager::deliverEvents: sending to" << it.key()
|
|
512 |
<< "gestures:" << it.value();
|
|
513 |
QGestureEvent event(it.value());
|
|
514 |
QApplication::sendEvent(it.key(), &event);
|
|
515 |
}
|
|
516 |
}
|
|
517 |
}
|
|
518 |
|
|
519 |
void QGestureManager::timerEvent(QTimerEvent *event)
|
|
520 |
{
|
|
521 |
QMap<QGesture*, QBasicTimer>::iterator it = maybeGestures.begin(),
|
|
522 |
e = maybeGestures.end();
|
|
523 |
for (; it != e; ) {
|
|
524 |
QBasicTimer &timer = it.value();
|
|
525 |
Q_ASSERT(timer.isActive());
|
|
526 |
if (timer.timerId() == event->timerId()) {
|
|
527 |
timer.stop();
|
|
528 |
QGesture *gesture = it.key();
|
|
529 |
it = maybeGestures.erase(it);
|
|
530 |
DEBUG() << "QGestureManager::timerEvent: gesture stopped due to timeout:"
|
|
531 |
<< gesture;
|
|
532 |
QGestureRecognizer *recognizer = gestureToRecognizer.value(gesture, 0);
|
|
533 |
if (recognizer)
|
|
534 |
recognizer->reset(gesture);
|
|
535 |
} else {
|
|
536 |
++it;
|
|
537 |
}
|
|
538 |
}
|
|
539 |
}
|
|
540 |
|
|
541 |
QT_END_NAMESPACE
|
|
542 |
|
|
543 |
#include "moc_qgesturemanager_p.cpp"
|