diff -r 41300fa6a67c -r f7bc934e204c src/gui/graphicsview/qgraphicsitem_p.h --- a/src/gui/graphicsview/qgraphicsitem_p.h Tue Feb 02 00:43:10 2010 +0200 +++ b/src/gui/graphicsview/qgraphicsitem_p.h Wed Mar 31 11:06:36 2010 +0300 @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** @@ -71,6 +71,62 @@ class QGraphicsItemPrivate; +#ifndef QDECLARATIVELISTPROPERTY +#define QDECLARATIVELISTPROPERTY +template +struct QDeclarativeListProperty { + typedef void (*AppendFunction)(QDeclarativeListProperty *, T*); + typedef int (*CountFunction)(QDeclarativeListProperty *); + typedef T *(*AtFunction)(QDeclarativeListProperty *, int); + typedef void (*ClearFunction)(QDeclarativeListProperty *); + + QDeclarativeListProperty() + : object(0), data(0), append(0), count(0), at(0), clear(0), dummy1(0), dummy2(0) {} + QDeclarativeListProperty(QObject *o, QList &list) + : object(o), data(&list), append(qlist_append), count(qlist_count), at(qlist_at), + clear(qlist_clear), dummy1(0), dummy2(0) {} + QDeclarativeListProperty(QObject *o, void *d, AppendFunction a, CountFunction c = 0, AtFunction t = 0, + ClearFunction r = 0) + : object(o), data(d), append(a), count(c), at(t), clear(r), dummy1(0), dummy2(0) {} + + bool operator==(const QDeclarativeListProperty &o) const { + return object == o.object && + data == o.data && + append == o.append && + count == o.count && + at == o.at && + clear == o.clear; + } + + QObject *object; + void *data; + + AppendFunction append; + + CountFunction count; + AtFunction at; + + ClearFunction clear; + + void *dummy1; + void *dummy2; + +private: + static void qlist_append(QDeclarativeListProperty *p, T *v) { + ((QList *)p->data)->append(v); + } + static int qlist_count(QDeclarativeListProperty *p) { + return ((QList *)p->data)->count(); + } + static T *qlist_at(QDeclarativeListProperty *p, int idx) { + return ((QList *)p->data)->at(idx); + } + static void qlist_clear(QDeclarativeListProperty *p) { + return ((QList *)p->data)->clear(); + } +}; +#endif + class QGraphicsItemCache { public: @@ -153,7 +209,7 @@ dirtyChildren(0), localCollisionHack(0), inSetPosHelper(0), - needSortChildren(1), // ### can be 0 by default? + needSortChildren(0), allChildrenDirty(0), fullUpdatePending(0), flags(0), @@ -178,6 +234,8 @@ sequentialOrdering(1), updateDueToGraphicsEffect(0), scenePosDescendants(0), + pendingPolish(0), + mayHaveChildWithGraphicsEffect(0), globalStackingOrder(-1), q_ptr(0) { @@ -195,8 +253,10 @@ return item->d_ptr.data(); } + void updateChildWithGraphicsEffectFlagRecursively(); void updateAncestorFlag(QGraphicsItem::GraphicsItemFlag childFlag, AncestorFlag flag = NoFlag, bool enabled = false, bool root = true); + void updateAncestorFlags(); void setIsMemberOfGroup(bool enabled); void remapItemPos(QEvent *event, QGraphicsItem *item); QPointF genericMapFromScene(const QPointF &pos, const QWidget *viewport) const; @@ -223,13 +283,19 @@ 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(); void addChild(QGraphicsItem *child); void removeChild(QGraphicsItem *child); - void setParentItemHelper(QGraphicsItem *parent); + QDeclarativeListProperty childrenList(); + void setParentItemHelper(QGraphicsItem *parent, const QVariant *newParentVariant, + const QVariant *thisPointerVariant); void childrenBoundingRectHelper(QTransform *x, QRectF *rect); void initStyleOption(QStyleOptionGraphicsItem *option, const QTransform &worldTransform, const QRegion &exposedRegion, bool allItems = false) const; @@ -349,14 +415,20 @@ return o; } + inline bool isOpacityNull() const + { return (opacity < qreal(0.001)); } + + static inline bool isOpacityNull(qreal opacity) + { return (opacity < qreal(0.001)); } + inline bool isFullyTransparent() const { - if (opacity < 0.001) + if (isOpacityNull()) return true; if (!parent) return false; - return calcEffectiveOpacity() < 0.001; + return isOpacityNull(calcEffectiveOpacity()); } inline qreal effectiveOpacity() const { @@ -397,7 +469,10 @@ return !visible || (childrenCombineOpacity() && isFullyTransparent()); } - void setFocusHelper(Qt::FocusReason focusReason, bool climb); + inline void markParentDirty(bool updateBoundingRect = false); + + void setFocusHelper(Qt::FocusReason focusReason, bool climb, bool focusFromShow); + void clearFocusHelper(bool giveFocusToParent); void setSubFocus(QGraphicsItem *rootItem = 0); void clearSubFocus(QGraphicsItem *rootItem = 0); void resetFocusProxy(); @@ -405,11 +480,21 @@ inline QTransform transformToParent() const; inline void ensureSortedChildren(); + static void append(QDeclarativeListProperty *list, QGraphicsObject *item); static inline bool insertionOrder(QGraphicsItem *a, QGraphicsItem *b); void ensureSequentialSiblingIndex(); inline void sendScenePosChange(); virtual void siblingOrderChange(); + // Private Properties + virtual qreal width() const; + virtual void setWidth(qreal); + virtual void resetWidth(); + + virtual qreal height() const; + virtual void setHeight(qreal); + virtual void resetHeight(); + QRectF childrenBoundingRect; QRectF needsRepaint; QMap paintedViewBoundingRects; @@ -484,6 +569,8 @@ quint32 sequentialOrdering : 1; quint32 updateDueToGraphicsEffect : 1; quint32 scenePosDescendants : 1; + quint32 pendingPolish : 1; + quint32 mayHaveChildWithGraphicsEffect : 1; // Optional stacking order int globalStackingOrder; @@ -609,6 +696,7 @@ QPixmap pixmap(Qt::CoordinateSystem system, QPoint *offset, QGraphicsEffect::PixmapPadMode mode) const; + QRect paddedEffectRect(Qt::CoordinateSystem system, QGraphicsEffect::PixmapPadMode mode, const QRectF &sourceRect, bool *unpadded = 0) const; QGraphicsItem *item; QGraphicsItemPaintInfo *info; @@ -720,11 +808,13 @@ inline void QGraphicsItemPrivate::ensureSortedChildren() { if (needSortChildren) { - qSort(children.begin(), children.end(), qt_notclosestLeaf); needSortChildren = 0; sequentialOrdering = 1; + if (children.isEmpty()) + return; + qSort(children.begin(), children.end(), qt_notclosestLeaf); for (int i = 0; i < children.size(); ++i) { - if (children[i]->d_ptr->siblingIndex != i) { + if (children.at(i)->d_ptr->siblingIndex != i) { sequentialOrdering = 0; break; } @@ -740,6 +830,37 @@ return a->d_ptr->siblingIndex < b->d_ptr->siblingIndex; } +/*! + \internal +*/ +inline void QGraphicsItemPrivate::markParentDirty(bool updateBoundingRect) +{ + QGraphicsItemPrivate *parentp = this; + while (parentp->parent) { + parentp = parentp->parent->d_ptr.data(); + parentp->dirtyChildren = 1; + + if (updateBoundingRect) { + parentp->dirtyChildrenBoundingRect = 1; + // ### Only do this if the parent's effect applies to the entire subtree. + parentp->notifyBoundingRectChanged = 1; + } +#ifndef QT_NO_GRAPHICSEFFECT + if (parentp->graphicsEffect) { + if (updateBoundingRect) { + parentp->notifyInvalidated = 1; + static_cast(parentp->graphicsEffect->d_func() + ->source->d_func())->invalidateCache(); + } + if (parentp->graphicsEffect->isEnabled()) { + parentp->dirty = 1; + parentp->fullUpdatePending = 1; + } + } +#endif + } +} + QT_END_NAMESPACE #endif // QT_NO_GRAPHICSVIEW