From e5be6baa698f4779b6af97175015856d146bc479 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Samuel=20R=C3=B8dal?= Date: Thu, 14 Jan 2010 13:46:52 +0100 Subject: Fixed child items with graphics effects not inheriting opacity. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We need to invalidate the graphics source pixmap cache for both child items and parent items when changing the opacity of a graphics item. Reviewed-by: Bjørn Erik Nilsen --- src/gui/graphicsview/qgraphicsitem.cpp | 23 +++++++++++++-- src/gui/graphicsview/qgraphicsitem_p.h | 6 +++- tests/auto/qgraphicseffect/tst_qgraphicseffect.cpp | 34 ++++++++++++++++++++-- 3 files changed, 57 insertions(+), 6 deletions(-) diff --git a/src/gui/graphicsview/qgraphicsitem.cpp b/src/gui/graphicsview/qgraphicsitem.cpp index d43176b..b8d392d 100644 --- a/src/gui/graphicsview/qgraphicsitem.cpp +++ b/src/gui/graphicsview/qgraphicsitem.cpp @@ -2565,7 +2565,9 @@ void QGraphicsItem::setOpacity(qreal opacity) // Update. if (d_ptr->scene) { #ifndef QT_NO_GRAPHICSEFFECT - d_ptr->invalidateGraphicsEffectsRecursively(); + d_ptr->invalidateParentGraphicsEffectsRecursively(); + if (!(d_ptr->flags & ItemDoesntPropagateOpacityToChildren)) + d_ptr->invalidateChildGraphicsEffectsRecursively(QGraphicsItemPrivate::OpacityChanged); #endif //QT_NO_GRAPHICSEFFECT d_ptr->scene->d_func()->markDirty(this, QRectF(), /*invalidateChildren=*/true, @@ -5075,7 +5077,7 @@ int QGraphicsItemPrivate::depth() const \internal */ #ifndef QT_NO_GRAPHICSEFFECT -void QGraphicsItemPrivate::invalidateGraphicsEffectsRecursively() +void QGraphicsItemPrivate::invalidateParentGraphicsEffectsRecursively() { QGraphicsItemPrivate *itemPrivate = this; do { @@ -5087,6 +5089,21 @@ void QGraphicsItemPrivate::invalidateGraphicsEffectsRecursively() } } while ((itemPrivate = itemPrivate->parent ? itemPrivate->parent->d_ptr.data() : 0)); } + +void QGraphicsItemPrivate::invalidateChildGraphicsEffectsRecursively(QGraphicsItemPrivate::InvalidateReason reason) +{ + for (int i = 0; i < children.size(); ++i) { + QGraphicsItemPrivate *childPrivate = children.at(i)->d_ptr.data(); + if (reason == OpacityChanged && (childPrivate->flags & QGraphicsItem::ItemIgnoresParentOpacity)) + continue; + if (childPrivate->graphicsEffect) { + childPrivate->notifyInvalidated = 1; + static_cast(childPrivate->graphicsEffect->d_func()->source->d_func())->invalidateCache(); + } + + childPrivate->invalidateChildGraphicsEffectsRecursively(reason); + } +} #endif //QT_NO_GRAPHICSEFFECT /*! @@ -5331,7 +5348,7 @@ void QGraphicsItem::update(const QRectF &rect) // Make sure we notify effects about invalidated source. #ifndef QT_NO_GRAPHICSEFFECT - d_ptr->invalidateGraphicsEffectsRecursively(); + d_ptr->invalidateParentGraphicsEffectsRecursively(); #endif //QT_NO_GRAPHICSEFFECT if (CacheMode(d_ptr->cacheMode) != NoCache) { diff --git a/src/gui/graphicsview/qgraphicsitem_p.h b/src/gui/graphicsview/qgraphicsitem_p.h index bdd8863..ff6e8bd 100644 --- a/src/gui/graphicsview/qgraphicsitem_p.h +++ b/src/gui/graphicsview/qgraphicsitem_p.h @@ -225,7 +225,11 @@ public: bool ignoreDirtyBit = false, bool ignoreOpacity = false) const; int depth() const; #ifndef QT_NO_GRAPHICSEFFECT - void invalidateGraphicsEffectsRecursively(); + enum InvalidateReason { + OpacityChanged + }; + void invalidateParentGraphicsEffectsRecursively(); + void invalidateChildGraphicsEffectsRecursively(InvalidateReason reason); #endif //QT_NO_GRAPHICSEFFECT void invalidateDepthRecursively(); void resolveDepth(); diff --git a/tests/auto/qgraphicseffect/tst_qgraphicseffect.cpp b/tests/auto/qgraphicseffect/tst_qgraphicseffect.cpp index 51e2a57..795431b 100644 --- a/tests/auto/qgraphicseffect/tst_qgraphicseffect.cpp +++ b/tests/auto/qgraphicseffect/tst_qgraphicseffect.cpp @@ -71,6 +71,7 @@ private slots: void colorize(); void drawPixmapItem(); void deviceCoordinateTranslateCaching(); + void inheritOpacity(); }; void tst_QGraphicsEffect::initTestCase() @@ -79,8 +80,8 @@ void tst_QGraphicsEffect::initTestCase() class CustomItem : public QGraphicsRectItem { public: - CustomItem(qreal x, qreal y, qreal width, qreal height) - : QGraphicsRectItem(x, y, width, height), numRepaints(0), + CustomItem(qreal x, qreal y, qreal width, qreal height, QGraphicsItem *parent = 0) + : QGraphicsRectItem(x, y, width, height, parent), numRepaints(0), m_painter(0), m_styleOption(0) {} @@ -560,6 +561,35 @@ void tst_QGraphicsEffect::deviceCoordinateTranslateCaching() QVERIFY(item->numRepaints == numRepaints); } +void tst_QGraphicsEffect::inheritOpacity() +{ + QGraphicsScene scene; + QGraphicsRectItem *rectItem = new QGraphicsRectItem(0, 0, 10, 10); + CustomItem *item = new CustomItem(0, 0, 10, 10, rectItem); + + scene.addItem(rectItem); + + item->setGraphicsEffect(new DeviceEffect); + item->setPen(Qt::NoPen); + item->setBrush(Qt::red); + + rectItem->setOpacity(0.5); + + QGraphicsView view(&scene); + view.show(); + QTest::qWaitForWindowShown(&view); + + QTRY_VERIFY(item->numRepaints >= 1); + + int numRepaints = item->numRepaints; + + rectItem->setOpacity(1); + QTest::qWait(50); + + // item should have been rerendered due to opacity changing + QTRY_VERIFY(item->numRepaints > numRepaints); +} + QTEST_MAIN(tst_QGraphicsEffect) #include "tst_qgraphicseffect.moc" -- cgit v0.12