diff options
Diffstat (limited to 'src/gui/graphicsview')
-rw-r--r-- | src/gui/graphicsview/qgraphicsitem.cpp | 23 | ||||
-rw-r--r-- | src/gui/graphicsview/qgraphicsitem.h | 3 | ||||
-rw-r--r-- | src/gui/graphicsview/qgraphicsitem_p.h | 2 | ||||
-rw-r--r-- | src/gui/graphicsview/qgraphicsscene.cpp | 109 | ||||
-rw-r--r-- | src/gui/graphicsview/qgraphicsscene_p.h | 1 | ||||
-rw-r--r-- | src/gui/graphicsview/qgraphicsview.cpp | 8 |
6 files changed, 132 insertions, 14 deletions
diff --git a/src/gui/graphicsview/qgraphicsitem.cpp b/src/gui/graphicsview/qgraphicsitem.cpp index d70b039..2fd499d 100644 --- a/src/gui/graphicsview/qgraphicsitem.cpp +++ b/src/gui/graphicsview/qgraphicsitem.cpp @@ -7343,19 +7343,32 @@ QGraphicsObject::QGraphicsObject(QGraphicsItemPrivate &dd, QGraphicsItem *parent } /*! - Subscribes the graphics object to the given \a gesture for the specified \a context. + Subscribes the graphics object to the given \a gesture with specific \a flags. - \sa QGestureEvent + \sa ungrabGesture(), QGestureEvent */ - -void QGraphicsObject::grabGesture(Qt::GestureType gesture, Qt::GestureContext context) +void QGraphicsObject::grabGesture(Qt::GestureType gesture, Qt::GestureFlags flags) { QGraphicsItemPrivate * const d = QGraphicsItem::d_func(); - d->gestureContext.insert(gesture, context); + d->gestureContext.insert(gesture, flags); (void)QGestureManager::instance(); // create a gesture manager } /*! + Unsubscribes the graphics object from the given \a gesture. + + \sa grabGesture(), QGestureEvent +*/ +void QGraphicsObject::ungrabGesture(Qt::GestureType gesture) +{ + QGraphicsItemPrivate * const d = QGraphicsItem::d_func(); + if (d->gestureContext.remove(gesture)) { + QGestureManager *manager = QGestureManager::instance(); + manager->cleanupCachedGestures(this, gesture); + } +} + +/*! \property QGraphicsObject::parent \brief the parent of the item diff --git a/src/gui/graphicsview/qgraphicsitem.h b/src/gui/graphicsview/qgraphicsitem.h index f3fe99c..f091e34 100644 --- a/src/gui/graphicsview/qgraphicsitem.h +++ b/src/gui/graphicsview/qgraphicsitem.h @@ -555,7 +555,8 @@ public: using QObject::children; #endif - void grabGesture(Qt::GestureType type, Qt::GestureContext context = Qt::ItemWithChildrenGesture); + void grabGesture(Qt::GestureType type, Qt::GestureFlags flags = Qt::GestureFlags()); + void ungrabGesture(Qt::GestureType type); Q_SIGNALS: void parentChanged(); diff --git a/src/gui/graphicsview/qgraphicsitem_p.h b/src/gui/graphicsview/qgraphicsitem_p.h index ca56c18..51d2ffd 100644 --- a/src/gui/graphicsview/qgraphicsitem_p.h +++ b/src/gui/graphicsview/qgraphicsitem_p.h @@ -453,7 +453,7 @@ public: QGraphicsItem *focusScopeItem; Qt::InputMethodHints imHints; QGraphicsItem::PanelModality panelModality; - QMap<Qt::GestureType, Qt::GestureContext> gestureContext; + QMap<Qt::GestureType, Qt::GestureFlags> gestureContext; // Packed 32 bits quint32 acceptedMouseButtons : 5; diff --git a/src/gui/graphicsview/qgraphicsscene.cpp b/src/gui/graphicsview/qgraphicsscene.cpp index f982f4b..dc036f8 100644 --- a/src/gui/graphicsview/qgraphicsscene.cpp +++ b/src/gui/graphicsview/qgraphicsscene.cpp @@ -1064,9 +1064,8 @@ bool QGraphicsScenePrivate::filterEvent(QGraphicsItem *item, QEvent *event) bool QGraphicsScenePrivate::sendEvent(QGraphicsItem *item, QEvent *event) { if (QGraphicsObject *object = item->toGraphicsObject()) { - QApplicationPrivate *qAppPriv = QApplicationPrivate::instance(); - if (qAppPriv->gestureManager) { - if (qAppPriv->gestureManager->filterEvent(object, event)) + if (qt_gestureManager) { + if (qt_gestureManager->filterEvent(object, event)) return true; } } @@ -5765,7 +5764,7 @@ void QGraphicsScenePrivate::gestureEventHandler(QGestureEvent *event) QWidget *viewport = event->widget(); if (!viewport) return; - QList<QGesture *> allGestures = event->allGestures(); + QList<QGesture *> allGestures = event->gestures(); DEBUG() << "QGraphicsScenePrivate::gestureEventHandler:" << "Delivering gestures:" << allGestures; @@ -5904,7 +5903,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::GestureFlags>::iterator contextit = + gid->gestureContext.find(g->gestureType()); + bool deliver = contextit != gid->gestureContext.end() && + (g->state() == Qt::GestureStarted || + (contextit.value() & Qt::ReceivePartialGestures)); + if (deliver) gestures += g; } if (gestures.isEmpty()) @@ -5917,8 +5921,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 @@ -5945,6 +5953,13 @@ void QGraphicsScenePrivate::gestureEventHandler(QGestureEvent *event) continue; } } + foreach (QGesture *g, startedGestures) { + 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, event->widget()); + } + } // forget about targets for gestures that have ended foreach (QGesture *g, allGestures) { @@ -5959,6 +5974,88 @@ void QGraphicsScenePrivate::gestureEventHandler(QGestureEvent *event) } } +void QGraphicsScenePrivate::cancelGesturesForChildren(QGesture *original, QWidget *viewport) +{ + Q_ASSERT(original); + QGraphicsItem *originalItem = gestureTargets.value(original); + Q_ASSERT(originalItem); + + // iterate over all active gestures and for each find the owner + // if the owner is part of our sub-hierarchy, cancel it. + + QSet<QGesture *> canceledGestures; + QHash<QGesture *, QGraphicsObject *>::Iterator iter = gestureTargets.begin(); + while (iter != gestureTargets.end()) { + QGraphicsObject *item = iter.value(); + // note that we don't touch the gestures for our originalItem + if (item != originalItem && originalItem->isAncestorOf(item)) { + DEBUG() << " found a gesture to cancel" << iter.key(); + iter.key()->d_func()->state = Qt::GestureCanceled; + canceledGestures << iter.key(); + } + ++iter; + } + + // sort them per target item by cherry picking from almostCanceledGestures and delivering + QSet<QGesture *> almostCanceledGestures = canceledGestures; + QSet<QGesture *>::Iterator setIter; + while (!almostCanceledGestures.isEmpty()) { + QGraphicsObject *target = 0; + QSet<QGesture*> gestures; + setIter = almostCanceledGestures.begin(); + // sort per target item + while (setIter != almostCanceledGestures.end()) { + QGraphicsObject *item = gestureTargets.value(*setIter); + if (target == 0) + target = item; + if (target == item) { + gestures << *setIter; + setIter = almostCanceledGestures.erase(setIter); + } else { + ++setIter; + } + } + Q_ASSERT(target); + + QList<QGesture *> list = gestures.toList(); + QGestureEvent ev(list); + sendEvent(target, &ev); + + foreach (QGesture *g, list) { + if (ev.isAccepted() || ev.isAccepted(g)) + gestures.remove(g); + } + + foreach (QGesture *g, gestures) { + if (!g->hasHotSpot()) + continue; + + QPoint screenPos = g->hotSpot().toPoint(); + QList<QGraphicsItem *> items = itemsAtPosition(screenPos, QPointF(), viewport); + for (int j = 0; j < items.size(); ++j) { + QGraphicsObject *item = items.at(j)->toGraphicsObject(); + if (!item) + continue; + QGraphicsItemPrivate *d = item->QGraphicsItem::d_func(); + if (d->gestureContext.contains(g->gestureType())) { + QList<QGesture *> list; + list << g; + QGestureEvent ev(list); + sendEvent(item, &ev); + if (ev.isAccepted() || ev.isAccepted(g)) + break; // successfully delivered + } + } + } + } + + Q_ASSERT(qt_gestureManager); // it would be very odd if we got called without a manager. + for (setIter = canceledGestures.begin(); setIter != canceledGestures.end(); ++setIter) { + qt_gestureManager->recycle(*setIter); + gestureTargets.remove(*setIter); + } +} + QT_END_NAMESPACE #include "moc_qgraphicsscene.cpp" diff --git a/src/gui/graphicsview/qgraphicsscene_p.h b/src/gui/graphicsview/qgraphicsscene_p.h index cd20fd0..f8db084 100644 --- a/src/gui/graphicsview/qgraphicsscene_p.h +++ b/src/gui/graphicsview/qgraphicsscene_p.h @@ -288,6 +288,7 @@ public: QMap<Qt::GestureType, QGesture *> *conflictedGestures, QList<QList<QGraphicsObject *> > *conflictedItems, QHash<QGesture *, QGraphicsObject *> *normalGestures); + void cancelGesturesForChildren(QGesture *original, QWidget *viewport); void updateInputMethodSensitivityInViews(); diff --git a/src/gui/graphicsview/qgraphicsview.cpp b/src/gui/graphicsview/qgraphicsview.cpp index f72aa8a..c88f678 100644 --- a/src/gui/graphicsview/qgraphicsview.cpp +++ b/src/gui/graphicsview/qgraphicsview.cpp @@ -281,6 +281,7 @@ static const int QGRAPHICSVIEW_PREALLOC_STYLE_OPTIONS = 503; // largest prime < #include <QtGui/qstyleoption.h> #include <QtGui/qinputcontext.h> #ifdef Q_WS_X11 +#include <QtGui/qpaintengine.h> #include <private/qt_x11_p.h> #endif @@ -3294,7 +3295,12 @@ void QGraphicsView::paintEvent(QPaintEvent *event) backgroundPainter.setClipRegion(d->backgroundPixmapExposed, Qt::ReplaceClip); if (viewTransformed) backgroundPainter.setTransform(viewTransform); - backgroundPainter.setCompositionMode(QPainter::CompositionMode_Source); +#ifdef Q_WS_X11 +#undef X11 + if (backgroundPainter.paintEngine()->type() != QPaintEngine::X11) +#define X11 qt_x11Data +#endif + backgroundPainter.setCompositionMode(QPainter::CompositionMode_Source); drawBackground(&backgroundPainter, exposedSceneRect); d->backgroundPixmapExposed = QRegion(); } |