summaryrefslogtreecommitdiffstats
path: root/src/gui/graphicsview/qgraphicsitem.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/gui/graphicsview/qgraphicsitem.cpp')
-rw-r--r--src/gui/graphicsview/qgraphicsitem.cpp53
1 files changed, 33 insertions, 20 deletions
diff --git a/src/gui/graphicsview/qgraphicsitem.cpp b/src/gui/graphicsview/qgraphicsitem.cpp
index 58395f5f20..096be63c7d 100644
--- a/src/gui/graphicsview/qgraphicsitem.cpp
+++ b/src/gui/graphicsview/qgraphicsitem.cpp
@@ -1272,37 +1272,40 @@ void QGraphicsItemPrivate::setParentItemHelper(QGraphicsItem *newParent, const Q
Returns the bounding rect of this item's children (excluding itself).
*/
-void QGraphicsItemPrivate::childrenBoundingRectHelper(QTransform *x, QRectF *rect, bool doClip)
+void QGraphicsItemPrivate::childrenBoundingRectHelper(QTransform *x, QRectF *rect, QGraphicsItem *topMostEffectItem)
{
Q_Q(QGraphicsItem);
QRectF childrenRect;
QRectF *result = rect;
rect = &childrenRect;
+ const bool setTopMostEffectItem = !topMostEffectItem;
for (int i = 0; i < children.size(); ++i) {
QGraphicsItem *child = children.at(i);
QGraphicsItemPrivate *childd = child->d_ptr.data();
+ if (setTopMostEffectItem)
+ topMostEffectItem = child;
bool hasPos = !childd->pos.isNull();
if (hasPos || childd->transformData) {
// COMBINE
QTransform matrix = childd->transformToParent();
if (x)
matrix *= *x;
- *rect |= matrix.mapRect(child->d_ptr->effectiveBoundingRect());
+ *rect |= matrix.mapRect(child->d_ptr->effectiveBoundingRect(topMostEffectItem));
if (!childd->children.isEmpty())
- childd->childrenBoundingRectHelper(&matrix, rect);
+ childd->childrenBoundingRectHelper(&matrix, rect, topMostEffectItem);
} else {
if (x)
- *rect |= x->mapRect(child->d_ptr->effectiveBoundingRect());
+ *rect |= x->mapRect(child->d_ptr->effectiveBoundingRect(topMostEffectItem));
else
- *rect |= child->d_ptr->effectiveBoundingRect();
+ *rect |= child->d_ptr->effectiveBoundingRect(topMostEffectItem);
if (!childd->children.isEmpty())
- childd->childrenBoundingRectHelper(x, rect);
+ childd->childrenBoundingRectHelper(x, rect, topMostEffectItem);
}
}
- if (doClip && (flags & QGraphicsItem::ItemClipsChildrenToShape)){
+ if (flags & QGraphicsItem::ItemClipsChildrenToShape){
if (x)
*rect &= x->mapRect(q->boundingRect());
else
@@ -1870,6 +1873,10 @@ void QGraphicsItem::setFlags(GraphicsItemFlags flags)
// Item children clipping changes. Propagate the ancestor flag to
// all children.
d_ptr->updateAncestorFlag(ItemClipsChildrenToShape);
+ // The childrenBoundingRect is clipped to the boundingRect in case of ItemClipsChildrenToShape,
+ // which means we have to invalidate the cached childrenBoundingRect whenever this flag changes.
+ d_ptr->dirtyChildrenBoundingRect = 1;
+ d_ptr->markParentDirty(true);
}
if ((flags & ItemIgnoresTransformations) != (oldFlags & ItemIgnoresTransformations)) {
@@ -2800,6 +2807,8 @@ QRectF QGraphicsItemPrivate::effectiveBoundingRect(const QRectF &rect) const
Q_Q(const QGraphicsItem);
QGraphicsEffect *effect = graphicsEffect;
if (scene && effect && effect->isEnabled()) {
+ if (scene->d_func()->views.isEmpty())
+ return effect->boundingRectFor(rect);
QRectF sceneRect = q->mapRectToScene(rect);
QRectF sceneEffectRect;
foreach (QGraphicsView *view, scene->views()) {
@@ -2823,12 +2832,12 @@ QRectF QGraphicsItemPrivate::effectiveBoundingRect(const QRectF &rect) const
\sa boundingRect()
*/
-QRectF QGraphicsItemPrivate::effectiveBoundingRect() const
+QRectF QGraphicsItemPrivate::effectiveBoundingRect(QGraphicsItem *topMostEffectItem) const
{
#ifndef QT_NO_GRAPHICSEFFECT
Q_Q(const QGraphicsItem);
QRectF brect = effectiveBoundingRect(q_ptr->boundingRect());
- if (ancestorFlags & QGraphicsItemPrivate::AncestorClipsChildren)
+ if (ancestorFlags & QGraphicsItemPrivate::AncestorClipsChildren || topMostEffectItem == q)
return brect;
const QGraphicsItem *effectParent = parent;
@@ -2839,8 +2848,10 @@ QRectF QGraphicsItemPrivate::effectiveBoundingRect() const
const QRectF effectRectInParentSpace = effectParent->d_ptr->effectiveBoundingRect(brectInParentSpace);
brect = effectParent->mapRectToItem(q, effectRectInParentSpace);
}
- if (effectParent->d_ptr->ancestorFlags & QGraphicsItemPrivate::AncestorClipsChildren)
+ if (effectParent->d_ptr->ancestorFlags & QGraphicsItemPrivate::AncestorClipsChildren
+ || topMostEffectItem == effectParent) {
return brect;
+ }
effectParent = effectParent->d_ptr->parent;
}
@@ -4715,7 +4726,7 @@ QRectF QGraphicsItem::childrenBoundingRect() const
return d_ptr->childrenBoundingRect;
d_ptr->childrenBoundingRect = QRectF();
- d_ptr->childrenBoundingRectHelper(0, &d_ptr->childrenBoundingRect);
+ d_ptr->childrenBoundingRectHelper(0, &d_ptr->childrenBoundingRect, 0);
d_ptr->dirtyChildrenBoundingRect = 0;
return d_ptr->childrenBoundingRect;
}
@@ -7676,6 +7687,14 @@ QGraphicsObject *QGraphicsItemPrivate::children_at(QDeclarativeListProperty<QGra
return 0;
}
+void QGraphicsItemPrivate::children_clear(QDeclarativeListProperty<QGraphicsObject> *list)
+{
+ QGraphicsItemPrivate *d = QGraphicsItemPrivate::get(static_cast<QGraphicsObject *>(list->object));
+ int childCount = d->children.count();
+ for (int index = 0; index < childCount; index++)
+ QGraphicsItemPrivate::get(d->children.at(0))->setParentItemHelper(0, /*newParentVariant=*/0, /*thisPointerVariant=*/0);
+}
+
/*!
Returns a list of this item's children.
@@ -7689,7 +7708,7 @@ QDeclarativeListProperty<QGraphicsObject> QGraphicsItemPrivate::childrenList()
if (isObject) {
QGraphicsObject *that = static_cast<QGraphicsObject *>(q);
return QDeclarativeListProperty<QGraphicsObject>(that, &children, children_append,
- children_count, children_at);
+ children_count, children_at, children_clear);
} else {
//QGraphicsItem is not supported for this property
return QDeclarativeListProperty<QGraphicsObject>();
@@ -11166,14 +11185,8 @@ QRectF QGraphicsItemEffectSourcePrivate::boundingRect(Qt::CoordinateSystem syste
}
QRectF rect = item->boundingRect();
- if (!item->d_ptr->children.isEmpty()) {
- if (dirtyChildrenBoundingRect) {
- childrenBoundingRect = QRectF();
- item->d_ptr->childrenBoundingRectHelper(0, &childrenBoundingRect, true);
- dirtyChildrenBoundingRect = false;
- }
- rect |= childrenBoundingRect;
- }
+ if (!item->d_ptr->children.isEmpty())
+ rect |= item->childrenBoundingRect();
if (deviceCoordinates) {
Q_ASSERT(info->painter);