summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/gui/graphicsview/qgraphicsitem.cpp39
-rw-r--r--src/gui/graphicsview/qgraphicsitem_p.h6
2 files changed, 35 insertions, 10 deletions
diff --git a/src/gui/graphicsview/qgraphicsitem.cpp b/src/gui/graphicsview/qgraphicsitem.cpp
index 327b352..23787a7 100644
--- a/src/gui/graphicsview/qgraphicsitem.cpp
+++ b/src/gui/graphicsview/qgraphicsitem.cpp
@@ -1102,10 +1102,7 @@ void QGraphicsItem::setParentItem(QGraphicsItem *parent)
}
// Resolve opacity.
- if (QGraphicsItem *p = d_ptr->parent)
- d_ptr->resolveEffectiveOpacity(p->effectiveOpacity());
- else
- d_ptr->resolveEffectiveOpacity(1.0);
+ d_ptr->updateEffectiveOpacity();
// Resolve depth.
d_ptr->resolveDepth(parent ? parent->d_ptr->depth : -1);
@@ -1246,12 +1243,8 @@ void QGraphicsItem::setFlags(GraphicsItemFlags flags)
// Reresolve effective opacity if the opacity flags change.
static const quint32 opacityFlagsMask = ItemIgnoresParentOpacity | ItemDoesntPropagateOpacityToChildren;
- if ((flags & opacityFlagsMask) != (oldFlags & opacityFlagsMask)) {
- if (QGraphicsItem *p = d_ptr->parent)
- d_ptr->resolveEffectiveOpacity(p->effectiveOpacity());
- else
- d_ptr->resolveEffectiveOpacity(1.0);
- }
+ if ((flags & opacityFlagsMask) != (oldFlags & opacityFlagsMask))
+ d_ptr->updateEffectiveOpacity();
if (!(d_ptr->flags & ItemIsFocusable) && hasFocus()) {
// Clear focus on the item if it has focus when the focusable flag
@@ -3693,6 +3686,32 @@ void QGraphicsItemPrivate::fullUpdateHelper(bool childrenOnly, bool maybeDirtyCl
dirtyChildren = 1;
}
+static inline bool allChildrenCombineOpacity(QGraphicsItem *parent)
+{
+ Q_ASSERT(parent);
+ if (parent->flags() & QGraphicsItem::ItemDoesntPropagateOpacityToChildren)
+ return false;
+
+ const QList<QGraphicsItem *> children(parent->childItems());
+ for (int i = 0; i < children.size(); ++i) {
+ if (children.at(i)->flags() & QGraphicsItem::ItemIgnoresParentOpacity)
+ return false;
+ }
+ return true;
+}
+
+void QGraphicsItemPrivate::updateEffectiveOpacity()
+{
+ Q_Q(QGraphicsItem);
+ if (parent) {
+ resolveEffectiveOpacity(parent->effectiveOpacity());
+ parent->d_ptr->allChildrenCombineOpacity = ::allChildrenCombineOpacity(parent);
+ } else {
+ resolveEffectiveOpacity(1.0);
+ }
+ allChildrenCombineOpacity = ::allChildrenCombineOpacity(q);
+}
+
/*!
\internal
diff --git a/src/gui/graphicsview/qgraphicsitem_p.h b/src/gui/graphicsview/qgraphicsitem_p.h
index dabbe53..c795915 100644
--- a/src/gui/graphicsview/qgraphicsitem_p.h
+++ b/src/gui/graphicsview/qgraphicsitem_p.h
@@ -141,6 +141,7 @@ public:
dirtyClipPath(1),
emptyClipPath(0),
inSetPosHelper(0),
+ allChildrenCombineOpacity(1),
globalStackingOrder(-1),
sceneTransformIndex(-1),
q_ptr(0)
@@ -166,6 +167,7 @@ public:
void setEnabledHelper(bool newEnabled, bool explicitly, bool update = true);
void updateHelper(const QRectF &rect = QRectF(), bool force = false, bool maybeDirtyClipPath = false);
void fullUpdateHelper(bool childrenOnly = false, bool maybeDirtyClipPath = false);
+ void updateEffectiveOpacity();
void resolveEffectiveOpacity(qreal effectiveParentOpacity);
void resolveDepth(int parentDepth);
void invalidateSceneTransformCache();
@@ -264,6 +266,9 @@ public:
&& qFuzzyCompare(q_func()->effectiveOpacity() + 1, qreal(1.0)));
}
+ inline bool childrenCombineOpacity() const
+ { return allChildrenCombineOpacity || children.isEmpty(); }
+
inline bool isClippedAway() const
{ return !dirtyClipPath && q_func()->isClipped() && (emptyClipPath || cachedClipPath.isEmpty()); }
@@ -308,6 +313,7 @@ public:
quint32 dirtyClipPath : 1;
quint32 emptyClipPath : 1;
quint32 inSetPosHelper : 1;
+ quint32 allChildrenCombineOpacity : 1;
// Optional stacking order
int globalStackingOrder;