diff options
Diffstat (limited to 'src/gui/graphicsview/qgraphicsitem_p.h')
-rw-r--r-- | src/gui/graphicsview/qgraphicsitem_p.h | 202 |
1 files changed, 171 insertions, 31 deletions
diff --git a/src/gui/graphicsview/qgraphicsitem_p.h b/src/gui/graphicsview/qgraphicsitem_p.h index 233c674..9c1ee4f 100644 --- a/src/gui/graphicsview/qgraphicsitem_p.h +++ b/src/gui/graphicsview/qgraphicsitem_p.h @@ -54,6 +54,9 @@ // #include "qgraphicsitem.h" +#include "qpixmapcache.h" + +#include <QtCore/qpoint.h> #if !defined(QT_NO_GRAPHICSVIEW) || (QT_EDITION & QT_MODULE_GRAPHICSVIEW) != QT_MODULE_GRAPHICSVIEW @@ -69,13 +72,14 @@ public: // ItemCoordinateCache only QRect boundingRect; QSize fixedSize; - QString key; + QPixmapCache::Key key; // DeviceCoordinateCache only struct DeviceData { + DeviceData() {} QTransform lastTransform; QPoint cacheIndent; - QString key; + QPixmapCache::Key key; }; QMap<QPaintDevice *, DeviceData> deviceData; @@ -92,14 +96,11 @@ class Q_AUTOTEST_EXPORT QGraphicsItemPrivate Q_DECLARE_PUBLIC(QGraphicsItem) public: enum Extra { - ExtraTransform, ExtraToolTip, ExtraCursor, ExtraCacheData, ExtraMaxDeviceCoordCacheSize, - ExtraBoundingRegionGranularity, - ExtraOpacity, - ExtraEffectiveOpacity + ExtraBoundingRegionGranularity }; enum AncestorFlag { @@ -111,8 +112,10 @@ public: inline QGraphicsItemPrivate() : z(0), + opacity(1.), scene(0), parent(0), + transformData(0), index(-1), depth(0), acceptedMouseButtons(0x1f), @@ -126,14 +129,10 @@ public: isMemberOfGroup(0), handlesChildEvents(0), itemDiscovered(0), - hasTransform(0), hasCursor(0), ancestorFlags(0), cacheMode(0), hasBoundingRegionGranularity(0), - flags(0), - hasOpacity(0), - hasEffectiveOpacity(0), isWidget(0), dirty(0), dirtyChildren(0), @@ -141,9 +140,17 @@ public: dirtyClipPath(1), emptyClipPath(0), inSetPosHelper(0), - allChildrenCombineOpacity(1), + needSortChildren(1), + allChildrenDirty(0), + fullUpdatePending(0), + flags(0), + dirtyChildrenBoundingRect(1), + paintedViewBoundingRectsNeedRepaint(0), + dirtySceneTransform(1), + geometryChanged(0), + inDestructor(0), + isObject(0), globalStackingOrder(-1), - sceneTransformIndex(-1), q_ptr(0) { } @@ -156,23 +163,32 @@ public: void setIsMemberOfGroup(bool enabled); void remapItemPos(QEvent *event, QGraphicsItem *item); QPointF genericMapFromScene(const QPointF &pos, const QWidget *viewport) const; - bool itemIsUntransformable() const; + inline bool itemIsUntransformable() const + { + return (flags & QGraphicsItem::ItemIgnoresTransformations) + || (ancestorFlags & AncestorIgnoresTransformations); + } + void combineTransformToParent(QTransform *x, const QTransform *viewTransform = 0) const; + void combineTransformFromParent(QTransform *x, const QTransform *viewTransform = 0) const; + // ### Qt 5: Remove. Workaround for reimplementation added after Qt 4.4. virtual QVariant inputMethodQueryHelper(Qt::InputMethodQuery query) const; static bool movableAncestorIsSelected(const QGraphicsItem *item); void setPosHelper(const QPointF &pos); + void setTransformHelper(const QTransform &transform); void setVisibleHelper(bool newVisible, bool explicitly, bool update = true); void setEnabledHelper(bool newEnabled, bool explicitly, bool update = true); bool discardUpdateRequest(bool ignoreClipping = false, bool ignoreVisibleBit = false, bool ignoreDirtyBit = false, bool ignoreOpacity = false) const; - void updateHelper(const QRectF &rect = QRectF(), bool force = false, bool maybeDirtyClipPath = false); - void fullUpdateHelper(bool childrenOnly = false, bool maybeDirtyClipPath = false, bool ignoreOpacity = false); - void updateEffectiveOpacity(); - void resolveEffectiveOpacity(qreal effectiveParentOpacity); void resolveDepth(int parentDepth); - void invalidateSceneTransformCache(); + void addChild(QGraphicsItem *child); + void removeChild(QGraphicsItem *child); + void setParentItemHelper(QGraphicsItem *parent); + void childrenBoundingRectHelper(QTransform *x, QRectF *rect); + void initStyleOption(QStyleOptionGraphicsItem *option, const QTransform &worldTransform, + const QRegion &exposedRegion, bool allItems = false) const; virtual void resolveFont(uint inheritedMask) { @@ -224,7 +240,7 @@ public: } } } - + struct ExtraStruct { ExtraStruct(Extra type, QVariant value) : type(type), value(value) @@ -236,8 +252,10 @@ public: bool operator<(Extra extra) const { return type < extra; } }; + QList<ExtraStruct> extras; + QGraphicsItemCache *maybeExtraItemCache() const; QGraphicsItemCache *extraItemCache() const; void removeExtraItemCache(); @@ -261,12 +279,67 @@ public: void invalidateCachedClipPathRecursively(bool childrenOnly = false, const QRectF &emptyIfOutsideThisRect = QRectF()); void updateCachedClipPathFromSetPosHelper(const QPointF &newPos); + void ensureSceneTransformRecursive(QGraphicsItem **topMostDirtyItem); + + inline void invalidateChildrenSceneTransform() + { + for (int i = 0; i < children.size(); ++i) + children.at(i)->d_ptr->dirtySceneTransform = 1; + } + + inline qreal calcEffectiveOpacity() const + { + qreal o = opacity; + QGraphicsItem *p = parent; + int myFlags = flags; + while (p) { + int parentFlags = p->d_ptr->flags; + + // If I have a parent, and I don't ignore my parent's opacity, and my + // parent propagates to me, then combine my local opacity with my parent's + // effective opacity into my effective opacity. + if ((myFlags & QGraphicsItem::ItemIgnoresParentOpacity) + || (parentFlags & QGraphicsItem::ItemDoesntPropagateOpacityToChildren)) { + break; + } + + o *= p->d_ptr->opacity; + p = p->d_ptr->parent; + myFlags = parentFlags; + } + return o; + } inline bool isFullyTransparent() const - { return hasEffectiveOpacity && qFuzzyCompare(q_func()->effectiveOpacity() + 1, qreal(1.0)); } + { + if (opacity < 0.001) + return true; + if (!parent) + return false; + + return calcEffectiveOpacity() < 0.001; + } + + inline qreal effectiveOpacity() const { + if (!parent || !opacity) + return opacity; + + return calcEffectiveOpacity(); + } inline bool childrenCombineOpacity() const - { return allChildrenCombineOpacity || children.isEmpty(); } + { + if (!children.size()) + return true; + if (flags & QGraphicsItem::ItemDoesntPropagateOpacityToChildren) + return false; + + for (int i = 0; i < children.size(); ++i) { + if (children.at(i)->d_ptr->flags & QGraphicsItem::ItemIgnoresParentOpacity) + return false; + } + return true; + } inline bool isClippedAway() const { return !dirtyClipPath && q_func()->isClipped() && (emptyClipPath || cachedClipPath.isEmpty()); } @@ -281,16 +354,25 @@ public: || (childrenCombineOpacity() && isFullyTransparent()); } + inline QTransform transformToParent() const; + QPainterPath cachedClipPath; + QRectF childrenBoundingRect; + QRectF needsRepaint; + QMap<QWidget *, QRect> paintedViewBoundingRects; QPointF pos; qreal z; + qreal opacity; QGraphicsScene *scene; QGraphicsItem *parent; QList<QGraphicsItem *> children; + struct TransformData; + TransformData *transformData; + QTransform sceneTransform; int index; int depth; - // Packed 32 bytes + // Packed 32 bits quint32 acceptedMouseButtons : 5; quint32 visible : 1; quint32 explicitlyHidden : 1; @@ -302,16 +384,10 @@ public: quint32 isMemberOfGroup : 1; quint32 handlesChildEvents : 1; quint32 itemDiscovered : 1; - quint32 hasTransform : 1; quint32 hasCursor : 1; quint32 ancestorFlags : 3; quint32 cacheMode : 2; quint32 hasBoundingRegionGranularity : 1; - quint32 flags : 9; - - // New 32 bytes - quint32 hasOpacity : 1; - quint32 hasEffectiveOpacity : 1; quint32 isWidget : 1; quint32 dirty : 1; quint32 dirtyChildren : 1; @@ -319,15 +395,79 @@ public: quint32 dirtyClipPath : 1; quint32 emptyClipPath : 1; quint32 inSetPosHelper : 1; - quint32 allChildrenCombineOpacity : 1; + quint32 needSortChildren : 1; + quint32 allChildrenDirty : 1; + quint32 fullUpdatePending : 1; + + // New 32 bits + quint32 flags : 12; + quint32 dirtyChildrenBoundingRect : 1; + quint32 paintedViewBoundingRectsNeedRepaint : 1; + quint32 dirtySceneTransform : 1; + quint32 geometryChanged : 1; + quint32 inDestructor : 1; + quint32 isObject : 1; + quint32 unused : 14; // feel free to use // Optional stacking order int globalStackingOrder; - int sceneTransformIndex; - QGraphicsItem *q_ptr; }; +struct QGraphicsItemPrivate::TransformData { + QTransform transform; + qreal xScale; + qreal yScale; + qreal xRotation; + qreal yRotation; + qreal zRotation; + qreal horizontalShear; + qreal verticalShear; + qreal xOrigin; + qreal yOrigin; + bool onlyTransform; + + TransformData() : + xScale(1.0), yScale(1.0), xRotation(0.0), yRotation(0.0), zRotation(0.0), + horizontalShear(0.0), verticalShear(0.0), xOrigin(0.0), yOrigin(0.0), + onlyTransform(true) + {} + + QTransform computedFullTransform(QTransform *postmultiplyTransform = 0) const + { + if (onlyTransform) { + if (!postmultiplyTransform) + return transform; + QTransform x(transform); + x *= *postmultiplyTransform; + return x; + } + + QTransform x(transform); + if (xOrigin != 0 || yOrigin != 0) + x *= QTransform::fromTranslate(xOrigin, yOrigin); + x.rotate(xRotation, Qt::XAxis); + x.rotate(yRotation, Qt::YAxis); + x.rotate(zRotation, Qt::ZAxis); + x.shear(horizontalShear, verticalShear); + x.scale(xScale, yScale); + x.translate(-xOrigin, -yOrigin); + if (postmultiplyTransform) + x *= *postmultiplyTransform; + return x; + } +}; + +/* + return the full transform of the item to the parent. This include the position and all the transform data +*/ +inline QTransform QGraphicsItemPrivate::transformToParent() const +{ + QTransform matrix; + combineTransformToParent(&matrix); + return matrix; +} + QT_END_NAMESPACE #endif // QT_NO_GRAPHICSVIEW |