|
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" |