diff options
author | Denis Dzyubenko <denis.dzyubenko@nokia.com> | 2009-05-07 19:07:50 (GMT) |
---|---|---|
committer | Denis Dzyubenko <denis.dzyubenko@nokia.com> | 2009-05-11 14:52:03 (GMT) |
commit | 9f9904c52d3d598b91e589c435fa96333ef1232f (patch) | |
tree | f3784a2b869a5e195983f0d293f4774b746d3856 /src/gui | |
parent | 73a0bca60630abe73deaab49ce310e2537a31abb (diff) | |
download | Qt-9f9904c52d3d598b91e589c435fa96333ef1232f.zip Qt-9f9904c52d3d598b91e589c435fa96333ef1232f.tar.gz Qt-9f9904c52d3d598b91e589c435fa96333ef1232f.tar.bz2 |
Improved gesture target widget detection.
Gesture is now associated with a target widget and whenever several
gesture events occur at the same time if they are supposed to be handled
by different widgets, each widget will receive only gestures related to
itself.
For example this makes possible to use gesture framework with multitouch
when user interacts with two widgets at the same time.
GraphicsView implements is not implemented yet.
Diffstat (limited to 'src/gui')
-rw-r--r-- | src/gui/kernel/qevent.h | 1 | ||||
-rw-r--r-- | src/gui/kernel/qgesture_p.h | 2 | ||||
-rw-r--r-- | src/gui/kernel/qgesturemanager.cpp | 86 | ||||
-rw-r--r-- | src/gui/kernel/qgesturemanager_p.h | 6 |
4 files changed, 61 insertions, 34 deletions
diff --git a/src/gui/kernel/qevent.h b/src/gui/kernel/qevent.h index 280ca79..666cd3f 100644 --- a/src/gui/kernel/qevent.h +++ b/src/gui/kernel/qevent.h @@ -736,6 +736,7 @@ protected: QSet<QString> m_cancelledGestures; friend class QApplication; + friend class QGestureManager; }; #ifndef QT_NO_DEBUG_STREAM diff --git a/src/gui/kernel/qgesture_p.h b/src/gui/kernel/qgesture_p.h index cf4e760..22d6d7f 100644 --- a/src/gui/kernel/qgesture_p.h +++ b/src/gui/kernel/qgesture_p.h @@ -85,6 +85,8 @@ public: QString type; Qt::GestureState state; + QPointer<QWidget> widget; + QRect rect; QPoint hotSpot; QDateTime startTime; diff --git a/src/gui/kernel/qgesturemanager.cpp b/src/gui/kernel/qgesturemanager.cpp index ef4b3d0..a93248a 100644 --- a/src/gui/kernel/qgesturemanager.cpp +++ b/src/gui/kernel/qgesturemanager.cpp @@ -41,6 +41,7 @@ #include "qgesturemanager_p.h" #include "qgesture.h" +#include "qgesture_p.h" #include "qevent.h" #include "qapplication.h" @@ -66,7 +67,7 @@ bool qt_sendSpontaneousEvent(QObject *receiver, QEvent *event); static const unsigned int MaximumGestureRecognitionTimeout = 2000; QGestureManager::QGestureManager(QObject *parent) - : QObject(parent), targetWidget(0), eventDeliveryDelayTimeout(300), + : QObject(parent), eventDeliveryDelayTimeout(300), delayedPressTimer(0), lastMousePressReceiver(0), lastMousePressEvent(QEvent::None, QPoint(), Qt::NoButton, 0, 0), lastGestureId(0), state(NotGesture) { @@ -95,16 +96,6 @@ void QGestureManager::removeRecognizer(QGestureRecognizer *recognizer) bool QGestureManager::filterEvent(QWidget *receiver, QEvent *event) { - if (state != Gesture) { - // find the target widget - QWidget *w = receiver; - while (w && w->d_func()->gestures.isEmpty()) - w = w->parentWidget(); - if (!w) // no widget in the tree that accepts gestures. - return false; - targetWidget = w; - } - QPoint currentPos; switch (event->type()) { case QEvent::MouseButtonPress: @@ -127,7 +118,6 @@ bool QGestureManager::filterEvent(QWidget *receiver, QEvent *event) DEBUG() << "QGestureManager: current event processing state: " << (state == NotGesture ? "NotGesture" : "MaybeGesture"); - Q_ASSERT(targetWidget != 0); QSet<QGestureRecognizer*> stillMaybeGestures; // try other recognizers. foreach(QGestureRecognizer *r, recognizers) { @@ -186,9 +176,7 @@ bool QGestureManager::filterEvent(QWidget *receiver, QEvent *event) gestures << gesture; } Q_ASSERT(!gestures.isEmpty()); - QGestureEvent event(gestures); - ret = sendGestureEvent(targetWidget, &event); - ret = ret && event.isAccepted(); + ret = sendGestureEvent(receiver, gestures); if (!activeGestures.isEmpty()) { DEBUG() << "QGestureManager: new state = Gesture"; @@ -251,6 +239,7 @@ bool QGestureManager::filterEvent(QWidget *receiver, QEvent *event) } } } + // TODO: make sure that if gesture recognizer ignored the event we dont swallow it. activeGestures -= newMaybeGestures; activeGestures -= cancelledGestures; @@ -291,9 +280,7 @@ bool QGestureManager::filterEvent(QWidget *receiver, QEvent *event) foreach(QGestureRecognizer *r, cancelledGestures) cancelledGestureNames << r->gestureType(); if(!gestures.isEmpty()) { - QGestureEvent event(gestures, cancelledGestureNames); - ret = sendGestureEvent(targetWidget, &event); - ret = ret && event.isAccepted(); + ret = sendGestureEvent(receiver, gestures, cancelledGestureNames); } foreach(QGestureRecognizer *r, finishedGestures) @@ -343,6 +330,7 @@ bool QGestureManager::filterEvent(QWidget *receiver, QEvent *event) } lastMousePressReceiver = 0; } + lastMousePressReceiver = 0; killTimer(delayedPressTimer); delayedPressTimer = 0; } else if (state == MaybeGesture && event->type() == QEvent::MouseButtonPress @@ -394,6 +382,7 @@ void QGestureManager::timerEvent(QTimerEvent *event) lastMousePressReceiver = 0; } + lastMousePressReceiver = 0; killTimer(delayedPressTimer); delayedPressTimer = 0; } else { @@ -425,11 +414,6 @@ bool QGestureManager::inGestureMode() return state == Gesture; } -void QGestureManager::setGestureTargetWidget(QWidget *widget) -{ - targetWidget = widget; -} - void QGestureManager::recognizerStateChanged(QGestureRecognizer::Result result) { QGestureRecognizer *recognizer = qobject_cast<QGestureRecognizer*>(sender()); @@ -459,8 +443,7 @@ void QGestureManager::recognizerStateChanged(QGestureRecognizer::Result result) if (QGesture *gesture = recognizer->getGesture()) gestures << gesture; if(!gestures.isEmpty()) { - QGestureEvent event(gestures); - sendGestureEvent(targetWidget, &event); + //FIXME: sendGestureEvent(targetWidget, gestures); } if (result == QGestureRecognizer::GestureFinished) recognizer->reset(); @@ -469,9 +452,7 @@ void QGestureManager::recognizerStateChanged(QGestureRecognizer::Result result) case QGestureRecognizer::MaybeGesture: { DEBUG() << "QGestureManager: maybe gesture: " << recognizer; if (activeGestures.contains(recognizer)) { - QGestureEvent event(QList<QGesture*>(), - QSet<QString>() << recognizer->gestureType()); - sendGestureEvent(targetWidget, &event); + //FIXME: sendGestureEvent(targetWidget, QList<QGesture*>(), QSet<QString>() << recognizer->gestureType()); } if (!maybeGestures.contains(recognizer)) { int timerId = startTimer(MaximumGestureRecognitionTimeout); @@ -499,9 +480,54 @@ void QGestureManager::recognizerStateChanged(QGestureRecognizer::Result result) } } -bool QGestureManager::sendGestureEvent(QWidget *receiver, QGestureEvent *event) +bool QGestureManager::sendGestureEvent(QWidget *receiver, const QList<QGesture*> &gestures, + const QSet<QString> &cancelled) { - return qt_sendSpontaneousEvent(receiver, event); + typedef QMap<QWidget*, QList<QGesture*> > WidgetGesturesMap; + WidgetGesturesMap widgetGestures; + for(QList<QGesture*>::const_iterator it = gestures.begin(), e = gestures.end(); + it != e; ++it) { + QGesture *g = *it; + QGesturePrivate *gd = g->d_func(); + if (g->state() == Qt::GestureStarted) { + // find the target widget + QWidget *w = receiver; + while (w) { + QSet<int>::iterator it = w->d_func()->gestures.begin(), + e = w->d_func()->gestures.end(); + for (; it != e; ++it) { + if (gestureNameFromId(*it) == g->type()) + break; + } + if (it != e) + break; + w = w->parentWidget(); + } + if (!w) // no widget in the tree that accepts this gesture. + continue; + gd->widget = w; + } + if (!gd->widget) { + DEBUG() << "QGestureManager: didn't find a widget to send gesture event (" + << g->type() << ") for tree:" << receiver; + continue; + } + widgetGestures[gd->widget].append(g); + } + + // we return true and stop original from being delivered if any of + // the gesture events were accepted by a receiver. + bool ret = false; + for(WidgetGesturesMap::const_iterator it = widgetGestures.begin(), e = widgetGestures.end(); + it != e; ++it) { + QWidget *receiver = it.key(); + Q_ASSERT(receiver != 0 /*should be taken care above*/); + // TODO: send cancelled gesture event to the widget that received the original gesture! + QGestureEvent event(it.value(), cancelled); + if (qt_sendSpontaneousEvent(receiver, &event) && event.isAccepted()) + ret = true; + } + return ret; } int QGestureManager::eventDeliveryDelay() const diff --git a/src/gui/kernel/qgesturemanager_p.h b/src/gui/kernel/qgesturemanager_p.h index 2b86fcd..beed323 100644 --- a/src/gui/kernel/qgesturemanager_p.h +++ b/src/gui/kernel/qgesturemanager_p.h @@ -70,8 +70,6 @@ class Q_GUI_EXPORT QGestureManager : public QObject public: QGestureManager(QObject *parent); - void setGestureTargetWidget(QWidget *widget); - int eventDeliveryDelay() const; void setEventDeliveryDelay(int ms); @@ -95,13 +93,13 @@ private slots: void recognizerStateChanged(QGestureRecognizer::Result); private: - bool sendGestureEvent(QWidget *receiver, QGestureEvent *event); + bool sendGestureEvent(QWidget *receiver, const QList<QGesture*> &gestures, + const QSet<QString> &cancelled = QSet<QString>()); QSet<QGestureRecognizer*> activeGestures; QMap<QGestureRecognizer*, int> maybeGestures; QSet<QGestureRecognizer*> recognizers; - QWidget *targetWidget; QPoint lastPos; int eventDeliveryDelayTimeout; |