summaryrefslogtreecommitdiffstats
path: root/src/gui/kernel/qgesturemanager.cpp
diff options
context:
space:
mode:
authorThomas Zander <t.zander@nokia.com>2009-10-27 14:31:16 (GMT)
committerThomas Zander <thomas.zander@trolltech.com>2009-10-28 11:37:04 (GMT)
commit4470801f73b86d3ee06a866fbbdafcaeb9f294a6 (patch)
tree0b587d391267b55b369c7c7439a7033bab087918 /src/gui/kernel/qgesturemanager.cpp
parent9a9cd7765bfe879b53488fe18bba75425e4c5c61 (diff)
downloadQt-4470801f73b86d3ee06a866fbbdafcaeb9f294a6.zip
Qt-4470801f73b86d3ee06a866fbbdafcaeb9f294a6.tar.gz
Qt-4470801f73b86d3ee06a866fbbdafcaeb9f294a6.tar.bz2
Introduce QGesture::GestureCancelPolicy, a way to auto-cancel gestures
On accepting one gesture Qt can automatically cancel other gestures that belong to other targets. The policy is normally set to not cancel any other gestures and can be set to cancel all active gestures in the context. For example for all child widgets. Reviewed-By: Denis Dzyubenko
Diffstat (limited to 'src/gui/kernel/qgesturemanager.cpp')
-rw-r--r--src/gui/kernel/qgesturemanager.cpp85
1 files changed, 81 insertions, 4 deletions
diff --git a/src/gui/kernel/qgesturemanager.cpp b/src/gui/kernel/qgesturemanager.cpp
index 52f8eef..fc7c8b2 100644
--- a/src/gui/kernel/qgesturemanager.cpp
+++ b/src/gui/kernel/qgesturemanager.cpp
@@ -322,21 +322,96 @@ bool QGestureManager::filterEventThroughContexts(const QMap<QObject *,
deliverEvents(startedGestures+triggeredGestures+finishedGestures+canceledGestures,
&undeliveredGestures);
+ foreach (QGesture *g, startedGestures) {
+ if (undeliveredGestures.contains(g))
+ continue;
+ if (g->gestureCancelPolicy() == QGesture::CancelAllInContext) {
+ DEBUG() << "lets try to cancel some";
+ // find gestures in context in Qt::GestureStarted or Qt::GestureUpdated state and cancel them
+ cancelGesturesForChildren(g);
+ }
+ }
+
activeGestures -= undeliveredGestures;
// reset gestures that ended
QSet<QGesture *> endedGestures =
finishedGestures + canceledGestures + undeliveredGestures;
foreach (QGesture *gesture, endedGestures) {
- if (QGestureRecognizer *recognizer = gestureToRecognizer.value(gesture, 0))
+ if (QGestureRecognizer *recognizer = gestureToRecognizer.value(gesture, 0)) {
+ gesture->setGestureCancelPolicy(QGesture::CancelNone);
recognizer->reset(gesture);
- else
+ } else {
cleanupGesturesForRemovedRecognizer(gesture);
+ }
gestureTargets.remove(gesture);
}
return ret;
}
+// Cancel all gestures of children of the widget that original is associated with
+void QGestureManager::cancelGesturesForChildren(QGesture *original)
+{
+ Q_ASSERT(original);
+ QWidget *originatingWidget = gestureTargets.value(original);
+ Q_ASSERT(originatingWidget);
+
+ // iterate over all active gestures and all maybe gestures
+ // for each find the owner
+ // if the owner is part of our sub-hierarchy, cancel it.
+
+ QSet<QGesture*> cancelledGestures;
+ QSet<QGesture*>::Iterator iter = activeGestures.begin();
+ while (iter != activeGestures.end()) {
+ QWidget *widget = gestureTargets.value(*iter);
+ // note that we don't touch the gestures for our originatingWidget
+ if (widget != originatingWidget && originatingWidget->isAncestorOf(widget)) {
+ DEBUG() << " found a gesture to cancel" << (*iter);
+ (*iter)->d_func()->state = Qt::GestureCanceled;
+ cancelledGestures << *iter;
+ iter = activeGestures.erase(iter);
+ } else {
+ ++iter;
+ }
+ }
+
+ // TODO handle 'maybe' gestures too
+
+ // sort them per target widget by cherry picking from almostCanceledGestures and delivering
+ QSet<QGesture *> almostCanceledGestures = cancelledGestures;
+ while (!almostCanceledGestures.isEmpty()) {
+ QWidget *target = 0;
+ QSet<QGesture*> gestures;
+ iter = almostCanceledGestures.begin();
+ // sort per target widget
+ while (iter != almostCanceledGestures.end()) {
+ QWidget *widget = gestureTargets.value(*iter);
+ if (target == 0)
+ target = widget;
+ if (target == widget) {
+ gestures << *iter;
+ iter = almostCanceledGestures.erase(iter);
+ } else {
+ ++iter;
+ }
+ }
+ Q_ASSERT(target);
+
+ QSet<QGesture*> undeliveredGestures;
+ deliverEvents(gestures, &undeliveredGestures);
+ }
+
+ for (iter = cancelledGestures.begin(); iter != cancelledGestures.end(); ++iter) {
+ QGestureRecognizer *recognizer = gestureToRecognizer.value(*iter, 0);
+ if (recognizer) {
+ (*iter)->setGestureCancelPolicy(QGesture::CancelNone);
+ recognizer->reset(*iter);
+ } else {
+ cleanupGesturesForRemovedRecognizer(*iter);
+ }
+ }
+}
+
void QGestureManager::cleanupGesturesForRemovedRecognizer(QGesture *gesture)
{
QGestureRecognizer *recognizer = m_deletedRecognizers.value(gesture);
@@ -585,10 +660,12 @@ void QGestureManager::timerEvent(QTimerEvent *event)
DEBUG() << "QGestureManager::timerEvent: gesture stopped due to timeout:"
<< gesture;
QGestureRecognizer *recognizer = gestureToRecognizer.value(gesture, 0);
- if (recognizer)
+ if (recognizer) {
+ gesture->setGestureCancelPolicy(QGesture::CancelNone);
recognizer->reset(gesture);
- else
+ } else {
cleanupGesturesForRemovedRecognizer(gesture);
+ }
} else {
++it;
}