source: trunk/src/gui/graphicsview/qgraphicsitem_p.h@ 711

Last change on this file since 711 was 651, checked in by Dmitry A. Kuminov, 16 years ago

trunk: Merged in qt 4.6.2 sources.

File size: 24.3 KB
Line 
1/****************************************************************************
2**
3** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
4** All rights reserved.
5** Contact: Nokia Corporation ([email protected])
6**
7** This file is part of the QtGui module of the Qt Toolkit.
8**
9** $QT_BEGIN_LICENSE:LGPL$
10** Commercial Usage
11** Licensees holding valid Qt Commercial licenses may use this file in
12** accordance with the Qt Commercial License Agreement provided with the
13** Software or, alternatively, in accordance with the terms contained in
14** a written agreement between you and Nokia.
15**
16** GNU Lesser General Public License Usage
17** Alternatively, this file may be used under the terms of the GNU Lesser
18** General Public License version 2.1 as published by the Free Software
19** Foundation and appearing in the file LICENSE.LGPL included in the
20** packaging of this file. Please review the following information to
21** ensure the GNU Lesser General Public License version 2.1 requirements
22** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
23**
24** In addition, as a special exception, Nokia gives you certain additional
25** rights. These rights are described in the Nokia Qt LGPL Exception
26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
27**
28** GNU General Public License Usage
29** Alternatively, this file may be used under the terms of the GNU
30** General Public License version 3.0 as published by the Free Software
31** Foundation and appearing in the file LICENSE.GPL included in the
32** packaging of this file. Please review the following information to
33** ensure the GNU General Public License version 3.0 requirements will be
34** met: http://www.gnu.org/copyleft/gpl.html.
35**
36** If you have questions regarding the use of this file, please contact
37** Nokia at [email protected].
38** $QT_END_LICENSE$
39**
40****************************************************************************/
41
42#ifndef QGRAPHICSITEM_P_H
43#define QGRAPHICSITEM_P_H
44
45//
46// W A R N I N G
47// -------------
48//
49// This file is not part of the Qt API. It exists for the convenience
50// of other Qt classes. This header file may change from version to
51// version without notice, or even be removed.
52//
53// We mean it.
54//
55
56#include "qgraphicsitem.h"
57#include "qset.h"
58#include "qpixmapcache.h"
59#include <private/qgraphicsview_p.h>
60#include "qgraphicstransform.h"
61#include <private/qgraphicstransform_p.h>
62
63#include <private/qgraphicseffect_p.h>
64#include <qgraphicseffect.h>
65
66#include <QtCore/qpoint.h>
67
68#if !defined(QT_NO_GRAPHICSVIEW) || (QT_EDITION & QT_MODULE_GRAPHICSVIEW) != QT_MODULE_GRAPHICSVIEW
69
70QT_BEGIN_NAMESPACE
71
72class QGraphicsItemPrivate;
73
74class QGraphicsItemCache
75{
76public:
77 QGraphicsItemCache() : allExposed(false) { }
78
79 // ItemCoordinateCache only
80 QRect boundingRect;
81 QSize fixedSize;
82 QPixmapCache::Key key;
83
84 // DeviceCoordinateCache only
85 struct DeviceData {
86 DeviceData() {}
87 QTransform lastTransform;
88 QPoint cacheIndent;
89 QPixmapCache::Key key;
90 };
91 QMap<QPaintDevice *, DeviceData> deviceData;
92
93 // List of logical exposed rects
94 QVector<QRectF> exposed;
95 bool allExposed;
96
97 // Empty cache
98 void purge();
99};
100
101class Q_GUI_EXPORT QGraphicsItemPrivate
102{
103 Q_DECLARE_PUBLIC(QGraphicsItem)
104public:
105 enum Extra {
106 ExtraToolTip,
107 ExtraCursor,
108 ExtraCacheData,
109 ExtraMaxDeviceCoordCacheSize,
110 ExtraBoundingRegionGranularity
111 };
112
113 enum AncestorFlag {
114 NoFlag = 0,
115 AncestorHandlesChildEvents = 0x1,
116 AncestorClipsChildren = 0x2,
117 AncestorIgnoresTransformations = 0x4,
118 AncestorFiltersChildEvents = 0x8
119 };
120
121 inline QGraphicsItemPrivate()
122 : z(0),
123 opacity(1.),
124 scene(0),
125 parent(0),
126 transformData(0),
127 graphicsEffect(0),
128 index(-1),
129 siblingIndex(-1),
130 itemDepth(-1),
131 focusProxy(0),
132 subFocusItem(0),
133 focusScopeItem(0),
134 imHints(Qt::ImhNone),
135 panelModality(QGraphicsItem::NonModal),
136 acceptedMouseButtons(0x1f),
137 visible(1),
138 explicitlyHidden(0),
139 enabled(1),
140 explicitlyDisabled(0),
141 selected(0),
142 acceptsHover(0),
143 acceptDrops(0),
144 isMemberOfGroup(0),
145 handlesChildEvents(0),
146 itemDiscovered(0),
147 hasCursor(0),
148 ancestorFlags(0),
149 cacheMode(0),
150 hasBoundingRegionGranularity(0),
151 isWidget(0),
152 dirty(0),
153 dirtyChildren(0),
154 localCollisionHack(0),
155 inSetPosHelper(0),
156 needSortChildren(0),
157 allChildrenDirty(0),
158 fullUpdatePending(0),
159 flags(0),
160 dirtyChildrenBoundingRect(1),
161 paintedViewBoundingRectsNeedRepaint(0),
162 dirtySceneTransform(1),
163 geometryChanged(1),
164 inDestructor(0),
165 isObject(0),
166 ignoreVisible(0),
167 ignoreOpacity(0),
168 acceptTouchEvents(0),
169 acceptedTouchBeginEvent(0),
170 filtersDescendantEvents(0),
171 sceneTransformTranslateOnly(0),
172 notifyBoundingRectChanged(0),
173 notifyInvalidated(0),
174 mouseSetsFocus(1),
175 explicitActivate(0),
176 wantsActive(0),
177 holesInSiblingIndex(0),
178 sequentialOrdering(1),
179 updateDueToGraphicsEffect(0),
180 scenePosDescendants(0),
181 pendingPolish(0),
182 mayHaveChildWithGraphicsEffect(0),
183 globalStackingOrder(-1),
184 q_ptr(0)
185 {
186 }
187
188 inline virtual ~QGraphicsItemPrivate()
189 { }
190
191 static const QGraphicsItemPrivate *get(const QGraphicsItem *item)
192 {
193 return item->d_ptr.data();
194 }
195 static QGraphicsItemPrivate *get(QGraphicsItem *item)
196 {
197 return item->d_ptr.data();
198 }
199
200 void updateChildWithGraphicsEffectFlagRecursively();
201 void updateAncestorFlag(QGraphicsItem::GraphicsItemFlag childFlag,
202 AncestorFlag flag = NoFlag, bool enabled = false, bool root = true);
203 void updateAncestorFlags();
204 void setIsMemberOfGroup(bool enabled);
205 void remapItemPos(QEvent *event, QGraphicsItem *item);
206 QPointF genericMapFromScene(const QPointF &pos, const QWidget *viewport) const;
207 inline bool itemIsUntransformable() const
208 {
209 return (flags & QGraphicsItem::ItemIgnoresTransformations)
210 || (ancestorFlags & AncestorIgnoresTransformations);
211 }
212
213 void combineTransformToParent(QTransform *x, const QTransform *viewTransform = 0) const;
214 void combineTransformFromParent(QTransform *x, const QTransform *viewTransform = 0) const;
215 virtual void updateSceneTransformFromParent();
216
217 // ### Qt 5: Remove. Workaround for reimplementation added after Qt 4.4.
218 virtual QVariant inputMethodQueryHelper(Qt::InputMethodQuery query) const;
219 static bool movableAncestorIsSelected(const QGraphicsItem *item);
220
221 virtual void setPosHelper(const QPointF &pos);
222 void setTransformHelper(const QTransform &transform);
223 void appendGraphicsTransform(QGraphicsTransform *t);
224 void setVisibleHelper(bool newVisible, bool explicitly, bool update = true);
225 void setEnabledHelper(bool newEnabled, bool explicitly, bool update = true);
226 bool discardUpdateRequest(bool ignoreVisibleBit = false,
227 bool ignoreDirtyBit = false, bool ignoreOpacity = false) const;
228 int depth() const;
229#ifndef QT_NO_GRAPHICSEFFECT
230 enum InvalidateReason {
231 OpacityChanged
232 };
233 void invalidateParentGraphicsEffectsRecursively();
234 void invalidateChildGraphicsEffectsRecursively(InvalidateReason reason);
235#endif //QT_NO_GRAPHICSEFFECT
236 void invalidateDepthRecursively();
237 void resolveDepth();
238 void addChild(QGraphicsItem *child);
239 void removeChild(QGraphicsItem *child);
240 void setParentItemHelper(QGraphicsItem *parent, const QVariant *newParentVariant,
241 const QVariant *thisPointerVariant);
242 void childrenBoundingRectHelper(QTransform *x, QRectF *rect);
243 void initStyleOption(QStyleOptionGraphicsItem *option, const QTransform &worldTransform,
244 const QRegion &exposedRegion, bool allItems = false) const;
245 QRectF effectiveBoundingRect() const;
246 QRectF sceneEffectiveBoundingRect() const;
247
248 QRectF effectiveBoundingRect(const QRectF &rect) const;
249
250 virtual void resolveFont(uint inheritedMask)
251 {
252 for (int i = 0; i < children.size(); ++i)
253 children.at(i)->d_ptr->resolveFont(inheritedMask);
254 }
255
256 virtual void resolvePalette(uint inheritedMask)
257 {
258 for (int i = 0; i < children.size(); ++i)
259 children.at(i)->d_ptr->resolveFont(inheritedMask);
260 }
261
262 virtual bool isProxyWidget() const;
263
264 inline QVariant extra(Extra type) const
265 {
266 for (int i = 0; i < extras.size(); ++i) {
267 const ExtraStruct &extra = extras.at(i);
268 if (extra.type == type)
269 return extra.value;
270 }
271 return QVariant();
272 }
273
274 inline void setExtra(Extra type, const QVariant &value)
275 {
276 int index = -1;
277 for (int i = 0; i < extras.size(); ++i) {
278 if (extras.at(i).type == type) {
279 index = i;
280 break;
281 }
282 }
283
284 if (index == -1) {
285 extras << ExtraStruct(type, value);
286 } else {
287 extras[index].value = value;
288 }
289 }
290
291 inline void unsetExtra(Extra type)
292 {
293 for (int i = 0; i < extras.size(); ++i) {
294 if (extras.at(i).type == type) {
295 extras.removeAt(i);
296 return;
297 }
298 }
299 }
300
301 struct ExtraStruct {
302 ExtraStruct(Extra type, QVariant value)
303 : type(type), value(value)
304 { }
305
306 Extra type;
307 QVariant value;
308
309 bool operator<(Extra extra) const
310 { return type < extra; }
311 };
312
313 QList<ExtraStruct> extras;
314
315 QGraphicsItemCache *maybeExtraItemCache() const;
316 QGraphicsItemCache *extraItemCache() const;
317 void removeExtraItemCache();
318
319 void ensureSceneTransformRecursive(QGraphicsItem **topMostDirtyItem);
320 inline void ensureSceneTransform()
321 {
322 QGraphicsItem *that = q_func();
323 ensureSceneTransformRecursive(&that);
324 }
325
326 inline bool hasTranslateOnlySceneTransform()
327 {
328 ensureSceneTransform();
329 return sceneTransformTranslateOnly;
330 }
331
332 inline void invalidateChildrenSceneTransform()
333 {
334 for (int i = 0; i < children.size(); ++i)
335 children.at(i)->d_ptr->dirtySceneTransform = 1;
336 }
337
338 inline qreal calcEffectiveOpacity() const
339 {
340 qreal o = opacity;
341 QGraphicsItem *p = parent;
342 int myFlags = flags;
343 while (p) {
344 int parentFlags = p->d_ptr->flags;
345
346 // If I have a parent, and I don't ignore my parent's opacity, and my
347 // parent propagates to me, then combine my local opacity with my parent's
348 // effective opacity into my effective opacity.
349 if ((myFlags & QGraphicsItem::ItemIgnoresParentOpacity)
350 || (parentFlags & QGraphicsItem::ItemDoesntPropagateOpacityToChildren)) {
351 break;
352 }
353
354 o *= p->d_ptr->opacity;
355 p = p->d_ptr->parent;
356 myFlags = parentFlags;
357 }
358 return o;
359 }
360
361 inline bool isOpacityNull() const
362 { return (opacity < qreal(0.001)); }
363
364 static inline bool isOpacityNull(qreal opacity)
365 { return (opacity < qreal(0.001)); }
366
367 inline bool isFullyTransparent() const
368 {
369 if (isOpacityNull())
370 return true;
371 if (!parent)
372 return false;
373
374 return isOpacityNull(calcEffectiveOpacity());
375 }
376
377 inline qreal effectiveOpacity() const {
378 if (!parent || !opacity)
379 return opacity;
380
381 return calcEffectiveOpacity();
382 }
383
384 inline qreal combineOpacityFromParent(qreal parentOpacity) const
385 {
386 if (parent && !(flags & QGraphicsItem::ItemIgnoresParentOpacity)
387 && !(parent->d_ptr->flags & QGraphicsItem::ItemDoesntPropagateOpacityToChildren)) {
388 return parentOpacity * opacity;
389 }
390 return opacity;
391 }
392
393 inline bool childrenCombineOpacity() const
394 {
395 if (!children.size())
396 return true;
397 if (flags & QGraphicsItem::ItemDoesntPropagateOpacityToChildren)
398 return false;
399
400 for (int i = 0; i < children.size(); ++i) {
401 if (children.at(i)->d_ptr->flags & QGraphicsItem::ItemIgnoresParentOpacity)
402 return false;
403 }
404 return true;
405 }
406
407 inline bool childrenClippedToShape() const
408 { return (flags & QGraphicsItem::ItemClipsChildrenToShape) || children.isEmpty(); }
409
410 inline bool isInvisible() const
411 {
412 return !visible || (childrenCombineOpacity() && isFullyTransparent());
413 }
414
415 inline void markParentDirty(bool updateBoundingRect = false);
416
417 void setFocusHelper(Qt::FocusReason focusReason, bool climb);
418 void setSubFocus(QGraphicsItem *rootItem = 0);
419 void clearSubFocus(QGraphicsItem *rootItem = 0);
420 void resetFocusProxy();
421 virtual void subFocusItemChange();
422
423 inline QTransform transformToParent() const;
424 inline void ensureSortedChildren();
425 static inline bool insertionOrder(QGraphicsItem *a, QGraphicsItem *b);
426 void ensureSequentialSiblingIndex();
427 inline void sendScenePosChange();
428 virtual void siblingOrderChange();
429
430 QRectF childrenBoundingRect;
431 QRectF needsRepaint;
432 QMap<QWidget *, QRect> paintedViewBoundingRects;
433 QPointF pos;
434 qreal z;
435 qreal opacity;
436 QGraphicsScene *scene;
437 QGraphicsItem *parent;
438 QList<QGraphicsItem *> children;
439 struct TransformData;
440 TransformData *transformData;
441 QGraphicsEffect *graphicsEffect;
442 QTransform sceneTransform;
443 int index;
444 int siblingIndex;
445 int itemDepth; // Lazily calculated when calling depth().
446 QGraphicsItem *focusProxy;
447 QList<QGraphicsItem **> focusProxyRefs;
448 QGraphicsItem *subFocusItem;
449 QGraphicsItem *focusScopeItem;
450 Qt::InputMethodHints imHints;
451 QGraphicsItem::PanelModality panelModality;
452 QMap<Qt::GestureType, Qt::GestureFlags> gestureContext;
453
454 // Packed 32 bits
455 quint32 acceptedMouseButtons : 5;
456 quint32 visible : 1;
457 quint32 explicitlyHidden : 1;
458 quint32 enabled : 1;
459 quint32 explicitlyDisabled : 1;
460 quint32 selected : 1;
461 quint32 acceptsHover : 1;
462 quint32 acceptDrops : 1;
463 quint32 isMemberOfGroup : 1;
464 quint32 handlesChildEvents : 1;
465 quint32 itemDiscovered : 1;
466 quint32 hasCursor : 1;
467 quint32 ancestorFlags : 4;
468 quint32 cacheMode : 2;
469 quint32 hasBoundingRegionGranularity : 1;
470 quint32 isWidget : 1;
471 quint32 dirty : 1;
472 quint32 dirtyChildren : 1;
473 quint32 localCollisionHack : 1;
474 quint32 inSetPosHelper : 1;
475 quint32 needSortChildren : 1;
476 quint32 allChildrenDirty : 1;
477
478 // Packed 32 bits
479 quint32 fullUpdatePending : 1;
480 quint32 flags : 17;
481 quint32 dirtyChildrenBoundingRect : 1;
482 quint32 paintedViewBoundingRectsNeedRepaint : 1;
483 quint32 dirtySceneTransform : 1;
484 quint32 geometryChanged : 1;
485 quint32 inDestructor : 1;
486 quint32 isObject : 1;
487 quint32 ignoreVisible : 1;
488 quint32 ignoreOpacity : 1;
489 quint32 acceptTouchEvents : 1;
490 quint32 acceptedTouchBeginEvent : 1;
491 quint32 filtersDescendantEvents : 1;
492 quint32 sceneTransformTranslateOnly : 1;
493 quint32 notifyBoundingRectChanged : 1;
494 quint32 notifyInvalidated : 1;
495
496 // New 32 bits
497 quint32 mouseSetsFocus : 1;
498 quint32 explicitActivate : 1;
499 quint32 wantsActive : 1;
500 quint32 holesInSiblingIndex : 1;
501 quint32 sequentialOrdering : 1;
502 quint32 updateDueToGraphicsEffect : 1;
503 quint32 scenePosDescendants : 1;
504 quint32 pendingPolish : 1;
505 quint32 mayHaveChildWithGraphicsEffect : 1;
506
507 // Optional stacking order
508 int globalStackingOrder;
509 QGraphicsItem *q_ptr;
510};
511
512struct QGraphicsItemPrivate::TransformData
513{
514 QTransform transform;
515 qreal scale;
516 qreal rotation;
517 qreal xOrigin;
518 qreal yOrigin;
519 QList<QGraphicsTransform *> graphicsTransforms;
520 bool onlyTransform;
521
522 TransformData() :
523 scale(1.0), rotation(0.0),
524 xOrigin(0.0), yOrigin(0.0),
525 onlyTransform(true)
526 { }
527
528 QTransform computedFullTransform(QTransform *postmultiplyTransform = 0) const
529 {
530 if (onlyTransform) {
531 if (!postmultiplyTransform || postmultiplyTransform->isIdentity())
532 return transform;
533 if (transform.isIdentity())
534 return *postmultiplyTransform;
535 return transform * *postmultiplyTransform;
536 }
537
538 QTransform x(transform);
539 if (!graphicsTransforms.isEmpty()) {
540 QMatrix4x4 m;
541 for (int i = 0; i < graphicsTransforms.size(); ++i)
542 graphicsTransforms.at(i)->applyTo(&m);
543 x *= m.toTransform();
544 }
545 x.translate(xOrigin, yOrigin);
546 x.rotate(rotation);
547 x.scale(scale, scale);
548 x.translate(-xOrigin, -yOrigin);
549 if (postmultiplyTransform)
550 x *= *postmultiplyTransform;
551 return x;
552 }
553};
554
555struct QGraphicsItemPaintInfo
556{
557 inline QGraphicsItemPaintInfo(const QTransform *const xform1, const QTransform *const xform2,
558 const QTransform *const xform3,
559 QRegion *r, QWidget *w, QStyleOptionGraphicsItem *opt,
560 QPainter *p, qreal o, bool b1, bool b2)
561 : viewTransform(xform1), transformPtr(xform2), effectTransform(xform3), exposedRegion(r), widget(w),
562 option(opt), painter(p), opacity(o), wasDirtySceneTransform(b1), drawItem(b2)
563 {}
564
565 const QTransform *viewTransform;
566 const QTransform *transformPtr;
567 const QTransform *effectTransform;
568 QRegion *exposedRegion;
569 QWidget *widget;
570 QStyleOptionGraphicsItem *option;
571 QPainter *painter;
572 qreal opacity;
573 quint32 wasDirtySceneTransform : 1;
574 quint32 drawItem : 1;
575};
576
577#ifndef QT_NO_GRAPHICSEFFECT
578class QGraphicsItemEffectSourcePrivate : public QGraphicsEffectSourcePrivate
579{
580public:
581 QGraphicsItemEffectSourcePrivate(QGraphicsItem *i)
582 : QGraphicsEffectSourcePrivate(), item(i), info(0)
583 {}
584
585 inline void detach()
586 {
587 item->d_ptr->graphicsEffect = 0;
588 item->prepareGeometryChange();
589 }
590
591 inline const QGraphicsItem *graphicsItem() const
592 { return item; }
593
594 inline const QWidget *widget() const
595 { return 0; }
596
597 inline void update() {
598 item->d_ptr->updateDueToGraphicsEffect = true;
599 item->update();
600 item->d_ptr->updateDueToGraphicsEffect = false;
601 }
602
603 inline void effectBoundingRectChanged()
604 { item->prepareGeometryChange(); }
605
606 inline bool isPixmap() const
607 {
608 return item->type() == QGraphicsPixmapItem::Type
609 && !(item->flags() & QGraphicsItem::ItemIsSelectable)
610 && item->d_ptr->children.size() == 0;
611 //|| (item->d_ptr->isObject && qobject_cast<QmlGraphicsImage *>(q_func()));
612 }
613
614 inline const QStyleOption *styleOption() const
615 { return info ? info->option : 0; }
616
617 inline QRect deviceRect() const
618 {
619 if (!info || !info->widget) {
620 qWarning("QGraphicsEffectSource::deviceRect: Not yet implemented, lacking device context");
621 return QRect();
622 }
623 return info->widget->rect();
624 }
625
626 QRectF boundingRect(Qt::CoordinateSystem system) const;
627 void draw(QPainter *);
628 QPixmap pixmap(Qt::CoordinateSystem system,
629 QPoint *offset,
630 QGraphicsEffect::PixmapPadMode mode) const;
631 QRect paddedEffectRect(Qt::CoordinateSystem system, QGraphicsEffect::PixmapPadMode mode, const QRectF &sourceRect, bool *unpadded = 0) const;
632
633 QGraphicsItem *item;
634 QGraphicsItemPaintInfo *info;
635 QTransform lastEffectTransform;
636};
637#endif //QT_NO_GRAPHICSEFFECT
638
639/*!
640 Returns true if \a item1 is on top of \a item2.
641 The items dont need to be siblings.
642
643 \internal
644*/
645inline bool qt_closestItemFirst(const QGraphicsItem *item1, const QGraphicsItem *item2)
646{
647 // Siblings? Just check their z-values.
648 const QGraphicsItemPrivate *d1 = item1->d_ptr.data();
649 const QGraphicsItemPrivate *d2 = item2->d_ptr.data();
650 if (d1->parent == d2->parent)
651 return qt_closestLeaf(item1, item2);
652
653 // Find common ancestor, and each item's ancestor closest to the common
654 // ancestor.
655 int item1Depth = d1->depth();
656 int item2Depth = d2->depth();
657 const QGraphicsItem *p = item1;
658 const QGraphicsItem *t1 = item1;
659 while (item1Depth > item2Depth && (p = p->d_ptr->parent)) {
660 if (p == item2) {
661 // item2 is one of item1's ancestors; item1 is on top
662 return !(t1->d_ptr->flags & QGraphicsItem::ItemStacksBehindParent);
663 }
664 t1 = p;
665 --item1Depth;
666 }
667 p = item2;
668 const QGraphicsItem *t2 = item2;
669 while (item2Depth > item1Depth && (p = p->d_ptr->parent)) {
670 if (p == item1) {
671 // item1 is one of item2's ancestors; item1 is not on top
672 return (t2->d_ptr->flags & QGraphicsItem::ItemStacksBehindParent);
673 }
674 t2 = p;
675 --item2Depth;
676 }
677
678 // item1Ancestor is now at the same level as item2Ancestor, but not the same.
679 const QGraphicsItem *p1 = t1;
680 const QGraphicsItem *p2 = t2;
681 while (t1 && t1 != t2) {
682 p1 = t1;
683 p2 = t2;
684 t1 = t1->d_ptr->parent;
685 t2 = t2->d_ptr->parent;
686 }
687
688 // in case we have a common ancestor, we compare the immediate children in the ancestor's path.
689 // otherwise we compare the respective items' topLevelItems directly.
690 return qt_closestLeaf(p1, p2);
691}
692
693/*!
694 Returns true if \a item2 is on top of \a item1.
695 The items dont need to be siblings.
696
697 \internal
698*/
699inline bool qt_closestItemLast(const QGraphicsItem *item1, const QGraphicsItem *item2)
700{
701 return qt_closestItemFirst(item2, item1);
702}
703
704/*!
705 \internal
706*/
707inline bool qt_closestLeaf(const QGraphicsItem *item1, const QGraphicsItem *item2)
708{
709 // Return true if sibling item1 is on top of item2.
710 const QGraphicsItemPrivate *d1 = item1->d_ptr.data();
711 const QGraphicsItemPrivate *d2 = item2->d_ptr.data();
712 bool f1 = d1->flags & QGraphicsItem::ItemStacksBehindParent;
713 bool f2 = d2->flags & QGraphicsItem::ItemStacksBehindParent;
714 if (f1 != f2)
715 return f2;
716 if (d1->z != d2->z)
717 return d1->z > d2->z;
718 return d1->siblingIndex > d2->siblingIndex;
719}
720
721/*!
722 \internal
723*/
724inline bool qt_notclosestLeaf(const QGraphicsItem *item1, const QGraphicsItem *item2)
725{ return qt_closestLeaf(item2, item1); }
726
727/*
728 return the full transform of the item to the parent. This include the position and all the transform data
729*/
730inline QTransform QGraphicsItemPrivate::transformToParent() const
731{
732 QTransform matrix;
733 combineTransformToParent(&matrix);
734 return matrix;
735}
736
737/*!
738 \internal
739*/
740inline void QGraphicsItemPrivate::ensureSortedChildren()
741{
742 if (needSortChildren) {
743 needSortChildren = 0;
744 sequentialOrdering = 1;
745 if (children.isEmpty())
746 return;
747 qSort(children.begin(), children.end(), qt_notclosestLeaf);
748 for (int i = 0; i < children.size(); ++i) {
749 if (children.at(i)->d_ptr->siblingIndex != i) {
750 sequentialOrdering = 0;
751 break;
752 }
753 }
754 }
755}
756
757/*!
758 \internal
759*/
760inline bool QGraphicsItemPrivate::insertionOrder(QGraphicsItem *a, QGraphicsItem *b)
761{
762 return a->d_ptr->siblingIndex < b->d_ptr->siblingIndex;
763}
764
765/*!
766 \internal
767*/
768inline void QGraphicsItemPrivate::markParentDirty(bool updateBoundingRect)
769{
770 QGraphicsItemPrivate *parentp = this;
771 while (parentp->parent) {
772 parentp = parentp->parent->d_ptr.data();
773 parentp->dirtyChildren = 1;
774
775 if (updateBoundingRect) {
776 parentp->dirtyChildrenBoundingRect = 1;
777 // ### Only do this if the parent's effect applies to the entire subtree.
778 parentp->notifyBoundingRectChanged = 1;
779 }
780#ifndef QT_NO_GRAPHICSEFFECT
781 if (parentp->graphicsEffect) {
782 if (updateBoundingRect) {
783 parentp->notifyInvalidated = 1;
784 static_cast<QGraphicsItemEffectSourcePrivate *>(parentp->graphicsEffect->d_func()
785 ->source->d_func())->invalidateCache();
786 }
787 if (parentp->graphicsEffect->isEnabled()) {
788 parentp->dirty = 1;
789 parentp->fullUpdatePending = 1;
790 }
791 }
792#endif
793 }
794}
795
796QT_END_NAMESPACE
797
798#endif // QT_NO_GRAPHICSVIEW
799
800#endif
Note: See TracBrowser for help on using the repository browser.