diff options
author | Denis Dzyubenko <denis.dzyubenko@nokia.com> | 2009-10-28 20:40:14 (GMT) |
---|---|---|
committer | Denis Dzyubenko <denis.dzyubenko@nokia.com> | 2009-11-03 10:26:06 (GMT) |
commit | cfcfae65778f2e1e7fc3936c66689e3685f1cc77 (patch) | |
tree | 728c38f0e9603e174e0d6391ab50542693ed2191 /src | |
parent | 4843b437b90800d238f14e7a4558045ddc37cd4b (diff) | |
download | Qt-cfcfae65778f2e1e7fc3936c66689e3685f1cc77.zip Qt-cfcfae65778f2e1e7fc3936c66689e3685f1cc77.tar.gz Qt-cfcfae65778f2e1e7fc3936c66689e3685f1cc77.tar.bz2 |
Modified gesture events propagation.
By default if the gesture is ignored, only gestures in the started state
are propagated, and accepting a gesture in the started state adds an
implicit grab meaning all the following events in the gesture sequence
will be delivered to that widget. This is similar to the way QTouchEvent
is propagated.
Also added a hint, which specifies if gestures in any state can be
propagated to the widget which has enabled the hint.
Reviewed-by: Thomas Zander
Diffstat (limited to 'src')
-rw-r--r-- | src/corelib/global/qnamespace.h | 12 | ||||
-rw-r--r-- | src/corelib/global/qnamespace.qdoc | 18 | ||||
-rw-r--r-- | src/gui/graphicsview/qgraphicsscene.cpp | 13 | ||||
-rw-r--r-- | src/gui/kernel/qapplication.cpp | 7 | ||||
-rw-r--r-- | src/gui/kernel/qgesturemanager.cpp | 16 |
5 files changed, 54 insertions, 12 deletions
diff --git a/src/corelib/global/qnamespace.h b/src/corelib/global/qnamespace.h index aeaca54..561ffc1 100644 --- a/src/corelib/global/qnamespace.h +++ b/src/corelib/global/qnamespace.h @@ -1715,14 +1715,19 @@ public: LastGestureType = ~0u }; - enum GestureContext + enum GestureContextFlag { WidgetGesture = 0, WidgetWithChildrenGesture = 3, - ItemGesture = WidgetGesture, - ItemWithChildrenGesture = WidgetWithChildrenGesture + ItemGesture = WidgetGesture, + ItemWithChildrenGesture = WidgetWithChildrenGesture, + + GestureContext_Mask = 0x00ff, + AcceptPartialGesturesHint = 0x0100, + GestureContextHint_Mask = 0xff00 }; + Q_DECLARE_FLAGS(GestureContext, GestureContextFlag) enum NavigationMode { @@ -1757,6 +1762,7 @@ Q_DECLARE_OPERATORS_FOR_FLAGS(Qt::MatchFlags) Q_DECLARE_OPERATORS_FOR_FLAGS(Qt::TextInteractionFlags) Q_DECLARE_OPERATORS_FOR_FLAGS(Qt::InputMethodHints) Q_DECLARE_OPERATORS_FOR_FLAGS(Qt::TouchPointStates) +Q_DECLARE_OPERATORS_FOR_FLAGS(Qt::GestureContext) typedef bool (*qInternalCallback)(void **); diff --git a/src/corelib/global/qnamespace.qdoc b/src/corelib/global/qnamespace.qdoc index 3fcbe57..f2a8882 100644 --- a/src/corelib/global/qnamespace.qdoc +++ b/src/corelib/global/qnamespace.qdoc @@ -2917,11 +2917,11 @@ QApplication::registerGestureRecognizer() function which generates a custom gesture ID in the range of values from CustomGesture to LastGestureType. - \sa QGesture, QWidget::grabGesture() + \sa QGesture, QWidget::grabGesture(), QGraphicsObject::grabGesture() */ /*! - \enum Qt::GestureContext + \enum Qt::GestureContextFlag \since 4.6 This enum type describes the context of a gesture. @@ -2937,7 +2937,19 @@ \value ItemWithChildrenGesture Gestures can start on the item or over any of its children. - \sa QWidget::grabGesture() + \value AcceptPartialGesturesHint Allows any ignored gesture events to be + propagated to parent widgets which have specified this hint. By default + only gestures that are in the Qt::GestureStarted state are propagated and + the widget only gets the full gesture sequence starting with a gesture in + the Qt::GestureStarted state and ending with a gesture in the + Qt::GestureFinished or Qt::GestureCanceled states. + + \value GestureContext_Mask A mask for extracting the context type of the + context flags. + \value GestureContextHint_Mask A mask for extracting additional hints for + the context. + + \sa QWidget::grabGesture(), QGraphicsObject::grabGesture() */ /*! diff --git a/src/gui/graphicsview/qgraphicsscene.cpp b/src/gui/graphicsview/qgraphicsscene.cpp index 9279fe3..f5bb408 100644 --- a/src/gui/graphicsview/qgraphicsscene.cpp +++ b/src/gui/graphicsview/qgraphicsscene.cpp @@ -5900,7 +5900,12 @@ void QGraphicsScenePrivate::gestureEventHandler(QGestureEvent *event) QGraphicsItemPrivate *gid = item->QGraphicsItem::d_func(); foreach(QGesture *g, alreadyIgnoredGestures) { - if (gid->gestureContext.contains(g->gestureType())) + QMap<Qt::GestureType, Qt::GestureContext>::iterator contextit = + gid->gestureContext.find(g->gestureType()); + bool deliver = contextit != gid->gestureContext.end() && + (g->state() == Qt::GestureStarted || + (contextit.value() & Qt::GestureContextHint_Mask) & Qt::AcceptPartialGesturesHint); + if (deliver) gestures += g; } if (gestures.isEmpty()) @@ -5913,8 +5918,12 @@ void QGraphicsScenePrivate::gestureEventHandler(QGestureEvent *event) sendEvent(item, &ev); QSet<QGesture *> ignoredGestures; foreach (QGesture *g, gestures) { - if (!ev.isAccepted() && !ev.isAccepted(g)) + if (!ev.isAccepted() && !ev.isAccepted(g)) { ignoredGestures.insert(g); + } else { + if (g->state() == Qt::GestureStarted) + gestureTargets[g] = item; + } } if (!ignoredGestures.isEmpty()) { // get a list of items under the (current) hotspot of each ignored diff --git a/src/gui/kernel/qapplication.cpp b/src/gui/kernel/qapplication.cpp index 06787eb..b9e7d52 100644 --- a/src/gui/kernel/qapplication.cpp +++ b/src/gui/kernel/qapplication.cpp @@ -4161,7 +4161,12 @@ bool QApplication::notify(QObject *receiver, QEvent *e) for (int i = 0; i < allGestures.size();) { QGesture *g = allGestures.at(i); Qt::GestureType type = g->gestureType(); - if (wd->gestureContext.contains(type)) { + QMap<Qt::GestureType, Qt::GestureContext>::iterator contextit = + wd->gestureContext.find(type); + bool deliver = contextit != wd->gestureContext.end() && + (g->state() == Qt::GestureStarted || w == receiver || + (contextit.value() & Qt::GestureContextHint_Mask) & Qt::AcceptPartialGesturesHint); + if (deliver) { allGestures.removeAt(i); gestures.append(g); } else { diff --git a/src/gui/kernel/qgesturemanager.cpp b/src/gui/kernel/qgesturemanager.cpp index 318d4b5..e4a1eb4 100644 --- a/src/gui/kernel/qgesturemanager.cpp +++ b/src/gui/kernel/qgesturemanager.cpp @@ -448,7 +448,7 @@ bool QGestureManager::filterEvent(QWidget *receiver, QEvent *event) { for (ContextIterator it = w->d_func()->gestureContext.begin(), e = w->d_func()->gestureContext.end(); it != e; ++it) { - if (it.value() == Qt::WidgetWithChildrenGesture) { + if ((it.value() & Qt::GestureContext_Mask) == Qt::WidgetWithChildrenGesture) { if (!types.contains(it.key())) { types.insert(it.key()); contexts.insertMulti(w, it.key()); @@ -482,7 +482,7 @@ bool QGestureManager::filterEvent(QGraphicsObject *receiver, QEvent *event) typedef QMap<Qt::GestureType, Qt::GestureContext>::const_iterator ContextIterator; for (ContextIterator it = item->QGraphicsItem::d_func()->gestureContext.begin(), e = item->QGraphicsItem::d_func()->gestureContext.end(); it != e; ++it) { - if (it.value() == Qt::ItemWithChildrenGesture) { + if ((it.value() & Qt::GestureContext_Mask) == Qt::ItemWithChildrenGesture) { if (!types.contains(it.key())) { types.insert(it.key()); contexts.insertMulti(item, it.key()); @@ -525,7 +525,7 @@ void QGestureManager::getGestureTargets(const QSet<QGesture*> &gestures, = w->d_func()->gestureContext.find(type); if (it != w->d_func()->gestureContext.end()) { // i.e. 'w' listens to gesture 'type' - Qt::GestureContext context = it.value(); + Qt::GestureContext context = it.value() & Qt::GestureContext_Mask; if (context == Qt::WidgetWithChildrenGesture && w != widget) { // conflicting gesture! (*conflicts)[widget].append(gestures[widget]); @@ -645,6 +645,16 @@ void QGestureManager::deliverEvents(const QSet<QGesture *> &gestures, << "gestures:" << it.value(); QGestureEvent event(it.value()); QApplication::sendEvent(it.key(), &event); + bool eventAccepted = event.isAccepted(); + foreach (QGesture *gesture, event.allGestures()) { + if (gesture->state() == Qt::GestureStarted && + (eventAccepted || event.isAccepted(gesture))) { + QWidget *w = event.d_func()->targetWidgets.value(gesture->gestureType(), 0); + Q_ASSERT(w); + DEBUG() << "started gesture was delivered and accepted by" << w; + m_gestureTargets[gesture] = w; + } + } } } } |