diff options
author | Marius Bugge Monsen <mmonsen@trolltech.com> | 2009-07-02 12:06:25 (GMT) |
---|---|---|
committer | Marius Bugge Monsen <mmonsen@trolltech.com> | 2009-07-14 11:22:50 (GMT) |
commit | 34fde4a4b7220c92b03dfa92607feb6179454066 (patch) | |
tree | 13cb867a895b31e3dc79ab497db5e83aeef074ce /src/gui/graphicsview | |
parent | af2b01c4571b468a57cb4e5e72dab481f6d88eb1 (diff) | |
download | Qt-34fde4a4b7220c92b03dfa92607feb6179454066.zip Qt-34fde4a4b7220c92b03dfa92607feb6179454066.tar.gz Qt-34fde4a4b7220c92b03dfa92607feb6179454066.tar.bz2 |
Add QGraphicsView::filtersChildEvents property.
This obsoletes QGraphicsView::handlesChildEvents.
Diffstat (limited to 'src/gui/graphicsview')
-rw-r--r-- | src/gui/graphicsview/qgraphicsitem.cpp | 49 | ||||
-rw-r--r-- | src/gui/graphicsview/qgraphicsitem.h | 3 | ||||
-rw-r--r-- | src/gui/graphicsview/qgraphicsitem_p.h | 15 | ||||
-rw-r--r-- | src/gui/graphicsview/qgraphicsscene.cpp | 90 | ||||
-rw-r--r-- | src/gui/graphicsview/qgraphicsscene_p.h | 1 |
5 files changed, 149 insertions, 9 deletions
diff --git a/src/gui/graphicsview/qgraphicsitem.cpp b/src/gui/graphicsview/qgraphicsitem.cpp index 03014d8..cb0418c 100644 --- a/src/gui/graphicsview/qgraphicsitem.cpp +++ b/src/gui/graphicsview/qgraphicsitem.cpp @@ -650,6 +650,10 @@ void QGraphicsItemPrivate::updateAncestorFlag(QGraphicsItem::GraphicsItemFlag ch // For root items only. This is the item that has either enabled or // disabled \a childFlag, or has been reparented. switch (int(childFlag)) { + case -2: + flag = AncestorFiltersChildEvents; + enabled = q->filtersChildEvents(); + break; case -1: flag = AncestorHandlesChildEvents; enabled = q->handlesChildEvents(); @@ -670,7 +674,8 @@ void QGraphicsItemPrivate::updateAncestorFlag(QGraphicsItem::GraphicsItemFlag ch // Inherit the enabled-state from our parents. if ((parent && ((parent->d_ptr->ancestorFlags & flag) || (int(parent->d_ptr->flags & childFlag) == childFlag) - || (childFlag == -1 && parent->d_ptr->handlesChildEvents)))) { + || (childFlag == -1 && parent->d_ptr->handlesChildEvents) + || (childFlag == -2 && parent->d_ptr->filtersDescendantEvents)))) { enabled = true; ancestorFlags |= flag; } @@ -691,7 +696,9 @@ void QGraphicsItemPrivate::updateAncestorFlag(QGraphicsItem::GraphicsItemFlag ch ancestorFlags &= ~flag; // Don't process children if the item has the main flag set on itself. - if ((childFlag != -1 && int(flags & childFlag) == childFlag) || (int(childFlag) == -1 && handlesChildEvents)) + if ((childFlag != -1 && int(flags & childFlag) == childFlag) + || (int(childFlag) == -1 && handlesChildEvents) + || (int(childFlag) == -2 && filtersDescendantEvents)) return; } @@ -953,6 +960,7 @@ void QGraphicsItemPrivate::setParentItemHelper(QGraphicsItem *newParent) } // Inherit ancestor flags from the new parent. + updateAncestorFlag(QGraphicsItem::GraphicsItemFlag(-2)); updateAncestorFlag(QGraphicsItem::GraphicsItemFlag(-1)); updateAncestorFlag(QGraphicsItem::ItemClipsChildrenToShape); updateAncestorFlag(QGraphicsItem::ItemIgnoresTransformations); @@ -969,6 +977,7 @@ void QGraphicsItemPrivate::setParentItemHelper(QGraphicsItem *newParent) } else { // Inherit ancestor flags from the new parent. + updateAncestorFlag(QGraphicsItem::GraphicsItemFlag(-2)); updateAncestorFlag(QGraphicsItem::GraphicsItemFlag(-1)); updateAncestorFlag(QGraphicsItem::ItemClipsChildrenToShape); updateAncestorFlag(QGraphicsItem::ItemIgnoresTransformations); @@ -2352,6 +2361,40 @@ void QGraphicsItem::setAcceptTouchEvents(bool enabled) } /*! + Returns true if this item filters child events (i.e., all events + intended for any of its children are instead sent to this item); + otherwise, false is returned. + + The default value is false; child events are not filtered. + + \sa setFiltersChildEvents() +*/ +bool QGraphicsItem::filtersChildEvents() const +{ + return d_ptr->filtersDescendantEvents; +} + +/*! + If \a enabled is true, this item is set to filter all events for + all its children (i.e., all events intented for any of its + children are instead sent to this item); otherwise, if \a enabled + is false, this item will only handle its own events. The default + value is false. + + \sa filtersChildEvents() +*/ +void QGraphicsItem::setFiltersChildEvents(bool enabled) +{ + if (d_ptr->filtersDescendantEvents == enabled) + return; + + d_ptr->filtersDescendantEvents = enabled; + d_ptr->updateAncestorFlag(QGraphicsItem::GraphicsItemFlag(-2)); +} + +/*! + \obsolete + Returns true if this item handles child events (i.e., all events intended for any of its children are instead sent to this item); otherwise, false is returned. @@ -2372,6 +2415,8 @@ bool QGraphicsItem::handlesChildEvents() const } /*! + \obsolete + If \a enabled is true, this item is set to handle all events for all its children (i.e., all events intented for any of its children are instead sent to this item); otherwise, if \a enabled diff --git a/src/gui/graphicsview/qgraphicsitem.h b/src/gui/graphicsview/qgraphicsitem.h index 72c4830..a307622 100644 --- a/src/gui/graphicsview/qgraphicsitem.h +++ b/src/gui/graphicsview/qgraphicsitem.h @@ -216,6 +216,9 @@ public: bool acceptTouchEvents() const; void setAcceptTouchEvents(bool enabled); + bool filtersChildEvents() const; + void setFiltersChildEvents(bool enabled); + bool handlesChildEvents() const; void setHandlesChildEvents(bool enabled); diff --git a/src/gui/graphicsview/qgraphicsitem_p.h b/src/gui/graphicsview/qgraphicsitem_p.h index 9bdd273..4729634 100644 --- a/src/gui/graphicsview/qgraphicsitem_p.h +++ b/src/gui/graphicsview/qgraphicsitem_p.h @@ -109,7 +109,8 @@ public: NoFlag = 0, AncestorHandlesChildEvents = 0x1, AncestorClipsChildren = 0x2, - AncestorIgnoresTransformations = 0x4 + AncestorIgnoresTransformations = 0x4, + AncestorFiltersChildEvents = 0x8 }; inline QGraphicsItemPrivate() @@ -157,6 +158,7 @@ public: ignoreOpacity(0), acceptTouchEvents(0), acceptedTouchBeginEvent(0), + filtersDescendantEvents(0), sceneTransformTranslateOnly(0), globalStackingOrder(-1), q_ptr(0) @@ -421,7 +423,7 @@ public: quint32 handlesChildEvents : 1; quint32 itemDiscovered : 1; quint32 hasCursor : 1; - quint32 ancestorFlags : 3; + quint32 ancestorFlags : 4; quint32 cacheMode : 2; quint32 hasBoundingRegionGranularity : 1; quint32 isWidget : 1; @@ -433,13 +435,13 @@ public: quint32 inSetPosHelper : 1; quint32 needSortChildren : 1; quint32 allChildrenDirty : 1; - quint32 fullUpdatePending : 1; // New 32 bits - quint32 flags : 13; + quint32 fullUpdatePending : 1; + quint32 flags : 12; quint32 dirtyChildrenBoundingRect : 1; quint32 paintedViewBoundingRectsNeedRepaint : 1; - quint32 dirtySceneTransform : 1; + quint32 dirtySceneTransform : 1; quint32 geometryChanged : 1; quint32 inDestructor : 1; quint32 isObject : 1; @@ -447,8 +449,9 @@ public: quint32 ignoreOpacity : 1; quint32 acceptTouchEvents : 1; quint32 acceptedTouchBeginEvent : 1; + quint32 filtersDescendantEvents : 1; quint32 sceneTransformTranslateOnly : 1; - quint32 unused : 8; // feel free to use + quint32 unused : 7; // feel free to use // Optional stacking order int globalStackingOrder; diff --git a/src/gui/graphicsview/qgraphicsscene.cpp b/src/gui/graphicsview/qgraphicsscene.cpp index c8e178a..e2458f5 100644 --- a/src/gui/graphicsview/qgraphicsscene.cpp +++ b/src/gui/graphicsview/qgraphicsscene.cpp @@ -853,6 +853,24 @@ void QGraphicsScenePrivate::removeSceneEventFilter(QGraphicsItem *watched, QGrap } /*! + \internal +*/ +bool QGraphicsScenePrivate::filterDescendantEvent(QGraphicsItem *item, QEvent *event) +{ + if (item && (item->d_ptr->ancestorFlags & QGraphicsItemPrivate::AncestorFiltersChildEvents)) { + QGraphicsItem *parent = item->parentItem(); + while (parent) { + if (parent->d_ptr->filtersDescendantEvents && parent->sceneEventFilter(item, event)) + return true; + if (!(parent->d_ptr->ancestorFlags & QGraphicsItemPrivate::AncestorFiltersChildEvents)) + return false; + parent = parent->parentItem(); + } + } + return false; +} + +/*! \internal */ bool QGraphicsScenePrivate::filterEvent(QGraphicsItem *item, QEvent *event) @@ -884,7 +902,9 @@ bool QGraphicsScenePrivate::sendEvent(QGraphicsItem *item, QEvent *event) { if (filterEvent(item, event)) return false; - return (item && item->isEnabled()) ? item->sceneEvent(event) : false; + if (filterDescendantEvent(item, event)) + return false; + return (item && item->isEnabled() ? item->sceneEvent(event) : false); } /*! @@ -3022,6 +3042,74 @@ bool QGraphicsScene::event(QEvent *event) return true; } +<<<<<<< HEAD:src/gui/graphicsview/qgraphicsscene.cpp +======= +void QGraphicsScenePrivate::sendGestureEvent(const QSet<QGesture*> &gestures, const QSet<QString> &cancelled) +{ + 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); + } + } + + 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); + 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; + if (processed && g->isAccepted()) { + continue; + } + QGesturePrivate *gd = g->d_func(); + QGraphicsItem *item = gd->graphicsItem; + Q_UNUSED(item); // ### REMOVE + 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); +} + +>>>>>>> 296da87... Add QGraphicsView::filtersChildEvents property.:src/gui/graphicsview/qgraphicsscene.cpp /*! \reimp diff --git a/src/gui/graphicsview/qgraphicsscene_p.h b/src/gui/graphicsview/qgraphicsscene_p.h index ffd62d5..9a91acc 100644 --- a/src/gui/graphicsview/qgraphicsscene_p.h +++ b/src/gui/graphicsview/qgraphicsscene_p.h @@ -172,6 +172,7 @@ public: QMultiMap<QGraphicsItem *, QGraphicsItem *> sceneEventFilters; void installSceneEventFilter(QGraphicsItem *watched, QGraphicsItem *filter); void removeSceneEventFilter(QGraphicsItem *watched, QGraphicsItem *filter); + bool filterDescendantEvent(QGraphicsItem *item, QEvent *event); bool filterEvent(QGraphicsItem *item, QEvent *event); bool sendEvent(QGraphicsItem *item, QEvent *event); |