266 |
266 |
267 \sa QGraphicsScene, QGraphicsView, {The Graphics View Framework} |
267 \sa QGraphicsScene, QGraphicsView, {The Graphics View Framework} |
268 */ |
268 */ |
269 |
269 |
270 /*! |
270 /*! |
|
271 \variable QGraphicsItem::Type |
|
272 |
|
273 The type value returned by the virtual type() function in standard |
|
274 graphics item classes in Qt. All such standard graphics item |
|
275 classes in Qt are associated with a unique value for Type, |
|
276 e.g. the value returned by QGraphicsPathItem::type() is 2. |
|
277 |
|
278 \snippet doc/src/snippets/code/src_gui_graphicsview_qgraphicsitem.cpp 18 |
|
279 */ |
|
280 |
|
281 /*! |
271 \variable QGraphicsItem::UserType |
282 \variable QGraphicsItem::UserType |
272 |
283 |
273 The lowest permitted type value for custom items (subclasses |
284 The lowest permitted type value for custom items (subclasses |
274 of QGraphicsItem or any of the standard items). This value is |
285 of QGraphicsItem or any of the standard items). This value is |
275 used in conjunction with a reimplementation of QGraphicsItem::type() |
286 used in conjunction with a reimplementation of QGraphicsItem::type() |
276 and declaring a Type enum value. Example: |
287 and declaring a Type enum value. Example: |
277 |
288 |
278 \snippet doc/src/snippets/code/src_gui_graphicsview_qgraphicsitem.cpp 1 |
289 \snippet doc/src/snippets/code/src_gui_graphicsview_qgraphicsitem.cpp 1 |
|
290 |
|
291 \note UserType = 65536 |
279 */ |
292 */ |
280 |
293 |
281 /*! |
294 /*! |
282 \enum QGraphicsItem::GraphicsItemFlag |
295 \enum QGraphicsItem::GraphicsItemFlag |
283 |
296 |
304 an input item). Enabling this flag will allow the item to accept focus, |
317 an input item). Enabling this flag will allow the item to accept focus, |
305 which again allows the delivery of key events to |
318 which again allows the delivery of key events to |
306 QGraphicsItem::keyPressEvent() and QGraphicsItem::keyReleaseEvent(). |
319 QGraphicsItem::keyPressEvent() and QGraphicsItem::keyReleaseEvent(). |
307 |
320 |
308 \value ItemClipsToShape The item clips to its own shape. The item cannot |
321 \value ItemClipsToShape The item clips to its own shape. The item cannot |
309 draw or receive mouse, tablet, drag and drop or hover events outside ts |
322 draw or receive mouse, tablet, drag and drop or hover events outside its |
310 shape. It is disabled by default. This behavior is enforced by |
323 shape. It is disabled by default. This behavior is enforced by |
311 QGraphicsView::drawItems() or QGraphicsScene::drawItems(). This flag was |
324 QGraphicsView::drawItems() or QGraphicsScene::drawItems(). This flag was |
312 introduced in Qt 4.3. |
325 introduced in Qt 4.3. |
313 |
326 |
314 \value ItemClipsChildrenToShape The item clips the painting of all its |
327 \value ItemClipsChildrenToShape The item clips the painting of all its |
342 |
355 |
343 \value ItemStacksBehindParent The item is stacked behind its parent. By |
356 \value ItemStacksBehindParent The item is stacked behind its parent. By |
344 default, child items are stacked on top of the parent item. But setting |
357 default, child items are stacked on top of the parent item. But setting |
345 this flag, the child will be stacked behind it. This flag is useful for |
358 this flag, the child will be stacked behind it. This flag is useful for |
346 drop shadow effects and for decoration objects that follow the parent |
359 drop shadow effects and for decoration objects that follow the parent |
347 item's geometry without drawing on top of it. |
360 item's geometry without drawing on top of it. This flag was introduced |
|
361 in Qt 4.5. |
348 |
362 |
349 \value ItemUsesExtendedStyleOption The item makes use of either |
363 \value ItemUsesExtendedStyleOption The item makes use of either |
350 \l{QStyleOptionGraphicsItem::}{exposedRect} or |
364 \l{QStyleOptionGraphicsItem::} {exposedRect} or |
351 \l{QStyleOptionGraphicsItem::}{matrix} in QStyleOptionGraphicsItem. By default, |
365 \l{QStyleOptionGraphicsItem::} {matrix} in |
352 the \l{QStyleOptionGraphicsItem::}{exposedRect} is initialized to the item's |
366 QStyleOptionGraphicsItem. By default, the |
353 boundingRect() and the \l{QStyleOptionGraphicsItem::}{matrix} is untransformed. |
367 \l{QStyleOptionGraphicsItem::} {exposedRect} is initialized to the |
354 You can enable this flag for the style options to be set up with more |
368 item's boundingRect() and the |
355 fine-grained values. |
369 \l{QStyleOptionGraphicsItem::}{matrix} is untransformed. You can |
356 Note that QStyleOptionGraphicsItem::levelOfDetail is unaffected by this flag |
370 enable this flag for the style options to be set up with more |
|
371 fine-grained values. Note that |
|
372 QStyleOptionGraphicsItem::levelOfDetail is unaffected by this flag |
357 and always initialized to 1. Use |
373 and always initialized to 1. Use |
358 QStyleOptionGraphicsItem::levelOfDetailFromTransform() if you need a higher |
374 QStyleOptionGraphicsItem::levelOfDetailFromTransform() if you need |
359 value. |
375 a higher value. This flag was introduced in Qt 4.6. |
360 |
376 |
361 \value ItemHasNoContents The item does not paint anything (i.e., calling |
377 \value ItemHasNoContents The item does not paint anything (i.e., calling |
362 paint() on the item has no effect). You should set this flag on items that |
378 paint() on the item has no effect). You should set this flag on items that |
363 do not need to be painted to ensure that Graphics View avoids unnecessary |
379 do not need to be painted to ensure that Graphics View avoids unnecessary |
364 painting preparations. This flag was introduced in Qt 4.6. |
380 painting preparations. This flag was introduced in Qt 4.6. |
372 |
388 |
373 \value ItemAcceptsInputMethod The item supports input methods typically |
389 \value ItemAcceptsInputMethod The item supports input methods typically |
374 used for Asian languages. |
390 used for Asian languages. |
375 This flag was introduced in Qt 4.6. |
391 This flag was introduced in Qt 4.6. |
376 |
392 |
377 \value ItemNegativeZStacksBehindParent The item automatically stacks behind |
393 \value ItemNegativeZStacksBehindParent The item automatically |
378 it's parent if it's z-value is negative. This flag enables setZValue() to |
394 stacks behind it's parent if it's z-value is negative. This flag |
379 toggle ItemStacksBehindParent. |
395 enables setZValue() to toggle ItemStacksBehindParent. This flag |
|
396 was introduced in Qt 4.6. |
380 |
397 |
381 \value ItemIsPanel The item is a panel. A panel provides activation and |
398 \value ItemIsPanel The item is a panel. A panel provides activation and |
382 contained focus handling. Only one panel can be active at a time (see |
399 contained focus handling. Only one panel can be active at a time (see |
383 QGraphicsItem::isActive()). When no panel is active, QGraphicsScene |
400 QGraphicsItem::isActive()). When no panel is active, QGraphicsScene |
384 activates all non-panel items. Window items (i.e., |
401 activates all non-panel items. Window items (i.e., |
628 This enum specifies the behavior of a modal panel. A modal panel |
639 This enum specifies the behavior of a modal panel. A modal panel |
629 is one that blocks input to other panels. Note that items that |
640 is one that blocks input to other panels. Note that items that |
630 are children of a modal panel are not blocked. |
641 are children of a modal panel are not blocked. |
631 |
642 |
632 The values are: |
643 The values are: |
633 \value NonModal The panel is not modal and does not block input to other panels. |
644 |
634 \value PanelModal The panel is modal to a single item hierarchy and blocks input to its parent pane, all grandparent panels, and all siblings of its parent and grandparent panels. |
645 \value NonModal The panel is not modal and does not block input to |
635 \value SceneModal The window is modal to the entire scene and blocks input to all panels. |
646 other panels. This is the default value for panels. |
|
647 |
|
648 \value PanelModal The panel is modal to a single item hierarchy |
|
649 and blocks input to its parent pane, all grandparent panels, and |
|
650 all siblings of its parent and grandparent panels. |
|
651 |
|
652 \value SceneModal The window is modal to the entire scene and |
|
653 blocks input to all panels. |
636 |
654 |
637 \sa QGraphicsItem::setPanelModality(), QGraphicsItem::panelModality(), QGraphicsItem::ItemIsPanel |
655 \sa QGraphicsItem::setPanelModality(), QGraphicsItem::panelModality(), QGraphicsItem::ItemIsPanel |
638 */ |
656 */ |
639 |
657 |
640 #include "qgraphicsitem.h" |
658 #include "qgraphicsitem.h" |
796 || (int(childFlag) == -1 && handlesChildEvents) |
814 || (int(childFlag) == -1 && handlesChildEvents) |
797 || (int(childFlag) == -2 && filtersDescendantEvents)) |
815 || (int(childFlag) == -2 && filtersDescendantEvents)) |
798 return; |
816 return; |
799 } |
817 } |
800 |
818 |
801 foreach (QGraphicsItem *child, children) |
819 for (int i = 0; i < children.size(); ++i) |
802 child->d_ptr->updateAncestorFlag(childFlag, flag, enabled, false); |
820 children.at(i)->d_ptr->updateAncestorFlag(childFlag, flag, enabled, false); |
|
821 } |
|
822 |
|
823 void QGraphicsItemPrivate::updateAncestorFlags() |
|
824 { |
|
825 int flags = 0; |
|
826 if (parent) { |
|
827 // Inherit the parent's ancestor flags. |
|
828 QGraphicsItemPrivate *pd = parent->d_ptr.data(); |
|
829 flags = pd->ancestorFlags; |
|
830 |
|
831 // Add in flags from the parent. |
|
832 if (pd->filtersDescendantEvents) |
|
833 flags |= AncestorFiltersChildEvents; |
|
834 if (pd->handlesChildEvents) |
|
835 flags |= AncestorHandlesChildEvents; |
|
836 if (pd->flags & QGraphicsItem::ItemClipsChildrenToShape) |
|
837 flags |= AncestorClipsChildren; |
|
838 if (pd->flags & QGraphicsItem::ItemIgnoresTransformations) |
|
839 flags |= AncestorIgnoresTransformations; |
|
840 } |
|
841 |
|
842 if (ancestorFlags == flags) |
|
843 return; // No change; stop propagation. |
|
844 ancestorFlags = flags; |
|
845 |
|
846 // Propagate to children recursively. |
|
847 for (int i = 0; i < children.size(); ++i) |
|
848 children.at(i)->d_ptr->updateAncestorFlags(); |
803 } |
849 } |
804 |
850 |
805 /*! |
851 /*! |
806 \internal |
852 \internal |
807 |
853 |
982 |
1028 |
983 Make sure not to trigger any pure virtual function calls (e.g., |
1029 Make sure not to trigger any pure virtual function calls (e.g., |
984 prepareGeometryChange) if the item is in its destructor, i.e. |
1030 prepareGeometryChange) if the item is in its destructor, i.e. |
985 inDestructor is 1. |
1031 inDestructor is 1. |
986 */ |
1032 */ |
987 void QGraphicsItemPrivate::setParentItemHelper(QGraphicsItem *newParent) |
1033 void QGraphicsItemPrivate::setParentItemHelper(QGraphicsItem *newParent, const QVariant *newParentVariant, |
|
1034 const QVariant *thisPointerVariant) |
988 { |
1035 { |
989 Q_Q(QGraphicsItem); |
1036 Q_Q(QGraphicsItem); |
990 if (newParent == q) { |
|
991 qWarning("QGraphicsItem::setParentItem: cannot assign %p as a parent of itself", this); |
|
992 return; |
|
993 } |
|
994 if (newParent == parent) |
1037 if (newParent == parent) |
995 return; |
1038 return; |
996 |
1039 |
997 const QVariant newParentVariant(q->itemChange(QGraphicsItem::ItemParentChange, |
|
998 qVariantFromValue<QGraphicsItem *>(newParent))); |
|
999 newParent = qVariantValue<QGraphicsItem *>(newParentVariant); |
|
1000 if (newParent == parent) |
|
1001 return; |
|
1002 |
|
1003 if (scene) { |
1040 if (scene) { |
1004 // Deliver the change to the index |
1041 // Deliver the change to the index |
1005 scene->d_func()->index->itemChange(q, QGraphicsItem::ItemParentChange, newParentVariant); |
1042 if (scene->d_func()->indexMethod != QGraphicsScene::NoIndex) |
|
1043 scene->d_func()->index->itemChange(q, QGraphicsItem::ItemParentChange, newParent); |
1006 |
1044 |
1007 // Disable scene pos notifications for old ancestors |
1045 // Disable scene pos notifications for old ancestors |
1008 if (scenePosDescendants || (flags & QGraphicsItem::ItemSendsScenePositionChanges)) |
1046 if (scenePosDescendants || (flags & QGraphicsItem::ItemSendsScenePositionChanges)) |
1009 scene->d_func()->setScenePosItemEnabled(q, false); |
1047 scene->d_func()->setScenePosItemEnabled(q, false); |
1010 } |
1048 } |
1018 // removed from the index at a later stage, and the whole scene will be |
1056 // removed from the index at a later stage, and the whole scene will be |
1019 // updated. |
1057 // updated. |
1020 if (!inDestructor) |
1058 if (!inDestructor) |
1021 q_ptr->prepareGeometryChange(); |
1059 q_ptr->prepareGeometryChange(); |
1022 |
1060 |
1023 const QVariant thisPointerVariant(qVariantFromValue<QGraphicsItem *>(q)); |
|
1024 if (parent) { |
1061 if (parent) { |
1025 // Remove from current parent |
1062 // Remove from current parent |
1026 parent->d_ptr->removeChild(q); |
1063 parent->d_ptr->removeChild(q); |
1027 parent->itemChange(QGraphicsItem::ItemChildRemovedChange, thisPointerVariant); |
1064 if (thisPointerVariant) |
|
1065 parent->itemChange(QGraphicsItem::ItemChildRemovedChange, *thisPointerVariant); |
1028 } |
1066 } |
1029 |
1067 |
1030 // Update toplevelitem list. If this item is being deleted, its parent |
1068 // Update toplevelitem list. If this item is being deleted, its parent |
1031 // will be 0 but we don't want to register/unregister it in the TLI list. |
1069 // will be 0 but we don't want to register/unregister it in the TLI list. |
1032 if (scene && !inDestructor) { |
1070 if (scene && !inDestructor) { |
1053 break; |
1091 break; |
1054 } |
1092 } |
1055 p = p->d_ptr->parent; |
1093 p = p->d_ptr->parent; |
1056 } |
1094 } |
1057 |
1095 |
|
1096 // Update graphics effect optimization flag |
|
1097 if (newParent && (graphicsEffect || mayHaveChildWithGraphicsEffect)) |
|
1098 newParent->d_ptr->updateChildWithGraphicsEffectFlagRecursively(); |
|
1099 |
1058 // Update focus scope item ptr in new scope. |
1100 // Update focus scope item ptr in new scope. |
1059 QGraphicsItem *newFocusScopeItem = subFocusItem ? subFocusItem : parentFocusScopeItem; |
1101 QGraphicsItem *newFocusScopeItem = subFocusItem ? subFocusItem : parentFocusScopeItem; |
1060 if (newFocusScopeItem && newParent) { |
1102 if (newFocusScopeItem && newParent) { |
1061 if (subFocusItem) { |
1103 if (subFocusItem) { |
1062 // Find the subFocusItem's topmost focus scope. |
1104 // Find the subFocusItem's topmost focus scope. |
1063 QGraphicsItem *ancestorScope = 0; |
1105 QGraphicsItem *ancestorScope = 0; |
1064 QGraphicsItem *p = subFocusItem->d_ptr->parent; |
1106 QGraphicsItem *p = subFocusItem->d_ptr->parent; |
1065 while (p) { |
1107 while (p) { |
1066 if (p->flags() & QGraphicsItem::ItemIsFocusScope) |
1108 if (p->d_ptr->flags & QGraphicsItem::ItemIsFocusScope) |
1067 ancestorScope = p; |
1109 ancestorScope = p; |
1068 if (p->isPanel()) |
1110 if (p->d_ptr->flags & QGraphicsItem::ItemIsPanel) |
1069 break; |
1111 break; |
1070 p = p->parentItem(); |
1112 p = p->d_ptr->parent; |
1071 } |
1113 } |
1072 if (ancestorScope) |
1114 if (ancestorScope) |
1073 newFocusScopeItem = ancestorScope; |
1115 newFocusScopeItem = ancestorScope; |
1074 } |
1116 } |
1075 |
1117 |
1076 QGraphicsItem *p = newParent; |
1118 QGraphicsItem *p = newParent; |
1077 while (p) { |
1119 while (p) { |
1078 if (p->flags() & QGraphicsItem::ItemIsFocusScope) { |
1120 if (p->d_ptr->flags & QGraphicsItem::ItemIsFocusScope) { |
1079 p->d_ptr->focusScopeItem = newFocusScopeItem; |
1121 p->d_ptr->focusScopeItem = newFocusScopeItem; |
1080 // Ensure the new item is no longer the subFocusItem. The |
1122 // Ensure the new item is no longer the subFocusItem. The |
1081 // only way to set focus on a child of a focus scope is |
1123 // only way to set focus on a child of a focus scope is |
1082 // by setting focus on the scope itself. |
1124 // by setting focus on the scope itself. |
1083 if (subFocusItem && !p->focusItem()) |
1125 if (subFocusItem && !p->focusItem()) |
1086 } |
1128 } |
1087 p = p->d_ptr->parent; |
1129 p = p->d_ptr->parent; |
1088 } |
1130 } |
1089 } |
1131 } |
1090 |
1132 |
|
1133 // Resolve depth. |
|
1134 invalidateDepthRecursively(); |
|
1135 |
1091 if ((parent = newParent)) { |
1136 if ((parent = newParent)) { |
1092 bool implicitUpdate = false; |
|
1093 if (parent->d_func()->scene && parent->d_func()->scene != scene) { |
1137 if (parent->d_func()->scene && parent->d_func()->scene != scene) { |
1094 // Move this item to its new parent's scene |
1138 // Move this item to its new parent's scene |
1095 parent->d_func()->scene->addItem(q); |
1139 parent->d_func()->scene->addItem(q); |
1096 implicitUpdate = true; |
|
1097 } else if (!parent->d_func()->scene && scene) { |
1140 } else if (!parent->d_func()->scene && scene) { |
1098 // Remove this item from its former scene |
1141 // Remove this item from its former scene |
1099 scene->removeItem(q); |
1142 scene->removeItem(q); |
1100 } |
1143 } |
1101 |
1144 |
1102 parent->d_ptr->addChild(q); |
1145 parent->d_ptr->addChild(q); |
1103 parent->itemChange(QGraphicsItem::ItemChildAddedChange, thisPointerVariant); |
1146 if (thisPointerVariant) |
|
1147 parent->itemChange(QGraphicsItem::ItemChildAddedChange, *thisPointerVariant); |
1104 if (scene) { |
1148 if (scene) { |
1105 if (!implicitUpdate) |
|
1106 scene->d_func()->markDirty(q_ptr); |
|
1107 |
|
1108 // Re-enable scene pos notifications for new ancestors |
1149 // Re-enable scene pos notifications for new ancestors |
1109 if (scenePosDescendants || (flags & QGraphicsItem::ItemSendsScenePositionChanges)) |
1150 if (scenePosDescendants || (flags & QGraphicsItem::ItemSendsScenePositionChanges)) |
1110 scene->d_func()->setScenePosItemEnabled(q, true); |
1151 scene->d_func()->setScenePosItemEnabled(q, true); |
1111 } |
1152 } |
1112 |
1153 |
|
1154 // Propagate dirty flags to the new parent |
|
1155 markParentDirty(/*updateBoundingRect=*/true); |
|
1156 |
1113 // Inherit ancestor flags from the new parent. |
1157 // Inherit ancestor flags from the new parent. |
1114 updateAncestorFlag(QGraphicsItem::GraphicsItemFlag(-2)); |
1158 updateAncestorFlags(); |
1115 updateAncestorFlag(QGraphicsItem::GraphicsItemFlag(-1)); |
|
1116 updateAncestorFlag(QGraphicsItem::ItemClipsChildrenToShape); |
|
1117 updateAncestorFlag(QGraphicsItem::ItemIgnoresTransformations); |
|
1118 |
1159 |
1119 // Update item visible / enabled. |
1160 // Update item visible / enabled. |
1120 if (parent->isVisible() != visible) { |
1161 if (parent->d_ptr->visible != visible) { |
1121 if (!parent->isVisible() || !explicitlyHidden) |
1162 if (!parent->d_ptr->visible || !explicitlyHidden) |
1122 setVisibleHelper(parent->isVisible(), /* explicit = */ false, /* update = */ !implicitUpdate); |
1163 setVisibleHelper(parent->d_ptr->visible, /* explicit = */ false, /* update = */ false); |
1123 } |
1164 } |
1124 if (parent->isEnabled() != enabled) { |
1165 if (parent->isEnabled() != enabled) { |
1125 if (!parent->isEnabled() || !explicitlyDisabled) |
1166 if (!parent->d_ptr->enabled || !explicitlyDisabled) |
1126 setEnabledHelper(parent->isEnabled(), /* explicit = */ false, /* update = */ !implicitUpdate); |
1167 setEnabledHelper(parent->d_ptr->enabled, /* explicit = */ false, /* update = */ false); |
1127 } |
1168 } |
1128 |
1169 |
1129 // Auto-activate if visible and the parent is active. |
1170 // Auto-activate if visible and the parent is active. |
1130 if (q->isVisible() && parent->isActive()) |
1171 if (visible && parent->isActive()) |
1131 q->setActive(true); |
1172 q->setActive(true); |
1132 } else { |
1173 } else { |
1133 // Inherit ancestor flags from the new parent. |
1174 // Inherit ancestor flags from the new parent. |
1134 updateAncestorFlag(QGraphicsItem::GraphicsItemFlag(-2)); |
1175 updateAncestorFlags(); |
1135 updateAncestorFlag(QGraphicsItem::GraphicsItemFlag(-1)); |
|
1136 updateAncestorFlag(QGraphicsItem::ItemClipsChildrenToShape); |
|
1137 updateAncestorFlag(QGraphicsItem::ItemIgnoresTransformations); |
|
1138 |
1176 |
1139 if (!inDestructor) { |
1177 if (!inDestructor) { |
1140 // Update item visible / enabled. |
1178 // Update item visible / enabled. |
1141 if (!visible && !explicitlyHidden) |
1179 if (!visible && !explicitlyHidden) |
1142 setVisibleHelper(true, /* explicit = */ false); |
1180 setVisibleHelper(true, /* explicit = */ false); |
1143 if (!enabled && !explicitlyDisabled) |
1181 if (!enabled && !explicitlyDisabled) |
1144 setEnabledHelper(true, /* explicit = */ false); |
1182 setEnabledHelper(true, /* explicit = */ false); |
1145 |
|
1146 // If the item is being deleted, the whole scene will be updated. |
|
1147 if (scene) |
|
1148 scene->d_func()->markDirty(q_ptr); |
|
1149 } |
1183 } |
1150 } |
1184 } |
1151 |
1185 |
1152 // Resolve depth. |
|
1153 invalidateDepthRecursively(); |
|
1154 dirtySceneTransform = 1; |
1186 dirtySceneTransform = 1; |
1155 |
1187 |
1156 // Restore the sub focus chain. |
1188 // Restore the sub focus chain. |
1157 if (subFocusItem) { |
1189 if (subFocusItem) { |
1158 subFocusItem->d_ptr->setSubFocus(newParent); |
1190 subFocusItem->d_ptr->setSubFocus(newParent); |
1159 if (parent && parent->isActive()) |
1191 if (parent && parent->isActive()) |
1160 subFocusItem->setFocus(); |
1192 subFocusItem->setFocus(); |
1161 } |
1193 } |
1162 |
1194 |
1163 // Deliver post-change notification |
1195 // Deliver post-change notification |
1164 q->itemChange(QGraphicsItem::ItemParentHasChanged, newParentVariant); |
1196 if (newParentVariant) |
|
1197 q->itemChange(QGraphicsItem::ItemParentHasChanged, *newParentVariant); |
1165 |
1198 |
1166 if (isObject) |
1199 if (isObject) |
1167 emit static_cast<QGraphicsObject *>(q)->parentChanged(); |
1200 emit static_cast<QGraphicsObject *>(q)->parentChanged(); |
1168 } |
1201 } |
1169 |
1202 |
1541 { |
1575 { |
1542 return d_ptr->isObject ? static_cast<const QGraphicsObject *>(this) : 0; |
1576 return d_ptr->isObject ? static_cast<const QGraphicsObject *>(this) : 0; |
1543 } |
1577 } |
1544 |
1578 |
1545 /*! |
1579 /*! |
1546 Sets this item's parent item to \a parent. If this item already has a |
1580 Sets this item's parent item to \a newParent. If this item already |
1547 parent, it is first removed from the previous parent. If \a parent is 0, |
1581 has a parent, it is first removed from the previous parent. If \a |
1548 this item will become a top-level item. |
1582 newParent is 0, this item will become a top-level item. |
1549 |
1583 |
1550 Note that this implicitly adds this graphics item to the scene of |
1584 Note that this implicitly adds this graphics item to the scene of |
1551 the parent. You should not \l{QGraphicsScene::addItem()}{add} the |
1585 the parent. You should not \l{QGraphicsScene::addItem()}{add} the |
1552 item to the scene yourself. |
1586 item to the scene yourself. |
1553 |
1587 |
1554 Calling this function on an item that is an ancestor of \a parent have undefined behaviour. |
1588 Calling this function on an item that is an ancestor of \a newParent |
1555 |
1589 have undefined behaviour. |
1556 \sa parentItem(), childItems() |
1590 |
1557 */ |
1591 \sa parentItem(), childItems() |
1558 void QGraphicsItem::setParentItem(QGraphicsItem *parent) |
1592 */ |
1559 { |
1593 void QGraphicsItem::setParentItem(QGraphicsItem *newParent) |
1560 d_ptr->setParentItemHelper(parent); |
1594 { |
|
1595 if (newParent == this) { |
|
1596 qWarning("QGraphicsItem::setParentItem: cannot assign %p as a parent of itself", this); |
|
1597 return; |
|
1598 } |
|
1599 if (newParent == d_ptr->parent) |
|
1600 return; |
|
1601 |
|
1602 const QVariant newParentVariant(itemChange(QGraphicsItem::ItemParentChange, |
|
1603 qVariantFromValue<QGraphicsItem *>(newParent))); |
|
1604 newParent = qVariantValue<QGraphicsItem *>(newParentVariant); |
|
1605 if (newParent == d_ptr->parent) |
|
1606 return; |
|
1607 |
|
1608 const QVariant thisPointerVariant(qVariantFromValue<QGraphicsItem *>(this)); |
|
1609 d_ptr->setParentItemHelper(newParent, &newParentVariant, &thisPointerVariant); |
1561 } |
1610 } |
1562 |
1611 |
1563 /*! |
1612 /*! |
1564 \obsolete |
1613 \obsolete |
1565 |
1614 |
1691 if (quint32(d_ptr->flags) == quint32(flags)) |
1740 if (quint32(d_ptr->flags) == quint32(flags)) |
1692 return; |
1741 return; |
1693 flags = GraphicsItemFlags(itemChange(ItemFlagsChange, quint32(flags)).toUInt()); |
1742 flags = GraphicsItemFlags(itemChange(ItemFlagsChange, quint32(flags)).toUInt()); |
1694 if (quint32(d_ptr->flags) == quint32(flags)) |
1743 if (quint32(d_ptr->flags) == quint32(flags)) |
1695 return; |
1744 return; |
1696 if (d_ptr->scene) |
1745 if (d_ptr->scene && d_ptr->scene->d_func()->indexMethod != QGraphicsScene::NoIndex) |
1697 d_ptr->scene->d_func()->index->itemChange(this, ItemFlagsChange, quint32(flags)); |
1746 d_ptr->scene->d_func()->index->itemChange(this, ItemFlagsChange, &flags); |
1698 |
1747 |
1699 // Flags that alter the geometry of the item (or its children). |
1748 // Flags that alter the geometry of the item (or its children). |
1700 const quint32 geomChangeFlagsMask = (ItemClipsChildrenToShape | ItemClipsToShape | ItemIgnoresTransformations | ItemIsSelectable); |
1749 const quint32 geomChangeFlagsMask = (ItemClipsChildrenToShape | ItemClipsToShape | ItemIgnoresTransformations | ItemIsSelectable); |
1701 bool fullUpdate = (quint32(flags) & geomChangeFlagsMask) != (d_ptr->flags & geomChangeFlagsMask); |
1750 bool fullUpdate = (quint32(flags) & geomChangeFlagsMask) != (d_ptr->flags & geomChangeFlagsMask); |
1702 if (fullUpdate) |
1751 if (fullUpdate) |
1703 d_ptr->paintedViewBoundingRectsNeedRepaint = 1; |
1752 d_ptr->paintedViewBoundingRectsNeedRepaint = 1; |
1704 |
1753 |
1705 // Keep the old flags to compare the diff. |
1754 // Keep the old flags to compare the diff. |
1706 GraphicsItemFlags oldFlags = this->flags(); |
1755 GraphicsItemFlags oldFlags = GraphicsItemFlags(d_ptr->flags); |
1707 |
1756 |
1708 // Update flags. |
1757 // Update flags. |
1709 d_ptr->flags = flags; |
1758 d_ptr->flags = flags; |
1710 |
1759 |
1711 if (!(d_ptr->flags & ItemIsFocusable) && hasFocus()) { |
1760 if (!(d_ptr->flags & ItemIsFocusable) && hasFocus()) { |
1730 // Item children clipping changes. Propagate the ancestor flag to |
1779 // Item children clipping changes. Propagate the ancestor flag to |
1731 // all children. |
1780 // all children. |
1732 d_ptr->updateAncestorFlag(ItemIgnoresTransformations); |
1781 d_ptr->updateAncestorFlag(ItemIgnoresTransformations); |
1733 } |
1782 } |
1734 |
1783 |
|
1784 if ((flags & ItemNegativeZStacksBehindParent) != (oldFlags & ItemNegativeZStacksBehindParent)) { |
|
1785 // NB! We change the flags directly here, so we must also update d_ptr->flags. |
|
1786 // Note that this has do be done before the ItemStacksBehindParent check |
|
1787 // below; otherwise we will loose the change. |
|
1788 |
|
1789 // Update stack-behind. |
|
1790 if (d_ptr->z < qreal(0.0)) |
|
1791 flags |= ItemStacksBehindParent; |
|
1792 else |
|
1793 flags &= ~ItemStacksBehindParent; |
|
1794 d_ptr->flags = flags; |
|
1795 } |
|
1796 |
1735 if ((flags & ItemStacksBehindParent) != (oldFlags & ItemStacksBehindParent)) { |
1797 if ((flags & ItemStacksBehindParent) != (oldFlags & ItemStacksBehindParent)) { |
|
1798 // NB! This check has to come after the ItemNegativeZStacksBehindParent |
|
1799 // check above. Be careful. |
|
1800 |
1736 // Ensure child item sorting is up to date when toggling this flag. |
1801 // Ensure child item sorting is up to date when toggling this flag. |
1737 if (d_ptr->parent) |
1802 if (d_ptr->parent) |
1738 d_ptr->parent->d_ptr->needSortChildren = 1; |
1803 d_ptr->parent->d_ptr->needSortChildren = 1; |
1739 else if (d_ptr->scene) |
1804 else if (d_ptr->scene) |
1740 d_ptr->scene->d_func()->needSortTopLevelItems = 1; |
1805 d_ptr->scene->d_func()->needSortTopLevelItems = 1; |
2114 // Schedule redrawing |
2176 // Schedule redrawing |
2115 if (update) { |
2177 if (update) { |
2116 QGraphicsItemCache *c = (QGraphicsItemCache *)qVariantValue<void *>(extra(ExtraCacheData)); |
2178 QGraphicsItemCache *c = (QGraphicsItemCache *)qVariantValue<void *>(extra(ExtraCacheData)); |
2117 if (c) |
2179 if (c) |
2118 c->purge(); |
2180 c->purge(); |
2119 if (scene) |
2181 if (scene) { |
|
2182 #ifndef QT_NO_GRAPHICSEFFECT |
|
2183 invalidateParentGraphicsEffectsRecursively(); |
|
2184 #endif //QT_NO_GRAPHICSEFFECT |
2120 scene->d_func()->markDirty(q_ptr, QRectF(), /*invalidateChildren=*/false, /*force=*/true); |
2185 scene->d_func()->markDirty(q_ptr, QRectF(), /*invalidateChildren=*/false, /*force=*/true); |
|
2186 } |
2121 } |
2187 } |
2122 |
2188 |
2123 // Certain properties are dropped as an item becomes invisible. |
2189 // Certain properties are dropped as an item becomes invisible. |
|
2190 bool hasFocus = q_ptr->hasFocus(); |
2124 if (!newVisible) { |
2191 if (!newVisible) { |
2125 if (scene) { |
2192 if (scene) { |
2126 if (scene->d_func()->mouseGrabberItems.contains(q)) |
2193 if (scene->d_func()->mouseGrabberItems.contains(q)) |
2127 q->ungrabMouse(); |
2194 q->ungrabMouse(); |
2128 if (scene->d_func()->keyboardGrabberItems.contains(q)) |
2195 if (scene->d_func()->keyboardGrabberItems.contains(q)) |
2129 q->ungrabKeyboard(); |
2196 q->ungrabKeyboard(); |
2130 if (q->isPanel() && panelModality != QGraphicsItem::NonModal) |
2197 if (q->isPanel() && panelModality != QGraphicsItem::NonModal) |
2131 scene->d_func()->leaveModal(q_ptr); |
2198 scene->d_func()->leaveModal(q_ptr); |
2132 } |
2199 } |
2133 if (q_ptr->hasFocus() && scene) { |
2200 if (hasFocus && scene) { |
2134 // Hiding the closest non-panel ancestor of the focus item |
2201 // Hiding the closest non-panel ancestor of the focus item |
2135 QGraphicsItem *focusItem = scene->focusItem(); |
2202 QGraphicsItem *focusItem = scene->focusItem(); |
2136 bool clear = true; |
2203 bool clear = true; |
2137 if (isWidget && !focusItem->isPanel()) { |
2204 if (isWidget && !focusItem->isPanel()) { |
2138 do { |
2205 do { |
2179 scene->setActivePanel(parent); |
2246 scene->setActivePanel(parent); |
2180 } |
2247 } |
2181 } |
2248 } |
2182 |
2249 |
2183 // Enable subfocus |
2250 // Enable subfocus |
2184 if (scene && newVisible) { |
2251 if (scene) { |
2185 QGraphicsItem *p = parent; |
2252 if (newVisible) { |
2186 bool done = false; |
2253 // Item is shown |
2187 while (p) { |
2254 QGraphicsItem *p = parent; |
2188 if (p->flags() & QGraphicsItem::ItemIsFocusScope) { |
2255 bool done = false; |
2189 QGraphicsItem *fsi = p->d_ptr->focusScopeItem; |
2256 while (p) { |
2190 if (q_ptr == fsi || q_ptr->isAncestorOf(fsi)) { |
2257 if (p->flags() & QGraphicsItem::ItemIsFocusScope) { |
2191 done = true; |
2258 QGraphicsItem *fsi = p->d_ptr->focusScopeItem; |
2192 while (fsi->d_ptr->focusScopeItem && fsi->d_ptr->focusScopeItem->isVisible()) |
2259 if (q_ptr == fsi || q_ptr->isAncestorOf(fsi)) { |
2193 fsi = fsi->d_ptr->focusScopeItem; |
2260 done = true; |
2194 scene->setFocusItem(fsi); |
2261 while (fsi->d_ptr->focusScopeItem && fsi->d_ptr->focusScopeItem->isVisible()) |
|
2262 fsi = fsi->d_ptr->focusScopeItem; |
|
2263 fsi->d_ptr->setFocusHelper(Qt::OtherFocusReason, /* climb = */ true, |
|
2264 /* focusFromShow = */ true); |
|
2265 } |
|
2266 break; |
2195 } |
2267 } |
2196 break; |
2268 p = p->d_ptr->parent; |
2197 } |
2269 } |
2198 p = p->d_ptr->parent; |
2270 if (!done) { |
2199 } |
2271 QGraphicsItem *fi = subFocusItem; |
2200 if (!done) { |
2272 if (fi && fi != scene->focusItem()) { |
2201 QGraphicsItem *fi = subFocusItem; |
2273 scene->setFocusItem(fi); |
2202 if (fi && fi != scene->focusItem()) { |
2274 } |
2203 scene->setFocusItem(fi); |
2275 } |
|
2276 } else { |
|
2277 // Item is hidden |
|
2278 if (hasFocus) { |
|
2279 QGraphicsItem *p = parent; |
|
2280 while (p) { |
|
2281 if (p->flags() & QGraphicsItem::ItemIsFocusScope) { |
|
2282 if (p->d_ptr->visible) { |
|
2283 p->d_ptr->setFocusHelper(Qt::OtherFocusReason, /* climb = */ true, |
|
2284 /* focusFromShow = */ true); |
|
2285 } |
|
2286 break; |
|
2287 } |
|
2288 p = p->d_ptr->parent; |
|
2289 } |
2204 } |
2290 } |
2205 } |
2291 } |
2206 } |
2292 } |
2207 |
2293 |
2208 // Deliver post-change notification. |
2294 // Deliver post-change notification. |
2513 |
2599 |
2514 // No change? Done. |
2600 // No change? Done. |
2515 if (newOpacity == d_ptr->opacity) |
2601 if (newOpacity == d_ptr->opacity) |
2516 return; |
2602 return; |
2517 |
2603 |
|
2604 bool wasFullyTransparent = d_ptr->isOpacityNull(); |
2518 d_ptr->opacity = newOpacity; |
2605 d_ptr->opacity = newOpacity; |
2519 |
2606 |
2520 // Notify change. |
2607 // Notify change. |
2521 itemChange(ItemOpacityHasChanged, newOpacityVariant); |
2608 itemChange(ItemOpacityHasChanged, newOpacityVariant); |
2522 |
2609 |
2523 // Update. |
2610 // Update. |
2524 if (d_ptr->scene) { |
2611 if (d_ptr->scene) { |
2525 #ifndef QT_NO_GRAPHICSEFFECT |
2612 #ifndef QT_NO_GRAPHICSEFFECT |
2526 d_ptr->invalidateGraphicsEffectsRecursively(); |
2613 d_ptr->invalidateParentGraphicsEffectsRecursively(); |
|
2614 if (!(d_ptr->flags & ItemDoesntPropagateOpacityToChildren)) |
|
2615 d_ptr->invalidateChildGraphicsEffectsRecursively(QGraphicsItemPrivate::OpacityChanged); |
2527 #endif //QT_NO_GRAPHICSEFFECT |
2616 #endif //QT_NO_GRAPHICSEFFECT |
2528 d_ptr->scene->d_func()->markDirty(this, QRectF(), |
2617 d_ptr->scene->d_func()->markDirty(this, QRectF(), |
2529 /*invalidateChildren=*/true, |
2618 /*invalidateChildren=*/true, |
2530 /*force=*/false, |
2619 /*force=*/false, |
2531 /*ignoreOpacity=*/true); |
2620 /*ignoreOpacity=*/d_ptr->isOpacityNull()); |
|
2621 if (wasFullyTransparent) |
|
2622 d_ptr->paintedViewBoundingRectsNeedRepaint = 1; |
2532 } |
2623 } |
2533 |
2624 |
2534 if (d_ptr->isObject) |
2625 if (d_ptr->isObject) |
2535 emit static_cast<QGraphicsObject *>(this)->opacityChanged(); |
2626 emit static_cast<QGraphicsObject *>(this)->opacityChanged(); |
2536 } |
2627 } |
3089 |
3202 |
3090 \sa setFocus(), hasFocus(), QGraphicsWidget::focusPolicy |
3203 \sa setFocus(), hasFocus(), QGraphicsWidget::focusPolicy |
3091 */ |
3204 */ |
3092 void QGraphicsItem::clearFocus() |
3205 void QGraphicsItem::clearFocus() |
3093 { |
3206 { |
3094 // Pass focus to the closest parent focus scope. |
3207 d_ptr->clearFocusHelper(/* giveFocusToParent = */ true); |
3095 if (!d_ptr->inDestructor) { |
3208 } |
3096 QGraphicsItem *p = d_ptr->parent; |
3209 |
3097 while (p) { |
3210 /*! |
3098 if (p->flags() & ItemIsFocusScope) { |
3211 \internal |
3099 p->d_ptr->setFocusHelper(Qt::OtherFocusReason, /* climb = */ false); |
3212 */ |
3100 return; |
3213 void QGraphicsItemPrivate::clearFocusHelper(bool giveFocusToParent) |
|
3214 { |
|
3215 if (giveFocusToParent) { |
|
3216 // Pass focus to the closest parent focus scope |
|
3217 if (!inDestructor) { |
|
3218 QGraphicsItem *p = parent; |
|
3219 while (p) { |
|
3220 if (p->flags() & QGraphicsItem::ItemIsFocusScope) { |
|
3221 p->d_ptr->setFocusHelper(Qt::OtherFocusReason, /* climb = */ false, |
|
3222 /* focusFromShow = */ false); |
|
3223 return; |
|
3224 } |
|
3225 p = p->d_ptr->parent; |
3101 } |
3226 } |
3102 p = p->d_ptr->parent; |
|
3103 } |
3227 } |
3104 } |
3228 } |
3105 |
3229 |
3106 // Invisible items with focus must explicitly clear subfocus. |
3230 // Invisible items with focus must explicitly clear subfocus. |
3107 d_ptr->clearSubFocus(this); |
3231 clearSubFocus(q_ptr); |
3108 |
3232 |
3109 if (hasFocus()) { |
3233 if (q_ptr->hasFocus()) { |
3110 // If this item has the scene's input focus, clear it. |
3234 // If this item has the scene's input focus, clear it. |
3111 d_ptr->scene->setFocusItem(0); |
3235 scene->setFocusItem(0); |
3112 } |
3236 } |
3113 } |
3237 } |
3114 |
3238 |
3115 /*! |
3239 /*! |
3116 \since 4.6 |
3240 \since 4.6 |
5024 |
5148 |
5025 /*! |
5149 /*! |
5026 \internal |
5150 \internal |
5027 */ |
5151 */ |
5028 #ifndef QT_NO_GRAPHICSEFFECT |
5152 #ifndef QT_NO_GRAPHICSEFFECT |
5029 void QGraphicsItemPrivate::invalidateGraphicsEffectsRecursively() |
5153 void QGraphicsItemPrivate::invalidateParentGraphicsEffectsRecursively() |
5030 { |
5154 { |
5031 QGraphicsItemPrivate *itemPrivate = this; |
5155 QGraphicsItemPrivate *itemPrivate = this; |
5032 do { |
5156 do { |
5033 if (itemPrivate->graphicsEffect) { |
5157 if (itemPrivate->graphicsEffect) { |
5034 itemPrivate->notifyInvalidated = 1; |
5158 itemPrivate->notifyInvalidated = 1; |
5035 |
5159 |
5036 if (!itemPrivate->updateDueToGraphicsEffect) |
5160 if (!itemPrivate->updateDueToGraphicsEffect) |
5037 static_cast<QGraphicsItemEffectSourcePrivate *>(itemPrivate->graphicsEffect->d_func()->source->d_func())->invalidateCache(); |
5161 static_cast<QGraphicsItemEffectSourcePrivate *>(itemPrivate->graphicsEffect->d_func()->source->d_func())->invalidateCache(); |
5038 } |
5162 } |
5039 } while ((itemPrivate = itemPrivate->parent ? itemPrivate->parent->d_ptr.data() : 0)); |
5163 } while ((itemPrivate = itemPrivate->parent ? itemPrivate->parent->d_ptr.data() : 0)); |
|
5164 } |
|
5165 |
|
5166 void QGraphicsItemPrivate::invalidateChildGraphicsEffectsRecursively(QGraphicsItemPrivate::InvalidateReason reason) |
|
5167 { |
|
5168 if (!mayHaveChildWithGraphicsEffect) |
|
5169 return; |
|
5170 |
|
5171 for (int i = 0; i < children.size(); ++i) { |
|
5172 QGraphicsItemPrivate *childPrivate = children.at(i)->d_ptr.data(); |
|
5173 if (reason == OpacityChanged && (childPrivate->flags & QGraphicsItem::ItemIgnoresParentOpacity)) |
|
5174 continue; |
|
5175 if (childPrivate->graphicsEffect) { |
|
5176 childPrivate->notifyInvalidated = 1; |
|
5177 static_cast<QGraphicsItemEffectSourcePrivate *>(childPrivate->graphicsEffect->d_func()->source->d_func())->invalidateCache(); |
|
5178 } |
|
5179 |
|
5180 childPrivate->invalidateChildGraphicsEffectsRecursively(reason); |
|
5181 } |
5040 } |
5182 } |
5041 #endif //QT_NO_GRAPHICSEFFECT |
5183 #endif //QT_NO_GRAPHICSEFFECT |
5042 |
5184 |
5043 /*! |
5185 /*! |
5044 \internal |
5186 \internal |
7156 d_ptr->paintedViewBoundingRectsNeedRepaint = 1; |
7302 d_ptr->paintedViewBoundingRectsNeedRepaint = 1; |
7157 d_ptr->notifyBoundingRectChanged = !d_ptr->inSetPosHelper; |
7303 d_ptr->notifyBoundingRectChanged = !d_ptr->inSetPosHelper; |
7158 |
7304 |
7159 QGraphicsScenePrivate *scenePrivate = d_ptr->scene->d_func(); |
7305 QGraphicsScenePrivate *scenePrivate = d_ptr->scene->d_func(); |
7160 scenePrivate->index->prepareBoundingRectChange(this); |
7306 scenePrivate->index->prepareBoundingRectChange(this); |
7161 scenePrivate->markDirty(this, QRectF(), /*invalidateChildren=*/true); |
7307 scenePrivate->markDirty(this, QRectF(), /*invalidateChildren=*/true, /*force=*/false, |
|
7308 /*ignoreOpacity=*/ false, /*removingItemFromScene=*/ false, |
|
7309 /*updateBoundingRect=*/true); |
7162 |
7310 |
7163 // For compatibility reasons, we have to update the item's old geometry |
7311 // For compatibility reasons, we have to update the item's old geometry |
7164 // if someone is connected to the changed signal or the scene has no views. |
7312 // if someone is connected to the changed signal or the scene has no views. |
7165 // Note that this has to be done *after* markDirty to ensure that |
7313 // Note that this has to be done *after* markDirty to ensure that |
7166 // _q_processDirtyItems is called before _q_emitUpdated. |
7314 // _q_processDirtyItems is called before _q_emitUpdated. |
7320 QGestureManager *manager = QGestureManager::instance(); |
7456 QGestureManager *manager = QGestureManager::instance(); |
7321 manager->cleanupCachedGestures(this, gesture); |
7457 manager->cleanupCachedGestures(this, gesture); |
7322 } |
7458 } |
7323 } |
7459 } |
7324 |
7460 |
|
7461 void QGraphicsItemPrivate::append(QDeclarativeListProperty<QGraphicsObject> *list, QGraphicsObject *item) |
|
7462 { |
|
7463 QGraphicsItemPrivate::get(item)->setParentItemHelper(static_cast<QGraphicsObject *>(list->object), /*newParentVariant=*/0, /*thisPointerVariant=*/0); |
|
7464 } |
|
7465 |
|
7466 /*! |
|
7467 Returns a list of this item's children. |
|
7468 |
|
7469 The items are sorted by stacking order. This takes into account both the |
|
7470 items' insertion order and their Z-values. |
|
7471 |
|
7472 */ |
|
7473 QDeclarativeListProperty<QGraphicsObject> QGraphicsItemPrivate::childrenList() |
|
7474 { |
|
7475 Q_Q(QGraphicsItem); |
|
7476 if (isObject) { |
|
7477 QGraphicsObject *that = static_cast<QGraphicsObject *>(q); |
|
7478 return QDeclarativeListProperty<QGraphicsObject>(that, &children, QGraphicsItemPrivate::append); |
|
7479 } else { |
|
7480 //QGraphicsItem is not supported for this property |
|
7481 return QDeclarativeListProperty<QGraphicsObject>(); |
|
7482 } |
|
7483 } |
|
7484 |
|
7485 /*! |
|
7486 \internal |
|
7487 Returns the width of the item |
|
7488 Reimplemented by QGraphicsWidget |
|
7489 */ |
|
7490 qreal QGraphicsItemPrivate::width() const |
|
7491 { |
|
7492 return 0; |
|
7493 } |
|
7494 |
|
7495 /*! |
|
7496 \internal |
|
7497 Set the width of the item |
|
7498 Reimplemented by QGraphicsWidget |
|
7499 */ |
|
7500 void QGraphicsItemPrivate::setWidth(qreal w) |
|
7501 { |
|
7502 Q_UNUSED(w); |
|
7503 } |
|
7504 |
|
7505 /*! |
|
7506 \internal |
|
7507 Reset the width of the item |
|
7508 Reimplemented by QGraphicsWidget |
|
7509 */ |
|
7510 void QGraphicsItemPrivate::resetWidth() |
|
7511 { |
|
7512 } |
|
7513 |
|
7514 /*! |
|
7515 \internal |
|
7516 Returns the height of the item |
|
7517 Reimplemented by QGraphicsWidget |
|
7518 */ |
|
7519 qreal QGraphicsItemPrivate::height() const |
|
7520 { |
|
7521 return 0; |
|
7522 } |
|
7523 |
|
7524 /*! |
|
7525 \internal |
|
7526 Set the height of the item |
|
7527 Reimplemented by QGraphicsWidget |
|
7528 */ |
|
7529 void QGraphicsItemPrivate::setHeight(qreal h) |
|
7530 { |
|
7531 Q_UNUSED(h); |
|
7532 } |
|
7533 |
|
7534 /*! |
|
7535 \internal |
|
7536 Reset the height of the item |
|
7537 Reimplemented by QGraphicsWidget |
|
7538 */ |
|
7539 void QGraphicsItemPrivate::resetHeight() |
|
7540 { |
|
7541 } |
|
7542 |
7325 /*! |
7543 /*! |
7326 \property QGraphicsObject::parent |
7544 \property QGraphicsObject::parent |
7327 \brief the parent of the item |
7545 \brief the parent of the item |
7328 |
7546 |
7329 \note The item's parent is set independently of the parent object returned |
7547 \note The item's parent is set independently of the parent object returned |
10713 info->widget, info->opacity, &effectTransform, info->wasDirtySceneTransform, |
10948 info->widget, info->opacity, &effectTransform, info->wasDirtySceneTransform, |
10714 info->drawItem); |
10949 info->drawItem); |
10715 } |
10950 } |
10716 } |
10951 } |
10717 |
10952 |
10718 QPixmap QGraphicsItemEffectSourcePrivate::pixmap(Qt::CoordinateSystem system, QPoint *offset, |
10953 // sourceRect must be in the given coordinate system |
10719 QGraphicsEffect::PixmapPadMode mode) const |
10954 QRect QGraphicsItemEffectSourcePrivate::paddedEffectRect(Qt::CoordinateSystem system, QGraphicsEffect::PixmapPadMode mode, const QRectF &sourceRect, bool *unpadded) const |
10720 { |
10955 { |
10721 const bool deviceCoordinates = (system == Qt::DeviceCoordinates); |
|
10722 if (!info && deviceCoordinates) { |
|
10723 // Device coordinates without info not yet supported. |
|
10724 qWarning("QGraphicsEffectSource::pixmap: Not yet implemented, lacking device context"); |
|
10725 return QPixmap(); |
|
10726 } |
|
10727 if (!item->d_ptr->scene) |
|
10728 return QPixmap(); |
|
10729 QGraphicsScenePrivate *scened = item->d_ptr->scene->d_func(); |
|
10730 |
|
10731 const QRectF sourceRect = boundingRect(system); |
|
10732 QRectF effectRectF; |
10956 QRectF effectRectF; |
10733 |
10957 |
10734 bool unpadded = false; |
10958 if (unpadded) |
|
10959 *unpadded = false; |
|
10960 |
10735 if (mode == QGraphicsEffect::PadToEffectiveBoundingRect) { |
10961 if (mode == QGraphicsEffect::PadToEffectiveBoundingRect) { |
10736 if (info) { |
10962 if (info) { |
10737 effectRectF = item->graphicsEffect()->boundingRectFor(boundingRect(Qt::DeviceCoordinates)); |
10963 QRectF deviceRect = system == Qt::DeviceCoordinates ? sourceRect : info->painter->worldTransform().mapRect(sourceRect); |
10738 unpadded = (effectRectF.size() == sourceRect.size()); |
10964 effectRectF = item->graphicsEffect()->boundingRectFor(deviceRect); |
|
10965 if (unpadded) |
|
10966 *unpadded = (effectRectF.size() == sourceRect.size()); |
10739 if (info && system == Qt::LogicalCoordinates) |
10967 if (info && system == Qt::LogicalCoordinates) |
10740 effectRectF = info->painter->worldTransform().inverted().mapRect(effectRectF); |
10968 effectRectF = info->painter->worldTransform().inverted().mapRect(effectRectF); |
10741 } else { |
10969 } else { |
10742 // no choice but to send a logical coordinate bounding rect to boundingRectFor |
10970 // no choice but to send a logical coordinate bounding rect to boundingRectFor |
10743 effectRectF = item->graphicsEffect()->boundingRectFor(sourceRect); |
10971 effectRectF = item->graphicsEffect()->boundingRectFor(sourceRect); |
10745 } else if (mode == QGraphicsEffect::PadToTransparentBorder) { |
10973 } else if (mode == QGraphicsEffect::PadToTransparentBorder) { |
10746 // adjust by 1.5 to account for cosmetic pens |
10974 // adjust by 1.5 to account for cosmetic pens |
10747 effectRectF = sourceRect.adjusted(-1.5, -1.5, 1.5, 1.5); |
10975 effectRectF = sourceRect.adjusted(-1.5, -1.5, 1.5, 1.5); |
10748 } else { |
10976 } else { |
10749 effectRectF = sourceRect; |
10977 effectRectF = sourceRect; |
10750 unpadded = true; |
10978 if (unpadded) |
10751 } |
10979 *unpadded = true; |
10752 |
10980 } |
10753 QRect effectRect = effectRectF.toAlignedRect(); |
10981 |
|
10982 return effectRectF.toAlignedRect(); |
|
10983 } |
|
10984 |
|
10985 QPixmap QGraphicsItemEffectSourcePrivate::pixmap(Qt::CoordinateSystem system, QPoint *offset, |
|
10986 QGraphicsEffect::PixmapPadMode mode) const |
|
10987 { |
|
10988 const bool deviceCoordinates = (system == Qt::DeviceCoordinates); |
|
10989 if (!info && deviceCoordinates) { |
|
10990 // Device coordinates without info not yet supported. |
|
10991 qWarning("QGraphicsEffectSource::pixmap: Not yet implemented, lacking device context"); |
|
10992 return QPixmap(); |
|
10993 } |
|
10994 if (!item->d_ptr->scene) |
|
10995 return QPixmap(); |
|
10996 QGraphicsScenePrivate *scened = item->d_ptr->scene->d_func(); |
|
10997 |
|
10998 bool unpadded; |
|
10999 const QRectF sourceRect = boundingRect(system); |
|
11000 QRect effectRect = paddedEffectRect(system, mode, sourceRect, &unpadded); |
10754 |
11001 |
10755 if (offset) |
11002 if (offset) |
10756 *offset = effectRect.topLeft(); |
11003 *offset = effectRect.topLeft(); |
10757 |
11004 |
10758 bool untransformed = !deviceCoordinates |
11005 bool untransformed = !deviceCoordinates |
10761 if (offset) |
11008 if (offset) |
10762 *offset = boundingRect(system).topLeft().toPoint(); |
11009 *offset = boundingRect(system).topLeft().toPoint(); |
10763 return static_cast<QGraphicsPixmapItem *>(item)->pixmap(); |
11010 return static_cast<QGraphicsPixmapItem *>(item)->pixmap(); |
10764 } |
11011 } |
10765 |
11012 |
10766 if (deviceCoordinates) { |
|
10767 // Clip to viewport rect. |
|
10768 int left, top, right, bottom; |
|
10769 effectRect.getCoords(&left, &top, &right, &bottom); |
|
10770 if (left < 0) { |
|
10771 if (offset) |
|
10772 offset->rx() += -left; |
|
10773 effectRect.setX(0); |
|
10774 } |
|
10775 if (top < 0) { |
|
10776 if (offset) |
|
10777 offset->ry() += -top; |
|
10778 effectRect.setY(0); |
|
10779 } |
|
10780 // NB! We use +-1 for historical reasons (see QRect documentation). |
|
10781 QPaintDevice *device = info->painter->device(); |
|
10782 const int deviceWidth = device->width(); |
|
10783 const int deviceHeight = device->height(); |
|
10784 if (right + 1 > deviceWidth) |
|
10785 effectRect.setRight(deviceWidth - 1); |
|
10786 if (bottom + 1 > deviceHeight) |
|
10787 effectRect.setBottom(deviceHeight -1); |
|
10788 |
|
10789 } |
|
10790 if (effectRect.isEmpty()) |
11013 if (effectRect.isEmpty()) |
10791 return QPixmap(); |
11014 return QPixmap(); |
10792 |
11015 |
10793 QPixmap pixmap(effectRect.size()); |
11016 QPixmap pixmap(effectRect.size()); |
10794 pixmap.fill(Qt::transparent); |
11017 pixmap.fill(Qt::transparent); |