diff options
author | Bjørn Erik Nilsen <bjorn.nilsen@nokia.com> | 2010-06-24 13:11:05 (GMT) |
---|---|---|
committer | Bjørn Erik Nilsen <bjorn.nilsen@nokia.com> | 2010-06-24 13:29:04 (GMT) |
commit | 7bc00632dde1b718cbe1412e988ad006dc3d125f (patch) | |
tree | 8531eff6273230e8fd967df979217008b3cbed65 | |
parent | bf65425213b451d83e13c7423b289f391fd9f81c (diff) | |
download | Qt-7bc00632dde1b718cbe1412e988ad006dc3d125f.zip Qt-7bc00632dde1b718cbe1412e988ad006dc3d125f.tar.gz Qt-7bc00632dde1b718cbe1412e988ad006dc3d125f.tar.bz2 |
Add a new (internal) flag QGraphicsItem::ItemStopsClickFocusPropagation.
This flag allows you to create a non-focusable item that can be clicked
on without changing the focus. This is also possible to achieve by
using focus scopes / panels, however the implementation is then way
more complex. Thew new flag is tailored for simple uses cases where
you simply want to stop the propagation and nothing more.
Auto test included.
Task-number: QT-3499
Reviewed-by: yoann
-rw-r--r-- | src/gui/graphicsview/qgraphicsitem.cpp | 8 | ||||
-rw-r--r-- | src/gui/graphicsview/qgraphicsitem.h | 3 | ||||
-rw-r--r-- | src/gui/graphicsview/qgraphicsitem_p.h | 6 | ||||
-rw-r--r-- | src/gui/graphicsview/qgraphicsscene.cpp | 2 | ||||
-rw-r--r-- | tests/auto/qgraphicsitem/tst_qgraphicsitem.cpp | 54 |
5 files changed, 69 insertions, 4 deletions
diff --git a/src/gui/graphicsview/qgraphicsitem.cpp b/src/gui/graphicsview/qgraphicsitem.cpp index 2de3638..61285d2 100644 --- a/src/gui/graphicsview/qgraphicsitem.cpp +++ b/src/gui/graphicsview/qgraphicsitem.cpp @@ -411,6 +411,11 @@ these notifications are disabled by default. You must enable this flag to receive notifications for scene position changes. This flag was introduced in Qt 4.6. + + \omitvalue ItemStopsClickFocusPropagation \omit The item stops propagating + click focus to items underneath when being clicked on. This flag + allows you create a non-focusable item that can be clicked on without + changing the focus. \endomit */ /*! @@ -11432,6 +11437,9 @@ QDebug operator<<(QDebug debug, QGraphicsItem::GraphicsItemFlag flag) case QGraphicsItem::ItemSendsScenePositionChanges: str = "ItemSendsScenePositionChanges"; break; + case QGraphicsItem::ItemStopsClickFocusPropagation: + str = "ItemStopsClickFocusPropagation"; + break; } debug << str; return debug; diff --git a/src/gui/graphicsview/qgraphicsitem.h b/src/gui/graphicsview/qgraphicsitem.h index d7d5332..3c193cd 100644 --- a/src/gui/graphicsview/qgraphicsitem.h +++ b/src/gui/graphicsview/qgraphicsitem.h @@ -106,7 +106,8 @@ public: ItemNegativeZStacksBehindParent = 0x2000, ItemIsPanel = 0x4000, ItemIsFocusScope = 0x8000, // internal - ItemSendsScenePositionChanges = 0x10000 + ItemSendsScenePositionChanges = 0x10000, + ItemStopsClickFocusPropagation = 0x20000 // NB! Don't forget to increase the d_ptr->flags bit field by 1 when adding a new flag. }; Q_DECLARE_FLAGS(GraphicsItemFlags, GraphicsItemFlag) diff --git a/src/gui/graphicsview/qgraphicsitem_p.h b/src/gui/graphicsview/qgraphicsitem_p.h index bde6e7d..f9f5d3d 100644 --- a/src/gui/graphicsview/qgraphicsitem_p.h +++ b/src/gui/graphicsview/qgraphicsitem_p.h @@ -556,7 +556,7 @@ public: quint32 dirtyChildrenBoundingRect : 1; // Packed 32 bits - quint32 flags : 17; + quint32 flags : 18; quint32 paintedViewBoundingRectsNeedRepaint : 1; quint32 dirtySceneTransform : 1; quint32 geometryChanged : 1; @@ -571,9 +571,9 @@ public: quint32 notifyBoundingRectChanged : 1; quint32 notifyInvalidated : 1; quint32 mouseSetsFocus : 1; - quint32 explicitActivate : 1; // New 32 bits + quint32 explicitActivate : 1; quint32 wantsActive : 1; quint32 holesInSiblingIndex : 1; quint32 sequentialOrdering : 1; @@ -582,7 +582,7 @@ public: quint32 pendingPolish : 1; quint32 mayHaveChildWithGraphicsEffect : 1; quint32 isDeclarativeItem : 1; - quint32 padding : 24; + quint32 padding : 23; // Optional stacking order int globalStackingOrder; diff --git a/src/gui/graphicsview/qgraphicsscene.cpp b/src/gui/graphicsview/qgraphicsscene.cpp index ca3b56f..d04074a 100644 --- a/src/gui/graphicsview/qgraphicsscene.cpp +++ b/src/gui/graphicsview/qgraphicsscene.cpp @@ -1336,6 +1336,8 @@ void QGraphicsScenePrivate::mousePressEventHandler(QGraphicsSceneMouseEvent *mou break; } } + if (item->d_ptr->flags & QGraphicsItem::ItemStopsClickFocusPropagation) + break; if (item->isPanel()) break; } diff --git a/tests/auto/qgraphicsitem/tst_qgraphicsitem.cpp b/tests/auto/qgraphicsitem/tst_qgraphicsitem.cpp index fe68c8e..31a6845 100644 --- a/tests/auto/qgraphicsitem/tst_qgraphicsitem.cpp +++ b/tests/auto/qgraphicsitem/tst_qgraphicsitem.cpp @@ -442,6 +442,7 @@ private slots: void updateMicroFocus(); void textItem_shortcuts(); void scroll(); + void stopClickFocusPropagation(); // task specific tests below me void task141694_textItemEnsureVisible(); @@ -10268,6 +10269,59 @@ void tst_QGraphicsItem::scroll() QCOMPARE(item2->lastExposedRect, expectedItem2Expose); } +void tst_QGraphicsItem::stopClickFocusPropagation() +{ + class MyItem : public QGraphicsRectItem + { + public: + MyItem() : QGraphicsRectItem(0, 0, 100, 100) {} + void paint(QPainter *painter, const QStyleOptionGraphicsItem *, QWidget *) + { + painter->fillRect(boundingRect(), hasFocus() ? QBrush(Qt::red) : brush()); + } + }; + + QGraphicsScene scene(-50, -50, 400, 400); + scene.setStickyFocus(true); + + QGraphicsRectItem *noFocusOnTop = new MyItem; + noFocusOnTop->setBrush(Qt::yellow); + noFocusOnTop->setFlag(QGraphicsItem::ItemStopsClickFocusPropagation); + + QGraphicsRectItem *focusableUnder = new MyItem; + focusableUnder->setBrush(Qt::blue); + focusableUnder->setFlag(QGraphicsItem::ItemIsFocusable); + focusableUnder->setPos(50, 50); + + QGraphicsRectItem *itemWithFocus = new MyItem; + itemWithFocus->setBrush(Qt::black); + itemWithFocus->setFlag(QGraphicsItem::ItemIsFocusable); + itemWithFocus->setPos(250, 10); + + scene.addItem(noFocusOnTop); + scene.addItem(focusableUnder); + scene.addItem(itemWithFocus); + focusableUnder->stackBefore(noFocusOnTop); + itemWithFocus->setFocus(); + + QGraphicsView view(&scene); + view.show(); + QTest::qWaitForWindowShown(&view); + + QApplication::setActiveWindow(&view); + QTRY_COMPARE(QApplication::activeWindow(), static_cast<QWidget *>(&view)); + QVERIFY(itemWithFocus->hasFocus()); + + QPointF mousePressPoint = noFocusOnTop->mapToScene(QPointF()); + mousePressPoint.rx() += 60; + mousePressPoint.ry() += 60; + const QList<QGraphicsItem *> itemsAtMousePressPosition = scene.items(mousePressPoint); + QVERIFY(itemsAtMousePressPosition.contains(focusableUnder)); + + sendMousePress(&scene, mousePressPoint); + QVERIFY(itemWithFocus->hasFocus()); +} + void tst_QGraphicsItem::QTBUG_5418_textItemSetDefaultColor() { struct Item : public QGraphicsTextItem |