From fc84e3a05d01cce25949c605fc56dba4b4d3d183 Mon Sep 17 00:00:00 2001 From: Denis Dzyubenko Date: Thu, 5 Mar 2009 18:41:10 +0100 Subject: Fixes: improved gesture manager event filtering. Details: Several fixes - parsing only spontaneous mouse events and send gesture events to QGraphicsSceneItems according to their z-order --- src/gui/graphicsview/qgraphicsitem.cpp | 5 ++++ src/gui/graphicsview/qgraphicsitem.h | 1 + src/gui/graphicsview/qgraphicsscene.cpp | 19 ++++++++++----- src/gui/kernel/qapplication.cpp | 43 ++++++++++++++++++--------------- 4 files changed, 42 insertions(+), 26 deletions(-) diff --git a/src/gui/graphicsview/qgraphicsitem.cpp b/src/gui/graphicsview/qgraphicsitem.cpp index 58f04f0..a9ad1e1 100644 --- a/src/gui/graphicsview/qgraphicsitem.cpp +++ b/src/gui/graphicsview/qgraphicsitem.cpp @@ -5802,6 +5802,11 @@ void QGraphicsItem::releaseGesture(const Qt::GestureType &type) d_ptr->scene->d_func()->releaseGesture(this, type); } +QSet QGraphicsItem::gestures() const +{ + return d_ptr->gestures; +} + /*! This virtual function is called by QGraphicsItem to notify custom items that some part of the item's state changes. By reimplementing this diff --git a/src/gui/graphicsview/qgraphicsitem.h b/src/gui/graphicsview/qgraphicsitem.h index 42a5110..2b4cdf5 100644 --- a/src/gui/graphicsview/qgraphicsitem.h +++ b/src/gui/graphicsview/qgraphicsitem.h @@ -340,6 +340,7 @@ public: void grabGesture(const Qt::GestureType &type); void releaseGesture(const Qt::GestureType &type); + QSet gestures() const; enum { Type = 1, diff --git a/src/gui/graphicsview/qgraphicsscene.cpp b/src/gui/graphicsview/qgraphicsscene.cpp index 873e28c..21c7c81 100644 --- a/src/gui/graphicsview/qgraphicsscene.cpp +++ b/src/gui/graphicsview/qgraphicsscene.cpp @@ -5614,18 +5614,25 @@ void QGraphicsScene::gestureEvent(QGestureEvent *event) { Q_D(QGraphicsScene); QList gestureTypes = event->gestureTypes(); - QList pts; QGraphicsView *view = qobject_cast(event->targetWidget()); if (!view) { // something is wrong. Q_ASSERT(view); return; } - foreach(const Qt::GestureType &type, gestureTypes) - pts << view->mapToScene(event->gesture(type)->hotSpot()); - foreach(QGraphicsItem *item, d->itemsWithGestures) { - for (int i = 0; i < pts.size(); ++i) { - if (item->contains(item->mapFromScene(pts.at(i)))) { + QPolygonF poly; + QMap hotSpots; + foreach(const Qt::GestureType &type, gestureTypes) { + QPointF pt = view->mapToScene(event->gesture(type)->hotSpot()); + hotSpots.insert(type, pt); + poly << pt; + } + + foreach(QGraphicsItem *item, items(poly, Qt::IntersectsItemBoundingRect)) { + QMap::const_iterator it = hotSpots.begin(), + e = hotSpots.end(); + for(; it != e; ++it) { + if (item->contains(item->mapFromScene(it.value())) && item->gestures().contains(it.key())) { d->sendGestureEvent(item, event); if (event->isAccepted()) break; diff --git a/src/gui/kernel/qapplication.cpp b/src/gui/kernel/qapplication.cpp index b39cbc3..88871a4 100644 --- a/src/gui/kernel/qapplication.cpp +++ b/src/gui/kernel/qapplication.cpp @@ -3706,28 +3706,31 @@ bool QApplication::notify(QObject *receiver, QEvent *e) QMouseEvent* mouse = static_cast(e); QPoint relpos = mouse->pos(); - if (QApplication::testAttribute(Qt::AA_EnableGestures)) { - if (!gestureManager) - gestureManager = new QGestureManager; - // if we are in gesture mode, we send all mouse events - // directly to gesture recognizer. - if (gestureManager->inGestureMode()) { - // ### should I send events through all application event filters? - if (gestureManager->filterEvent(e)) - return true; - } - if (w && (mouse->type() != QEvent::MouseMove || mouse->buttons() != 0)) { - // find the gesture target widget - QWidget *target = w; - while (target && target->gestures().isEmpty()) - target = target->parentWidget(); - if (target) { - gestureManager->setGestureTargetWidget(target); - res = gestureManager->filterEvent(e); + if (e->spontaneous()) { + if (QApplication::testAttribute(Qt::AA_EnableGestures)) { + QWidget *w = static_cast(receiver); + if (!gestureManager) + gestureManager = new QGestureManager; + // if we are in gesture mode, we send all mouse events + // directly to gesture recognizer. + if (gestureManager->inGestureMode()) { + if (gestureManager->filterEvent(e)) + return true; + } else { + QMouseEvent* mouse = static_cast(e); + if (w && (mouse->type() != QEvent::MouseMove || mouse->buttons() != 0)) { + // find the gesture target widget + QWidget *target = w; + while (target && target->gestures().isEmpty()) + target = target->parentWidget(); + if (target) { + gestureManager->setGestureTargetWidget(target); + if (gestureManager->filterEvent(e)) + return true; + } + } } } - } - if (e->spontaneous()) { if (e->type() == QEvent::MouseButtonPress) { QApplicationPrivate::giveFocusAccordingToFocusPolicy(w, Qt::ClickFocus, -- cgit v0.12