diff options
Diffstat (limited to 'src/gui/graphicsview/qgraphicsitem_p.h')
-rw-r--r-- | src/gui/graphicsview/qgraphicsitem_p.h | 319 |
1 files changed, 206 insertions, 113 deletions
diff --git a/src/gui/graphicsview/qgraphicsitem_p.h b/src/gui/graphicsview/qgraphicsitem_p.h index a2cb4ab..a542646 100644 --- a/src/gui/graphicsview/qgraphicsitem_p.h +++ b/src/gui/graphicsview/qgraphicsitem_p.h @@ -1,7 +1,7 @@ /**************************************************************************** ** ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Qt Software Information (qt-info@nokia.com) +** Contact: Nokia Corporation (qt-info@nokia.com) ** ** This file is part of the QtGui module of the Qt Toolkit. ** @@ -34,7 +34,7 @@ ** met: http://www.gnu.org/copyleft/gpl.html. ** ** If you are unsure which license is appropriate for your use, please -** contact the sales department at qt-sales@nokia.com. +** contact the sales department at http://www.qtsoftware.com/contact. ** $QT_END_LICENSE$ ** ****************************************************************************/ @@ -54,7 +54,9 @@ // #include "qgraphicsitem.h" +#include "qset.h" #include "qpixmapcache.h" +#include "qgraphicsview_p.h" #include <QtCore/qpoint.h> @@ -91,31 +93,25 @@ public: void purge(); }; +class QGestureExtraData +{ +public: + QSet<int> gestures; +}; + class Q_AUTOTEST_EXPORT QGraphicsItemPrivate { Q_DECLARE_PUBLIC(QGraphicsItem) public: - struct TransformData - { - TransformData() : rotationX(0),rotationY(0),rotationZ(0),scaleX(1),scaleY(1), dirty(true) {} - QTransform baseTransform; - QTransform transform; - QPointF transformCenter; - qreal rotationX,rotationY,rotationZ,scaleX,scaleY; - bool dirty; - }; enum Extra { - ExtraTransform, ExtraToolTip, ExtraCursor, ExtraCacheData, ExtraMaxDeviceCoordCacheSize, ExtraBoundingRegionGranularity, - ExtraOpacity, - ExtraEffectiveOpacity, - ExtraDecomposedTransform, ExtraEffect, ExtraEffectPixmap, + ExtraGestures }; enum AncestorFlag { @@ -127,9 +123,10 @@ public: inline QGraphicsItemPrivate() : z(0), + opacity(1.), scene(0), parent(0), - siblingIndex(-1), + transformData(0), index(-1), depth(0), acceptedMouseButtons(0x1f), @@ -143,13 +140,10 @@ public: isMemberOfGroup(0), handlesChildEvents(0), itemDiscovered(0), - hasTransform(0), hasCursor(0), ancestorFlags(0), cacheMode(0), hasBoundingRegionGranularity(0), - hasOpacity(0), - hasEffectiveOpacity(0), isWidget(0), dirty(0), dirtyChildren(0), @@ -158,13 +152,21 @@ public: emptyClipPath(0), inSetPosHelper(0), hasEffect(0), + needSortChildren(1), + allChildrenDirty(0), + fullUpdatePending(0), flags(0), - allChildrenCombineOpacity(1), - hasDecomposedTransform(0), - dirtyTransform(0), - dirtyTransformComponents(0), + dirtyChildrenBoundingRect(1), + paintedViewBoundingRectsNeedRepaint(0), + dirtySceneTransform(1), + geometryChanged(0), + inDestructor(0), + isObject(0), + ignoreVisible(0), + ignoreOpacity(0), + acceptTouchEvents(0), + acceptedTouchBeginEvent(0), globalStackingOrder(-1), - sceneTransformIndex(-1), q_ptr(0) { } @@ -177,26 +179,29 @@ 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, bool deleting); + void setParentItemHelper(QGraphicsItem *parent); void childrenBoundingRectHelper(QTransform *x, QRectF *rect); void initStyleOption(QStyleOptionGraphicsItem *option, const QTransform &worldTransform, const QRegion &exposedRegion, bool allItems = false) const; @@ -251,7 +256,7 @@ public: } } } - + struct ExtraStruct { ExtraStruct(Extra type, QVariant value) : type(type), value(value) @@ -263,7 +268,7 @@ public: bool operator<(Extra extra) const { return type < extra; } }; - + QList<ExtraStruct> extras; QGraphicsItemCache *maybeExtraItemCache() const; @@ -290,12 +295,76 @@ 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 && qFuzzyIsNull(q_func()->effectiveOpacity()); } + { + 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 qreal combineOpacityFromParent(qreal parentOpacity) const + { + if (parent && !(flags & QGraphicsItem::ItemIgnoresParentOpacity) + && !(parent->d_ptr->flags & QGraphicsItem::ItemDoesntPropagateOpacityToChildren)) { + return parentOpacity * opacity; + } + return opacity; + } 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()); } @@ -310,17 +379,49 @@ 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; - int siblingIndex; + struct TransformData; + TransformData *transformData; + QTransform sceneTransform; int index; int depth; - // Packed 32 bits + inline QGestureExtraData* extraGestures() const + { + QGestureExtraData *c = (QGestureExtraData *)qVariantValue<void *>(extra(ExtraGestures)); + if (!c) { + QGraphicsItemPrivate *that = const_cast<QGraphicsItemPrivate *>(this); + c = new QGestureExtraData; + that->setExtra(ExtraGestures, qVariantFromValue<void *>(c)); + } + return c; + } + QGestureExtraData* maybeExtraGestures() const + { + return (QGestureExtraData *)qVariantValue<void *>(extra(ExtraGestures)); + } + inline void removeExtraGestures() + { + QGestureExtraData *c = (QGestureExtraData *)qVariantValue<void *>(extra(ExtraGestures)); + delete c; + unsetExtra(ExtraGestures); + } + bool hasGesture(const QString &gesture) const; + void grabGesture(int id); + bool releaseGesture(int id); + + // Packed 32 bytes quint32 acceptedMouseButtons : 5; quint32 visible : 1; quint32 explicitlyHidden : 1; @@ -332,104 +433,96 @@ 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 hasOpacity : 1; - quint32 hasEffectiveOpacity : 1; quint32 isWidget : 1; - quint32 dirty : 1; - quint32 dirtyChildren : 1; + quint32 dirty : 1; + quint32 dirtyChildren : 1; quint32 localCollisionHack : 1; quint32 dirtyClipPath : 1; quint32 emptyClipPath : 1; quint32 inSetPosHelper : 1; + quint32 needSortChildren : 1; + quint32 allChildrenDirty : 1; + quint32 fullUpdatePending : 1; // New 32 bits + quint32 flags : 12; quint32 hasEffect : 1; - quint32 flags : 10; - quint32 allChildrenCombineOpacity : 1; - quint32 hasDecomposedTransform : 1; - quint32 dirtyTransform : 1; - quint32 dirtyTransformComponents : 1; - quint32 padding : 17; // feel free to use + quint32 dirtyChildrenBoundingRect : 1; + quint32 paintedViewBoundingRectsNeedRepaint : 1; + quint32 dirtySceneTransform : 1; + quint32 geometryChanged : 1; + quint32 inDestructor : 1; + quint32 isObject : 1; + quint32 ignoreVisible : 1; + quint32 ignoreOpacity : 1; + quint32 acceptTouchEvents : 1; + quint32 acceptedTouchBeginEvent : 1; + quint32 unused : 9; // feel free to use // Optional stacking order int globalStackingOrder; - int sceneTransformIndex; + QGraphicsItem *q_ptr; +}; - struct DecomposedTransform; - DecomposedTransform *decomposedTransform() const +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 { - QGraphicsItemPrivate *that = const_cast<QGraphicsItemPrivate *>(this); - DecomposedTransform *decomposed; - if (hasDecomposedTransform) { - decomposed = qVariantValue<DecomposedTransform *>(extra(ExtraDecomposedTransform)); - } else { - decomposed = new DecomposedTransform; - that->setExtra(ExtraDecomposedTransform, qVariantFromValue<DecomposedTransform *>(decomposed)); - that->hasDecomposedTransform = 1; - if (!dirtyTransformComponents) - decomposed->reset(); - } - if (dirtyTransformComponents) { - decomposed->initFrom(q_ptr->transform()); - that->dirtyTransformComponents = 0; - } - return decomposed; - } - - struct DecomposedTransform { - qreal xScale; - qreal yScale; - qreal xRotation; - qreal yRotation; - qreal zRotation; - qreal horizontalShear; - qreal verticalShear; - qreal xOrigin; - qreal yOrigin; - - inline void reset() - { - 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; - } - - inline void initFrom(const QTransform &x) - { - reset(); - // ### decompose transform - Q_UNUSED(x); + if (onlyTransform) { + if (!postmultiplyTransform) + return transform; + QTransform x(transform); + x *= *postmultiplyTransform; + return x; } - inline void generateTransform(QTransform *x) const - { - x->translate(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); - } - }; - - QGraphicsItem *q_ptr; + 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; + } }; -QT_END_NAMESPACE +/* + 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; +} -Q_DECLARE_METATYPE(QGraphicsItemPrivate::DecomposedTransform *) +QT_END_NAMESPACE #endif // QT_NO_GRAPHICSVIEW |