75 #if defined(QT_MAC_USE_COCOA) |
87 #if defined(QT_MAC_USE_COCOA) |
76 registerGestureRecognizer(new QMacPanGestureRecognizer); |
88 registerGestureRecognizer(new QMacPanGestureRecognizer); |
77 #endif |
89 #endif |
78 #else |
90 #else |
79 registerGestureRecognizer(new QPanGestureRecognizer); |
91 registerGestureRecognizer(new QPanGestureRecognizer); |
|
92 registerGestureRecognizer(new QPinchGestureRecognizer); |
|
93 registerGestureRecognizer(new QSwipeGestureRecognizer); |
|
94 registerGestureRecognizer(new QTapGestureRecognizer); |
80 #endif |
95 #endif |
|
96 #if defined(Q_OS_WIN) |
|
97 #if !defined(QT_NO_NATIVE_GESTURES) |
|
98 registerGestureRecognizer(new QWinNativePanGestureRecognizer); |
|
99 #endif |
|
100 #else |
|
101 registerGestureRecognizer(new QTapAndHoldGestureRecognizer); |
|
102 #endif |
81 } |
103 } |
82 |
104 |
83 QGestureManager::~QGestureManager() |
105 QGestureManager::~QGestureManager() |
84 { |
106 { |
85 |
107 qDeleteAll(m_recognizers.values()); |
|
108 foreach (QGestureRecognizer *recognizer, m_obsoleteGestures.keys()) { |
|
109 qDeleteAll(m_obsoleteGestures.value(recognizer)); |
|
110 delete recognizer; |
|
111 } |
|
112 m_obsoleteGestures.clear(); |
86 } |
113 } |
87 |
114 |
88 Qt::GestureType QGestureManager::registerGestureRecognizer(QGestureRecognizer *recognizer) |
115 Qt::GestureType QGestureManager::registerGestureRecognizer(QGestureRecognizer *recognizer) |
89 { |
116 { |
90 QGesture *dummy = recognizer->createGesture(0); |
117 QGesture *dummy = recognizer->create(0); |
91 if (!dummy) { |
118 if (!dummy) { |
92 qWarning("QGestureManager::registerGestureRecognizer: " |
119 qWarning("QGestureManager::registerGestureRecognizer: " |
93 "the recognizer fails to create a gesture object, skipping registration."); |
120 "the recognizer fails to create a gesture object, skipping registration."); |
94 return Qt::GestureType(0); |
121 return Qt::GestureType(0); |
95 } |
122 } |
96 Qt::GestureType type = dummy->gestureType(); |
123 Qt::GestureType type = dummy->gestureType(); |
97 if (type == Qt::CustomGesture) { |
124 if (type == Qt::CustomGesture) { |
98 // generate a new custom gesture id |
125 // generate a new custom gesture id |
99 ++lastCustomGestureId; |
126 ++m_lastCustomGestureId; |
100 type = Qt::GestureType(Qt::CustomGesture + lastCustomGestureId); |
127 type = Qt::GestureType(Qt::CustomGesture + m_lastCustomGestureId); |
101 } |
128 } |
102 recognizers.insertMulti(type, recognizer); |
129 m_recognizers.insertMulti(type, recognizer); |
103 delete dummy; |
130 delete dummy; |
104 return type; |
131 return type; |
105 } |
132 } |
106 |
133 |
107 void QGestureManager::unregisterGestureRecognizer(Qt::GestureType) |
134 void QGestureManager::unregisterGestureRecognizer(Qt::GestureType type) |
108 { |
135 { |
109 |
136 QList<QGestureRecognizer *> list = m_recognizers.values(type); |
110 } |
137 m_recognizers.remove(type); |
111 |
138 foreach (QGesture *g, m_gestureToRecognizer.keys()) { |
112 QGesture *QGestureManager::getState(QObject *object, Qt::GestureType type) |
139 QGestureRecognizer *recognizer = m_gestureToRecognizer.value(g); |
|
140 if (list.contains(recognizer)) { |
|
141 m_deletedRecognizers.insert(g, recognizer); |
|
142 m_gestureToRecognizer.remove(g); |
|
143 } |
|
144 } |
|
145 |
|
146 foreach (QGestureRecognizer *recognizer, list) { |
|
147 QList<QGesture *> obsoleteGestures; |
|
148 QMap<ObjectGesture, QList<QGesture *> >::Iterator iter = m_objectGestures.begin(); |
|
149 while (iter != m_objectGestures.end()) { |
|
150 ObjectGesture objectGesture = iter.key(); |
|
151 if (objectGesture.gesture == type) |
|
152 obsoleteGestures << iter.value(); |
|
153 ++iter; |
|
154 } |
|
155 m_obsoleteGestures.insert(recognizer, obsoleteGestures); |
|
156 } |
|
157 } |
|
158 |
|
159 void QGestureManager::cleanupCachedGestures(QObject *target, Qt::GestureType type) |
|
160 { |
|
161 QMap<ObjectGesture, QList<QGesture *> >::Iterator iter = m_objectGestures.begin(); |
|
162 while (iter != m_objectGestures.end()) { |
|
163 ObjectGesture objectGesture = iter.key(); |
|
164 if (objectGesture.gesture == type && target == objectGesture.object.data()) { |
|
165 qDeleteAll(iter.value()); |
|
166 iter = m_objectGestures.erase(iter); |
|
167 } else { |
|
168 ++iter; |
|
169 } |
|
170 } |
|
171 } |
|
172 |
|
173 // get or create a QGesture object that will represent the state for a given object, used by the recognizer |
|
174 QGesture *QGestureManager::getState(QObject *object, QGestureRecognizer *recognizer, Qt::GestureType type) |
113 { |
175 { |
114 // if the widget is being deleted we should be carefull and not to |
176 // 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 |
177 // create a new state, as it will create QWeakPointer which doesnt work |
116 // from the destructor. |
178 // from the destructor. |
117 if (object->isWidgetType()) { |
179 if (object->isWidgetType()) { |
118 if (static_cast<QWidget *>(object)->d_func()->data.in_destructor) |
180 if (static_cast<QWidget *>(object)->d_func()->data.in_destructor) |
119 return 0; |
181 return 0; |
120 } else if (QGesture *g = qobject_cast<QGesture *>(object)) { |
182 } else if (QGesture *g = qobject_cast<QGesture *>(object)) { |
121 return g; |
183 return g; |
|
184 #ifndef QT_NO_GRAPHICSVIEW |
122 } else { |
185 } else { |
123 Q_ASSERT(qobject_cast<QGraphicsObject *>(object)); |
186 Q_ASSERT(qobject_cast<QGraphicsObject *>(object)); |
124 } |
187 #endif |
125 |
188 } |
126 QGesture *state = |
189 |
127 objectGestures.value(QGestureManager::ObjectGesture(object, type)); |
190 // check if the QGesture for this recognizer has already been created |
128 if (!state) { |
191 foreach (QGesture *state, m_objectGestures.value(QGestureManager::ObjectGesture(object, type))) { |
129 QGestureRecognizer *recognizer = recognizers.value(type); |
192 if (m_gestureToRecognizer.value(state) == recognizer) |
130 if (recognizer) { |
193 return state; |
131 state = recognizer->createGesture(object); |
194 } |
132 if (!state) |
195 |
133 return 0; |
196 Q_ASSERT(recognizer); |
134 if (state->gestureType() == Qt::CustomGesture) { |
197 QGesture *state = recognizer->create(object); |
135 // if the recognizer didn't fill in the gesture type, then this |
198 if (!state) |
136 // is a custom gesture with autogenerated it and we fill it. |
199 return 0; |
137 state->d_func()->gestureType = type; |
200 state->setParent(this); |
|
201 if (state->gestureType() == Qt::CustomGesture) { |
|
202 // if the recognizer didn't fill in the gesture type, then this |
|
203 // is a custom gesture with autogenerated id and we fill it. |
|
204 state->d_func()->gestureType = type; |
138 #if defined(GESTURE_DEBUG) |
205 #if defined(GESTURE_DEBUG) |
139 state->setObjectName(QString::number((int)type)); |
206 state->setObjectName(QString::number((int)type)); |
140 #endif |
207 #endif |
141 } |
208 } |
142 objectGestures.insert(QGestureManager::ObjectGesture(object, type), state); |
209 m_objectGestures[QGestureManager::ObjectGesture(object, type)].append(state); |
143 gestureToRecognizer[state] = recognizer; |
210 m_gestureToRecognizer[state] = recognizer; |
144 gestureOwners[state] = object; |
211 m_gestureOwners[state] = object; |
145 } |
212 |
146 } |
|
147 return state; |
213 return state; |
148 } |
214 } |
149 |
215 |
150 bool QGestureManager::filterEventThroughContexts(const QMap<QObject *, |
216 bool QGestureManager::filterEventThroughContexts(const QMultiMap<QObject *, |
151 Qt::GestureType> &contexts, |
217 Qt::GestureType> &contexts, |
152 QEvent *event) |
218 QEvent *event) |
153 { |
219 { |
154 QSet<QGesture *> triggeredGestures; |
220 QSet<QGesture *> triggeredGestures; |
155 QSet<QGesture *> finishedGestures; |
221 QSet<QGesture *> finishedGestures; |
156 QSet<QGesture *> newMaybeGestures; |
222 QSet<QGesture *> newMaybeGestures; |
157 QSet<QGesture *> canceledGestures; |
|
158 QSet<QGesture *> notGestures; |
223 QSet<QGesture *> notGestures; |
159 |
224 |
160 // TODO: sort contexts by the gesture type and check if one of the contexts |
225 // TODO: sort contexts by the gesture type and check if one of the contexts |
161 // is already active. |
226 // is already active. |
162 |
227 |
|
228 bool ret = false; |
|
229 |
163 // filter the event through recognizers |
230 // filter the event through recognizers |
164 typedef QMap<QObject *, Qt::GestureType>::const_iterator ContextIterator; |
231 typedef QMultiMap<QObject *, Qt::GestureType>::const_iterator ContextIterator; |
165 for (ContextIterator cit = contexts.begin(), ce = contexts.end(); cit != ce; ++cit) { |
232 for (ContextIterator cit = contexts.begin(), ce = contexts.end(); cit != ce; ++cit) { |
166 Qt::GestureType gestureType = cit.value(); |
233 Qt::GestureType gestureType = cit.value(); |
167 QMap<Qt::GestureType, QGestureRecognizer *>::const_iterator |
234 QMap<Qt::GestureType, QGestureRecognizer *>::const_iterator |
168 rit = recognizers.lowerBound(gestureType), |
235 rit = m_recognizers.lowerBound(gestureType), |
169 re = recognizers.upperBound(gestureType); |
236 re = m_recognizers.upperBound(gestureType); |
170 for (; rit != re; ++rit) { |
237 for (; rit != re; ++rit) { |
171 QGestureRecognizer *recognizer = rit.value(); |
238 QGestureRecognizer *recognizer = rit.value(); |
172 QObject *target = cit.key(); |
239 QObject *target = cit.key(); |
173 QGesture *state = getState(target, gestureType); |
240 QGesture *state = getState(target, recognizer, gestureType); |
174 if (!state) |
241 if (!state) |
175 continue; |
242 continue; |
176 QGestureRecognizer::Result result = recognizer->filterEvent(state, target, event); |
243 QGestureRecognizer::Result result = recognizer->recognize(state, target, event); |
177 QGestureRecognizer::Result type = result & QGestureRecognizer::ResultState_Mask; |
244 QGestureRecognizer::Result type = result & QGestureRecognizer::ResultState_Mask; |
178 if (type == QGestureRecognizer::GestureTriggered) { |
245 result &= QGestureRecognizer::ResultHint_Mask; |
179 DEBUG() << "QGestureManager: gesture triggered: " << state; |
246 if (type == QGestureRecognizer::TriggerGesture) { |
|
247 DEBUG() << "QGestureManager:Recognizer: gesture triggered: " << state; |
180 triggeredGestures << state; |
248 triggeredGestures << state; |
181 } else if (type == QGestureRecognizer::GestureFinished) { |
249 } else if (type == QGestureRecognizer::FinishGesture) { |
182 DEBUG() << "QGestureManager: gesture finished: " << state; |
250 DEBUG() << "QGestureManager:Recognizer: gesture finished: " << state; |
183 finishedGestures << state; |
251 finishedGestures << state; |
184 } else if (type == QGestureRecognizer::MaybeGesture) { |
252 } else if (type == QGestureRecognizer::MayBeGesture) { |
185 DEBUG() << "QGestureManager: maybe gesture: " << state; |
253 DEBUG() << "QGestureManager:Recognizer: maybe gesture: " << state; |
186 newMaybeGestures << state; |
254 newMaybeGestures << state; |
187 } else if (type == QGestureRecognizer::NotGesture) { |
255 } else if (type == QGestureRecognizer::CancelGesture) { |
188 DEBUG() << "QGestureManager: not gesture: " << state; |
256 DEBUG() << "QGestureManager:Recognizer: not gesture: " << state; |
189 notGestures << state; |
257 notGestures << state; |
190 } else if (type == QGestureRecognizer::Ignore) { |
258 } else if (type == QGestureRecognizer::Ignore) { |
191 DEBUG() << "QGestureManager: gesture ignored the event: " << state; |
259 DEBUG() << "QGestureManager:Recognizer: ignored the event: " << state; |
192 } else { |
260 } else { |
193 DEBUG() << "QGestureManager: hm, lets assume the recognizer" |
261 DEBUG() << "QGestureManager:Recognizer: hm, lets assume the recognizer" |
194 << "ignored the event: " << state; |
262 << "ignored the event: " << state; |
195 } |
263 } |
196 if (result & QGestureRecognizer::ConsumeEventHint) { |
264 if (result & QGestureRecognizer::ConsumeEventHint) { |
197 DEBUG() << "QGestureManager: we were asked to consume the event: " |
265 DEBUG() << "QGestureManager: we were asked to consume the event: " |
198 << state; |
266 << state; |
199 //TODO: consume events if asked |
267 ret = true; |
200 } |
268 } |
201 } |
269 } |
202 } |
270 } |
203 |
271 if (triggeredGestures.isEmpty() && finishedGestures.isEmpty() |
204 QSet<QGesture *> startedGestures = triggeredGestures - activeGestures; |
272 && newMaybeGestures.isEmpty() && notGestures.isEmpty()) |
205 triggeredGestures &= activeGestures; |
273 return ret; |
|
274 |
|
275 QSet<QGesture *> startedGestures = triggeredGestures - m_activeGestures; |
|
276 triggeredGestures &= m_activeGestures; |
206 |
277 |
207 // check if a running gesture switched back to maybe state |
278 // check if a running gesture switched back to maybe state |
208 QSet<QGesture *> activeToMaybeGestures = activeGestures & newMaybeGestures; |
279 QSet<QGesture *> activeToMaybeGestures = m_activeGestures & newMaybeGestures; |
209 |
280 |
210 // check if a running gesture switched back to not gesture state, |
281 // check if a running gesture switched back to not gesture state, |
211 // i.e. were canceled |
282 // i.e. were canceled |
212 QSet<QGesture *> activeToCancelGestures = activeGestures & notGestures; |
283 QSet<QGesture *> canceledGestures = m_activeGestures & notGestures; |
213 canceledGestures += activeToCancelGestures; |
|
214 |
284 |
215 // start timers for new gestures in maybe state |
285 // start timers for new gestures in maybe state |
216 foreach (QGesture *state, newMaybeGestures) { |
286 foreach (QGesture *state, newMaybeGestures) { |
217 QBasicTimer &timer = maybeGestures[state]; |
287 QBasicTimer &timer = m_maybeGestures[state]; |
218 if (!timer.isActive()) |
288 if (!timer.isActive()) |
219 timer.start(3000, this); |
289 timer.start(3000, this); |
220 } |
290 } |
221 // kill timers for gestures that were in maybe state |
291 // kill timers for gestures that were in maybe state |
222 QSet<QGesture *> notMaybeGestures = (startedGestures | triggeredGestures |
292 QSet<QGesture *> notMaybeGestures = (startedGestures | triggeredGestures |
223 | finishedGestures | canceledGestures |
293 | finishedGestures | canceledGestures |
224 | notGestures); |
294 | notGestures); |
225 foreach(QGesture *gesture, notMaybeGestures) { |
295 foreach(QGesture *gesture, notMaybeGestures) { |
226 QMap<QGesture *, QBasicTimer>::iterator it = |
296 QHash<QGesture *, QBasicTimer>::iterator it = |
227 maybeGestures.find(gesture); |
297 m_maybeGestures.find(gesture); |
228 if (it != maybeGestures.end()) { |
298 if (it != m_maybeGestures.end()) { |
229 it.value().stop(); |
299 it.value().stop(); |
230 maybeGestures.erase(it); |
300 m_maybeGestures.erase(it); |
231 } |
301 } |
232 } |
302 } |
233 |
303 |
234 Q_ASSERT((startedGestures & finishedGestures).isEmpty()); |
304 Q_ASSERT((startedGestures & finishedGestures).isEmpty()); |
235 Q_ASSERT((startedGestures & newMaybeGestures).isEmpty()); |
305 Q_ASSERT((startedGestures & newMaybeGestures).isEmpty()); |
236 Q_ASSERT((startedGestures & canceledGestures).isEmpty()); |
306 Q_ASSERT((startedGestures & canceledGestures).isEmpty()); |
237 Q_ASSERT((finishedGestures & newMaybeGestures).isEmpty()); |
307 Q_ASSERT((finishedGestures & newMaybeGestures).isEmpty()); |
238 Q_ASSERT((finishedGestures & canceledGestures).isEmpty()); |
308 Q_ASSERT((finishedGestures & canceledGestures).isEmpty()); |
239 Q_ASSERT((canceledGestures & newMaybeGestures).isEmpty()); |
309 Q_ASSERT((canceledGestures & newMaybeGestures).isEmpty()); |
240 |
310 |
241 QSet<QGesture *> notStarted = finishedGestures - activeGestures; |
311 QSet<QGesture *> notStarted = finishedGestures - m_activeGestures; |
242 if (!notStarted.isEmpty()) { |
312 if (!notStarted.isEmpty()) { |
243 // there are some gestures that claim to be finished, but never started. |
313 // 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. |
314 // probably those are "singleshot" gestures so we'll fake the started state. |
245 foreach (QGesture *gesture, notStarted) |
315 foreach (QGesture *gesture, notStarted) |
246 gesture->d_func()->state = Qt::GestureStarted; |
316 gesture->d_func()->state = Qt::GestureStarted; |
247 QSet<QGesture *> undeliveredGestures; |
317 QSet<QGesture *> undeliveredGestures; |
248 deliverEvents(notStarted, &undeliveredGestures); |
318 deliverEvents(notStarted, &undeliveredGestures); |
249 finishedGestures -= undeliveredGestures; |
319 finishedGestures -= undeliveredGestures; |
250 } |
320 } |
251 |
321 |
252 activeGestures += startedGestures; |
322 m_activeGestures += startedGestures; |
253 // sanity check: all triggered gestures should already be in active gestures list |
323 // sanity check: all triggered gestures should already be in active gestures list |
254 Q_ASSERT((activeGestures & triggeredGestures).size() == triggeredGestures.size()); |
324 Q_ASSERT((m_activeGestures & triggeredGestures).size() == triggeredGestures.size()); |
255 activeGestures -= finishedGestures; |
325 m_activeGestures -= finishedGestures; |
256 activeGestures -= activeToMaybeGestures; |
326 m_activeGestures -= activeToMaybeGestures; |
257 activeGestures -= canceledGestures; |
327 m_activeGestures -= canceledGestures; |
258 |
328 |
259 // set the proper gesture state on each gesture |
329 // set the proper gesture state on each gesture |
260 foreach (QGesture *gesture, startedGestures) |
330 foreach (QGesture *gesture, startedGestures) |
261 gesture->d_func()->state = Qt::GestureStarted; |
331 gesture->d_func()->state = Qt::GestureStarted; |
262 foreach (QGesture *gesture, triggeredGestures) |
332 foreach (QGesture *gesture, triggeredGestures) |
266 foreach (QGesture *gesture, canceledGestures) |
336 foreach (QGesture *gesture, canceledGestures) |
267 gesture->d_func()->state = Qt::GestureCanceled; |
337 gesture->d_func()->state = Qt::GestureCanceled; |
268 foreach (QGesture *gesture, activeToMaybeGestures) |
338 foreach (QGesture *gesture, activeToMaybeGestures) |
269 gesture->d_func()->state = Qt::GestureFinished; |
339 gesture->d_func()->state = Qt::GestureFinished; |
270 |
340 |
271 if (!activeGestures.isEmpty() || !maybeGestures.isEmpty() || |
341 if (!m_activeGestures.isEmpty() || !m_maybeGestures.isEmpty() || |
272 !startedGestures.isEmpty() || !triggeredGestures.isEmpty() || |
342 !startedGestures.isEmpty() || !triggeredGestures.isEmpty() || |
273 !finishedGestures.isEmpty() || !canceledGestures.isEmpty()) { |
343 !finishedGestures.isEmpty() || !canceledGestures.isEmpty()) { |
274 DEBUG() << "QGestureManager::filterEvent:" |
344 DEBUG() << "QGestureManager::filterEventThroughContexts:" |
275 << "\n\tactiveGestures:" << activeGestures |
345 << "\n\tactiveGestures:" << m_activeGestures |
276 << "\n\tmaybeGestures:" << maybeGestures.keys() |
346 << "\n\tmaybeGestures:" << m_maybeGestures.keys() |
277 << "\n\tstarted:" << startedGestures |
347 << "\n\tstarted:" << startedGestures |
278 << "\n\ttriggered:" << triggeredGestures |
348 << "\n\ttriggered:" << triggeredGestures |
279 << "\n\tfinished:" << finishedGestures |
349 << "\n\tfinished:" << finishedGestures |
280 << "\n\tcanceled:" << canceledGestures; |
350 << "\n\tcanceled:" << canceledGestures; |
281 } |
351 } |
282 |
352 |
283 QSet<QGesture *> undeliveredGestures; |
353 QSet<QGesture *> undeliveredGestures; |
284 deliverEvents(startedGestures+triggeredGestures+finishedGestures+canceledGestures, |
354 deliverEvents(startedGestures+triggeredGestures+finishedGestures+canceledGestures, |
285 &undeliveredGestures); |
355 &undeliveredGestures); |
286 |
356 |
287 activeGestures -= undeliveredGestures; |
357 foreach (QGesture *g, startedGestures) { |
|
358 if (undeliveredGestures.contains(g)) |
|
359 continue; |
|
360 if (g->gestureCancelPolicy() == QGesture::CancelAllInContext) { |
|
361 DEBUG() << "lets try to cancel some"; |
|
362 // find gestures in context in Qt::GestureStarted or Qt::GestureUpdated state and cancel them |
|
363 cancelGesturesForChildren(g); |
|
364 } |
|
365 } |
|
366 |
|
367 m_activeGestures -= undeliveredGestures; |
288 |
368 |
289 // reset gestures that ended |
369 // reset gestures that ended |
290 QSet<QGesture *> endedGestures = |
370 QSet<QGesture *> endedGestures = |
291 finishedGestures + canceledGestures + undeliveredGestures; |
371 finishedGestures + canceledGestures + undeliveredGestures; |
292 foreach (QGesture *gesture, endedGestures) { |
372 foreach (QGesture *gesture, endedGestures) { |
293 if (QGestureRecognizer *recognizer = gestureToRecognizer.value(gesture, 0)) { |
373 recycle(gesture); |
294 recognizer->reset(gesture); |
374 m_gestureTargets.remove(gesture); |
295 } |
375 } |
296 gestureTargets.remove(gesture); |
376 return ret; |
297 } |
377 } |
298 return false; |
378 |
299 } |
379 // Cancel all gestures of children of the widget that original is associated with |
300 |
380 void QGestureManager::cancelGesturesForChildren(QGesture *original) |
|
381 { |
|
382 Q_ASSERT(original); |
|
383 QWidget *originatingWidget = m_gestureTargets.value(original); |
|
384 Q_ASSERT(originatingWidget); |
|
385 |
|
386 // iterate over all active gestures and all maybe gestures |
|
387 // for each find the owner |
|
388 // if the owner is part of our sub-hierarchy, cancel it. |
|
389 |
|
390 QSet<QGesture*> cancelledGestures; |
|
391 QSet<QGesture*>::Iterator iter = m_activeGestures.begin(); |
|
392 while (iter != m_activeGestures.end()) { |
|
393 QWidget *widget = m_gestureTargets.value(*iter); |
|
394 // note that we don't touch the gestures for our originatingWidget |
|
395 if (widget != originatingWidget && originatingWidget->isAncestorOf(widget)) { |
|
396 DEBUG() << " found a gesture to cancel" << (*iter); |
|
397 (*iter)->d_func()->state = Qt::GestureCanceled; |
|
398 cancelledGestures << *iter; |
|
399 iter = m_activeGestures.erase(iter); |
|
400 } else { |
|
401 ++iter; |
|
402 } |
|
403 } |
|
404 |
|
405 // TODO handle 'maybe' gestures too |
|
406 |
|
407 // sort them per target widget by cherry picking from almostCanceledGestures and delivering |
|
408 QSet<QGesture *> almostCanceledGestures = cancelledGestures; |
|
409 while (!almostCanceledGestures.isEmpty()) { |
|
410 QWidget *target = 0; |
|
411 QSet<QGesture*> gestures; |
|
412 iter = almostCanceledGestures.begin(); |
|
413 // sort per target widget |
|
414 while (iter != almostCanceledGestures.end()) { |
|
415 QWidget *widget = m_gestureTargets.value(*iter); |
|
416 if (target == 0) |
|
417 target = widget; |
|
418 if (target == widget) { |
|
419 gestures << *iter; |
|
420 iter = almostCanceledGestures.erase(iter); |
|
421 } else { |
|
422 ++iter; |
|
423 } |
|
424 } |
|
425 Q_ASSERT(target); |
|
426 |
|
427 QSet<QGesture*> undeliveredGestures; |
|
428 deliverEvents(gestures, &undeliveredGestures); |
|
429 } |
|
430 |
|
431 for (iter = cancelledGestures.begin(); iter != cancelledGestures.end(); ++iter) |
|
432 recycle(*iter); |
|
433 } |
|
434 |
|
435 void QGestureManager::cleanupGesturesForRemovedRecognizer(QGesture *gesture) |
|
436 { |
|
437 QGestureRecognizer *recognizer = m_deletedRecognizers.value(gesture); |
|
438 Q_ASSERT(recognizer); |
|
439 m_deletedRecognizers.remove(gesture); |
|
440 if (m_deletedRecognizers.keys(recognizer).isEmpty()) { |
|
441 // no more active gestures, cleanup! |
|
442 qDeleteAll(m_obsoleteGestures.value(recognizer)); |
|
443 m_obsoleteGestures.remove(recognizer); |
|
444 delete recognizer; |
|
445 } |
|
446 } |
|
447 |
|
448 // return true if accepted (consumed) |
301 bool QGestureManager::filterEvent(QWidget *receiver, QEvent *event) |
449 bool QGestureManager::filterEvent(QWidget *receiver, QEvent *event) |
302 { |
450 { |
303 QSet<Qt::GestureType> types; |
451 QMap<Qt::GestureType, int> types; |
304 QMap<QObject *, Qt::GestureType> contexts; |
452 QMultiMap<QObject *, Qt::GestureType> contexts; |
305 QWidget *w = receiver; |
453 QWidget *w = receiver; |
306 typedef QMap<Qt::GestureType, Qt::GestureContext>::const_iterator ContextIterator; |
454 typedef QMap<Qt::GestureType, Qt::GestureFlags>::const_iterator ContextIterator; |
307 if (!w->d_func()->gestureContext.isEmpty()) { |
455 if (!w->d_func()->gestureContext.isEmpty()) { |
308 for(ContextIterator it = w->d_func()->gestureContext.begin(), |
456 for(ContextIterator it = w->d_func()->gestureContext.begin(), |
309 e = w->d_func()->gestureContext.end(); it != e; ++it) { |
457 e = w->d_func()->gestureContext.end(); it != e; ++it) { |
310 types.insert(it.key()); |
458 types.insert(it.key(), 0); |
311 contexts.insertMulti(w, it.key()); |
459 contexts.insertMulti(w, it.key()); |
312 } |
460 } |
313 } |
461 } |
314 // find all gesture contexts for the widget tree |
462 // find all gesture contexts for the widget tree |
315 w = w->isWindow() ? 0 : w->parentWidget(); |
463 w = w->isWindow() ? 0 : w->parentWidget(); |
316 while (w) |
464 while (w) |
317 { |
465 { |
318 for (ContextIterator it = w->d_func()->gestureContext.begin(), |
466 for (ContextIterator it = w->d_func()->gestureContext.begin(), |
319 e = w->d_func()->gestureContext.end(); it != e; ++it) { |
467 e = w->d_func()->gestureContext.end(); it != e; ++it) { |
320 if (it.value() == Qt::WidgetWithChildrenGesture) { |
468 if (!(it.value() & Qt::DontStartGestureOnChildren)) { |
321 if (!types.contains(it.key())) { |
469 if (!types.contains(it.key())) { |
322 types.insert(it.key()); |
470 types.insert(it.key(), 0); |
323 contexts.insertMulti(w, it.key()); |
471 contexts.insertMulti(w, it.key()); |
324 } |
472 } |
325 } |
473 } |
326 } |
474 } |
327 if (w->isWindow()) |
475 if (w->isWindow()) |
328 break; |
476 break; |
329 w = w->parentWidget(); |
477 w = w->parentWidget(); |
330 } |
478 } |
331 return filterEventThroughContexts(contexts, event); |
479 return contexts.isEmpty() ? false : filterEventThroughContexts(contexts, event); |
332 } |
480 } |
333 |
481 |
|
482 #ifndef QT_NO_GRAPHICSVIEW |
334 bool QGestureManager::filterEvent(QGraphicsObject *receiver, QEvent *event) |
483 bool QGestureManager::filterEvent(QGraphicsObject *receiver, QEvent *event) |
335 { |
484 { |
336 QSet<Qt::GestureType> types; |
485 QMap<Qt::GestureType, int> types; |
337 QMap<QObject *, Qt::GestureType> contexts; |
486 QMultiMap<QObject *, Qt::GestureType> contexts; |
338 QGraphicsObject *item = receiver; |
487 QGraphicsObject *item = receiver; |
339 if (!item->QGraphicsItem::d_func()->gestureContext.isEmpty()) { |
488 if (!item->QGraphicsItem::d_func()->gestureContext.isEmpty()) { |
340 typedef QMap<Qt::GestureType, Qt::GestureContext>::const_iterator ContextIterator; |
489 typedef QMap<Qt::GestureType, Qt::GestureFlags>::const_iterator ContextIterator; |
341 for(ContextIterator it = item->QGraphicsItem::d_func()->gestureContext.begin(), |
490 for(ContextIterator it = item->QGraphicsItem::d_func()->gestureContext.begin(), |
342 e = item->QGraphicsItem::d_func()->gestureContext.end(); it != e; ++it) { |
491 e = item->QGraphicsItem::d_func()->gestureContext.end(); it != e; ++it) { |
343 types.insert(it.key()); |
492 types.insert(it.key(), 0); |
344 contexts.insertMulti(item, it.key()); |
493 contexts.insertMulti(item, it.key()); |
345 } |
494 } |
346 } |
495 } |
347 // find all gesture contexts for the graphics object tree |
496 // find all gesture contexts for the graphics object tree |
348 item = item->parentObject(); |
497 item = item->parentObject(); |
349 while (item) |
498 while (item) |
350 { |
499 { |
351 typedef QMap<Qt::GestureType, Qt::GestureContext>::const_iterator ContextIterator; |
500 typedef QMap<Qt::GestureType, Qt::GestureFlags>::const_iterator ContextIterator; |
352 for (ContextIterator it = item->QGraphicsItem::d_func()->gestureContext.begin(), |
501 for (ContextIterator it = item->QGraphicsItem::d_func()->gestureContext.begin(), |
353 e = item->QGraphicsItem::d_func()->gestureContext.end(); it != e; ++it) { |
502 e = item->QGraphicsItem::d_func()->gestureContext.end(); it != e; ++it) { |
354 if (it.value() == Qt::ItemWithChildrenGesture) { |
503 if (!(it.value() & Qt::DontStartGestureOnChildren)) { |
355 if (!types.contains(it.key())) |
504 if (!types.contains(it.key())) { |
|
505 types.insert(it.key(), 0); |
356 contexts.insertMulti(item, it.key()); |
506 contexts.insertMulti(item, it.key()); |
|
507 } |
357 } |
508 } |
358 } |
509 } |
359 item = item->parentObject(); |
510 item = item->parentObject(); |
360 } |
511 } |
361 return filterEventThroughContexts(contexts, event); |
512 return contexts.isEmpty() ? false : filterEventThroughContexts(contexts, event); |
362 } |
513 } |
363 |
514 #endif |
364 bool QGestureManager::filterEvent(QGesture *state, QEvent *event) |
515 |
365 { |
516 bool QGestureManager::filterEvent(QObject *receiver, QEvent *event) |
366 QMap<QObject *, Qt::GestureType> contexts; |
517 { |
|
518 if (!m_gestureToRecognizer.contains(static_cast<QGesture *>(receiver))) |
|
519 return false; |
|
520 QGesture *state = static_cast<QGesture *>(receiver); |
|
521 QMultiMap<QObject *, Qt::GestureType> contexts; |
367 contexts.insert(state, state->gestureType()); |
522 contexts.insert(state, state->gestureType()); |
368 return filterEventThroughContexts(contexts, event); |
523 return filterEventThroughContexts(contexts, event); |
369 } |
524 } |
370 |
525 |
371 void QGestureManager::getGestureTargets(const QSet<QGesture*> &gestures, |
526 void QGestureManager::getGestureTargets(const QSet<QGesture*> &gestures, |