diff options
author | Bradley T. Hughes <bradley.hughes@nokia.com> | 2009-05-18 13:32:39 (GMT) |
---|---|---|
committer | Bradley T. Hughes <bradley.hughes@nokia.com> | 2009-05-18 13:32:39 (GMT) |
commit | 6cc1e0106845a0dfe9433c4413b3c064c73ccfe2 (patch) | |
tree | a0372fb3e03000dc1e1f93a4154adecd70fd5119 /src/gui/graphicsview | |
parent | 86edc526684d80e405bcd1c63b5a314b70408679 (diff) | |
parent | 537243d70de1474cf234880b215c75e83e80abcd (diff) | |
download | Qt-6cc1e0106845a0dfe9433c4413b3c064c73ccfe2.zip Qt-6cc1e0106845a0dfe9433c4413b3c064c73ccfe2.tar.gz Qt-6cc1e0106845a0dfe9433c4413b3c064c73ccfe2.tar.bz2 |
Merge branch 'master' of git@scm.dev.nokia.troll.no:qt/qt-multitouch
Diffstat (limited to 'src/gui/graphicsview')
-rw-r--r-- | src/gui/graphicsview/qgraphicsitem.cpp | 44 | ||||
-rw-r--r-- | src/gui/graphicsview/qgraphicsitem_p.h | 6 | ||||
-rw-r--r-- | src/gui/graphicsview/qgraphicsproxywidget.cpp | 16 | ||||
-rw-r--r-- | src/gui/graphicsview/qgraphicsscene.cpp | 120 | ||||
-rw-r--r-- | src/gui/graphicsview/qgraphicsscene_p.h | 5 | ||||
-rw-r--r-- | src/gui/graphicsview/qgraphicssceneevent.cpp | 9 | ||||
-rw-r--r-- | src/gui/graphicsview/qgraphicssceneevent.h | 1 | ||||
-rw-r--r-- | src/gui/graphicsview/qgraphicsview.cpp | 1 |
8 files changed, 169 insertions, 33 deletions
diff --git a/src/gui/graphicsview/qgraphicsitem.cpp b/src/gui/graphicsview/qgraphicsitem.cpp index 747d510..ae33674 100644 --- a/src/gui/graphicsview/qgraphicsitem.cpp +++ b/src/gui/graphicsview/qgraphicsitem.cpp @@ -5857,6 +5857,7 @@ QVariant QGraphicsItem::inputMethodQuery(Qt::InputMethodQuery query) const */ int QGraphicsItem::grabGesture(Qt::GestureType gesture) { + /// TODO: if we are QGraphicsProxyWidget we should subscribe the widget to gesture as well. return grabGesture(qt_getStandardGestureTypeName(gesture)); } @@ -5872,12 +5873,30 @@ int QGraphicsItem::grabGesture(Qt::GestureType gesture) int QGraphicsItem::grabGesture(const QString &gesture) { int id = QGestureManager::instance()->makeGestureId(gesture); - d_ptr->gestures << id; - if (d_ptr->scene) - d_ptr->scene->d_func()->grabGesture(this, id); + d_ptr->grabGesture(id); return id; } +void QGraphicsItemPrivate::grabGesture(int id) +{ + Q_Q(QGraphicsItem); + gestures << id; + if (scene) + scene->d_func()->grabGesture(q, id); +} + +bool QGraphicsItemPrivate::releaseGesture(int id) +{ + Q_Q(QGraphicsItem); + if (gestures.contains(id)) { + if (scene) + scene->d_func()->releaseGesture(q, id); + gestures.remove(id); + return true; + } + return false; +} + /*! \since 4.6 @@ -5888,10 +5907,9 @@ int QGraphicsItem::grabGesture(const QString &gesture) */ void QGraphicsItem::releaseGesture(int gestureId) { - if (d_ptr->scene) - d_ptr->scene->d_func()->releaseGesture(this, gestureId); - QGestureManager::instance()->releaseGestureId(gestureId); - d_ptr->gestures.remove(gestureId); + /// TODO: if we are QGraphicsProxyWidget we should unsubscribe the widget from gesture as well. + if (d_ptr->releaseGesture(gestureId)) + QGestureManager::instance()->releaseGestureId(gestureId); } /*! @@ -5909,6 +5927,18 @@ void QGraphicsItem::setGestureEnabled(int gestureId, bool enable) //### } +bool QGraphicsItemPrivate::hasGesture(const QString &name) const +{ + QGestureManager *gm = QGestureManager::instance(); + QSet<int>::const_iterator it = gestures.begin(), + e = gestures.end(); + for (; it != e; ++it) { + if (gm->gestureNameFromId(*it) == name) + return true; + } + return false; +} + /*! 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_p.h b/src/gui/graphicsview/qgraphicsitem_p.h index b6daa85..091a461 100644 --- a/src/gui/graphicsview/qgraphicsitem_p.h +++ b/src/gui/graphicsview/qgraphicsitem_p.h @@ -305,7 +305,11 @@ public: int depth; QSet<int> gestures; - // Packed 32 bits + bool hasGesture(const QString &gesture) const; + void grabGesture(int id); + bool releaseGesture(int id); + + // Packed 32 bytes quint32 acceptedMouseButtons : 5; quint32 visible : 1; quint32 explicitlyHidden : 1; diff --git a/src/gui/graphicsview/qgraphicsproxywidget.cpp b/src/gui/graphicsview/qgraphicsproxywidget.cpp index 01b7593..5641068 100644 --- a/src/gui/graphicsview/qgraphicsproxywidget.cpp +++ b/src/gui/graphicsview/qgraphicsproxywidget.cpp @@ -48,6 +48,7 @@ #include "private/qgraphicsproxywidget_p.h" #include "private/qwidget_p.h" #include "private/qapplication_p.h" +#include "private/qgesturemanager_p.h" #include <QtCore/qdebug.h> #include <QtGui/qevent.h> @@ -275,7 +276,7 @@ void QGraphicsProxyWidgetPrivate::sendWidgetMouseEvent(QGraphicsSceneMouseEvent QWidget *embeddedMouseGrabberPtr = (QWidget *)embeddedMouseGrabber; QApplicationPrivate::sendMouseEvent(receiver, mouseEvent, alienWidget, widget, - &embeddedMouseGrabberPtr, lastWidgetUnderMouse); + &embeddedMouseGrabberPtr, lastWidgetUnderMouse, event->spontaneous()); embeddedMouseGrabber = embeddedMouseGrabberPtr; // Handle enter/leave events when last button is released from mouse @@ -648,6 +649,9 @@ void QGraphicsProxyWidgetPrivate::setWidget_helper(QWidget *newWidget, bool auto q->setAttribute(Qt::WA_OpaquePaintEvent); widget = newWidget; + foreach(int gestureId, widget->d_func()->gestures) { + grabGesture(gestureId); + } // Changes only go from the widget to the proxy. enabledChangeMode = QGraphicsProxyWidgetPrivate::WidgetToProxyMode; @@ -871,6 +875,16 @@ bool QGraphicsProxyWidget::event(QEvent *event) } break; } + case QEvent::GraphicsSceneGesture: { + qDebug() << "QGraphicsProxyWidget: graphicsscenegesture"; + if (d->widget && d->widget->isVisible()) { + QGraphicsSceneGestureEvent *ge = static_cast<QGraphicsSceneGestureEvent*>(event); + //### TODO: widget->childAt(): decompose gesture event and find widget under hotspots. + //QGestureManager::instance()->sendGestureEvent(d->widget, ge->gestures().toSet(), ge->cancelledGestures()); + return true; + } + break; + } default: break; } diff --git a/src/gui/graphicsview/qgraphicsscene.cpp b/src/gui/graphicsview/qgraphicsscene.cpp index 4d0d991..8e5ebdb 100644 --- a/src/gui/graphicsview/qgraphicsscene.cpp +++ b/src/gui/graphicsview/qgraphicsscene.cpp @@ -248,6 +248,7 @@ static const int QGRAPHICSSCENE_INDEXTIMER_TIMEOUT = 2000; #include <private/qt_x11_p.h> #endif #include <private/qgesturemanager_p.h> +#include <private/qgesture_p.h> QT_BEGIN_NAMESPACE @@ -3919,40 +3920,44 @@ bool QGraphicsScene::event(QEvent *event) update(); break; case QEvent::GraphicsSceneGesture: { + qDebug() << "GraphicsSceneGesture"; QGraphicsSceneGestureEvent *ev = static_cast<QGraphicsSceneGestureEvent*>(event); - QList<QString> gestureTypes = ev->gestureTypes(); QGraphicsView *view = qobject_cast<QGraphicsView*>(ev->widget()); if (!view) { qWarning("QGraphicsScene::event: gesture event was received without a view"); break; } - // find graphics items that intersects with gestures hot spots. - QPolygonF poly; - QMap<QString, QPointF> sceneHotSpots; - foreach(const QString &type, gestureTypes) { - QPointF pt = ev->mapToScene(ev->gesture(type)->hotSpot()); - sceneHotSpots.insert(type, pt); - poly << pt; + // get a list of gestures that just started. + QSet<QGesture*> startedGestures; + QList<QGesture*> gestures = ev->gestures(); + 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 || gd->singleshot) { + startedGestures.insert(g); + } } - QList<QGraphicsItem*> itemsInGestureArea = items(poly, Qt::IntersectsItemBoundingRect); - - foreach(QGraphicsItem *item, itemsInGestureArea) { - QMap<QString, QPointF>::const_iterator it = sceneHotSpots.begin(), - e = sceneHotSpots.end(); - for(; it != e; ++it) { - if (item->contains(item->mapFromScene(it.value()))) { - const QString gestureName = it.key(); - foreach(int gestureId, item->d_ptr->gestures) { - if (QGestureManager::instance()->gestureNameFromId(gestureId) == gestureName) { - d->sendEvent(item, ev); - if (ev->isAccepted()) - break; - } + if (!startedGestures.isEmpty()) { + // find a target for each started gesture. + for(QSet<QGesture*>::const_iterator it = startedGestures.begin(), e = startedGestures.end(); + it != e; ++it) { + QGesture *g = *it; + QGesturePrivate *gd = g->d_func(); + QList<QGraphicsItem*> itemsInGestureArea = items(g->hotSpot()); + const QString gestureName = g->type(); + foreach(QGraphicsItem *item, itemsInGestureArea) { + if (item->d_func()->hasGesture(gestureName)) { + Q_ASSERT(gd->graphicsItem == 0); + gd->graphicsItem = item; + d->itemsWithGestures[item].insert(g); + break; } } } } + d->sendGestureEvent(ev->gestures().toSet(), ev->cancelledGestures()); } break; case QEvent::GraphicsSceneTouchBegin: @@ -3976,6 +3981,74 @@ bool QGraphicsScene::event(QEvent *event) return true; } +void QGraphicsScenePrivate::sendGestureEvent(const QSet<QGesture*> &gestures, const QSet<QString> &cancelled) +{ + qDebug() << "QGraphicsScenePrivate::sendGestureEvent:" << gestures; + Q_Q(QGraphicsScene); + typedef QMap<QGraphicsItem*, QSet<QGesture*> > ItemGesturesMap; + ItemGesturesMap itemGestures; + QSet<QGesture*> startedGestures; + for(QSet<QGesture*>::const_iterator it = gestures.begin(), e = gestures.end(); + it != e; ++it) { + QGesture *g = *it; + Q_ASSERT(g != 0); + QGesturePrivate *gd = g->d_func(); + if (gd->graphicsItem != 0) { + itemGestures[gd->graphicsItem].insert(g); + if (g->state() == Qt::GestureStarted || gd->singleshot) + startedGestures.insert(g); + } + } + + qDebug() << "QGraphicsScenePrivate::sendGestureEvent: started: " << startedGestures; + QSet<QGesture*> ignoredGestures; + for(ItemGesturesMap::const_iterator it = itemGestures.begin(), e = itemGestures.end(); + it != e; ++it) { + QGraphicsItem *receiver = it.key(); + Q_ASSERT(receiver != 0); + QGraphicsSceneGestureEvent event; + event.setGestures(it.value()); + event.setCancelledGestures(cancelled); + qDebug() << "QGraphicsScenePrivate::sendGestureEvent: sending to " << receiver << it.value(); + bool processed = sendEvent(receiver, &event); + QSet<QGesture*> started = startedGestures.intersect(it.value()); + if (event.isAccepted()) + foreach(QGesture *g, started) + g->accept(); + if (!started.isEmpty() && !(processed && event.isAccepted())) { + // there are started gestures event that weren't + // accepted, so propagating each gesture independently. + QSet<QGesture*>::const_iterator it = started.begin(), + e = started.end(); + for(; it != e; ++it) { + QGesture *g = *it; + qDebug() << "result: " << g << ":" << processed << g->isAccepted(); + if (processed && g->isAccepted()) { + continue; + } + QGesturePrivate *gd = g->d_func(); + QGraphicsItem *item = gd->graphicsItem; + gd->graphicsItem = 0; + + //### THIS IS BS, DONT FORGET TO REWRITE THIS CODE + // need to make sure we try to deliver event just once to each widget + const QString gestureType = g->type(); + QList<QGraphicsItem*> itemsUnderGesture = q->items(g->hotSpot()); + for (int i = 0; i < itemsUnderGesture.size(); ++i) { + QGraphicsItem *item = itemsUnderGesture.at(i); + if (item != receiver && item->d_func()->hasGesture(gestureType)) { + ignoredGestures.insert(g); + gd->graphicsItem = item; + break; + } + } + } + } + } + if (!ignoredGestures.isEmpty()) + sendGestureEvent(ignoredGestures, cancelled); +} + /*! \reimp @@ -5606,12 +5679,13 @@ void QGraphicsScenePrivate::grabGesture(QGraphicsItem *item, int gestureId) foreach(QGraphicsView *view, views) view->d_func()->grabGesture(gestureId); } - itemsWithGestures << item; + (void)itemsWithGestures[item]; grabbedGestures << gestureId; } void QGraphicsScenePrivate::releaseGesture(QGraphicsItem *item, int gestureId) { + itemsWithGestures.remove(item); //### } diff --git a/src/gui/graphicsview/qgraphicsscene_p.h b/src/gui/graphicsview/qgraphicsscene_p.h index 7928a45..160ba49 100644 --- a/src/gui/graphicsview/qgraphicsscene_p.h +++ b/src/gui/graphicsview/qgraphicsscene_p.h @@ -74,6 +74,7 @@ QT_BEGIN_NAMESPACE class QGraphicsView; class QGraphicsWidget; +class QGesture; class QGraphicsScenePrivate : public QObjectPrivate { @@ -267,10 +268,12 @@ public: void resolvePalette(); void updatePalette(const QPalette &palette); - QSet<QGraphicsItem*> itemsWithGestures; + // items with gestures -> list of started gestures. + QMap<QGraphicsItem*, QSet<QGesture*> > itemsWithGestures; QSet<int> grabbedGestures; void grabGesture(QGraphicsItem *item, int gestureId); void releaseGesture(QGraphicsItem *item, int gestureId); + void sendGestureEvent(const QSet<QGesture*> &gestures, const QSet<QString> &cancelled); mutable QVector<QTransform> sceneTransformCache; mutable QBitArray validTransforms; diff --git a/src/gui/graphicsview/qgraphicssceneevent.cpp b/src/gui/graphicsview/qgraphicssceneevent.cpp index d5d0fb9..2c5c946 100644 --- a/src/gui/graphicsview/qgraphicssceneevent.cpp +++ b/src/gui/graphicsview/qgraphicssceneevent.cpp @@ -1895,6 +1895,15 @@ void QGraphicsSceneGestureEvent::setGestures(const QList<QGesture*> &gestures) } /*! + Set a list of gesture objects containing extended information about \a gestures. +*/ +void QGraphicsSceneGestureEvent::setGestures(const QSet<QGesture*> &gestures) +{ + foreach(QGesture *g, gestures) + m_gestures.insert(g->type(), g); +} + +/*! Sets the accept flag of the all gestures inside the event object, the equivalent of calling \l{QEvent::accept()}{accept()} or \l{QEvent::setAccepted()}{setAccepted(true)}. diff --git a/src/gui/graphicsview/qgraphicssceneevent.h b/src/gui/graphicsview/qgraphicssceneevent.h index 01cdab9..8b24d33 100644 --- a/src/gui/graphicsview/qgraphicssceneevent.h +++ b/src/gui/graphicsview/qgraphicssceneevent.h @@ -325,6 +325,7 @@ public: const QGesture* gesture(const QString &type) const; QList<QGesture*> gestures() const; void setGestures(const QList<QGesture*> &gestures); + void setGestures(const QSet<QGesture*> &gestures); QSet<QString> cancelledGestures() const; void setCancelledGestures(const QSet<QString> &cancelledGestures); diff --git a/src/gui/graphicsview/qgraphicsview.cpp b/src/gui/graphicsview/qgraphicsview.cpp index b75619c..2babce9 100644 --- a/src/gui/graphicsview/qgraphicsview.cpp +++ b/src/gui/graphicsview/qgraphicsview.cpp @@ -2875,6 +2875,7 @@ bool QGraphicsView::viewportEvent(QEvent *event) gestureEvent.setGestures(ev->gestures()); gestureEvent.setCancelledGestures(ev->cancelledGestures()); QApplication::sendEvent(d->scene, &gestureEvent); + event->setAccepted(gestureEvent.isAccepted()); if (gestureEvent.isAccepted()) return true; } |