Changeset 846 for trunk/src/gui/graphicsview
- Timestamp:
- May 5, 2011, 5:36:53 AM (14 years ago)
- Location:
- trunk
- Files:
-
- 52 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk
- Property svn:mergeinfo changed
/branches/vendor/nokia/qt/4.7.2 (added) merged: 845 /branches/vendor/nokia/qt/current merged: 844 /branches/vendor/nokia/qt/4.6.3 removed
- Property svn:mergeinfo changed
-
trunk/src/gui/graphicsview/qgraph_p.h
r651 r846 1 1 /**************************************************************************** 2 2 ** 3 ** Copyright (C) 201 0Nokia Corporation and/or its subsidiary(-ies).3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). 4 4 ** All rights reserved. 5 5 ** Contact: Nokia Corporation (qt-info@nokia.com) -
trunk/src/gui/graphicsview/qgraphicsanchorlayout.cpp
r651 r846 1 1 /**************************************************************************** 2 2 ** 3 ** Copyright (C) 201 0Nokia Corporation and/or its subsidiary(-ies).3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). 4 4 ** All rights reserved. 5 5 ** Contact: Nokia Corporation (qt-info@nokia.com) -
trunk/src/gui/graphicsview/qgraphicsanchorlayout.h
r651 r846 1 1 /**************************************************************************** 2 2 ** 3 ** Copyright (C) 201 0Nokia Corporation and/or its subsidiary(-ies).3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). 4 4 ** All rights reserved. 5 5 ** Contact: Nokia Corporation (qt-info@nokia.com) -
trunk/src/gui/graphicsview/qgraphicsanchorlayout_p.cpp
r651 r846 1 1 /**************************************************************************** 2 2 ** 3 ** Copyright (C) 201 0Nokia Corporation and/or its subsidiary(-ies).3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). 4 4 ** All rights reserved. 5 5 ** Contact: Nokia Corporation (qt-info@nokia.com) -
trunk/src/gui/graphicsview/qgraphicsanchorlayout_p.h
r651 r846 1 1 /**************************************************************************** 2 2 ** 3 ** Copyright (C) 201 0Nokia Corporation and/or its subsidiary(-ies).3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). 4 4 ** All rights reserved. 5 5 ** Contact: Nokia Corporation (qt-info@nokia.com) -
trunk/src/gui/graphicsview/qgraphicsgridlayout.cpp
r651 r846 1 1 /**************************************************************************** 2 2 ** 3 ** Copyright (C) 201 0Nokia Corporation and/or its subsidiary(-ies).3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). 4 4 ** All rights reserved. 5 5 ** Contact: Nokia Corporation (qt-info@nokia.com) … … 65 65 destroying it. 66 66 67 \section1 Size Hints and Size Policies in QGraphicsGridLayout 68 69 QGraphicsGridLayout respects each item's size hints and size policies, 70 and when a cell in the grid has more space than the items can fill, each item 71 is arranged according to the layout's alignment for that item. You can set 72 an alignment for each item by calling setAlignment(), and check the 73 alignment for any item by calling alignment(). You can also set the alignment 74 for an entire row or column by calling setRowAlignment() and setColumnAlignment() 75 respectively. By default, items are aligned to the top left. 76 77 67 78 \sa QGraphicsLinearLayout, QGraphicsWidget 68 79 */ … … 95 106 }; 96 107 108 Q_GLOBAL_STATIC(QWidget, globalStyleInfoWidget); 109 97 110 QLayoutStyleInfo QGraphicsGridLayoutPrivate::styleInfo() const 98 111 { 99 static QWidget *wid = 0;100 if (!wid)101 wid = new QWidget;102 112 QGraphicsItem *item = parentItem(); 103 113 QStyle *style = (item && item->isWidget()) ? static_cast<QGraphicsWidget*>(item)->style() : QApplication::style(); 104 return QLayoutStyleInfo(style, wid);114 return QLayoutStyleInfo(style, globalStyleInfoWidget()); 105 115 } 106 116 … … 573 583 layoutItem->setParentLayoutItem(0); 574 584 d->engine.removeItem(gridItem); 585 586 // recalculate rowInfo.count if we remove an item that is on the right/bottommost row 587 for (int j = 0; j < NOrientations; ++j) { 588 // 0: Hor, 1: Ver 589 const Qt::Orientation orient = (j == 0 ? Qt::Horizontal : Qt::Vertical); 590 const int oldCount = d->engine.rowCount(orient); 591 if (gridItem->lastRow(orient) == oldCount - 1) { 592 const int newCount = d->engine.effectiveLastRow(orient) + 1; 593 d->engine.removeRows(newCount, oldCount - newCount, orient); 594 } 595 } 596 575 597 delete gridItem; 576 598 invalidate(); … … 631 653 qreal left, top, right, bottom; 632 654 getContentsMargins(&left, &top, &right, &bottom); 633 return d->engine.sizeHint(d->styleInfo(), which , constraint) + QSizeF(left + right, top + bottom); 655 const QSizeF extraMargins(left + right, top + bottom); 656 return d->engine.sizeHint(d->styleInfo(), which , constraint - extraMargins) + extraMargins; 634 657 } 635 658 -
trunk/src/gui/graphicsview/qgraphicsgridlayout.h
r651 r846 1 1 /**************************************************************************** 2 2 ** 3 ** Copyright (C) 201 0Nokia Corporation and/or its subsidiary(-ies).3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). 4 4 ** All rights reserved. 5 5 ** Contact: Nokia Corporation (qt-info@nokia.com) -
trunk/src/gui/graphicsview/qgraphicsitem.cpp
r769 r846 1 1 /**************************************************************************** 2 2 ** 3 ** Copyright (C) 201 0Nokia Corporation and/or its subsidiary(-ies).3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). 4 4 ** All rights reserved. 5 5 ** Contact: Nokia Corporation (qt-info@nokia.com) … … 51 51 This includes defining the item's geometry, collision detection, its 52 52 painting implementation and item interaction through its event handlers. 53 QGraphicsItem is part of \l{TheGraphics View Framework}53 QGraphicsItem is part of the \l{Graphics View Framework} 54 54 55 55 \image graphicsview-items.png … … 134 134 \img graphicsview-parentchild.png 135 135 136 \section1 Transformation 136 \target Transformations 137 \section1 Transformations 137 138 138 139 QGraphicsItem supports projective transformations in addition to its base … … 265 266 user's convenience. 266 267 267 \sa QGraphicsScene, QGraphicsView, { TheGraphics View Framework}268 \sa QGraphicsScene, QGraphicsView, {Graphics View Framework} 268 269 */ 269 270 … … 382 383 \value ItemSendsGeometryChanges The item enables itemChange() 383 384 notifications for ItemPositionChange, ItemPositionHasChanged, 384 ItemMatrixChange, ItemTransformChange, and ItemTransformHasChanged. For 385 ItemMatrixChange, ItemTransformChange, ItemTransformHasChanged, 386 ItemRotationChange, ItemRotationHasChanged, ItemScaleChange, ItemScaleHasChanged, 387 ItemTransformOriginPointChange, and ItemTransformOriginPointHasChanged. For 385 388 performance reasons, these notifications are disabled by default. You must 386 389 enable this flag to receive notifications for position and transform … … 410 413 to receive notifications for scene position changes. This flag was 411 414 introduced in Qt 4.6. 415 416 \omitvalue ItemStopsClickFocusPropagation \omit The item stops propagating 417 click focus to items underneath when being clicked on. This flag 418 allows you create a non-focusable item that can be clicked on without 419 changing the focus. \endomit 412 420 */ 413 421 … … 475 483 (same as transform()), and QGraphicsItem ignores the return value for this 476 484 notification (i.e., a read-only notification). 485 486 \value ItemRotationChange The item's rotation property changes. This 487 notification is sent if the ItemSendsGeometryChanges flag is enabled, and 488 when the item's rotation property changes (i.e., as a result of calling 489 setRotation()). The value argument is the new rotation (i.e., a double); 490 to get the old rotation, call rotation(). Do not call setRotation() in 491 itemChange() as this notification is delivered; instead, you can return 492 the new rotation from itemChange(). 493 494 \value ItemRotationHasChanged The item's rotation property has changed. 495 This notification is sent if the ItemSendsGeometryChanges flag is enabled, 496 and after the item's rotation property has changed. The value argument is 497 the new rotation (i.e., a double), and QGraphicsItem ignores the return 498 value for this notification (i.e., a read-only notification). Do not call 499 setRotation() in itemChange() as this notification is delivered. 500 501 \value ItemScaleChange The item's scale property changes. This notification 502 is sent if the ItemSendsGeometryChanges flag is enabled, and when the item's 503 scale property changes (i.e., as a result of calling setScale()). The value 504 argument is the new scale (i.e., a double); to get the old scale, call 505 scale(). Do not call setScale() in itemChange() as this notification is 506 delivered; instead, you can return the new scale from itemChange(). 507 508 \value ItemScaleHasChanged The item's scale property has changed. This 509 notification is sent if the ItemSendsGeometryChanges flag is enabled, and 510 after the item's scale property has changed. The value argument is the new 511 scale (i.e., a double), and QGraphicsItem ignores the return value for this 512 notification (i.e., a read-only notification). Do not call setScale() in 513 itemChange() as this notification is delivered. 514 515 \value ItemTransformOriginPointChange The item's transform origin point 516 property changes. This notification is sent if the ItemSendsGeometryChanges 517 flag is enabled, and when the item's transform origin point property changes 518 (i.e., as a result of calling setTransformOriginPoint()). The value argument 519 is the new origin point (i.e., a QPointF); to get the old origin point, call 520 transformOriginPoint(). Do not call setTransformOriginPoint() in itemChange() 521 as this notification is delivered; instead, you can return the new transform 522 origin point from itemChange(). 523 524 \value ItemTransformOriginPointHasChanged The item's transform origin point 525 property has changed. This notification is sent if the ItemSendsGeometryChanges 526 flag is enabled, and after the item's transform origin point property has 527 changed. The value argument is the new origin point (i.e., a QPointF), and 528 QGraphicsItem ignores the return value for this notification (i.e., a read-only 529 notification). Do not call setTransformOriginPoint() in itemChange() as this 530 notification is delivered. 477 531 478 532 \value ItemSelectedChange The item's selected state changes. If the item is … … 674 728 #include <QtCore/qvariant.h> 675 729 #include <QtCore/qvarlengtharray.h> 730 #include <QtCore/qnumeric.h> 676 731 #include <QtGui/qapplication.h> 677 732 #include <QtGui/qbitmap.h> … … 683 738 #include <QtGui/qinputcontext.h> 684 739 #include <QtGui/qgraphicseffect.h> 740 #ifndef QT_NO_ACCESSIBILITY 741 # include "qaccessible.h" 742 #endif 685 743 686 744 #include <private/qgraphicsitem_p.h> … … 690 748 #include <private/qtextengine_p.h> 691 749 #include <private/qwidget_p.h> 750 #include <private/qapplication_p.h> 692 751 693 752 #ifdef Q_WS_X11 … … 1038 1097 return; 1039 1098 1099 if (isWidget) 1100 static_cast<QGraphicsWidgetPrivate *>(this)->fixFocusChainBeforeReparenting((newParent && 1101 newParent->isWidget()) ? static_cast<QGraphicsWidget *>(newParent) : 0, 1102 scene); 1040 1103 if (scene) { 1041 1104 // Deliver the change to the index … … 1088 1151 parentFocusScopeItem = fsi; 1089 1152 p->d_ptr->focusScopeItem = 0; 1153 fsi->d_ptr->focusScopeItemChange(false); 1090 1154 } 1091 1155 break; … … 1120 1184 if (p->d_ptr->flags & QGraphicsItem::ItemIsFocusScope) { 1121 1185 p->d_ptr->focusScopeItem = newFocusScopeItem; 1186 newFocusScopeItem->d_ptr->focusScopeItemChange(true); 1122 1187 // Ensure the new item is no longer the subFocusItem. The 1123 1188 // only way to set focus on a child of a focus scope is … … 1185 1250 1186 1251 dirtySceneTransform = 1; 1252 if (!inDestructor && (transformData || (newParent && newParent->d_ptr->transformData))) 1253 transformChanged(); 1187 1254 1188 1255 // Restore the sub focus chain. … … 1206 1273 Returns the bounding rect of this item's children (excluding itself). 1207 1274 */ 1208 void QGraphicsItemPrivate::childrenBoundingRectHelper(QTransform *x, QRectF *rect) 1209 { 1275 void QGraphicsItemPrivate::childrenBoundingRectHelper(QTransform *x, QRectF *rect, QGraphicsItem *topMostEffectItem) 1276 { 1277 Q_Q(QGraphicsItem); 1278 1279 QRectF childrenRect; 1280 QRectF *result = rect; 1281 rect = &childrenRect; 1282 const bool setTopMostEffectItem = !topMostEffectItem; 1283 1210 1284 for (int i = 0; i < children.size(); ++i) { 1211 1285 QGraphicsItem *child = children.at(i); 1212 1286 QGraphicsItemPrivate *childd = child->d_ptr.data(); 1287 if (setTopMostEffectItem) 1288 topMostEffectItem = child; 1213 1289 bool hasPos = !childd->pos.isNull(); 1214 1290 if (hasPos || childd->transformData) { … … 1217 1293 if (x) 1218 1294 matrix *= *x; 1219 *rect |= matrix.mapRect(child-> boundingRect());1295 *rect |= matrix.mapRect(child->d_ptr->effectiveBoundingRect(topMostEffectItem)); 1220 1296 if (!childd->children.isEmpty()) 1221 childd->childrenBoundingRectHelper(&matrix, rect );1297 childd->childrenBoundingRectHelper(&matrix, rect, topMostEffectItem); 1222 1298 } else { 1223 1299 if (x) 1224 *rect |= x->mapRect(child-> boundingRect());1300 *rect |= x->mapRect(child->d_ptr->effectiveBoundingRect(topMostEffectItem)); 1225 1301 else 1226 *rect |= child-> boundingRect();1302 *rect |= child->d_ptr->effectiveBoundingRect(topMostEffectItem); 1227 1303 if (!childd->children.isEmpty()) 1228 childd->childrenBoundingRectHelper(x, rect );1304 childd->childrenBoundingRectHelper(x, rect, topMostEffectItem); 1229 1305 } 1230 1306 } 1307 1308 if (flags & QGraphicsItem::ItemClipsChildrenToShape){ 1309 if (x) 1310 *rect &= x->mapRect(q->boundingRect()); 1311 else 1312 *rect &= q->boundingRect(); 1313 } 1314 1315 *result |= *rect; 1231 1316 } 1232 1317 … … 1356 1441 QGraphicsItem::~QGraphicsItem() 1357 1442 { 1358 if (d_ptr->isObject) 1359 QObjectPrivate::get(static_cast<QGraphicsObject *>(this))->wasDeleted = true; 1443 if (d_ptr->isObject) { 1444 QGraphicsObject *o = static_cast<QGraphicsObject *>(this); 1445 QObjectPrivate *p = QObjectPrivate::get(o); 1446 p->wasDeleted = true; 1447 if (p->declarativeData) { 1448 QAbstractDeclarativeData::destroyed(p->declarativeData, o); 1449 p->declarativeData = 0; 1450 } 1451 } 1452 1360 1453 d_ptr->inDestructor = 1; 1361 1454 d_ptr->removeExtraItemCache(); 1455 1456 #ifndef QT_NO_GESTURES 1457 if (d_ptr->isObject && !d_ptr->gestureContext.isEmpty()) { 1458 QGraphicsObject *o = static_cast<QGraphicsObject *>(this); 1459 if (QGestureManager *manager = QGestureManager::instance()) { 1460 foreach (Qt::GestureType type, d_ptr->gestureContext.keys()) 1461 manager->cleanupCachedGestures(o, type); 1462 } 1463 } 1464 #endif 1362 1465 1363 1466 clearFocus(); … … 1734 1837 void QGraphicsItem::setFlags(GraphicsItemFlags flags) 1735 1838 { 1736 if (isWindow())1737 flags |= ItemIsPanel;1738 1739 1839 // Notify change and check for adjustment. 1740 1840 if (quint32(d_ptr->flags) == quint32(flags)) … … 1750 1850 bool fullUpdate = (quint32(flags) & geomChangeFlagsMask) != (d_ptr->flags & geomChangeFlagsMask); 1751 1851 if (fullUpdate) 1752 d_ptr-> paintedViewBoundingRectsNeedRepaint = 1;1852 d_ptr->updatePaintedViewBoundingRects(/*children=*/true); 1753 1853 1754 1854 // Keep the old flags to compare the diff. … … 1774 1874 // all children. 1775 1875 d_ptr->updateAncestorFlag(ItemClipsChildrenToShape); 1876 // The childrenBoundingRect is clipped to the boundingRect in case of ItemClipsChildrenToShape, 1877 // which means we have to invalidate the cached childrenBoundingRect whenever this flag changes. 1878 d_ptr->dirtyChildrenBoundingRect = 1; 1879 d_ptr->markParentDirty(true); 1776 1880 } 1777 1881 … … 2022 2126 \snippet doc/src/snippets/code/src_gui_graphicsview_qgraphicsitem.cpp 2 2023 2127 2024 If no cursor has been set, the parent's cursoris used.2128 If no cursor has been set, the cursor of the item beneath is used. 2025 2129 2026 2130 \sa setCursor(), hasCursor(), unsetCursor(), QWidget::cursor, … … 2262 2366 fsi = fsi->d_ptr->focusScopeItem; 2263 2367 fsi->d_ptr->setFocusHelper(Qt::OtherFocusReason, /* climb = */ true, 2264 /* focusFrom Show = */ true);2368 /* focusFromHide = */ false); 2265 2369 } 2266 2370 break; … … 2272 2376 if (fi && fi != scene->focusItem()) { 2273 2377 scene->setFocusItem(fi); 2378 } else if (flags & QGraphicsItem::ItemIsFocusScope && 2379 !scene->focusItem() && 2380 q->isAncestorOf(scene->d_func()->lastFocusItem)) { 2381 q_ptr->setFocus(); 2274 2382 } 2275 2383 } … … 2282 2390 if (p->d_ptr->visible) { 2283 2391 p->d_ptr->setFocusHelper(Qt::OtherFocusReason, /* climb = */ true, 2284 /* focusFrom Show= */ true);2392 /* focusFromHide = */ true); 2285 2393 } 2286 2394 break; … … 2704 2812 QGraphicsEffect *effect = graphicsEffect; 2705 2813 if (scene && effect && effect->isEnabled()) { 2814 if (scene->d_func()->views.isEmpty()) 2815 return effect->boundingRectFor(rect); 2706 2816 QRectF sceneRect = q->mapRectToScene(rect); 2707 2817 QRectF sceneEffectRect; … … 2727 2837 \sa boundingRect() 2728 2838 */ 2729 QRectF QGraphicsItemPrivate::effectiveBoundingRect( ) const2839 QRectF QGraphicsItemPrivate::effectiveBoundingRect(QGraphicsItem *topMostEffectItem) const 2730 2840 { 2731 2841 #ifndef QT_NO_GRAPHICSEFFECT 2732 2842 Q_Q(const QGraphicsItem); 2733 2843 QRectF brect = effectiveBoundingRect(q_ptr->boundingRect()); 2734 if (ancestorFlags & QGraphicsItemPrivate::AncestorClipsChildren )2844 if (ancestorFlags & QGraphicsItemPrivate::AncestorClipsChildren || topMostEffectItem == q) 2735 2845 return brect; 2736 2846 … … 2743 2853 brect = effectParent->mapRectToItem(q, effectRectInParentSpace); 2744 2854 } 2745 if (effectParent->d_ptr->ancestorFlags & QGraphicsItemPrivate::AncestorClipsChildren) 2855 if (effectParent->d_ptr->ancestorFlags & QGraphicsItemPrivate::AncestorClipsChildren 2856 || topMostEffectItem == effectParent) { 2746 2857 return brect; 2858 } 2747 2859 effectParent = effectParent->d_ptr->parent; 2748 2860 } … … 3138 3250 void QGraphicsItem::setFocus(Qt::FocusReason focusReason) 3139 3251 { 3140 d_ptr->setFocusHelper(focusReason, /* climb = */ true, /* focusFrom Show= */ false);3252 d_ptr->setFocusHelper(focusReason, /* climb = */ true, /* focusFromHide = */ false); 3141 3253 } 3142 3254 … … 3144 3256 \internal 3145 3257 */ 3146 void QGraphicsItemPrivate::setFocusHelper(Qt::FocusReason focusReason, bool climb, bool focusFrom Show)3258 void QGraphicsItemPrivate::setFocusHelper(Qt::FocusReason focusReason, bool climb, bool focusFromHide) 3147 3259 { 3148 3260 // Disabled / unfocusable items cannot accept focus. … … 3163 3275 while (p) { 3164 3276 if (p->flags() & QGraphicsItem::ItemIsFocusScope) { 3277 QGraphicsItem *oldFocusScopeItem = p->d_ptr->focusScopeItem; 3165 3278 p->d_ptr->focusScopeItem = q_ptr; 3166 if (!p->focusItem() && !focusFromShow) { 3279 if (!p->focusItem() && !focusFromHide) { 3280 if (oldFocusScopeItem) 3281 oldFocusScopeItem->d_ptr->focusScopeItemChange(false); 3282 focusScopeItemChange(true); 3167 3283 // If you call setFocus on a child of a focus scope that 3168 3284 // doesn't currently have a focus item, then stop. … … 3180 3296 3181 3297 // Update the child focus chain. 3182 f->d_ptr->setSubFocus(); 3298 QGraphicsItem *commonAncestor = 0; 3299 if (scene && scene->focusItem()) { 3300 commonAncestor = scene->focusItem()->commonAncestorItem(f); 3301 scene->focusItem()->d_ptr->clearSubFocus(scene->focusItem(), commonAncestor); 3302 } 3303 3304 f->d_ptr->setSubFocus(f, commonAncestor); 3183 3305 3184 3306 // Update the scene's focus item. … … 3219 3341 while (p) { 3220 3342 if (p->flags() & QGraphicsItem::ItemIsFocusScope) { 3221 p->d_ptr->setFocusHelper(Qt::OtherFocusReason, /* climb = */ false, 3222 /* focusFromShow = */ false); 3343 if (p->d_ptr->focusScopeItem == q_ptr) { 3344 p->d_ptr->focusScopeItem = 0; 3345 if (!q_ptr->hasFocus()) //if it has focus, focusScopeItemChange is called elsewhere 3346 focusScopeItemChange(false); 3347 } 3348 if (q_ptr->hasFocus()) 3349 p->d_ptr->setFocusHelper(Qt::OtherFocusReason, /* climb = */ false, 3350 /* focusFromHide = */ false); 3223 3351 return; 3224 3352 } … … 3228 3356 } 3229 3357 3230 // Invisible items with focus must explicitly clear subfocus.3231 clearSubFocus(q_ptr);3232 3233 3358 if (q_ptr->hasFocus()) { 3359 // Invisible items with focus must explicitly clear subfocus. 3360 clearSubFocus(q_ptr); 3361 3234 3362 // If this item has the scene's input focus, clear it. 3235 3363 scene->setFocusItem(0); … … 3485 3613 return; 3486 3614 3487 d_ptr->setPosHelper(QPointF(x, d_ptr->pos.y())); 3615 if (qIsNaN(x)) 3616 return; 3617 3618 setPos(QPointF(x, d_ptr->pos.y())); 3488 3619 } 3489 3620 … … 3509 3640 return; 3510 3641 3511 d_ptr->setPosHelper(QPointF(d_ptr->pos.x(), y)); 3642 if (qIsNaN(y)) 3643 return; 3644 3645 setPos(QPointF(d_ptr->pos.x(), y)); 3512 3646 } 3513 3647 … … 3556 3690 transformData->transform = transform; 3557 3691 dirtySceneTransform = 1; 3692 transformChanged(); 3558 3693 } 3559 3694 … … 3577 3712 3578 3713 // Update and repositition. 3579 if (!(d_ptr->flags & ItemSendsGeometryChanges)) {3714 if (!(d_ptr->flags & (ItemSendsGeometryChanges | ItemSendsScenePositionChanges))) { 3580 3715 d_ptr->setPosHelper(pos); 3581 3716 if (d_ptr->isWidget) 3582 3717 static_cast<QGraphicsWidget *>(this)->d_func()->setGeometryFromSetPos(); 3718 if (d_ptr->scenePosDescendants) 3719 d_ptr->sendScenePosChange(); 3583 3720 return; 3584 3721 } … … 3724 3861 { 3725 3862 prepareGeometryChange(); 3863 qreal newRotation = angle; 3864 3865 if (d_ptr->flags & ItemSendsGeometryChanges) { 3866 // Notify the item that the rotation is changing. 3867 const QVariant newRotationVariant(itemChange(ItemRotationChange, angle)); 3868 newRotation = newRotationVariant.toReal(); 3869 } 3870 3726 3871 if (!d_ptr->transformData) 3727 3872 d_ptr->transformData = new QGraphicsItemPrivate::TransformData; 3728 d_ptr->transformData->rotation = angle; 3873 3874 if (d_ptr->transformData->rotation == newRotation) 3875 return; 3876 3877 d_ptr->transformData->rotation = newRotation; 3729 3878 d_ptr->transformData->onlyTransform = false; 3730 3879 d_ptr->dirtySceneTransform = 1; 3731 3880 3881 // Send post-notification. 3882 if (d_ptr->flags & ItemSendsGeometryChanges) 3883 itemChange(ItemRotationHasChanged, newRotation); 3884 3732 3885 if (d_ptr->isObject) 3733 3886 emit static_cast<QGraphicsObject *>(this)->rotationChanged(); 3887 3888 d_ptr->transformChanged(); 3734 3889 } 3735 3890 … … 3767 3922 transformations() to map the item's coordinate system to the parent item. 3768 3923 3769 \sa scale(), setTransformOriginPoint(), {Transformations }3924 \sa scale(), setTransformOriginPoint(), {Transformations Example} 3770 3925 */ 3771 3926 void QGraphicsItem::setScale(qreal factor) 3772 3927 { 3773 3928 prepareGeometryChange(); 3929 qreal newScale = factor; 3930 3931 if (d_ptr->flags & ItemSendsGeometryChanges) { 3932 // Notify the item that the scale is changing. 3933 const QVariant newScaleVariant(itemChange(ItemScaleChange, factor)); 3934 newScale = newScaleVariant.toReal(); 3935 } 3936 3774 3937 if (!d_ptr->transformData) 3775 3938 d_ptr->transformData = new QGraphicsItemPrivate::TransformData; 3776 d_ptr->transformData->scale = factor; 3939 3940 if (d_ptr->transformData->scale == newScale) 3941 return; 3942 3943 d_ptr->transformData->scale = newScale; 3777 3944 d_ptr->transformData->onlyTransform = false; 3778 3945 d_ptr->dirtySceneTransform = 1; 3779 3946 3947 // Send post-notification. 3948 if (d_ptr->flags & ItemSendsGeometryChanges) 3949 itemChange(ItemScaleHasChanged, newScale); 3950 3780 3951 if (d_ptr->isObject) 3781 3952 emit static_cast<QGraphicsObject *>(this)->scaleChanged(); 3953 3954 d_ptr->transformChanged(); 3782 3955 } 3783 3956 … … 3789 3962 3790 3963 QGraphicsTransform is for applying and controlling a chain of individual 3791 transformation operations on an item. It's particular ily useful in3964 transformation operations on an item. It's particularly useful in 3792 3965 animations, where each transform operation needs to be interpolated 3793 3966 independently, or differently. … … 3816 3989 3817 3990 QGraphicsTransform is for applying and controlling a chain of individual 3818 transformation operations on an item. It's particular ily useful in3991 transformation operations on an item. It's particularly useful in 3819 3992 animations, where each transform operation needs to be interpolated 3820 3993 independently, or differently. … … 3835 4008 d_ptr->transformData->onlyTransform = false; 3836 4009 d_ptr->dirtySceneTransform = 1; 4010 d_ptr->transformChanged(); 4011 } 4012 4013 /*! 4014 \internal 4015 */ 4016 void QGraphicsItemPrivate::prependGraphicsTransform(QGraphicsTransform *t) 4017 { 4018 if (!transformData) 4019 transformData = new QGraphicsItemPrivate::TransformData; 4020 if (!transformData->graphicsTransforms.contains(t)) 4021 transformData->graphicsTransforms.prepend(t); 4022 4023 Q_Q(QGraphicsItem); 4024 t->d_func()->setItem(q); 4025 transformData->onlyTransform = false; 4026 dirtySceneTransform = 1; 4027 transformChanged(); 3837 4028 } 3838 4029 … … 3851 4042 transformData->onlyTransform = false; 3852 4043 dirtySceneTransform = 1; 4044 transformChanged(); 3853 4045 } 3854 4046 … … 3879 4071 { 3880 4072 prepareGeometryChange(); 4073 QPointF newOrigin = origin; 4074 4075 if (d_ptr->flags & ItemSendsGeometryChanges) { 4076 // Notify the item that the origin point is changing. 4077 const QVariant newOriginVariant(itemChange(ItemTransformOriginPointChange, 4078 qVariantFromValue<QPointF>(origin))); 4079 newOrigin = newOriginVariant.toPointF(); 4080 } 4081 3881 4082 if (!d_ptr->transformData) 3882 4083 d_ptr->transformData = new QGraphicsItemPrivate::TransformData; 3883 d_ptr->transformData->xOrigin = origin.x(); 3884 d_ptr->transformData->yOrigin = origin.y(); 4084 4085 if (d_ptr->transformData->xOrigin == newOrigin.x() 4086 && d_ptr->transformData->yOrigin == newOrigin.y()) { 4087 return; 4088 } 4089 4090 d_ptr->transformData->xOrigin = newOrigin.x(); 4091 d_ptr->transformData->yOrigin = newOrigin.y(); 3885 4092 d_ptr->transformData->onlyTransform = false; 3886 4093 d_ptr->dirtySceneTransform = 1; 4094 4095 // Send post-notification. 4096 if (d_ptr->flags & ItemSendsGeometryChanges) 4097 itemChange(ItemTransformOriginPointHasChanged, qVariantFromValue<QPointF>(newOrigin)); 3887 4098 } 3888 4099 … … 4189 4400 4190 4401 // Update and set the new transformation. 4191 if (!(d_ptr->flags & ItemSendsGeometryChanges)) {4402 if (!(d_ptr->flags & (ItemSendsGeometryChanges | ItemSendsScenePositionChanges))) { 4192 4403 d_ptr->setTransformHelper(newTransform); 4404 if (d_ptr->scenePosDescendants) 4405 d_ptr->sendScenePosChange(); 4193 4406 return; 4194 4407 } … … 4531 4744 4532 4745 d_ptr->childrenBoundingRect = QRectF(); 4533 d_ptr->childrenBoundingRectHelper(0, &d_ptr->childrenBoundingRect );4746 d_ptr->childrenBoundingRectHelper(0, &d_ptr->childrenBoundingRect, 0); 4534 4747 d_ptr->dirtyChildrenBoundingRect = 0; 4535 4748 return d_ptr->childrenBoundingRect; … … 4972 5185 contents. Although it's expensive to calculate, it's also more precise 4973 5186 than boundingRect(), and it can help to avoid unnecessary repainting when 4974 an item is updated. This is particular ily efficient for thin items (e.g.,5187 an item is updated. This is particularly efficient for thin items (e.g., 4975 5188 lines or simple polygons). You can tune the granularity for the bounding 4976 5189 region by calling setBoundingRegionGranularity(). The default granularity … … 5228 5441 child->d_ptr->siblingIndex = children.size(); 5229 5442 children.append(child); 5443 if (isObject) 5444 emit static_cast<QGraphicsObject *>(q_ptr)->childrenChanged(); 5230 5445 } 5231 5446 … … 5250 5465 // (see ensureSortedChildren()). 5251 5466 child->d_ptr->siblingIndex = -1; 5467 if (isObject) 5468 emit static_cast<QGraphicsObject *>(q_ptr)->childrenChanged(); 5252 5469 } 5253 5470 … … 5285 5502 } 5286 5503 unsetExtra(ExtraCacheData); 5504 } 5505 5506 void QGraphicsItemPrivate::updatePaintedViewBoundingRects(bool updateChildren) 5507 { 5508 if (!scene) 5509 return; 5510 5511 for (int i = 0; i < scene->d_func()->views.size(); ++i) { 5512 QGraphicsViewPrivate *viewPrivate = scene->d_func()->views.at(i)->d_func(); 5513 QRect rect = paintedViewBoundingRects.value(viewPrivate->viewport); 5514 rect.translate(viewPrivate->dirtyScrollOffset); 5515 viewPrivate->updateRect(rect); 5516 } 5517 5518 if (updateChildren) { 5519 for (int i = 0; i < children.size(); ++i) 5520 children.at(i)->d_ptr->updatePaintedViewBoundingRects(true); 5521 } 5287 5522 } 5288 5523 … … 5324 5559 \internal 5325 5560 */ 5326 void QGraphicsItemPrivate::setSubFocus(QGraphicsItem *rootItem )5561 void QGraphicsItemPrivate::setSubFocus(QGraphicsItem *rootItem, QGraphicsItem *stopItem) 5327 5562 { 5328 5563 // Update focus child chain. Stop at panels, or if this item 5329 5564 // is hidden, stop at the first item with a visible parent. 5330 5565 QGraphicsItem *parent = rootItem ? rootItem : q_ptr; 5566 if (parent->panel() != q_ptr->panel()) 5567 return; 5568 5331 5569 do { 5332 5570 // Clear any existing ancestor's subFocusItem. … … 5334 5572 if (parent->d_ptr->subFocusItem == q_ptr) 5335 5573 break; 5336 parent->d_ptr->subFocusItem->d_ptr->clearSubFocus( );5574 parent->d_ptr->subFocusItem->d_ptr->clearSubFocus(0, stopItem); 5337 5575 } 5338 5576 parent->d_ptr->subFocusItem = q_ptr; … … 5347 5585 \internal 5348 5586 */ 5349 void QGraphicsItemPrivate::clearSubFocus(QGraphicsItem *rootItem )5587 void QGraphicsItemPrivate::clearSubFocus(QGraphicsItem *rootItem, QGraphicsItem *stopItem) 5350 5588 { 5351 5589 // Reset sub focus chain. … … 5355 5593 break; 5356 5594 parent->d_ptr->subFocusItem = 0; 5357 parent->d_ptr->subFocusItemChange(); 5595 if (parent != stopItem && !parent->isAncestorOf(stopItem)) 5596 parent->d_ptr->subFocusItemChange(); 5358 5597 } while (!parent->isPanel() && (parent = parent->d_ptr->parent)); 5359 5598 } … … 5380 5619 void QGraphicsItemPrivate::subFocusItemChange() 5381 5620 { 5621 } 5622 5623 /*! 5624 \internal 5625 5626 Subclasses can reimplement this function to be notified when an item 5627 becomes a focusScopeItem (or is no longer a focusScopeItem). 5628 */ 5629 void QGraphicsItemPrivate::focusScopeItemChange(bool isSubFocusItem) 5630 { 5631 Q_UNUSED(isSubFocusItem); 5382 5632 } 5383 5633 … … 5446 5696 } 5447 5697 5448 if (d_ptr->discardUpdateRequest())5449 return;5450 5451 5698 if (d_ptr->scene) 5452 5699 d_ptr->scene->d_func()->markDirty(this, rect); … … 5470 5717 is equivalent to calling update(\a rect). 5471 5718 5719 \bold{Note:} Scrolling is only supported when QGraphicsItem::ItemCoordinateCache 5720 is enabled; in all other cases calling this function is equivalent to calling 5721 update(\a rect). If you for sure know that the item is opaque and not overlapped 5722 by other items, you can map the \a rect to viewport coordinates and scroll the 5723 viewport. 5724 5725 \snippet doc/src/snippets/code/src_gui_graphicsview_qgraphicsitem.cpp 19 5726 5472 5727 \sa boundingRect() 5473 5728 */ … … 5479 5734 if (!d->scene) 5480 5735 return; 5481 if (d->cacheMode != NoCache) { 5482 QGraphicsItemCache *c; 5483 bool scrollCache = qFuzzyIsNull(dx - int(dx)) && qFuzzyIsNull(dy - int(dy)) 5484 && (c = (QGraphicsItemCache *)qVariantValue<void *>(d_ptr->extra(QGraphicsItemPrivate::ExtraCacheData))) 5485 && (d->cacheMode == ItemCoordinateCache && !c->fixedSize.isValid()); 5486 if (scrollCache) { 5487 QPixmap pix; 5488 if (QPixmapCache::find(c->key, &pix)) { 5489 // Adjust with 2 pixel margin. Notice the loss of precision 5490 // when converting to QRect. 5491 int adjust = 2; 5492 QRectF br = boundingRect().adjusted(-adjust, -adjust, adjust, adjust); 5493 QRect irect = rect.toRect().translated(-br.x(), -br.y()); 5494 5495 pix.scroll(dx, dy, irect); 5496 5497 QPixmapCache::replace(c->key, pix); 5498 5499 // Translate the existing expose. 5500 foreach (QRectF exposedRect, c->exposed) 5501 c->exposed += exposedRect.translated(dx, dy) & rect; 5502 5503 // Calculate exposure. 5504 QRegion exposed; 5505 QRect r = rect.toRect(); 5506 exposed += r; 5507 exposed -= r.translated(dx, dy); 5508 foreach (QRect rect, exposed.rects()) 5509 update(rect); 5510 d->scene->d_func()->markDirty(this); 5511 } else { 5512 update(rect); 5513 } 5514 } else { 5515 // ### This is very slow, and can be done much better. If the cache is 5516 // local and matches the below criteria for rotation and scaling, we 5517 // can easily scroll. And if the cache is in device coordinates, we 5518 // can scroll both the viewport and the cache. 5519 update(rect); 5520 } 5736 5737 // Accelerated scrolling means moving pixels from one location to another 5738 // and only redraw the newly exposed area. The following requirements must 5739 // be fulfilled in order to do that: 5740 // 5741 // 1) Item is opaque. 5742 // 2) Item is not overlapped by other items. 5743 // 5744 // There's (yet) no way to detect whether an item is opaque or not, which means 5745 // we cannot do accelerated scrolling unless the cache is enabled. In case of using 5746 // DeviceCoordinate cache we also have to take the device transform into account in 5747 // order to determine whether we can do accelerated scrolling or not. That's left out 5748 // for simplicity here, but it is definitely something we can consider in the future 5749 // as a performance improvement. 5750 if (d->cacheMode != QGraphicsItem::ItemCoordinateCache 5751 || !qFuzzyIsNull(dx - int(dx)) || !qFuzzyIsNull(dy - int(dy))) { 5752 update(rect); 5521 5753 return; 5522 5754 } 5523 5755 5524 QRectF scrollRect = !rect.isNull() ? rect : boundingRect(); 5525 int couldntScroll = d->scene->views().size(); 5526 foreach (QGraphicsView *view, d->scene->views()) { 5527 if (view->viewport()->inherits("QGLWidget")) { 5528 // ### Please replace with a widget attribute; any widget that 5529 // doesn't support partial updates / doesn't support scrolling 5530 // should be skipped in this code. Qt::WA_NoPartialUpdates or so. 5756 QGraphicsItemCache *cache = d->extraItemCache(); 5757 if (cache->allExposed || cache->fixedSize.isValid()) { 5758 // Cache is either invalidated or item is scaled (see QGraphicsItem::setCacheMode). 5759 update(rect); 5760 return; 5761 } 5762 5763 // Find pixmap in cache. 5764 QPixmap cachedPixmap; 5765 if (!QPixmapCache::find(cache->key, &cachedPixmap)) { 5766 update(rect); 5767 return; 5768 } 5769 5770 QRect scrollRect = (rect.isNull() ? boundingRect() : rect).toAlignedRect(); 5771 if (!scrollRect.intersects(cache->boundingRect)) 5772 return; // Nothing to scroll. 5773 5774 // Remove from cache to avoid deep copy when modifying. 5775 QPixmapCache::remove(cache->key); 5776 5777 QRegion exposed; 5778 cachedPixmap.scroll(dx, dy, scrollRect.translated(-cache->boundingRect.topLeft()), &exposed); 5779 5780 // Reinsert into cache. 5781 cache->key = QPixmapCache::insert(cachedPixmap); 5782 5783 // Translate the existing expose. 5784 for (int i = 0; i < cache->exposed.size(); ++i) { 5785 QRectF &e = cache->exposed[i]; 5786 if (!rect.isNull() && !e.intersects(rect)) 5531 5787 continue; 5532 } 5533 5534 static const QLineF up(0, 0, 0, -1); 5535 static const QLineF down(0, 0, 0, 1); 5536 static const QLineF left(0, 0, -1, 0); 5537 static const QLineF right(0, 0, 1, 0); 5538 5539 QTransform deviceTr = deviceTransform(view->viewportTransform()); 5540 QRect deviceScrollRect = deviceTr.mapRect(scrollRect).toRect(); 5541 QLineF v1 = deviceTr.map(right); 5542 QLineF v2 = deviceTr.map(down); 5543 QLineF u1 = v1.unitVector(); u1.translate(-v1.p1()); 5544 QLineF u2 = v2.unitVector(); u2.translate(-v2.p1()); 5545 bool noScroll = false; 5546 5547 // Check if the delta resolves to ints in device space. 5548 QPointF deviceDelta = deviceTr.map(QPointF(dx, dy)); 5549 if ((deviceDelta.x() - int(deviceDelta.x())) 5550 || (deviceDelta.y() - int(deviceDelta.y()))) { 5551 noScroll = true; 5552 } else { 5553 // Check if the unit vectors have no fraction in device space. 5554 qreal v1l = v1.length(); 5555 if (v1l - int(v1l)) { 5556 noScroll = true; 5557 } else { 5558 dx *= v1.length(); 5559 } 5560 qreal v2l = v2.length(); 5561 if (v2l - int(v2l)) { 5562 noScroll = true; 5563 } else { 5564 dy *= v2.length(); 5565 } 5566 } 5567 5568 if (!noScroll) { 5569 if (u1 == right) { 5570 if (u2 == up) { 5571 // flipped 5572 dy = -dy; 5573 } else if (u2 == down) { 5574 // normal 5575 } else { 5576 noScroll = true; 5577 } 5578 } else if (u1 == left) { 5579 if (u2 == up) { 5580 // mirrored & flipped / rotated 180 degrees 5581 dx = -dx; 5582 dy = -dy; 5583 } else if (u2 == down) { 5584 // mirrored 5585 dx = -dx; 5586 } else { 5587 noScroll = true; 5588 } 5589 } else if (u1 == up) { 5590 if (u2 == left) { 5591 // rotated -90 & mirrored 5592 qreal tmp = dy; 5593 dy = -dx; 5594 dx = -tmp; 5595 } else if (u2 == right) { 5596 // rotated -90 5597 qreal tmp = dy; 5598 dy = -dx; 5599 dx = tmp; 5600 } else { 5601 noScroll = true; 5602 } 5603 } else if (u1 == down) { 5604 if (u2 == left) { 5605 // rotated 90 5606 qreal tmp = dy; 5607 dy = dx; 5608 dx = -tmp; 5609 } else if (u2 == right) { 5610 // rotated 90 & mirrored 5611 qreal tmp = dy; 5612 dy = dx; 5613 dx = tmp; 5614 } else { 5615 noScroll = true; 5616 } 5617 } 5618 } 5619 5620 if (!noScroll) { 5621 view->viewport()->scroll(int(dx), int(dy), deviceScrollRect); 5622 --couldntScroll; 5623 } 5624 } 5625 if (couldntScroll) 5626 update(rect); 5788 e.translate(dx, dy); 5789 } 5790 5791 // Append newly exposed areas. Note that the exposed region is currently 5792 // in pixmap coordinates, so we have to translate it to item coordinates. 5793 exposed.translate(cache->boundingRect.topLeft()); 5794 const QVector<QRect> exposedRects = exposed.rects(); 5795 for (int i = 0; i < exposedRects.size(); ++i) 5796 cache->exposed += exposedRects.at(i); 5797 5798 // Trigger update. This will redraw the newly exposed area and make sure 5799 // the pixmap is re-blitted in case there are overlapping items. 5800 d->scene->d_func()->markDirty(this, rect); 5627 5801 } 5628 5802 … … 6500 6674 } 6501 6675 6676 if (event->type() == QEvent::FocusOut) { 6677 focusOutEvent(static_cast<QFocusEvent *>(event)); 6678 return true; 6679 } 6680 6502 6681 if (!d_ptr->visible) { 6503 6682 // Eaten … … 6508 6687 case QEvent::FocusIn: 6509 6688 focusInEvent(static_cast<QFocusEvent *>(event)); 6510 break;6511 case QEvent::FocusOut:6512 focusOutEvent(static_cast<QFocusEvent *>(event));6513 6689 break; 6514 6690 case QEvent::GraphicsSceneContextMenu: … … 6985 7161 // calculate their diff by mapping viewport coordinates 6986 7162 // directly to parent coordinates. 6987 QTransform viewToParentTransform = (item->transform().translate(item->d_ptr->pos.x(), item->d_ptr->pos.y())) 7163 // COMBINE 7164 QTransform itemTransform; 7165 if (item->d_ptr->transformData) 7166 itemTransform = item->d_ptr->transformData->computedFullTransform(); 7167 itemTransform.translate(item->d_ptr->pos.x(), item->d_ptr->pos.y()); 7168 QTransform viewToParentTransform = itemTransform 6988 7169 * (item->sceneTransform() * view->viewportTransform()).inverted(); 6989 7170 currentParentPos = viewToParentTransform.map(QPointF(view->mapFromGlobal(event->screenPos()))); … … 7179 7360 Q_D(QGraphicsItem); 7180 7361 d->imHints = hints; 7362 if (!hasFocus()) 7363 return; 7364 d->scene->d_func()->updateInputMethodSensitivityInViews(); 7365 #if !defined(QT_NO_IM) && (defined(Q_WS_X11) || defined(Q_WS_QWS) || defined(Q_OS_SYMBIAN)) 7366 QWidget *fw = QApplication::focusWidget(); 7367 if (!fw) 7368 return; 7369 for (int i = 0 ; i < scene()->views().count() ; ++i) 7370 if (scene()->views().at(i) == fw) 7371 if (QInputContext *inputContext = fw->inputContext()) 7372 inputContext->update(); 7373 #endif 7374 } 7375 7376 /*! 7377 Updates the item's micro focus. 7378 7379 \since 4.7 7380 7381 \sa QInputContext 7382 */ 7383 void QGraphicsItem::updateMicroFocus() 7384 { 7385 #if !defined(QT_NO_IM) && (defined(Q_WS_X11) || defined(Q_WS_QWS) || defined(Q_OS_SYMBIAN)) 7386 if (QWidget *fw = QApplication::focusWidget()) { 7387 if (scene()) { 7388 for (int i = 0 ; i < scene()->views().count() ; ++i) { 7389 if (scene()->views().at(i) == fw) 7390 if (QInputContext *inputContext = fw->inputContext()) 7391 inputContext->update(); 7392 } 7393 } 7394 #ifndef QT_NO_ACCESSIBILITY 7395 // ##### is this correct 7396 QAccessible::updateAccessibility(fw, 0, QAccessible::StateChanged); 7397 #endif 7398 } 7399 #endif 7181 7400 } 7182 7401 … … 7431 7650 } 7432 7651 7652 #ifndef QT_NO_GESTURES 7433 7653 /*! 7434 7654 Subscribes the graphics object to the given \a gesture with specific \a flags. … … 7438 7658 void QGraphicsObject::grabGesture(Qt::GestureType gesture, Qt::GestureFlags flags) 7439 7659 { 7440 QGraphicsItemPrivate * const d = QGraphicsItem::d_func(); 7441 d->gestureContext.insert(gesture, flags); 7442 (void)QGestureManager::instance(); // create a gesture manager 7660 bool contains = QGraphicsItem::d_ptr->gestureContext.contains(gesture); 7661 QGraphicsItem::d_ptr->gestureContext.insert(gesture, flags); 7662 if (!contains && QGraphicsItem::d_ptr->scene) 7663 QGraphicsItem::d_ptr->scene->d_func()->grabGesture(this, gesture); 7443 7664 } 7444 7665 … … 7450 7671 void QGraphicsObject::ungrabGesture(Qt::GestureType gesture) 7451 7672 { 7452 QGraphicsItemPrivate * const d = QGraphicsItem::d_func(); 7453 if (d->gestureContext.remove(gesture)) { 7454 QGestureManager *manager = QGestureManager::instance(); 7455 manager->cleanupCachedGestures(this, gesture); 7456 } 7457 } 7673 if (QGraphicsItem::d_ptr->gestureContext.remove(gesture) && QGraphicsItem::d_ptr->scene) 7674 QGraphicsItem::d_ptr->scene->d_func()->ungrabGesture(this, gesture); 7675 } 7676 #endif // QT_NO_GESTURES 7677 7678 /*! 7679 Updates the item's micro focus. This is slot for convenience. 7680 7681 \since 4.7 7682 7683 \sa QInputContext 7684 */ 7685 void QGraphicsObject::updateMicroFocus() 7686 { 7687 QGraphicsItem::updateMicroFocus(); 7688 } 7689 7690 void QGraphicsItemPrivate::children_append(QDeclarativeListProperty<QGraphicsObject> *list, QGraphicsObject *item) 7691 { 7692 QGraphicsObject *graphicsObject = static_cast<QGraphicsObject *>(list->object); 7693 if (QGraphicsItemPrivate::get(graphicsObject)->sendParentChangeNotification) { 7694 item->setParentItem(graphicsObject); 7695 } else { 7696 QGraphicsItemPrivate::get(item)->setParentItemHelper(graphicsObject, 0, 0); 7697 } 7698 } 7699 7700 int QGraphicsItemPrivate::children_count(QDeclarativeListProperty<QGraphicsObject> *list) 7701 { 7702 QGraphicsItemPrivate *d = QGraphicsItemPrivate::get(static_cast<QGraphicsObject *>(list->object)); 7703 return d->children.count(); 7704 } 7705 7706 QGraphicsObject *QGraphicsItemPrivate::children_at(QDeclarativeListProperty<QGraphicsObject> *list, int index) 7707 { 7708 QGraphicsItemPrivate *d = QGraphicsItemPrivate::get(static_cast<QGraphicsObject *>(list->object)); 7709 if (index >= 0 && index < d->children.count()) 7710 return d->children.at(index)->toGraphicsObject(); 7711 else 7712 return 0; 7713 } 7714 7715 void QGraphicsItemPrivate::children_clear(QDeclarativeListProperty<QGraphicsObject> *list) 7716 { 7717 QGraphicsItemPrivate *d = QGraphicsItemPrivate::get(static_cast<QGraphicsObject *>(list->object)); 7718 int childCount = d->children.count(); 7719 if (d->sendParentChangeNotification) { 7720 for (int index = 0; index < childCount; index++) 7721 d->children.at(0)->setParentItem(0); 7722 } else { 7723 for (int index = 0; index < childCount; index++) 7724 QGraphicsItemPrivate::get(d->children.at(0))->setParentItemHelper(0, 0, 0); 7725 } 7726 } 7727 7728 /*! 7729 Returns a list of this item's children. 7730 7731 The items are sorted by stacking order. This takes into account both the 7732 items' insertion order and their Z-values. 7733 7734 */ 7735 QDeclarativeListProperty<QGraphicsObject> QGraphicsItemPrivate::childrenList() 7736 { 7737 Q_Q(QGraphicsItem); 7738 if (isObject) { 7739 QGraphicsObject *that = static_cast<QGraphicsObject *>(q); 7740 return QDeclarativeListProperty<QGraphicsObject>(that, &children, children_append, 7741 children_count, children_at, children_clear); 7742 } else { 7743 //QGraphicsItem is not supported for this property 7744 return QDeclarativeListProperty<QGraphicsObject>(); 7745 } 7746 } 7747 7748 /*! 7749 \internal 7750 Returns the width of the item 7751 Reimplemented by QGraphicsWidget 7752 */ 7753 qreal QGraphicsItemPrivate::width() const 7754 { 7755 return 0; 7756 } 7757 7758 /*! 7759 \internal 7760 Set the width of the item 7761 Reimplemented by QGraphicsWidget 7762 */ 7763 void QGraphicsItemPrivate::setWidth(qreal w) 7764 { 7765 Q_UNUSED(w); 7766 } 7767 7768 /*! 7769 \internal 7770 Reset the width of the item 7771 Reimplemented by QGraphicsWidget 7772 */ 7773 void QGraphicsItemPrivate::resetWidth() 7774 { 7775 } 7776 7777 /*! 7778 \internal 7779 Returns the height of the item 7780 Reimplemented by QGraphicsWidget 7781 */ 7782 qreal QGraphicsItemPrivate::height() const 7783 { 7784 return 0; 7785 } 7786 7787 /*! 7788 \internal 7789 Set the height of the item 7790 Reimplemented by QGraphicsWidget 7791 */ 7792 void QGraphicsItemPrivate::setHeight(qreal h) 7793 { 7794 Q_UNUSED(h); 7795 } 7796 7797 /*! 7798 \internal 7799 Reset the height of the item 7800 Reimplemented by QGraphicsWidget 7801 */ 7802 void QGraphicsItemPrivate::resetHeight() 7803 { 7804 } 7805 7806 /*! 7807 \property QGraphicsObject::children 7808 \since 4.7 7809 \internal 7810 */ 7811 7812 /*! 7813 \property QGraphicsObject::width 7814 \since 4.7 7815 \internal 7816 */ 7817 7818 /*! 7819 \property QGraphicsObject::height 7820 \since 4.7 7821 \internal 7822 */ 7458 7823 7459 7824 /*! … … 7643 8008 */ 7644 8009 8010 /*! 8011 \fn void QGraphicsObject::widthChanged() 8012 \internal 8013 */ 8014 8015 /*! 8016 \fn void QGraphicsObject::heightChanged() 8017 \internal 8018 */ 8019 8020 /*! 8021 8022 \fn QGraphicsObject::childrenChanged() 8023 8024 This signal gets emitted whenever the children list changes 8025 \internal 8026 */ 8027 8028 /*! 8029 \property QGraphicsObject::effect 8030 \since 4.7 8031 \brief the effect attached to this item 8032 8033 \sa QGraphicsItem::setGraphicsEffect(), QGraphicsItem::graphicsEffect() 8034 */ 7645 8035 7646 8036 /*! … … 7660 8050 \sa QGraphicsRectItem, QGraphicsEllipseItem, QGraphicsPathItem, 7661 8051 QGraphicsPolygonItem, QGraphicsTextItem, QGraphicsLineItem, 7662 QGraphicsPixmapItem, { TheGraphics View Framework}8052 QGraphicsPixmapItem, {Graphics View Framework} 7663 8053 */ 7664 8054 … … 7799 8189 7800 8190 \sa QGraphicsRectItem, QGraphicsEllipseItem, QGraphicsPolygonItem, 7801 QGraphicsTextItem, QGraphicsLineItem, QGraphicsPixmapItem, { TheGraphics8191 QGraphicsTextItem, QGraphicsLineItem, QGraphicsPixmapItem, {Graphics 7802 8192 View Framework} 7803 8193 */ … … 8008 8398 8009 8399 \sa QGraphicsPathItem, QGraphicsEllipseItem, QGraphicsPolygonItem, 8010 QGraphicsTextItem, QGraphicsLineItem, QGraphicsPixmapItem, { TheGraphics8400 QGraphicsTextItem, QGraphicsLineItem, QGraphicsPixmapItem, {Graphics 8011 8401 View Framework} 8012 8402 */ … … 8252 8642 8253 8643 \sa QGraphicsPathItem, QGraphicsRectItem, QGraphicsPolygonItem, 8254 QGraphicsTextItem, QGraphicsLineItem, QGraphicsPixmapItem, { TheGraphics8644 QGraphicsTextItem, QGraphicsLineItem, QGraphicsPixmapItem, {Graphics 8255 8645 View Framework} 8256 8646 */ … … 8561 8951 8562 8952 \sa QGraphicsPathItem, QGraphicsRectItem, QGraphicsEllipseItem, 8563 QGraphicsTextItem, QGraphicsLineItem, QGraphicsPixmapItem, { TheGraphics8953 QGraphicsTextItem, QGraphicsLineItem, QGraphicsPixmapItem, {Graphics 8564 8954 View Framework} 8565 8955 */ … … 8793 9183 8794 9184 \sa QGraphicsPathItem, QGraphicsRectItem, QGraphicsEllipseItem, 8795 QGraphicsTextItem, QGraphicsPolygonItem, QGraphicsPixmapItem, {The8796 Graphics View Framework}9185 QGraphicsTextItem, QGraphicsPolygonItem, QGraphicsPixmapItem, 9186 {Graphics View Framework} 8797 9187 */ 8798 9188 … … 9063 9453 9064 9454 \sa QGraphicsPathItem, QGraphicsRectItem, QGraphicsEllipseItem, 9065 QGraphicsTextItem, QGraphicsPolygonItem, QGraphicsLineItem, {The9066 Graphics View Framework}9455 QGraphicsTextItem, QGraphicsPolygonItem, QGraphicsLineItem, 9456 {Graphics View Framework} 9067 9457 */ 9068 9458 … … 9434 9824 \sa QGraphicsSimpleTextItem, QGraphicsPathItem, QGraphicsRectItem, 9435 9825 QGraphicsEllipseItem, QGraphicsPixmapItem, QGraphicsPolygonItem, 9436 QGraphicsLineItem, { TheGraphics View Framework}9826 QGraphicsLineItem, {Graphics View Framework} 9437 9827 */ 9438 9828 … … 9805 10195 } 9806 10196 break; 10197 case QEvent::ShortcutOverride: 10198 dd->sendControlEvent(event); 10199 return true; 9807 10200 default: 9808 10201 break; … … 10347 10740 \img graphicsview-simpletextitem.png 10348 10741 10349 \sa QGraphicsTextItem, QGraphicsPathItem, QGraphicsRectItem, QGraphicsEllipseItem,10350 QGraphics PixmapItem, QGraphicsPolygonItem, QGraphicsLineItem, {The10351 Graphics View Framework}10742 \sa QGraphicsTextItem, QGraphicsPathItem, QGraphicsRectItem, 10743 QGraphicsEllipseItem, QGraphicsPixmapItem, QGraphicsPolygonItem, 10744 QGraphicsLineItem, {Graphics View Framework} 10352 10745 */ 10353 10746 … … 10557 10950 /*! 10558 10951 \class QGraphicsItemGroup 10559 \brief The QGraphicsItemGroup class provides treating a group of items as10560 one.10952 \brief The QGraphicsItemGroup class provides a container that treats 10953 a group of items as a single item. 10561 10954 \since 4.2 10562 10955 \ingroup graphicsview-api … … 10610 11003 position and transformation remain intact. 10611 11004 10612 \sa QGraphicsItem, { TheGraphics View Framework}11005 \sa QGraphicsItem, {Graphics View Framework} 10613 11006 */ 10614 11007 … … 10931 11324 } else if (deviceCoordinates) { 10932 11325 // Device coordinates with info. 10933 scened->draw(item, &pixmapPainter, info->viewTransform, info->transformPtr, info->exposedRegion,11326 scened->draw(item, &pixmapPainter, info->viewTransform, info->transformPtr, 0, 10934 11327 info->widget, info->opacity, &effectTransform, info->wasDirtySceneTransform, 10935 11328 info->drawItem); … … 10938 11331 QTransform newEffectTransform = info->transformPtr->inverted(); 10939 11332 newEffectTransform *= effectTransform; 10940 scened->draw(item, &pixmapPainter, info->viewTransform, info->transformPtr, info->exposedRegion,11333 scened->draw(item, &pixmapPainter, info->viewTransform, info->transformPtr, 0, 10941 11334 info->widget, info->opacity, &newEffectTransform, info->wasDirtySceneTransform, 10942 11335 info->drawItem); … … 11074 11467 str = "ItemScenePositionHasChanged"; 11075 11468 break; 11469 case QGraphicsItem::ItemRotationChange: 11470 str = "ItemRotationChange"; 11471 break; 11472 case QGraphicsItem::ItemRotationHasChanged: 11473 str = "ItemRotationHasChanged"; 11474 break; 11475 case QGraphicsItem::ItemScaleChange: 11476 str = "ItemScaleChange"; 11477 break; 11478 case QGraphicsItem::ItemScaleHasChanged: 11479 str = "ItemScaleHasChanged"; 11480 break; 11481 case QGraphicsItem::ItemTransformOriginPointChange: 11482 str = "ItemTransformOriginPointChange"; 11483 break; 11484 case QGraphicsItem::ItemTransformOriginPointHasChanged: 11485 str = "ItemTransformOriginPointHasChanged"; 11486 break; 11076 11487 } 11077 11488 debug << str; … … 11134 11545 str = "ItemSendsScenePositionChanges"; 11135 11546 break; 11547 case QGraphicsItem::ItemStopsClickFocusPropagation: 11548 str = "ItemStopsClickFocusPropagation"; 11549 break; 11136 11550 } 11137 11551 debug << str; … … 11143 11557 debug << '('; 11144 11558 bool f = false; 11145 for (int i = 0; i < 1 6; ++i) {11559 for (int i = 0; i < 17; ++i) { 11146 11560 if (flags & (1 << i)) { 11147 11561 if (f) -
trunk/src/gui/graphicsview/qgraphicsitem.h
r651 r846 1 1 /**************************************************************************** 2 2 ** 3 ** Copyright (C) 201 0Nokia Corporation and/or its subsidiary(-ies).3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). 4 4 ** All rights reserved. 5 5 ** Contact: Nokia Corporation (qt-info@nokia.com) … … 107 107 ItemIsPanel = 0x4000, 108 108 ItemIsFocusScope = 0x8000, // internal 109 ItemSendsScenePositionChanges = 0x10000 109 ItemSendsScenePositionChanges = 0x10000, 110 ItemStopsClickFocusPropagation = 0x20000 110 111 // NB! Don't forget to increase the d_ptr->flags bit field by 1 when adding a new flag. 111 112 }; … … 140 141 ItemOpacityChange, 141 142 ItemOpacityHasChanged, 142 ItemScenePositionHasChanged 143 ItemScenePositionHasChanged, 144 ItemRotationChange, 145 ItemRotationHasChanged, 146 ItemScaleChange, 147 ItemScaleHasChanged, 148 ItemTransformOriginPointChange, 149 ItemTransformOriginPointHasChanged 143 150 }; 144 151 … … 419 426 420 427 protected: 428 void updateMicroFocus(); 421 429 virtual bool sceneEventFilter(QGraphicsItem *watched, QEvent *event); 422 430 virtual bool sceneEvent(QEvent *event); … … 479 487 friend class QGraphicsItemEffectSourcePrivate; 480 488 friend class QGraphicsTransformPrivate; 489 #ifndef QT_NO_GESTURES 481 490 friend class QGestureManager; 491 #endif 482 492 friend class ::tst_QGraphicsItem; 483 493 friend bool qt_closestLeaf(const QGraphicsItem *, const QGraphicsItem *); … … 541 551 Q_PROPERTY(bool enabled READ isEnabled WRITE setEnabled NOTIFY enabledChanged) 542 552 Q_PROPERTY(bool visible READ isVisible WRITE setVisible NOTIFY visibleChanged FINAL) 543 Q_PROPERTY(QPointF pos READ pos WRITE setPos )544 Q_PROPERTY(qreal x READ x WRITE setX NOTIFY xChanged )545 Q_PROPERTY(qreal y READ y WRITE setY NOTIFY yChanged )546 Q_PROPERTY(qreal z READ zValue WRITE setZValue NOTIFY zChanged )553 Q_PROPERTY(QPointF pos READ pos WRITE setPos FINAL) 554 Q_PROPERTY(qreal x READ x WRITE setX NOTIFY xChanged FINAL) 555 Q_PROPERTY(qreal y READ y WRITE setY NOTIFY yChanged FINAL) 556 Q_PROPERTY(qreal z READ zValue WRITE setZValue NOTIFY zChanged FINAL) 547 557 Q_PROPERTY(qreal rotation READ rotation WRITE setRotation NOTIFY rotationChanged) 548 558 Q_PROPERTY(qreal scale READ scale WRITE setScale NOTIFY scaleChanged) 549 559 Q_PROPERTY(QPointF transformOriginPoint READ transformOriginPoint WRITE setTransformOriginPoint) 560 #ifndef QT_NO_GRAPHICSEFFECT 561 Q_PROPERTY(QGraphicsEffect *effect READ graphicsEffect WRITE setGraphicsEffect) 562 #endif 563 Q_PRIVATE_PROPERTY(QGraphicsItem::d_func(), QDeclarativeListProperty<QGraphicsObject> children READ childrenList DESIGNABLE false NOTIFY childrenChanged) 564 Q_PRIVATE_PROPERTY(QGraphicsItem::d_func(), qreal width READ width WRITE setWidth NOTIFY widthChanged RESET resetWidth FINAL) 565 Q_PRIVATE_PROPERTY(QGraphicsItem::d_func(), qreal height READ height WRITE setHeight NOTIFY heightChanged RESET resetHeight FINAL) 566 Q_CLASSINFO("DefaultProperty", "children") 550 567 Q_INTERFACES(QGraphicsItem) 551 568 public: … … 559 576 #endif 560 577 578 #ifndef QT_NO_GESTURES 561 579 void grabGesture(Qt::GestureType type, Qt::GestureFlags flags = Qt::GestureFlags()); 562 580 void ungrabGesture(Qt::GestureType type); 581 #endif 582 583 protected Q_SLOTS: 584 void updateMicroFocus(); 563 585 564 586 Q_SIGNALS: … … 572 594 void rotationChanged(); 573 595 void scaleChanged(); 596 void childrenChanged(); 597 void widthChanged(); 598 void heightChanged(); 574 599 575 600 protected: -
trunk/src/gui/graphicsview/qgraphicsitem_p.h
r769 r846 1 1 /**************************************************************************** 2 2 ** 3 ** Copyright (C) 201 0Nokia Corporation and/or its subsidiary(-ies).3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). 4 4 ** All rights reserved. 5 5 ** Contact: Nokia Corporation (qt-info@nokia.com) … … 71 71 72 72 class QGraphicsItemPrivate; 73 74 #ifndef QDECLARATIVELISTPROPERTY 75 #define QDECLARATIVELISTPROPERTY 76 template<typename T> 77 class QDeclarativeListProperty { 78 public: 79 typedef void (*AppendFunction)(QDeclarativeListProperty<T> *, T*); 80 typedef int (*CountFunction)(QDeclarativeListProperty<T> *); 81 typedef T *(*AtFunction)(QDeclarativeListProperty<T> *, int); 82 typedef void (*ClearFunction)(QDeclarativeListProperty<T> *); 83 84 QDeclarativeListProperty() 85 : object(0), data(0), append(0), count(0), at(0), clear(0), dummy1(0), dummy2(0) {} 86 QDeclarativeListProperty(QObject *o, QList<T *> &list) 87 : object(o), data(&list), append(qlist_append), count(qlist_count), at(qlist_at), 88 clear(qlist_clear), dummy1(0), dummy2(0) {} 89 QDeclarativeListProperty(QObject *o, void *d, AppendFunction a, CountFunction c = 0, AtFunction t = 0, 90 ClearFunction r = 0) 91 : object(o), data(d), append(a), count(c), at(t), clear(r), dummy1(0), dummy2(0) {} 92 93 bool operator==(const QDeclarativeListProperty &o) const { 94 return object == o.object && 95 data == o.data && 96 append == o.append && 97 count == o.count && 98 at == o.at && 99 clear == o.clear; 100 } 101 102 QObject *object; 103 void *data; 104 105 AppendFunction append; 106 107 CountFunction count; 108 AtFunction at; 109 110 ClearFunction clear; 111 112 void *dummy1; 113 void *dummy2; 114 115 private: 116 static void qlist_append(QDeclarativeListProperty *p, T *v) { 117 ((QList<T *> *)p->data)->append(v); 118 } 119 static int qlist_count(QDeclarativeListProperty *p) { 120 return ((QList<T *> *)p->data)->count(); 121 } 122 static T *qlist_at(QDeclarativeListProperty *p, int idx) { 123 return ((QList<T *> *)p->data)->at(idx); 124 } 125 static void qlist_clear(QDeclarativeListProperty *p) { 126 return ((QList<T *> *)p->data)->clear(); 127 } 128 }; 129 #endif 73 130 74 131 class QGraphicsItemCache … … 157 214 allChildrenDirty(0), 158 215 fullUpdatePending(0), 216 dirtyChildrenBoundingRect(1), 159 217 flags(0), 160 dirtyChildrenBoundingRect(1),161 218 paintedViewBoundingRectsNeedRepaint(0), 162 219 dirtySceneTransform(1), … … 181 238 pendingPolish(0), 182 239 mayHaveChildWithGraphicsEffect(0), 240 isDeclarativeItem(0), 241 sendParentChangeNotification(0), 183 242 globalStackingOrder(-1), 184 243 q_ptr(0) … … 221 280 virtual void setPosHelper(const QPointF &pos); 222 281 void setTransformHelper(const QTransform &transform); 282 void prependGraphicsTransform(QGraphicsTransform *t); 223 283 void appendGraphicsTransform(QGraphicsTransform *t); 224 284 void setVisibleHelper(bool newVisible, bool explicitly, bool update = true); … … 226 286 bool discardUpdateRequest(bool ignoreVisibleBit = false, 227 287 bool ignoreDirtyBit = false, bool ignoreOpacity = false) const; 288 virtual void transformChanged() {} 228 289 int depth() const; 229 290 #ifndef QT_NO_GRAPHICSEFFECT … … 238 299 void addChild(QGraphicsItem *child); 239 300 void removeChild(QGraphicsItem *child); 301 QDeclarativeListProperty<QGraphicsObject> childrenList(); 240 302 void setParentItemHelper(QGraphicsItem *parent, const QVariant *newParentVariant, 241 303 const QVariant *thisPointerVariant); 242 void childrenBoundingRectHelper(QTransform *x, QRectF *rect );304 void childrenBoundingRectHelper(QTransform *x, QRectF *rect, QGraphicsItem *topMostEffectItem); 243 305 void initStyleOption(QStyleOptionGraphicsItem *option, const QTransform &worldTransform, 244 306 const QRegion &exposedRegion, bool allItems = false) const; 245 QRectF effectiveBoundingRect( ) const;307 QRectF effectiveBoundingRect(QGraphicsItem *topMostEffectItem = 0) const; 246 308 QRectF sceneEffectiveBoundingRect() const; 247 309 … … 317 379 void removeExtraItemCache(); 318 380 381 void updatePaintedViewBoundingRects(bool updateChildren); 319 382 void ensureSceneTransformRecursive(QGraphicsItem **topMostDirtyItem); 320 383 inline void ensureSceneTransform() … … 415 478 inline void markParentDirty(bool updateBoundingRect = false); 416 479 417 void setFocusHelper(Qt::FocusReason focusReason, bool climb, bool focusFrom Show);480 void setFocusHelper(Qt::FocusReason focusReason, bool climb, bool focusFromHide); 418 481 void clearFocusHelper(bool giveFocusToParent); 419 void setSubFocus(QGraphicsItem *rootItem = 0 );420 void clearSubFocus(QGraphicsItem *rootItem = 0 );482 void setSubFocus(QGraphicsItem *rootItem = 0, QGraphicsItem *stopItem = 0); 483 void clearSubFocus(QGraphicsItem *rootItem = 0, QGraphicsItem *stopItem = 0); 421 484 void resetFocusProxy(); 422 485 virtual void subFocusItemChange(); 486 virtual void focusScopeItemChange(bool isSubFocusItem); 487 488 static void children_append(QDeclarativeListProperty<QGraphicsObject> *list, QGraphicsObject *item); 489 static int children_count(QDeclarativeListProperty<QGraphicsObject> *list); 490 static QGraphicsObject *children_at(QDeclarativeListProperty<QGraphicsObject> *list, int); 491 static void children_clear(QDeclarativeListProperty<QGraphicsObject> *list); 423 492 424 493 inline QTransform transformToParent() const; … … 428 497 inline void sendScenePosChange(); 429 498 virtual void siblingOrderChange(); 499 500 // Private Properties 501 virtual qreal width() const; 502 virtual void setWidth(qreal); 503 virtual void resetWidth(); 504 505 virtual qreal height() const; 506 virtual void setHeight(qreal); 507 virtual void resetHeight(); 430 508 431 509 QRectF childrenBoundingRect; … … 451 529 Qt::InputMethodHints imHints; 452 530 QGraphicsItem::PanelModality panelModality; 531 #ifndef QT_NO_GESTURES 453 532 QMap<Qt::GestureType, Qt::GestureFlags> gestureContext; 533 #endif 454 534 455 535 // Packed 32 bits … … 476 556 quint32 needSortChildren : 1; 477 557 quint32 allChildrenDirty : 1; 558 quint32 fullUpdatePending : 1; 559 quint32 dirtyChildrenBoundingRect : 1; 478 560 479 561 // Packed 32 bits 480 quint32 fullUpdatePending : 1; 481 quint32 flags : 17; 482 quint32 dirtyChildrenBoundingRect : 1; 562 quint32 flags : 18; 483 563 quint32 paintedViewBoundingRectsNeedRepaint : 1; 484 564 quint32 dirtySceneTransform : 1; … … 494 574 quint32 notifyBoundingRectChanged : 1; 495 575 quint32 notifyInvalidated : 1; 576 quint32 mouseSetsFocus : 1; 496 577 497 578 // New 32 bits 498 quint32 mouseSetsFocus : 1;499 579 quint32 explicitActivate : 1; 500 580 quint32 wantsActive : 1; … … 505 585 quint32 pendingPolish : 1; 506 586 quint32 mayHaveChildWithGraphicsEffect : 1; 587 quint32 isDeclarativeItem : 1; 588 quint32 sendParentChangeNotification : 1; 589 quint32 padding : 22; 507 590 508 591 // Optional stacking order … … 610 693 && !(item->flags() & QGraphicsItem::ItemIsSelectable) 611 694 && item->d_ptr->children.size() == 0; 612 //|| (item->d_ptr->isObject && qobject_cast<Q mlGraphicsImage *>(q_func()));695 //|| (item->d_ptr->isObject && qobject_cast<QDeclarativeImage *>(q_func())); 613 696 } 614 697 … … 640 723 /*! 641 724 Returns true if \a item1 is on top of \a item2. 642 The items don t need to be siblings.725 The items don't need to be siblings. 643 726 644 727 \internal … … 694 777 /*! 695 778 Returns true if \a item2 is on top of \a item1. 696 The items don t need to be siblings.779 The items don't need to be siblings. 697 780 698 781 \internal … … 789 872 if (parentp->graphicsEffect) { 790 873 if (updateBoundingRect) { 791 parentp->notifyInvalidated = 1;792 874 static_cast<QGraphicsItemEffectSourcePrivate *>(parentp->graphicsEffect->d_func() 793 875 ->source->d_func())->invalidateCache(); 876 parentp->notifyInvalidated = 1; 794 877 } 795 if (parentp-> graphicsEffect->isEnabled()) {878 if (parentp->scene && parentp->graphicsEffect->isEnabled()) { 796 879 parentp->dirty = 1; 797 880 parentp->fullUpdatePending = 1; -
trunk/src/gui/graphicsview/qgraphicsitemanimation.cpp
r651 r846 1 1 /**************************************************************************** 2 2 ** 3 ** Copyright (C) 201 0Nokia Corporation and/or its subsidiary(-ies).3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). 4 4 ** All rights reserved. 5 5 ** Contact: Nokia Corporation (qt-info@nokia.com) … … 78 78 rotations) at the same step is not recommended. 79 79 80 \sa QTimeLine, { TheGraphics View Framework}80 \sa QTimeLine, {Graphics View Framework} 81 81 */ 82 82 -
trunk/src/gui/graphicsview/qgraphicsitemanimation.h
r651 r846 1 1 /**************************************************************************** 2 2 ** 3 ** Copyright (C) 201 0Nokia Corporation and/or its subsidiary(-ies).3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). 4 4 ** All rights reserved. 5 5 ** Contact: Nokia Corporation (qt-info@nokia.com) -
trunk/src/gui/graphicsview/qgraphicslayout.cpp
r651 r846 1 1 /**************************************************************************** 2 2 ** 3 ** Copyright (C) 201 0Nokia Corporation and/or its subsidiary(-ies).3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). 4 4 ** All rights reserved. 5 5 ** Contact: Nokia Corporation (qt-info@nokia.com) … … 308 308 // does more than we need. 309 309 layoutItem->d_func()->sizeHintCacheDirty = true; 310 layoutItem = layoutItem->parentLayoutItem(); 311 } 312 if (layoutItem) 310 layoutItem->d_func()->sizeHintWithConstraintCacheDirty = true; 311 layoutItem = layoutItem->parentLayoutItem(); 312 } 313 if (layoutItem) { 313 314 layoutItem->d_func()->sizeHintCacheDirty = true; 315 layoutItem->d_func()->sizeHintWithConstraintCacheDirty = true; 316 } 314 317 315 318 bool postIt = layoutItem ? !layoutItem->isLayout() : false; -
trunk/src/gui/graphicsview/qgraphicslayout.h
r651 r846 1 1 /**************************************************************************** 2 2 ** 3 ** Copyright (C) 201 0Nokia Corporation and/or its subsidiary(-ies).3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). 4 4 ** All rights reserved. 5 5 ** Contact: Nokia Corporation (qt-info@nokia.com) -
trunk/src/gui/graphicsview/qgraphicslayout_p.cpp
r651 r846 1 1 /**************************************************************************** 2 2 ** 3 ** Copyright (C) 201 0Nokia Corporation and/or its subsidiary(-ies).3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). 4 4 ** All rights reserved. 5 5 ** Contact: Nokia Corporation (qt-info@nokia.com) -
trunk/src/gui/graphicsview/qgraphicslayout_p.h
r651 r846 1 1 /**************************************************************************** 2 2 ** 3 ** Copyright (C) 201 0Nokia Corporation and/or its subsidiary(-ies).3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). 4 4 ** All rights reserved. 5 5 ** Contact: Nokia Corporation (qt-info@nokia.com) -
trunk/src/gui/graphicsview/qgraphicslayoutitem.cpp
r651 r846 1 1 /**************************************************************************** 2 2 ** 3 ** Copyright (C) 201 0Nokia Corporation and/or its subsidiary(-ies).3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). 4 4 ** All rights reserved. 5 5 ** Contact: Nokia Corporation (qt-info@nokia.com) … … 49 49 #include "qgraphicslayoutitem_p.h" 50 50 #include "qwidget.h" 51 #include "qgraphicswidget.h" 51 52 52 53 #include <QtDebug> … … 128 129 { 129 130 sizeHintCacheDirty = true; 130 size Policy = QSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred);131 sizeHintWithConstraintCacheDirty = true; 131 132 } 132 133 … … 137 138 { 138 139 Q_Q(const QGraphicsLayoutItem); 139 if (!sizeHintCacheDirty && cachedConstraint == constraint) 140 return cachedSizeHints; 140 QSizeF *sizeHintCache; 141 const bool hasConstraint = constraint.width() >= 0 || constraint.height() >= 0; 142 if (hasConstraint) { 143 if (!sizeHintWithConstraintCacheDirty && constraint == cachedConstraint) 144 return cachedSizeHintsWithConstraints; 145 sizeHintCache = cachedSizeHintsWithConstraints; 146 } else { 147 if (!sizeHintCacheDirty) 148 return cachedSizeHints; 149 sizeHintCache = cachedSizeHints; 150 } 141 151 142 152 for (int i = 0; i < Qt::NSizeHints; ++i) { 143 cachedSizeHints[i] = constraint;153 sizeHintCache[i] = constraint; 144 154 if (userSizeHints) 145 combineSize( cachedSizeHints[i], userSizeHints[i]);155 combineSize(sizeHintCache[i], userSizeHints[i]); 146 156 } 147 157 148 QSizeF &minS = cachedSizeHints[Qt::MinimumSize];149 QSizeF &prefS = cachedSizeHints[Qt::PreferredSize];150 QSizeF &maxS = cachedSizeHints[Qt::MaximumSize];151 QSizeF &descentS = cachedSizeHints[Qt::MinimumDescent];158 QSizeF &minS = sizeHintCache[Qt::MinimumSize]; 159 QSizeF &prefS = sizeHintCache[Qt::PreferredSize]; 160 QSizeF &maxS = sizeHintCache[Qt::MaximumSize]; 161 QSizeF &descentS = sizeHintCache[Qt::MinimumDescent]; 152 162 153 163 normalizeHints(minS.rwidth(), prefS.rwidth(), maxS.rwidth(), descentS.rwidth()); … … 175 185 // COMBINE_SIZE(descentS, q->sizeHint(Qt::MinimumDescent, constraint)); 176 186 177 cachedConstraint = constraint; 178 sizeHintCacheDirty = false; 179 return cachedSizeHints; 187 if (hasConstraint) { 188 cachedConstraint = constraint; 189 sizeHintWithConstraintCacheDirty = false; 190 } else { 191 sizeHintCacheDirty = false; 192 } 193 return sizeHintCache; 180 194 } 181 195 … … 232 246 if (size == userSizeHints[which]) 233 247 return; 234 } else if ( !size.isValid()) {248 } else if (size.width() < 0 && size.height() < 0) { 235 249 return; 236 250 } … … 260 274 } 261 275 276 277 bool QGraphicsLayoutItemPrivate::hasHeightForWidth() const 278 { 279 Q_Q(const QGraphicsLayoutItem); 280 if (isLayout) { 281 const QGraphicsLayout *l = static_cast<const QGraphicsLayout *>(q); 282 for (int i = l->count() - 1; i >= 0; --i) { 283 if (QGraphicsLayoutItemPrivate::get(l->itemAt(i))->hasHeightForWidth()) 284 return true; 285 } 286 } else if (QGraphicsItem *item = q->graphicsItem()) { 287 if (item->isWidget()) { 288 QGraphicsWidget *w = static_cast<QGraphicsWidget *>(item); 289 if (w->layout()) { 290 return QGraphicsLayoutItemPrivate::get(w->layout())->hasHeightForWidth(); 291 } 292 } 293 } 294 return q->sizePolicy().hasHeightForWidth(); 295 } 296 297 bool QGraphicsLayoutItemPrivate::hasWidthForHeight() const 298 { 299 // enable this code when we add QSizePolicy::hasWidthForHeight() (For 4.8) 300 #if 1 301 return false; 302 #else 303 Q_Q(const QGraphicsLayoutItem); 304 if (isLayout) { 305 const QGraphicsLayout *l = static_cast<const QGraphicsLayout *>(q); 306 for (int i = l->count() - 1; i >= 0; --i) { 307 if (QGraphicsLayoutItemPrivate::get(l->itemAt(i))->hasWidthForHeight()) 308 return true; 309 } 310 } else if (QGraphicsItem *item = q->graphicsItem()) { 311 if (item->isWidget()) { 312 QGraphicsWidget *w = static_cast<QGraphicsWidget *>(item); 313 if (w->layout()) { 314 return QGraphicsLayoutItemPrivate::get(w->layout())->hasWidthForHeight(); 315 } 316 } 317 } 318 return q->sizePolicy().hasWidthForHeight(); 319 #endif 320 } 321 262 322 /*! 263 323 \class QGraphicsLayoutItem … … 323 383 324 384 Qt uses QGraphicsLayoutItem to provide layout functionality in the 325 \l{ TheGraphics View Framework}, but in the future its use may spread385 \l{Graphics View Framework}, but in the future its use may spread 326 386 throughout Qt itself. 327 387 … … 340 400 Q_D(QGraphicsLayoutItem); 341 401 d->init(); 402 d->sizePolicy = QSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred); 342 403 d->q_ptr = this; 343 404 } … … 350 411 { 351 412 Q_D(QGraphicsLayoutItem); 413 d->init(); 352 414 d->q_ptr = this; 353 415 } … … 769 831 Q_D(QGraphicsLayoutItem); 770 832 d->sizeHintCacheDirty = true; 833 d->sizeHintWithConstraintCacheDirty = true; 771 834 } 772 835 -
trunk/src/gui/graphicsview/qgraphicslayoutitem.h
r651 r846 1 1 /**************************************************************************** 2 2 ** 3 ** Copyright (C) 201 0Nokia Corporation and/or its subsidiary(-ies).3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). 4 4 ** All rights reserved. 5 5 ** Contact: Nokia Corporation (qt-info@nokia.com) -
trunk/src/gui/graphicsview/qgraphicslayoutitem_p.h
r651 r846 1 1 /**************************************************************************** 2 2 ** 3 ** Copyright (C) 201 0Nokia Corporation and/or its subsidiary(-ies).3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). 4 4 ** All rights reserved. 5 5 ** Contact: Nokia Corporation (qt-info@nokia.com) … … 66 66 virtual ~QGraphicsLayoutItemPrivate(); 67 67 QGraphicsLayoutItemPrivate(QGraphicsLayoutItem *parent, bool isLayout); 68 static QGraphicsLayoutItemPrivate *get(QGraphicsLayoutItem *q) { return q->d_func();} 69 static const QGraphicsLayoutItemPrivate *get(const QGraphicsLayoutItem *q) { return q->d_func();} 70 68 71 void init(); 69 72 QSizeF *effectiveSizeHints(const QSizeF &constraint) const; … … 74 77 void setSizeComponent(Qt::SizeHint which, SizeComponent component, qreal value); 75 78 79 bool hasHeightForWidth() const; 80 bool hasWidthForHeight() const; 81 76 82 QSizePolicy sizePolicy; 77 83 QGraphicsLayoutItem *parent; … … 80 86 mutable QSizeF cachedSizeHints[Qt::NSizeHints]; 81 87 mutable QSizeF cachedConstraint; 88 mutable QSizeF cachedSizeHintsWithConstraints[Qt::NSizeHints]; 82 89 83 90 mutable quint32 sizeHintCacheDirty : 1; 91 mutable quint32 sizeHintWithConstraintCacheDirty : 1; 84 92 quint32 isLayout : 1; 85 93 quint32 ownedByLayout : 1; -
trunk/src/gui/graphicsview/qgraphicslinearlayout.cpp
r651 r846 1 1 /**************************************************************************** 2 2 ** 3 ** Copyright (C) 201 0Nokia Corporation and/or its subsidiary(-ies).3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). 4 4 ** All rights reserved. 5 5 ** Contact: Nokia Corporation (qt-info@nokia.com) … … 76 76 an alignment for each item by calling setAlignment(), and check the 77 77 alignment for any item by calling alignment(). By default, items are 78 centered both vertically and horizontally.78 aligned to the top left. 79 79 80 80 \section1 Spacing within QGraphicsLinearLayout … … 148 148 int index = gridItem->firstRow(orientation); 149 149 engine.removeItem(gridItem); 150 engine.removeRow (index, orientation);150 engine.removeRows(index, 1, orientation); 151 151 } 152 152 … … 172 172 } 173 173 174 Q_GLOBAL_STATIC(QWidget, globalStyleInfoWidget) 175 174 176 QLayoutStyleInfo QGraphicsLinearLayoutPrivate::styleInfo() const 175 177 { 176 static QWidget *wid = 0;177 if (!wid)178 wid = new QWidget;179 178 QGraphicsItem *item = parentItem(); 180 179 QStyle *style = (item && item->isWidget()) ? static_cast<QGraphicsWidget*>(item)->style() : QApplication::style(); 181 return QLayoutStyleInfo(style, wid);180 return QLayoutStyleInfo(style, globalStyleInfoWidget()); 182 181 } 183 182 … … 277 276 return; 278 277 } 278 Q_ASSERT(item); 279 280 //the order of the following instructions is very important because 281 //invalidating the layout before adding the child item will make the layout happen 282 //before we try to paint the item 283 invalidate(); 279 284 d->addChildLayoutItem(item); 280 285 281 Q_ASSERT(item);282 286 d->fixIndex(&index); 283 287 d->engine.insertRow(index, d->orientation); 284 288 new QGridLayoutItem(&d->engine, item, d->gridRow(index), d->gridColumn(index), 1, 1, 0, index); 285 invalidate();286 289 } 287 290 … … 444 447 /*! 445 448 Returns the alignment for \a item. The default alignment is 446 Qt::Align Center.449 Qt::AlignTop | Qt::AlignLeft. 447 450 448 451 The alignment decides how the item is positioned within its assigned space … … 530 533 qreal left, top, right, bottom; 531 534 getContentsMargins(&left, &top, &right, &bottom); 532 return d->engine.sizeHint(d->styleInfo(), which , constraint) + QSizeF(left + right, top + bottom); 535 const QSizeF extraMargins(left + right, top + bottom); 536 return d->engine.sizeHint(d->styleInfo(), which , constraint - extraMargins) + extraMargins; 533 537 } 534 538 … … 555 559 d->engine.dump(indent + 1); 556 560 } 561 #else 562 Q_UNUSED(indent); 557 563 #endif 558 564 } -
trunk/src/gui/graphicsview/qgraphicslinearlayout.h
r651 r846 1 1 /**************************************************************************** 2 2 ** 3 ** Copyright (C) 201 0Nokia Corporation and/or its subsidiary(-ies).3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). 4 4 ** All rights reserved. 5 5 ** Contact: Nokia Corporation (qt-info@nokia.com) -
trunk/src/gui/graphicsview/qgraphicsproxywidget.cpp
r769 r846 1 1 /**************************************************************************** 2 2 ** 3 ** Copyright (C) 201 0Nokia Corporation and/or its subsidiary(-ies).3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). 4 4 ** All rights reserved. 5 5 ** Contact: Nokia Corporation (qt-info@nokia.com) … … 976 976 } 977 977 break; 978 #ifndef QT_NO_TOOLTIP 978 979 case QEvent::ToolTipChange: 979 980 // Propagate tooltip change to the proxy. … … 984 985 } 985 986 break; 987 #endif 986 988 default: 987 989 break; … … 1025 1027 pos = d->mapToReceiver(pos, receiver); 1026 1028 1029 QPoint globalPos = receiver->mapToGlobal(pos.toPoint()); 1030 //If the receiver by-pass the proxy its popups 1031 //will be top level QWidgets therefore they need 1032 //the screen position. mapToGlobal expect the widget to 1033 //have proper coordinates in regards of the windowing system 1034 //but it's not true because the widget is embedded. 1035 if (bypassGraphicsProxyWidget(receiver)) 1036 globalPos = event->screenPos(); 1037 1027 1038 // Send mouse event. ### Doesn't propagate the event. 1028 1039 QContextMenuEvent contextMenuEvent(QContextMenuEvent::Reason(event->reason()), 1029 pos.toPoint(), receiver->mapToGlobal(pos.toPoint()), event->modifiers());1040 pos.toPoint(), globalPos, event->modifiers()); 1030 1041 QApplication::sendEvent(receiver, &contextMenuEvent); 1031 1042 … … 1498 1509 contained in this proxy. 1499 1510 1500 This function makes it possible to a quire proxies for1511 This function makes it possible to acquire proxies for 1501 1512 non top-level widgets. For instance, you can embed a dialog, 1502 1513 and then transform only one of its widgets. -
trunk/src/gui/graphicsview/qgraphicsproxywidget.h
r651 r846 1 1 /**************************************************************************** 2 2 ** 3 ** Copyright (C) 201 0Nokia Corporation and/or its subsidiary(-ies).3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). 4 4 ** All rights reserved. 5 5 ** Contact: Nokia Corporation (qt-info@nokia.com) -
trunk/src/gui/graphicsview/qgraphicsproxywidget_p.h
r769 r846 1 1 /**************************************************************************** 2 2 ** 3 ** Copyright (C) 201 0Nokia Corporation and/or its subsidiary(-ies).3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). 4 4 ** All rights reserved. 5 5 ** Contact: Nokia Corporation (qt-info@nokia.com) -
trunk/src/gui/graphicsview/qgraphicsscene.cpp
r769 r846 1 1 /**************************************************************************** 2 2 ** 3 ** Copyright (C) 201 0Nokia Corporation and/or its subsidiary(-ies).3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). 4 4 ** All rights reserved. 5 5 ** Contact: Nokia Corporation (qt-info@nokia.com) … … 51 51 with QGraphicsView for visualizing graphical items, such as lines, 52 52 rectangles, text, or even custom items, on a 2D surface. QGraphicsScene is 53 part of \l{TheGraphics View Framework}.53 part of the \l{Graphics View Framework}. 54 54 55 55 QGraphicsScene also provides functionality that lets you efficiently … … 229 229 #include <QtCore/qtimer.h> 230 230 #include <QtCore/qvarlengtharray.h> 231 #include <QtCore/QMetaMethod> 231 232 #include <QtGui/qapplication.h> 232 233 #include <QtGui/qdesktopwidget.h> … … 278 279 } 279 280 280 int QGraphicsScenePrivate::changedSignalIndex;281 282 281 /*! 283 282 \internal … … 292 291 calledEmitUpdated(false), 293 292 processDirtyItemsEmitted(false), 294 selectionChanging(0),295 293 needSortTopLevelItems(true), 296 294 holesInTopLevelSiblingIndex(false), … … 299 297 stickyFocus(false), 300 298 hasFocus(false), 299 lastMouseGrabberItemHasImplicitMouseGrab(false), 300 allItemsIgnoreHoverEvents(true), 301 allItemsUseDefaultCursor(true), 302 painterStateProtection(true), 303 sortCacheEnabled(false), 304 allItemsIgnoreTouchEvents(true), 305 selectionChanging(0), 306 rectAdjust(2), 301 307 focusItem(0), 302 308 lastFocusItem(0), … … 307 313 childExplicitActivation(0), 308 314 lastMouseGrabberItem(0), 309 lastMouseGrabberItemHasImplicitMouseGrab(false),310 315 dragDropItem(0), 311 316 enterWidget(0), 312 317 lastDropAction(Qt::IgnoreAction), 313 allItemsIgnoreHoverEvents(true), 314 allItemsUseDefaultCursor(true), 315 painterStateProtection(true), 316 sortCacheEnabled(false), 317 style(0), 318 allItemsIgnoreTouchEvents(true) 318 style(0) 319 319 { 320 320 } … … 330 330 331 331 // Keep this index so we can check for connected slots later on. 332 if (!changedSignalIndex) { 333 changedSignalIndex = signalIndex("changed(QList<QRectF>)"); 334 } 332 changedSignalIndex = signalIndex("changed(QList<QRectF>)"); 333 processDirtyItemsIndex = q->metaObject()->indexOfSlot("_q_processDirtyItems()"); 334 polishItemsIndex = q->metaObject()->indexOfSlot("_q_polishItems()"); 335 335 336 qApp->d_func()->scene_list.append(q); 336 337 q->update(); … … 690 691 lastMouseGrabberItem = 0; 691 692 693 // Reset the current drop item 694 if (item == dragDropItem) 695 dragDropItem = 0; 696 692 697 // Reenable selectionChanged() for individual items 693 698 --selectionChanging; … … 695 700 emit q->selectionChanged(); 696 701 702 #ifndef QT_NO_GESTURES 697 703 QHash<QGesture *, QGraphicsObject *>::iterator it; 698 704 for (it = gestureTargets.begin(); it != gestureTargets.end();) { … … 702 708 ++it; 703 709 } 710 711 QGraphicsObject *dummy = static_cast<QGraphicsObject *>(item); 712 cachedTargetItems.removeOne(dummy); 713 cachedItemGestures.remove(dummy); 714 cachedAlreadyDeliveredGestures.remove(dummy); 715 716 foreach (Qt::GestureType gesture, item->d_ptr->gestureContext.keys()) 717 ungrabGesture(item, gesture); 718 #endif // QT_NO_GESTURES 704 719 } 705 720 … … 816 831 #endif //QT_NO_IM 817 832 } 833 834 // This handles the case that the item has been removed from the 835 // scene in response to the FocusOut event. 836 if (item && item->scene() != q) 837 item = 0; 818 838 819 839 if (item) … … 871 891 } 872 892 if (!itemIsDying && widget->isVisible()) { 873 widget->hide(); 874 widget->QGraphicsItem::d_ptr->explicitlyHidden = 0; 893 widget->QGraphicsItem::d_ptr->setVisibleHelper(false, /* explicit = */ false); 875 894 } 876 895 } … … 1056 1075 Returns all items for the screen position in \a event. 1057 1076 */ 1058 QList<QGraphicsItem *> QGraphicsScenePrivate::itemsAtPosition(const QPoint & screenPos,1077 QList<QGraphicsItem *> QGraphicsScenePrivate::itemsAtPosition(const QPoint &/*screenPos*/, 1059 1078 const QPointF &scenePos, 1060 1079 QWidget *widget) const … … 1065 1084 return q->items(scenePos, Qt::IntersectsItemShape, Qt::DescendingOrder, QTransform()); 1066 1085 1067 const QRectF pointRect( QPointF(widget->mapFromGlobal(screenPos)), QSizeF(1, 1));1086 const QRectF pointRect(scenePos, QSizeF(1, 1)); 1068 1087 if (!view->isTransformed()) 1069 1088 return q->items(pointRect, Qt::IntersectsItemShape, Qt::DescendingOrder); 1070 1089 1071 1090 const QTransform viewTransform = view->viewportTransform(); 1072 if (viewTransform.type() <= QTransform::TxScale) { 1073 return q->items(viewTransform.inverted().mapRect(pointRect), Qt::IntersectsItemShape, 1074 Qt::DescendingOrder, viewTransform); 1075 } 1076 return q->items(viewTransform.inverted().map(pointRect), Qt::IntersectsItemShape, 1091 return q->items(pointRect, Qt::IntersectsItemShape, 1077 1092 Qt::DescendingOrder, viewTransform); 1078 1093 } … … 1169 1184 { 1170 1185 if (QGraphicsObject *object = item->toGraphicsObject()) { 1186 #ifndef QT_NO_GESTURES 1171 1187 QGestureManager *gestureManager = QApplicationPrivate::instance()->gestureManager; 1172 1188 if (gestureManager) { … … 1174 1190 return true; 1175 1191 } 1192 #endif // QT_NO_GESTURES 1176 1193 } 1177 1194 … … 1312 1329 break; 1313 1330 } 1314 if (item->isEnabled() && ((item->flags() & QGraphicsItem::ItemIsFocusable) && item->d_ptr->mouseSetsFocus)) {1331 if (item->isEnabled() && ((item->flags() & QGraphicsItem::ItemIsFocusable))) { 1315 1332 if (!item->isWidget() || ((QGraphicsWidget *)item)->focusPolicy() & Qt::ClickFocus) { 1316 1333 setFocus = true; 1317 if (item != q->focusItem() )1334 if (item != q->focusItem() && item->d_ptr->mouseSetsFocus) 1318 1335 q->setFocusItem(item, Qt::MouseFocusReason); 1319 1336 break; 1320 1337 } 1321 1338 } 1339 if (item->d_ptr->flags & QGraphicsItem::ItemStopsClickFocusPropagation) 1340 break; 1322 1341 if (item->isPanel()) 1323 1342 break; … … 1741 1760 1742 1761 // Transform the painter. 1743 painter->setClipRect(targetRect );1762 painter->setClipRect(targetRect, Qt::IntersectClip); 1744 1763 QTransform painterTransform; 1745 1764 painterTransform *= QTransform() … … 2534 2553 } 2535 2554 2536 if (d->unpolishedItems.isEmpty()) 2537 QMetaObject::invokeMethod(this, "_q_polishItems", Qt::QueuedConnection); 2538 d->unpolishedItems.append(item); 2539 item->d_ptr->pendingPolish = true; 2555 // QDeclarativeItems do not rely on initial itemChanged message, as the componentComplete 2556 // function allows far more opportunity for delayed-construction optimization. 2557 if (!item->d_ptr->isDeclarativeItem) { 2558 if (d->unpolishedItems.isEmpty()) { 2559 QMetaMethod method = metaObject()->method(d->polishItemsIndex); 2560 method.invoke(this, Qt::QueuedConnection); 2561 } 2562 d->unpolishedItems.append(item); 2563 item->d_ptr->pendingPolish = true; 2564 } 2540 2565 2541 2566 // Detach this item from its parent if the parent's scene is different … … 2584 2609 d->enableTouchEventsOnViews(); 2585 2610 } 2611 2612 #ifndef QT_NO_GESTURES 2613 foreach (Qt::GestureType gesture, item->d_ptr->gestureContext.keys()) 2614 d->grabGesture(item, gesture); 2615 #endif 2586 2616 2587 2617 // Update selection lists … … 3212 3242 for (int i = 0; i < d->views.size(); ++i) { 3213 3243 QGraphicsView *view = d->views.at(i); 3214 view->d_func()->updateRegion(QRegion(view->mapFromScene(rect).boundingRect())); 3244 if (view->isTransformed()) 3245 view->d_func()->updateRectF(view->viewportTransform().mapRect(rect)); 3246 else 3247 view->d_func()->updateRectF(rect); 3215 3248 } 3216 3249 } else { … … 3502 3535 d->touchEventHandler(static_cast<QTouchEvent *>(event)); 3503 3536 break; 3537 #ifndef QT_NO_GESTURES 3504 3538 case QEvent::Gesture: 3505 3539 case QEvent::GestureOverride: 3506 3540 d->gestureEventHandler(static_cast<QGestureEvent *>(event)); 3507 3541 break; 3542 #endif // QT_NO_GESTURES 3508 3543 default: 3509 3544 return QObject::event(event); … … 4131 4166 wheelEvent->widget()); 4132 4167 4168 #ifdef Q_WS_MAC 4169 // On Mac, ignore the event if the first item under the mouse is not the last opened 4170 // popup (or one of its descendant) 4171 if (!d->popupWidgets.isEmpty() && !wheelCandidates.isEmpty() && wheelCandidates.first() != d->popupWidgets.back() && !d->popupWidgets.back()->isAncestorOf(wheelCandidates.first())) { 4172 wheelEvent->accept(); 4173 return; 4174 } 4175 #else 4176 // Find the first popup under the mouse (including the popup's descendants) starting from the last. 4177 // Remove all popups after the one found, or all or them if no popup is under the mouse. 4178 // Then continue with the event. 4179 QList<QGraphicsWidget *>::const_iterator iter = d->popupWidgets.end(); 4180 while (--iter >= d->popupWidgets.begin() && !wheelCandidates.isEmpty()) { 4181 if (wheelCandidates.first() == *iter || (*iter)->isAncestorOf(wheelCandidates.first())) 4182 break; 4183 d->removePopup(*iter); 4184 } 4185 #endif 4186 4133 4187 bool hasSetFocus = false; 4134 4188 foreach (QGraphicsItem *item, wheelCandidates) { … … 4254 4308 if (painterStateProtection) 4255 4309 painter->restore(); 4310 } else if (widgetItem->autoFillBackground()) { 4311 painter->fillRect(option->exposedRect, widgetItem->palette().window()); 4256 4312 } 4257 4313 … … 4307 4363 } 4308 4364 4365 // Copied from qpaintengine_vg.cpp 4366 // Returns true for 90, 180, and 270 degree rotations. 4367 static inline bool transformIsSimple(const QTransform& transform) 4368 { 4369 QTransform::TransformationType type = transform.type(); 4370 if (type == QTransform::TxNone || type == QTransform::TxTranslate) { 4371 return true; 4372 } else if (type == QTransform::TxScale) { 4373 // Check for 0 and 180 degree rotations. 4374 // (0 might happen after 4 rotations of 90 degrees). 4375 qreal m11 = transform.m11(); 4376 qreal m12 = transform.m12(); 4377 qreal m21 = transform.m21(); 4378 qreal m22 = transform.m22(); 4379 if (m12 == 0.0f && m21 == 0.0f) { 4380 if (m11 == 1.0f && m22 == 1.0f) 4381 return true; // 0 degrees 4382 else if (m11 == -1.0f && m22 == -1.0f) 4383 return true; // 180 degrees. 4384 if(m11 == 1.0f && m22 == -1.0f) 4385 return true; // 0 degrees inverted y. 4386 else if(m11 == -1.0f && m22 == 1.0f) 4387 return true; // 180 degrees inverted y. 4388 } 4389 } else if (type == QTransform::TxRotate) { 4390 // Check for 90, and 270 degree rotations. 4391 qreal m11 = transform.m11(); 4392 qreal m12 = transform.m12(); 4393 qreal m21 = transform.m21(); 4394 qreal m22 = transform.m22(); 4395 if (m11 == 0.0f && m22 == 0.0f) { 4396 if (m12 == 1.0f && m21 == -1.0f) 4397 return true; // 90 degrees. 4398 else if (m12 == -1.0f && m21 == 1.0f) 4399 return true; // 270 degrees. 4400 else if (m12 == -1.0f && m21 == -1.0f) 4401 return true; // 90 degrees inverted y. 4402 else if (m12 == 1.0f && m21 == 1.0f) 4403 return true; // 270 degrees inverted y. 4404 } 4405 } 4406 return false; 4407 } 4408 4309 4409 /*! 4310 4410 \internal … … 4351 4451 QGraphicsItemCache *itemCache = itemd->extraItemCache(); 4352 4452 if (cacheMode == QGraphicsItem::ItemCoordinateCache) { 4353 if (itemCache->boundingRect != brect.toRect()) {4354 itemCache->boundingRect = brect.toRect();4355 itemCache->allExposed = true;4356 itemCache->exposed.clear();4357 }4358 4453 pixmapKey = itemCache->key; 4359 4454 } else { … … 4368 4463 QSize pixmapSize; 4369 4464 bool fixedCacheSize = false; 4370 QRect F brectAligned= brect.toAlignedRect();4465 QRect br = brect.toAlignedRect(); 4371 4466 if ((fixedCacheSize = itemCache->fixedSize.isValid())) { 4372 4467 pixmapSize = itemCache->fixedSize; 4373 4468 } else { 4374 pixmapSize = br ectAligned.size().toSize();4469 pixmapSize = br.size(); 4375 4470 } 4376 4471 … … 4378 4473 int adjust = itemCache->fixedSize.isValid() ? 0 : 2; 4379 4474 QSize adjustSize(adjust*2, adjust*2); 4380 QRectF br = brectAligned.adjusted(-adjust, -adjust, adjust, adjust);4475 br.adjust(-adjust, -adjust, adjust, adjust); 4381 4476 if (pix.isNull() || (!fixedCacheSize && (pixmapSize + adjustSize) != pix.size())) { 4382 4477 pix = QPixmap(pixmapSize + adjustSize); 4478 itemCache->boundingRect = br; 4479 itemCache->exposed.clear(); 4480 itemCache->allExposed = true; 4481 } else if (itemCache->boundingRect != br) { 4482 itemCache->boundingRect = br; 4383 4483 itemCache->exposed.clear(); 4384 4484 itemCache->allExposed = true; … … 4434 4534 if (newPainterOpacity != oldPainterOpacity) { 4435 4535 painter->setOpacity(newPainterOpacity); 4436 painter->drawPixmap(br , pix, QRectF(QPointF(), pix.size()));4536 painter->drawPixmap(br.topLeft(), pix); 4437 4537 painter->setOpacity(oldPainterOpacity); 4438 4538 } else { 4439 painter->drawPixmap(br , pix, QRectF(QPointF(), pix.size()));4539 painter->drawPixmap(br.topLeft(), pix); 4440 4540 } 4441 4541 return; … … 4475 4575 diff *= painter->worldTransform(); 4476 4576 deviceData->lastTransform = painter->worldTransform(); 4477 if (!invertable 4478 || diff.type() > QTransform::TxTranslate 4479 || painter->worldTransform().type() > QTransform::TxScale) { 4577 bool allowPartialCacheExposure = false; 4578 bool simpleTransform = invertable && diff.type() <= QTransform::TxTranslate 4579 && transformIsSimple(painter->worldTransform()); 4580 if (!simpleTransform) { 4480 4581 pixModified = true; 4481 4582 itemCache->allExposed = true; 4482 4583 itemCache->exposed.clear(); 4584 deviceData->cacheIndent = QPoint(); 4483 4585 pix = QPixmap(); 4484 } 4485 4486 // ### This is a pretty bad way to determine when to start partial 4487 // exposure for DeviceCoordinateCache but it's the least intrusive 4488 // approach for now. 4489 #if 0 4490 // Only if the device rect isn't fully contained. 4491 bool allowPartialCacheExposure = !viewRect.contains(deviceRect); 4492 #else 4493 // Only if deviceRect is 20% taller or wider than the desktop. 4494 bool allowPartialCacheExposure = false; 4495 if (widget) { 4496 QRect desktopRect = QApplication::desktop()->availableGeometry(widget); 4497 allowPartialCacheExposure = (desktopRect.width() * 1.2 < deviceRect.width() 4498 || desktopRect.height() * 1.2 < deviceRect.height()); 4499 } 4500 #endif 4586 } else if (!viewRect.isNull()) { 4587 allowPartialCacheExposure = deviceData->cacheIndent != QPoint(); 4588 } 4589 4590 // Allow partial cache exposure if the device rect isn't fully contained and 4591 // deviceRect is 20% taller or wider than the viewRect. 4592 if (!allowPartialCacheExposure && !viewRect.isNull() && !viewRect.contains(deviceRect)) { 4593 allowPartialCacheExposure = (viewRect.width() * 1.2 < deviceRect.width()) 4594 || (viewRect.height() * 1.2 < deviceRect.height()); 4595 } 4596 4501 4597 QRegion scrollExposure; 4502 if ( deviceData->cacheIndent != QPoint() ||allowPartialCacheExposure) {4598 if (allowPartialCacheExposure) { 4503 4599 // Part of pixmap is drawn. Either device contains viewrect (big 4504 4600 // item covers whole screen) or parts of device are outside the … … 4694 4790 const QRectF brect = adjustedItemEffectiveBoundingRect(item); 4695 4791 ENSURE_TRANSFORM_PTR 4696 QRect viewBoundingRect = translateOnlyTransform ? brect.translated(transformPtr->dx(), transformPtr->dy()).toRect() 4697 : transformPtr->mapRect(brect).toRect(); 4792 QRect viewBoundingRect = translateOnlyTransform ? brect.translated(transformPtr->dx(), transformPtr->dy()).toAlignedRect() 4793 : transformPtr->mapRect(brect).toAlignedRect(); 4794 viewBoundingRect.adjust(-int(rectAdjust), -int(rectAdjust), rectAdjust, rectAdjust); 4698 4795 if (widget) 4699 4796 item->d_ptr->paintedViewBoundingRects.insert(widget, viewBoundingRect); 4700 viewBoundingRect.adjust(-1, -1, 1, 1);4701 4797 drawItem = exposedRegion ? exposedRegion->intersects(viewBoundingRect) 4702 4798 : !viewBoundingRect.normalized().isEmpty(); … … 4719 4815 ENSURE_TRANSFORM_PTR; 4720 4816 QGraphicsItemPaintInfo info(viewTransform, transformPtr, effectTransform, exposedRegion, widget, &styleOptionTmp, 4721 painter, opacity, wasDirtyParentSceneTransform, drawItem);4817 painter, opacity, wasDirtyParentSceneTransform, itemHasContents && !itemIsFullyTransparent); 4722 4818 QGraphicsEffectSource *source = item->d_ptr->graphicsEffect->d_func()->source; 4723 4819 QGraphicsItemEffectSourcePrivate *sourced = static_cast<QGraphicsItemEffectSourcePrivate *> … … 4759 4855 } 4760 4856 4857 static inline void setClip(QPainter *painter, QGraphicsItem *item) 4858 { 4859 painter->save(); 4860 QRectF clipRect; 4861 const QPainterPath clipPath(item->shape()); 4862 if (QPathClipper::pathToRect(clipPath, &clipRect)) 4863 painter->setClipRect(clipRect, Qt::IntersectClip); 4864 else 4865 painter->setClipPath(clipPath, Qt::IntersectClip); 4866 } 4867 4868 static inline void setWorldTransform(QPainter *painter, const QTransform *const transformPtr, 4869 const QTransform *effectTransform) 4870 { 4871 Q_ASSERT(transformPtr); 4872 if (effectTransform) 4873 painter->setWorldTransform(*transformPtr * *effectTransform); 4874 else 4875 painter->setWorldTransform(*transformPtr); 4876 } 4877 4761 4878 void QGraphicsScenePrivate::draw(QGraphicsItem *item, QPainter *painter, const QTransform *const viewTransform, 4762 4879 const QTransform *const transformPtr, QRegion *exposedRegion, QWidget *widget, … … 4767 4884 const bool itemClipsChildrenToShape = (item->d_ptr->flags & QGraphicsItem::ItemClipsChildrenToShape); 4768 4885 const bool itemHasChildren = !item->d_ptr->children.isEmpty(); 4886 bool setChildClip = itemClipsChildrenToShape; 4887 bool itemHasChildrenStackedBehind = false; 4769 4888 4770 4889 int i = 0; 4771 4890 if (itemHasChildren) { 4891 if (itemClipsChildrenToShape) 4892 setWorldTransform(painter, transformPtr, effectTransform); 4893 4772 4894 item->d_ptr->ensureSortedChildren(); 4773 4774 if (itemClipsChildrenToShape) { 4775 painter->save(); 4776 Q_ASSERT(transformPtr); 4777 if (effectTransform) 4778 painter->setWorldTransform(*transformPtr * *effectTransform); 4779 else 4780 painter->setWorldTransform(*transformPtr); 4781 QRectF clipRect; 4782 const QPainterPath clipPath(item->shape()); 4783 if (QPathClipper::pathToRect(clipPath, &clipRect)) 4784 painter->setClipRect(clipRect, Qt::IntersectClip); 4785 else 4786 painter->setClipPath(clipPath, Qt::IntersectClip); 4787 } 4788 4789 // Draw children behind 4790 for (i = 0; i < item->d_ptr->children.size(); ++i) { 4791 QGraphicsItem *child = item->d_ptr->children.at(i); 4792 if (wasDirtyParentSceneTransform) 4793 child->d_ptr->dirtySceneTransform = 1; 4794 if (!(child->d_ptr->flags & QGraphicsItem::ItemStacksBehindParent)) 4795 break; 4796 if (itemIsFullyTransparent && !(child->d_ptr->flags & QGraphicsItem::ItemIgnoresParentOpacity)) 4797 continue; 4798 drawSubtreeRecursive(child, painter, viewTransform, exposedRegion, widget, opacity, effectTransform); 4895 // Items with the 'ItemStacksBehindParent' flag are put in front of the list 4896 // so all we have to do is to check the first item. 4897 itemHasChildrenStackedBehind = (item->d_ptr->children.at(0)->d_ptr->flags 4898 & QGraphicsItem::ItemStacksBehindParent); 4899 4900 if (itemHasChildrenStackedBehind) { 4901 if (itemClipsChildrenToShape) { 4902 setClip(painter, item); 4903 setChildClip = false; 4904 } 4905 4906 // Draw children behind 4907 for (i = 0; i < item->d_ptr->children.size(); ++i) { 4908 QGraphicsItem *child = item->d_ptr->children.at(i); 4909 if (wasDirtyParentSceneTransform) 4910 child->d_ptr->dirtySceneTransform = 1; 4911 if (!(child->d_ptr->flags & QGraphicsItem::ItemStacksBehindParent)) 4912 break; 4913 if (itemIsFullyTransparent && !(child->d_ptr->flags & QGraphicsItem::ItemIgnoresParentOpacity)) 4914 continue; 4915 drawSubtreeRecursive(child, painter, viewTransform, exposedRegion, widget, opacity, effectTransform); 4916 } 4799 4917 } 4800 4918 } … … 4809 4927 4810 4928 const bool itemClipsToShape = item->d_ptr->flags & QGraphicsItem::ItemClipsToShape; 4811 const bool savePainter = itemClipsToShape || painterStateProtection; 4812 if (savePainter) 4929 bool restorePainterClip = false; 4930 4931 if (!itemHasChildren || !itemClipsChildrenToShape) { 4932 // Item does not have children or clip children to shape. 4933 setWorldTransform(painter, transformPtr, effectTransform); 4934 if ((restorePainterClip = itemClipsToShape)) 4935 setClip(painter, item); 4936 } else if (itemHasChildrenStackedBehind){ 4937 // Item clips children to shape and has children stacked behind, which means 4938 // the painter is already clipped to the item's shape. 4939 if (itemClipsToShape) { 4940 // The clip is already correct. Ensure correct world transform. 4941 setWorldTransform(painter, transformPtr, effectTransform); 4942 } else { 4943 // Remove clip (this also ensures correct world transform). 4944 painter->restore(); 4945 setChildClip = true; 4946 } 4947 } else if (itemClipsToShape) { 4948 // Item clips children and itself to shape. It does not have hildren stacked 4949 // behind, which means the clip has not yet been set. We set it now and re-use it 4950 // for the children. 4951 setClip(painter, item); 4952 setChildClip = false; 4953 } 4954 4955 if (painterStateProtection && !restorePainterClip) 4813 4956 painter->save(); 4814 4957 4815 if (!itemHasChildren || !itemClipsChildrenToShape) {4816 if (effectTransform)4817 painter->setWorldTransform(*transformPtr * *effectTransform);4818 else4819 painter->setWorldTransform(*transformPtr);4820 }4821 4822 if (itemClipsToShape) {4823 QRectF clipRect;4824 const QPainterPath clipPath(item->shape());4825 if (QPathClipper::pathToRect(clipPath, &clipRect))4826 painter->setClipRect(clipRect, Qt::IntersectClip);4827 else4828 painter->setClipPath(clipPath, Qt::IntersectClip);4829 }4830 4958 painter->setOpacity(opacity); 4831 4832 4959 if (!item->d_ptr->cacheMode && !item->d_ptr->isWidget) 4833 4960 item->paint(painter, &styleOptionTmp, widget); … … 4835 4962 drawItemHelper(item, painter, &styleOptionTmp, widget, painterStateProtection); 4836 4963 4837 if ( savePainter)4964 if (painterStateProtection || restorePainterClip) 4838 4965 painter->restore(); 4839 4966 } … … 4841 4968 // Draw children in front 4842 4969 if (itemHasChildren) { 4970 if (setChildClip) 4971 setClip(painter, item); 4972 4843 4973 for (; i < item->d_ptr->children.size(); ++i) { 4844 4974 QGraphicsItem *child = item->d_ptr->children.at(i); … … 4849 4979 drawSubtreeRecursive(child, painter, viewTransform, exposedRegion, widget, opacity, effectTransform); 4850 4980 } 4851 } 4852 4853 // Restore child clip4854 if (itemHasChildren && itemClipsChildrenToShape)4855 painter->restore();4981 4982 // Restore child clip 4983 if (itemClipsChildrenToShape) 4984 painter->restore(); 4985 } 4856 4986 } 4857 4987 … … 4863 4993 if (updateAll) 4864 4994 return; 4995 4996 if (removingItemFromScene && !ignoreOpacity && !item->d_ptr->ignoreOpacity) { 4997 // If any of the item's ancestors ignore opacity, it means that the opacity 4998 // was set to 0 (and the update request has not yet been processed). That 4999 // also means that we have to ignore the opacity for the item itself; otherwise 5000 // things like: parent->setOpacity(0); scene->removeItem(child) won't work. 5001 // Note that we only do this when removing items from the scene. In all other 5002 // cases the ignoreOpacity bit propagates properly in processDirtyItems, but 5003 // since the item is removed immediately it won't be processed there. 5004 QGraphicsItem *p = item->d_ptr->parent; 5005 while (p) { 5006 if (p->d_ptr->ignoreOpacity) { 5007 item->d_ptr->ignoreOpacity = true; 5008 break; 5009 } 5010 p = p->d_ptr->parent; 5011 } 5012 } 4865 5013 4866 5014 if (item->d_ptr->discardUpdateRequest(/*ignoreVisibleBit=*/force, … … 4885 5033 4886 5034 if (!processDirtyItemsEmitted) { 4887 QMetaObject::invokeMethod(q_ptr, "_q_processDirtyItems", Qt::QueuedConnection); 5035 QMetaMethod method = q_ptr->metaObject()->method(processDirtyItemsIndex); 5036 method.invoke(q_ptr, Qt::QueuedConnection); 5037 // QMetaObject::invokeMethod(q_ptr, "_q_processDirtyItems", Qt::QueuedConnection); 4888 5038 processDirtyItemsEmitted = true; 4889 5039 } … … 4909 5059 } 4910 5060 4911 bool hasNoContents = item->d_ptr->flags & QGraphicsItem::ItemHasNoContents 4912 && !item->d_ptr->graphicsEffect; 5061 bool hasNoContents = item->d_ptr->flags & QGraphicsItem::ItemHasNoContents; 4913 5062 if (!hasNoContents) { 4914 5063 item->d_ptr->dirty = 1; … … 4917 5066 else if (!item->d_ptr->fullUpdatePending) 4918 5067 item->d_ptr->needsRepaint |= rect; 5068 } else if (item->d_ptr->graphicsEffect) { 5069 invalidateChildren = true; 4919 5070 } 4920 5071 … … 4945 5096 const QTransform xform = itemq->deviceTransform(viewq->viewportTransform()); 4946 5097 if (!item->hasBoundingRegionGranularity) 4947 return view->updateRect (xform.mapRect(rect).toRect());4948 return view->updateRegion( xform.map(QRegion(rect.toRect())));5098 return view->updateRectF(xform.mapRect(rect)); 5099 return view->updateRegion(rect, xform); 4949 5100 } 4950 5101 … … 4952 5103 const qreal dx = item->sceneTransform.dx(); 4953 5104 const qreal dy = item->sceneTransform.dy(); 4954 if (!item->hasBoundingRegionGranularity) { 4955 QRectF r(rect); 4956 r.translate(dx - view->horizontalScroll(), dy - view->verticalScroll()); 4957 return view->updateRect(r.toRect()); 4958 } 4959 QRegion r(rect.toRect()); 4960 r.translate(qRound(dx) - view->horizontalScroll(), qRound(dy) - view->verticalScroll()); 4961 return view->updateRegion(r); 5105 QRectF r(rect); 5106 r.translate(dx - view->horizontalScroll(), dy - view->verticalScroll()); 5107 return view->updateRectF(r); 4962 5108 } 4963 5109 4964 5110 if (!viewq->isTransformed()) { 4965 5111 if (!item->hasBoundingRegionGranularity) 4966 return view->updateRect (item->sceneTransform.mapRect(rect).toRect());4967 return view->updateRegion( item->sceneTransform.map(QRegion(rect.toRect())));5112 return view->updateRectF(item->sceneTransform.mapRect(rect)); 5113 return view->updateRegion(rect, item->sceneTransform); 4968 5114 } 4969 5115 … … 4971 5117 xform *= viewq->viewportTransform(); 4972 5118 if (!item->hasBoundingRegionGranularity) 4973 return view->updateRect (xform.mapRect(rect).toRect());4974 return view->updateRegion( xform.map(QRegion(rect.toRect())));5119 return view->updateRectF(xform.mapRect(rect)); 5120 return view->updateRegion(rect, xform); 4975 5121 } 4976 5122 … … 5052 5198 item->d_ptr->sceneTransform.dy())); 5053 5199 } else { 5054 q->update(item->d_ptr->sceneTransform.mapRect(itemBoundingRect)); 5200 QRectF rect = item->d_ptr->sceneTransform.mapRect(itemBoundingRect); 5201 if (!rect.isEmpty()) 5202 q->update(rect); 5055 5203 } 5056 5204 } else { … … 5108 5256 // Process children. 5109 5257 if (itemHasChildren && item->d_ptr->dirtyChildren) { 5258 const bool itemClipsChildrenToShape = item->d_ptr->flags & QGraphicsItem::ItemClipsChildrenToShape; 5259 // Items with no content are threated as 'dummy' items which means they are never drawn and 5260 // 'processed', so the painted view bounding rect is never up-to-date. This means that whenever 5261 // such an item changes geometry, its children have to take care of the update regardless 5262 // of whether the item clips children to shape or not. 5263 const bool bypassUpdateClip = !itemHasContents && wasDirtyParentViewBoundingRects; 5264 if (itemClipsChildrenToShape && !bypassUpdateClip) { 5265 // Make sure child updates are clipped to the item's bounding rect. 5266 for (int i = 0; i < views.size(); ++i) 5267 views.at(i)->d_func()->setUpdateClip(item); 5268 } 5110 5269 if (!dirtyAncestorContainsChildren) { 5111 5270 dirtyAncestorContainsChildren = item->d_ptr->fullUpdatePending 5112 && (item->d_ptr->flags & QGraphicsItem::ItemClipsChildrenToShape);5271 && itemClipsChildrenToShape; 5113 5272 } 5114 5273 const bool allChildrenDirty = item->d_ptr->allChildrenDirty; … … 5133 5292 processDirtyItemsRecursive(child, dirtyAncestorContainsChildren, opacity); 5134 5293 } 5294 5295 if (itemClipsChildrenToShape) { 5296 // Reset updateClip. 5297 for (int i = 0; i < views.size(); ++i) 5298 views.at(i)->d_func()->setUpdateClip(0); 5299 } 5135 5300 } else if (wasDirtyParentSceneTransform) { 5136 5301 item->d_ptr->invalidateChildrenSceneTransform(); … … 5181 5346 d->_q_polishItems(); 5182 5347 5183 d->updateAll = false;5348 const qreal opacity = painter->opacity(); 5184 5349 QTransform viewTransform = painter->worldTransform(); 5185 5350 Q_UNUSED(options); … … 5188 5353 QGraphicsView *view = widget ? qobject_cast<QGraphicsView *>(widget->parentWidget()) : 0; 5189 5354 QRegion *expose = 0; 5190 if (view) 5355 const quint32 oldRectAdjust = d->rectAdjust; 5356 if (view) { 5357 d->updateAll = false; 5191 5358 expose = &view->d_func()->exposedRegion; 5359 if (view->d_func()->optimizationFlags & QGraphicsView::DontAdjustForAntialiasing) 5360 d->rectAdjust = 1; 5361 else 5362 d->rectAdjust = 2; 5363 } 5192 5364 5193 5365 // Find all toplevels, they are already sorted. … … 5202 5374 } 5203 5375 5376 d->rectAdjust = oldRectAdjust; 5204 5377 // Reset discovery bits. 5205 5378 for (int i = 0; i < topLevelItems.size(); ++i) … … 5207 5380 5208 5381 painter->setWorldTransform(viewTransform); 5382 painter->setOpacity(opacity); 5209 5383 } 5210 5384 … … 5578 5752 { 5579 5753 views << view; 5754 #ifndef QT_NO_GESTURES 5755 foreach (Qt::GestureType gesture, grabbedGestures.keys()) 5756 view->viewport()->grabGesture(gesture); 5757 #endif 5580 5758 } 5581 5759 … … 5638 5816 5639 5817 if (sceneTouchEvent->deviceType() == QTouchEvent::TouchScreen) { 5640 // on touch-screens, combine this touch point with the closest one we find if it 5641 // is a a direct descendent or ancestor ( 5818 // on touch-screens, combine this touch point with the closest one we find 5642 5819 int closestTouchPointId = findClosestTouchPointId(touchPoint.scenePos()); 5643 5820 QGraphicsItem *closestItem = itemForTouchPointId.value(closestTouchPointId); 5644 if (!item 5645 || (closestItem 5646 && (item->isAncestorOf(closestItem) 5647 || closestItem->isAncestorOf(item)))) { 5821 if (!item || (closestItem && cachedItemsUnderMouse.contains(closestItem))) 5648 5822 item = closestItem; 5649 }5650 5823 } 5651 5824 if (!item) … … 5907 6080 } 5908 6081 5909 void QGraphicsScenePrivate::getGestureTargets(const QSet<QGesture *> &gestures, 5910 QWidget *viewport, 5911 QMap<Qt::GestureType, QGesture *> *conflictedGestures, 5912 QList<QList<QGraphicsObject *> > *conflictedItems, 5913 QHash<QGesture *, QGraphicsObject *> *normalGestures) 5914 { 6082 #ifndef QT_NO_GESTURES 6083 void QGraphicsScenePrivate::gestureTargetsAtHotSpots(const QSet<QGesture *> &gestures, 6084 Qt::GestureFlag flag, 6085 QHash<QGraphicsObject *, QSet<QGesture *> > *targets, 6086 QSet<QGraphicsObject *> *itemsSet, 6087 QSet<QGesture *> *normal, 6088 QSet<QGesture *> *conflicts) 6089 { 6090 QSet<QGesture *> normalGestures; // that are not in conflicted state. 5915 6091 foreach (QGesture *gesture, gestures) { 5916 Qt::GestureType gestureType = gesture->gestureType(); 5917 if (gesture->hasHotSpot()) { 5918 QPoint screenPos = gesture->hotSpot().toPoint(); 5919 QList<QGraphicsItem *> items = itemsAtPosition(screenPos, QPointF(), viewport); 5920 QList<QGraphicsObject *> result; 5921 for (int j = 0; j < items.size(); ++j) { 5922 QGraphicsItem *item = items.at(j); 5923 5924 // Check if the item is blocked by a modal panel and use it as 5925 // a target instead of this item. 5926 (void) item->isBlockedByModalPanel(&item); 5927 5928 if (QGraphicsObject *itemobj = item->toGraphicsObject()) { 5929 QGraphicsItemPrivate *d = item->d_func(); 5930 if (d->gestureContext.contains(gestureType)) { 5931 result.append(itemobj); 6092 if (!gesture->hasHotSpot()) 6093 continue; 6094 const Qt::GestureType gestureType = gesture->gestureType(); 6095 QList<QGraphicsItem *> items = itemsAtPosition(QPoint(), gesture->d_func()->sceneHotSpot, 0); 6096 for (int j = 0; j < items.size(); ++j) { 6097 QGraphicsItem *item = items.at(j); 6098 6099 // Check if the item is blocked by a modal panel and use it as 6100 // a target instead of this item. 6101 (void) item->isBlockedByModalPanel(&item); 6102 6103 if (QGraphicsObject *itemobj = item->toGraphicsObject()) { 6104 QGraphicsItemPrivate *d = item->QGraphicsItem::d_func(); 6105 QMap<Qt::GestureType, Qt::GestureFlags>::const_iterator it = 6106 d->gestureContext.find(gestureType); 6107 if (it != d->gestureContext.end() && (!flag || (it.value() & flag))) { 6108 if (normalGestures.contains(gesture)) { 6109 normalGestures.remove(gesture); 6110 if (conflicts) 6111 conflicts->insert(gesture); 6112 } else { 6113 normalGestures.insert(gesture); 5932 6114 } 6115 if (targets) 6116 (*targets)[itemobj].insert(gesture); 6117 if (itemsSet) 6118 (*itemsSet).insert(itemobj); 5933 6119 } 5934 // Don't propagate through panels.5935 if (item->isPanel())5936 break;5937 6120 } 5938 DEBUG() << "QGraphicsScenePrivate::getGestureTargets:" 5939 << gesture << result; 5940 if (result.size() == 1) { 5941 normalGestures->insert(gesture, result.first()); 5942 } else if (!result.isEmpty()) { 5943 conflictedGestures->insert(gestureType, gesture); 5944 conflictedItems->append(result); 5945 } 5946 } 5947 } 6121 // Don't propagate through panels. 6122 if (item->isPanel()) 6123 break; 6124 } 6125 } 6126 if (normal) 6127 *normal = normalGestures; 5948 6128 } 5949 6129 … … 5953 6133 if (!viewport) 5954 6134 return; 6135 QGraphicsView *graphicsView = qobject_cast<QGraphicsView *>(viewport->parent()); 6136 if (!graphicsView) 6137 return; 6138 5955 6139 QList<QGesture *> allGestures = event->gestures(); 5956 6140 DEBUG() << "QGraphicsScenePrivate::gestureEventHandler:" 5957 << "Delivering gestures:" << allGestures; 5958 5959 typedef QHash<QGraphicsObject *, QList<QGesture *> > GesturesPerItem; 5960 GesturesPerItem gesturesPerItem; 6141 << "Gestures:" << allGestures; 5961 6142 5962 6143 QSet<QGesture *> startedGestures; 6144 QPoint delta = viewport->mapFromGlobal(QPoint()); 6145 QTransform toScene = QTransform::fromTranslate(delta.x(), delta.y()) 6146 * graphicsView->viewportTransform().inverted(); 5963 6147 foreach (QGesture *gesture, allGestures) { 6148 // cache scene coordinates of the hot spot 6149 if (gesture->hasHotSpot()) { 6150 gesture->d_func()->sceneHotSpot = toScene.map(gesture->hotSpot()); 6151 } else { 6152 gesture->d_func()->sceneHotSpot = QPointF(); 6153 } 6154 5964 6155 QGraphicsObject *target = gestureTargets.value(gesture, 0); 5965 6156 if (!target) { … … 5968 6159 if (gesture->state() == Qt::GestureStarted) 5969 6160 startedGestures.insert(gesture); 5970 } else { 5971 gesturesPerItem[target].append(gesture); 5972 } 5973 } 5974 5975 QMap<Qt::GestureType, QGesture *> conflictedGestures; 5976 QList<QList<QGraphicsObject *> > conflictedItems; 5977 QHash<QGesture *, QGraphicsObject *> normalGestures; 5978 getGestureTargets(startedGestures, viewport, &conflictedGestures, &conflictedItems, 5979 &normalGestures); 5980 DEBUG() << "QGraphicsScenePrivate::gestureEventHandler:" 5981 << "Conflicting gestures:" << conflictedGestures.values() << conflictedItems; 5982 Q_ASSERT((conflictedGestures.isEmpty() && conflictedItems.isEmpty()) || 5983 (!conflictedGestures.isEmpty() && !conflictedItems.isEmpty())); 5984 5985 // gestures that were sent as override events, but no one accepted them 5986 QHash<QGesture *, QGraphicsObject *> ignoredConflictedGestures; 5987 5988 // deliver conflicted gestures as override events first 5989 while (!conflictedGestures.isEmpty() && !conflictedItems.isEmpty()) { 5990 // get the topmost item to deliver the override event 5991 Q_ASSERT(!conflictedItems.isEmpty()); 5992 Q_ASSERT(!conflictedItems.first().isEmpty()); 5993 QGraphicsObject *topmost = conflictedItems.first().first(); 5994 for (int i = 1; i < conflictedItems.size(); ++i) { 5995 QGraphicsObject *item = conflictedItems.at(i).first(); 5996 if (qt_closestItemFirst(item, topmost)) { 5997 topmost = item; 6161 } 6162 } 6163 6164 if (!startedGestures.isEmpty()) { 6165 QSet<QGesture *> normalGestures; // that have just one target 6166 QSet<QGesture *> conflictedGestures; // that have multiple possible targets 6167 gestureTargetsAtHotSpots(startedGestures, Qt::GestureFlag(0), &cachedItemGestures, 0, 6168 &normalGestures, &conflictedGestures); 6169 cachedTargetItems = cachedItemGestures.keys(); 6170 qSort(cachedTargetItems.begin(), cachedTargetItems.end(), qt_closestItemFirst); 6171 DEBUG() << "QGraphicsScenePrivate::gestureEventHandler:" 6172 << "Normal gestures:" << normalGestures 6173 << "Conflicting gestures:" << conflictedGestures; 6174 6175 // deliver conflicted gestures as override events AND remember 6176 // initial gesture targets 6177 if (!conflictedGestures.isEmpty()) { 6178 for (int i = 0; i < cachedTargetItems.size(); ++i) { 6179 QWeakPointer<QGraphicsObject> item = cachedTargetItems.at(i); 6180 6181 // get gestures to deliver to the current item 6182 QSet<QGesture *> gestures = conflictedGestures & cachedItemGestures.value(item.data()); 6183 if (gestures.isEmpty()) 6184 continue; 6185 6186 DEBUG() << "QGraphicsScenePrivate::gestureEventHandler:" 6187 << "delivering override to" 6188 << item.data() << gestures; 6189 // send gesture override 6190 QGestureEvent ev(gestures.toList()); 6191 ev.t = QEvent::GestureOverride; 6192 ev.setWidget(event->widget()); 6193 // mark event and individual gestures as ignored 6194 ev.ignore(); 6195 foreach(QGesture *g, gestures) 6196 ev.setAccepted(g, false); 6197 sendEvent(item.data(), &ev); 6198 // mark all accepted gestures to deliver them as normal gesture events 6199 foreach (QGesture *g, gestures) { 6200 if (ev.isAccepted() || ev.isAccepted(g)) { 6201 conflictedGestures.remove(g); 6202 // mark the item as a gesture target 6203 if (item) { 6204 gestureTargets.insert(g, item.data()); 6205 QHash<QGraphicsObject *, QSet<QGesture *> >::iterator it, e; 6206 it = cachedItemGestures.begin(); 6207 e = cachedItemGestures.end(); 6208 for(; it != e; ++it) 6209 it.value().remove(g); 6210 cachedItemGestures[item.data()].insert(g); 6211 } 6212 DEBUG() << "QGraphicsScenePrivate::gestureEventHandler:" 6213 << "override was accepted:" 6214 << g << item.data(); 6215 } 6216 // remember the first item that received the override event 6217 // as it most likely become a target if no one else accepts 6218 // the override event 6219 if (!gestureTargets.contains(g) && item) 6220 gestureTargets.insert(g, item.data()); 6221 6222 } 6223 if (conflictedGestures.isEmpty()) 6224 break; 5998 6225 } 5999 6226 } 6000 // get a list of gestures to send to the item 6001 QList<Qt::GestureType> grabbedGestures = 6002 topmost->QGraphicsItem::d_func()->gestureContext.keys(); 6003 QList<QGesture *> gestures; 6004 for (int i = 0; i < grabbedGestures.size(); ++i) { 6005 if (QGesture *g = conflictedGestures.value(grabbedGestures.at(i), 0)) { 6006 gestures.append(g); 6007 if (!ignoredConflictedGestures.contains(g)) 6008 ignoredConflictedGestures.insert(g, topmost); 6009 } 6010 } 6011 6012 // send gesture override to the topmost item 6013 QGestureEvent ev(gestures); 6014 ev.t = QEvent::GestureOverride; 6015 ev.setWidget(event->widget()); 6016 // mark event and individual gestures as ignored 6017 ev.ignore(); 6018 foreach(QGesture *g, gestures) 6019 ev.setAccepted(g, false); 6020 DEBUG() << "QGraphicsScenePrivate::gestureEventHandler:" 6021 << "delivering override to" 6022 << topmost << gestures; 6023 sendEvent(topmost, &ev); 6024 // mark all accepted gestures to deliver them as normal gesture events 6025 foreach (QGesture *g, gestures) { 6026 if (ev.isAccepted() || ev.isAccepted(g)) { 6027 conflictedGestures.remove(g->gestureType()); 6028 gestureTargets.remove(g); 6029 // add the gesture to the list of normal delivered gestures 6030 normalGestures.insert(g, topmost); 6031 DEBUG() << "QGraphicsScenePrivate::gestureEventHandler:" 6032 << "override was accepted:" 6033 << g << topmost; 6034 ignoredConflictedGestures.remove(g); 6035 } 6036 } 6037 // remove the item that we've already delivered from the list 6038 for (int i = 0; i < conflictedItems.size(); ) { 6039 QList<QGraphicsObject *> &items = conflictedItems[i]; 6040 if (items.first() == topmost) { 6041 items.removeFirst(); 6042 if (items.isEmpty()) { 6043 conflictedItems.removeAt(i); 6044 continue; 6227 // remember the initial target item for each gesture that was not in 6228 // the conflicted state. 6229 if (!normalGestures.isEmpty()) { 6230 for (int i = 0; i < cachedTargetItems.size() && !normalGestures.isEmpty(); ++i) { 6231 QGraphicsObject *item = cachedTargetItems.at(i); 6232 6233 // get gestures to deliver to the current item 6234 foreach (QGesture *g, cachedItemGestures.value(item)) { 6235 if (!gestureTargets.contains(g)) { 6236 gestureTargets.insert(g, item); 6237 normalGestures.remove(g); 6238 } 6045 6239 } 6046 6240 } 6047 ++i; 6048 } 6049 } 6050 6051 // put back those started gestures that are not in the conflicted state 6052 // and remember their targets 6053 QHash<QGesture *, QGraphicsObject *>::const_iterator it = normalGestures.begin(), 6054 e = normalGestures.end(); 6055 for (; it != e; ++it) { 6056 QGesture *g = it.key(); 6057 QGraphicsObject *receiver = it.value(); 6058 Q_ASSERT(!gestureTargets.contains(g)); 6059 gestureTargets.insert(g, receiver); 6060 gesturesPerItem[receiver].append(g); 6061 } 6062 it = ignoredConflictedGestures.begin(); 6063 e = ignoredConflictedGestures.end(); 6064 for (; it != e; ++it) { 6065 QGesture *g = it.key(); 6066 QGraphicsObject *receiver = it.value(); 6067 Q_ASSERT(!gestureTargets.contains(g)); 6068 gestureTargets.insert(g, receiver); 6069 gesturesPerItem[receiver].append(g); 6070 } 6071 6072 DEBUG() << "QGraphicsScenePrivate::gestureEventHandler:" 6073 << "Started gestures:" << normalGestures.keys() 6074 << "All gestures:" << gesturesPerItem.values(); 6075 6076 // deliver all events 6077 QList<QGesture *> alreadyIgnoredGestures; 6078 QHash<QGraphicsObject *, QSet<QGesture *> > itemIgnoredGestures; 6079 QList<QGraphicsObject *> targetItems = gesturesPerItem.keys(); 6080 qSort(targetItems.begin(), targetItems.end(), qt_closestItemFirst); 6081 for (int i = 0; i < targetItems.size(); ++i) { 6082 QGraphicsObject *item = targetItems.at(i); 6083 QList<QGesture *> gestures = gesturesPerItem.value(item); 6084 // remove gestures that were already delivered once and were ignored 6085 DEBUG() << "QGraphicsScenePrivate::gestureEventHandler:" 6086 << "already ignored gestures for item" 6087 << item << ":" << itemIgnoredGestures.value(item); 6088 6089 if (itemIgnoredGestures.contains(item)) // don't deliver twice to the same item 6090 continue; 6091 6092 QGraphicsItemPrivate *gid = item->QGraphicsItem::d_func(); 6093 foreach(QGesture *g, alreadyIgnoredGestures) { 6094 QMap<Qt::GestureType, Qt::GestureFlags>::iterator contextit = 6095 gid->gestureContext.find(g->gestureType()); 6096 bool deliver = contextit != gid->gestureContext.end() && 6097 (g->state() == Qt::GestureStarted || 6098 (contextit.value() & Qt::ReceivePartialGestures)); 6099 if (deliver) 6100 gestures += g; 6101 } 6241 } 6242 } 6243 6244 6245 // deliver all gesture events 6246 QSet<QGesture *> undeliveredGestures; 6247 QSet<QGesture *> parentPropagatedGestures; 6248 foreach (QGesture *gesture, allGestures) { 6249 if (QGraphicsObject *target = gestureTargets.value(gesture, 0)) { 6250 cachedItemGestures[target].insert(gesture); 6251 cachedTargetItems.append(target); 6252 undeliveredGestures.insert(gesture); 6253 QGraphicsItemPrivate *d = target->QGraphicsItem::d_func(); 6254 const Qt::GestureFlags flags = d->gestureContext.value(gesture->gestureType()); 6255 if (flags & Qt::IgnoredGesturesPropagateToParent) 6256 parentPropagatedGestures.insert(gesture); 6257 } else { 6258 DEBUG() << "QGraphicsScenePrivate::gestureEventHandler:" 6259 << "no target for" << gesture << "at" 6260 << gesture->hotSpot() << gesture->d_func()->sceneHotSpot; 6261 } 6262 } 6263 qSort(cachedTargetItems.begin(), cachedTargetItems.end(), qt_closestItemFirst); 6264 for (int i = 0; i < cachedTargetItems.size(); ++i) { 6265 QWeakPointer<QGraphicsObject> receiver = cachedTargetItems.at(i); 6266 QSet<QGesture *> gestures = 6267 undeliveredGestures & cachedItemGestures.value(receiver.data()); 6268 gestures -= cachedAlreadyDeliveredGestures.value(receiver.data()); 6269 6102 6270 if (gestures.isEmpty()) 6103 6271 continue; 6272 6273 cachedAlreadyDeliveredGestures[receiver.data()] += gestures; 6274 const bool isPanel = receiver.data()->isPanel(); 6275 6104 6276 DEBUG() << "QGraphicsScenePrivate::gestureEventHandler:" 6105 6277 << "delivering to" 6106 << item<< gestures;6107 QGestureEvent ev(gestures );6278 << receiver.data() << gestures; 6279 QGestureEvent ev(gestures.toList()); 6108 6280 ev.setWidget(event->widget()); 6109 sendEvent( item, &ev);6281 sendEvent(receiver.data(), &ev); 6110 6282 QSet<QGesture *> ignoredGestures; 6111 6283 foreach (QGesture *g, gestures) { 6112 6284 if (!ev.isAccepted() && !ev.isAccepted(g)) { 6113 ignoredGestures.insert(g); 6285 // if the gesture was ignored by its target, we will update the 6286 // targetItems list with a possible target items (items that 6287 // want to receive partial gestures). 6288 // ### wont' work if the target was destroyed in the event 6289 // we will just stop delivering it. 6290 if (receiver && receiver.data() == gestureTargets.value(g, 0)) 6291 ignoredGestures.insert(g); 6114 6292 } else { 6115 if (g->state() == Qt::GestureStarted) 6116 gestureTargets[g] = item; 6293 if (receiver && g->state() == Qt::GestureStarted) { 6294 // someone accepted the propagated initial GestureStarted 6295 // event, let it be the new target for all following events. 6296 gestureTargets[g] = receiver.data(); 6297 } 6298 undeliveredGestures.remove(g); 6117 6299 } 6118 6300 } 6119 if (!ignoredGestures.isEmpty()) { 6120 // get a list of items under the (current) hotspot of each ignored 6121 // gesture and start delivery again from the beginning 6301 if (undeliveredGestures.isEmpty()) 6302 break; 6303 6304 // ignoredGestures list is only filled when delivering to the gesture 6305 // target item, so it is safe to assume item == target. 6306 if (!ignoredGestures.isEmpty() && !isPanel) { 6307 // look for new potential targets for gestures that were ignored 6308 // and should be propagated. 6309 6310 QSet<QGraphicsObject *> targetsSet = cachedTargetItems.toSet(); 6311 6312 if (receiver) { 6313 // first if the gesture should be propagated to parents only 6314 for (QSet<QGesture *>::iterator it = ignoredGestures.begin(); 6315 it != ignoredGestures.end();) { 6316 if (parentPropagatedGestures.contains(*it)) { 6317 QGesture *gesture = *it; 6318 const Qt::GestureType gestureType = gesture->gestureType(); 6319 QGraphicsItem *item = receiver.data(); 6320 while (item) { 6321 if (QGraphicsObject *obj = item->toGraphicsObject()) { 6322 if (item->d_func()->gestureContext.contains(gestureType)) { 6323 targetsSet.insert(obj); 6324 cachedItemGestures[obj].insert(gesture); 6325 } 6326 } 6327 if (item->isPanel()) 6328 break; 6329 item = item->parentItem(); 6330 } 6331 6332 it = ignoredGestures.erase(it); 6333 continue; 6334 } 6335 ++it; 6336 } 6337 } 6338 6339 gestureTargetsAtHotSpots(ignoredGestures, Qt::ReceivePartialGestures, 6340 &cachedItemGestures, &targetsSet, 0, 0); 6341 6342 cachedTargetItems = targetsSet.toList(); 6343 qSort(cachedTargetItems.begin(), cachedTargetItems.end(), qt_closestItemFirst); 6122 6344 DEBUG() << "QGraphicsScenePrivate::gestureEventHandler:" 6123 << "item has ignored the event, will propagate." 6124 << item << ignoredGestures; 6125 itemIgnoredGestures[item] += ignoredGestures; 6126 QMap<Qt::GestureType, QGesture *> conflictedGestures; 6127 QList<QList<QGraphicsObject *> > itemsForConflictedGestures; 6128 QHash<QGesture *, QGraphicsObject *> normalGestures; 6129 getGestureTargets(ignoredGestures, viewport, 6130 &conflictedGestures, &itemsForConflictedGestures, 6131 &normalGestures); 6132 QSet<QGraphicsObject *> itemsSet = targetItems.toSet(); 6133 for (int k = 0; k < itemsForConflictedGestures.size(); ++k) 6134 itemsSet += itemsForConflictedGestures.at(k).toSet(); 6135 targetItems = itemsSet.toList(); 6136 qSort(targetItems.begin(), targetItems.end(), qt_closestItemFirst); 6137 alreadyIgnoredGestures = conflictedGestures.values(); 6138 DEBUG() << "QGraphicsScenePrivate::gestureEventHandler:" 6139 << "new targets:" << targetItems; 6345 << "new targets:" << cachedTargetItems; 6140 6346 i = -1; // start delivery again 6141 6347 continue; 6142 6348 } 6143 6349 } 6350 6144 6351 foreach (QGesture *g, startedGestures) { 6145 6352 if (g->gestureCancelPolicy() == QGesture::CancelAllInContext) { 6146 6353 DEBUG() << "lets try to cancel some"; 6147 6354 // find gestures in context in Qt::GestureStarted or Qt::GestureUpdated state and cancel them 6148 cancelGesturesForChildren(g , event->widget());6355 cancelGesturesForChildren(g); 6149 6356 } 6150 6357 } … … 6161 6368 } 6162 6369 } 6163 } 6164 6165 void QGraphicsScenePrivate::cancelGesturesForChildren(QGesture *original, QWidget *viewport) 6370 6371 cachedTargetItems.clear(); 6372 cachedItemGestures.clear(); 6373 cachedAlreadyDeliveredGestures.clear(); 6374 } 6375 6376 void QGraphicsScenePrivate::cancelGesturesForChildren(QGesture *original) 6166 6377 { 6167 6378 Q_ASSERT(original); 6168 6379 QGraphicsItem *originalItem = gestureTargets.value(original); 6169 Q_ASSERT(originalItem); 6380 if (originalItem == 0) // we only act on accepted gestures, which implies it has a target. 6381 return; 6170 6382 6171 6383 // iterate over all active gestures and for each find the owner … … 6219 6431 continue; 6220 6432 6221 QPoint screenPos = g->hotSpot().toPoint(); 6222 QList<QGraphicsItem *> items = itemsAtPosition(screenPos, QPointF(), viewport); 6433 QList<QGraphicsItem *> items = itemsAtPosition(QPoint(), g->d_func()->sceneHotSpot, 0); 6223 6434 for (int j = 0; j < items.size(); ++j) { 6224 6435 QGraphicsObject *item = items.at(j)->toGraphicsObject(); … … 6246 6457 } 6247 6458 6459 void QGraphicsScenePrivate::grabGesture(QGraphicsItem *, Qt::GestureType gesture) 6460 { 6461 (void)QGestureManager::instance(); // create a gesture manager 6462 if (!grabbedGestures[gesture]++) { 6463 foreach (QGraphicsView *view, views) 6464 view->viewport()->grabGesture(gesture); 6465 } 6466 } 6467 6468 void QGraphicsScenePrivate::ungrabGesture(QGraphicsItem *item, Qt::GestureType gesture) 6469 { 6470 // we know this can only be an object 6471 Q_ASSERT(item->d_ptr->isObject); 6472 QGraphicsObject *obj = static_cast<QGraphicsObject *>(item); 6473 QGestureManager::instance()->cleanupCachedGestures(obj, gesture); 6474 if (!--grabbedGestures[gesture]) { 6475 foreach (QGraphicsView *view, views) 6476 view->viewport()->ungrabGesture(gesture); 6477 } 6478 } 6479 #endif // QT_NO_GESTURES 6480 6248 6481 QT_END_NAMESPACE 6249 6482 -
trunk/src/gui/graphicsview/qgraphicsscene.h
r651 r846 1 1 /**************************************************************************** 2 2 ** 3 ** Copyright (C) 201 0Nokia Corporation and/or its subsidiary(-ies).3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). 4 4 ** All rights reserved. 5 5 ** Contact: Nokia Corporation (qt-info@nokia.com) … … 303 303 friend class QGraphicsItem; 304 304 friend class QGraphicsItemPrivate; 305 friend class QGraphicsObject; 305 306 friend class QGraphicsView; 306 307 friend class QGraphicsViewPrivate; … … 313 314 friend class QGraphicsSceneBspTreeIndexPrivate; 314 315 friend class QGraphicsItemEffectSourcePrivate; 316 #ifndef QT_NO_GESTURES 315 317 friend class QGesture; 318 #endif 316 319 }; 317 320 -
trunk/src/gui/graphicsview/qgraphicsscene_bsp.cpp
r651 r846 1 1 /**************************************************************************** 2 2 ** 3 ** Copyright (C) 201 0Nokia Corporation and/or its subsidiary(-ies).3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). 4 4 ** All rights reserved. 5 5 ** Contact: Nokia Corporation (qt-info@nokia.com) -
trunk/src/gui/graphicsview/qgraphicsscene_bsp_p.h
r651 r846 1 1 /**************************************************************************** 2 2 ** 3 ** Copyright (C) 201 0Nokia Corporation and/or its subsidiary(-ies).3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). 4 4 ** All rights reserved. 5 5 ** Contact: Nokia Corporation (qt-info@nokia.com) -
trunk/src/gui/graphicsview/qgraphicsscene_p.h
r769 r846 1 1 /**************************************************************************** 2 2 ** 3 ** Copyright (C) 201 0Nokia Corporation and/or its subsidiary(-ies).3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). 4 4 ** All rights reserved. 5 5 ** Contact: Nokia Corporation (qt-info@nokia.com) … … 88 88 static QGraphicsScenePrivate *get(QGraphicsScene *q); 89 89 90 static int changedSignalIndex; 90 int changedSignalIndex; 91 int processDirtyItemsIndex; 92 int polishItemsIndex; 91 93 92 94 QGraphicsScene::ItemIndexMethod indexMethod; … … 96 98 97 99 QRectF sceneRect; 98 bool hasSceneRect; 99 bool dirtyGrowingItemsBoundingRect; 100 101 quint32 hasSceneRect : 1; 102 quint32 dirtyGrowingItemsBoundingRect : 1; 103 quint32 updateAll : 1; 104 quint32 calledEmitUpdated : 1; 105 quint32 processDirtyItemsEmitted : 1; 106 quint32 needSortTopLevelItems : 1; 107 quint32 holesInTopLevelSiblingIndex : 1; 108 quint32 topLevelSequentialOrdering : 1; 109 quint32 scenePosDescendantsUpdatePending : 1; 110 quint32 stickyFocus : 1; 111 quint32 hasFocus : 1; 112 quint32 lastMouseGrabberItemHasImplicitMouseGrab : 1; 113 quint32 allItemsIgnoreHoverEvents : 1; 114 quint32 allItemsUseDefaultCursor : 1; 115 quint32 painterStateProtection : 1; 116 quint32 sortCacheEnabled : 1; // for compatibility 117 quint32 allItemsIgnoreTouchEvents : 1; 118 quint32 padding : 15; 119 100 120 QRectF growingItemsBoundingRect; 101 121 102 122 void _q_emitUpdated(); 103 123 QList<QRectF> updatedRects; 104 bool updateAll;105 bool calledEmitUpdated;106 bool processDirtyItemsEmitted;107 124 108 125 QPainterPath selectionArea; … … 111 128 QVector<QGraphicsItem *> unpolishedItems; 112 129 QList<QGraphicsItem *> topLevelItems; 113 bool needSortTopLevelItems;114 bool holesInTopLevelSiblingIndex;115 bool topLevelSequentialOrdering;116 130 117 131 QMap<QGraphicsItem *, QPointF> movingItemsInitialPositions; … … 124 138 125 139 QSet<QGraphicsItem *> scenePosItems; 126 bool scenePosDescendantsUpdatePending;127 140 void setScenePosItemEnabled(QGraphicsItem *item, bool enabled); 128 141 void registerScenePosItem(QGraphicsItem *item); … … 135 148 QBrush foregroundBrush; 136 149 137 bool stickyFocus; 138 bool hasFocus; 150 quint32 rectAdjust; 139 151 QGraphicsItem *focusItem; 140 152 QGraphicsItem *lastFocusItem; … … 152 164 153 165 QGraphicsItem *lastMouseGrabberItem; 154 bool lastMouseGrabberItemHasImplicitMouseGrab;155 166 QList<QGraphicsItem *> mouseGrabberItems; 156 167 void grabMouse(QGraphicsItem *item, bool implicit = false); … … 169 180 QList<QGraphicsItem *> hoverItems; 170 181 QPointF lastSceneMousePos; 171 bool allItemsIgnoreHoverEvents;172 bool allItemsUseDefaultCursor;173 182 void enableMouseTrackingOnViews(); 174 183 QMap<Qt::MouseButton, QPointF> mouseGrabberButtonDownPos; … … 183 192 void addView(QGraphicsView *view); 184 193 void removeView(QGraphicsView *view); 185 186 bool painterStateProtection;187 194 188 195 QMultiMap<QGraphicsItem *, QGraphicsItem *> sceneEventFilters; … … 206 213 void mousePressEventHandler(QGraphicsSceneMouseEvent *mouseEvent); 207 214 QGraphicsWidget *windowForItem(const QGraphicsItem *item) const; 208 209 bool sortCacheEnabled; // for compatibility210 215 211 216 void drawItemHelper(QGraphicsItem *item, QPainter *painter, … … 292 297 void touchEventHandler(QTouchEvent *touchEvent); 293 298 bool sendTouchBeginEvent(QGraphicsItem *item, QTouchEvent *touchEvent); 294 bool allItemsIgnoreTouchEvents;295 299 void enableTouchEventsOnViews(); 296 300 301 QList<QGraphicsObject *> cachedTargetItems; 302 #ifndef QT_NO_GESTURES 303 QHash<QGraphicsObject *, QSet<QGesture *> > cachedItemGestures; 304 QHash<QGraphicsObject *, QSet<QGesture *> > cachedAlreadyDeliveredGestures; 297 305 QHash<QGesture *, QGraphicsObject *> gestureTargets; 306 QHash<Qt::GestureType, int> grabbedGestures; 298 307 void gestureEventHandler(QGestureEvent *event); 299 void getGestureTargets(const QSet<QGesture *> &gestures, QWidget *viewport, 300 QMap<Qt::GestureType, QGesture *> *conflictedGestures, 301 QList<QList<QGraphicsObject *> > *conflictedItems, 302 QHash<QGesture *, QGraphicsObject *> *normalGestures); 303 void cancelGesturesForChildren(QGesture *original, QWidget *viewport); 308 void gestureTargetsAtHotSpots(const QSet<QGesture *> &gestures, 309 Qt::GestureFlag flag, 310 QHash<QGraphicsObject *, QSet<QGesture *> > *targets, 311 QSet<QGraphicsObject *> *itemsSet = 0, 312 QSet<QGesture *> *normal = 0, 313 QSet<QGesture *> *conflicts = 0); 314 void cancelGesturesForChildren(QGesture *original); 315 void grabGesture(QGraphicsItem *, Qt::GestureType gesture); 316 void ungrabGesture(QGraphicsItem *, Qt::GestureType gesture); 317 #endif // QT_NO_GESTURES 304 318 305 319 void updateInputMethodSensitivityInViews(); -
trunk/src/gui/graphicsview/qgraphicsscenebsptreeindex.cpp
r651 r846 1 1 /**************************************************************************** 2 2 ** 3 ** Copyright (C) 201 0Nokia Corporation and/or its subsidiary(-ies).3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). 4 4 ** All rights reserved. 5 5 ** Contact: Nokia Corporation (qt-info@nokia.com) -
trunk/src/gui/graphicsview/qgraphicsscenebsptreeindex_p.h
r651 r846 1 1 /**************************************************************************** 2 2 ** 3 ** Copyright (C) 201 0Nokia Corporation and/or its subsidiary(-ies).3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). 4 4 ** All rights reserved. 5 5 ** Contact: Nokia Corporation (qt-info@nokia.com) -
trunk/src/gui/graphicsview/qgraphicssceneevent.cpp
r651 r846 1 1 /**************************************************************************** 2 2 ** 3 ** Copyright (C) 201 0Nokia Corporation and/or its subsidiary(-ies).3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). 4 4 ** All rights reserved. 5 5 ** Contact: Nokia Corporation (qt-info@nokia.com) … … 1630 1630 1631 1631 /*! 1632 Returns the old position (i.e., the position immediat ly before the widget1632 Returns the old position (i.e., the position immediately before the widget 1633 1633 was moved). 1634 1634 -
trunk/src/gui/graphicsview/qgraphicssceneevent.h
r769 r846 1 1 /**************************************************************************** 2 2 ** 3 ** Copyright (C) 201 0Nokia Corporation and/or its subsidiary(-ies).3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). 4 4 ** All rights reserved. 5 5 ** Contact: Nokia Corporation (qt-info@nokia.com) -
trunk/src/gui/graphicsview/qgraphicssceneindex.cpp
r651 r846 1 1 /**************************************************************************** 2 2 ** 3 ** Copyright (C) 201 0Nokia Corporation and/or its subsidiary(-ies).3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). 4 4 ** All rights reserved. 5 5 ** Contact: Nokia Corporation (qt-info@nokia.com) -
trunk/src/gui/graphicsview/qgraphicssceneindex_p.h
r651 r846 1 1 /**************************************************************************** 2 2 ** 3 ** Copyright (C) 201 0Nokia Corporation and/or its subsidiary(-ies).3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). 4 4 ** All rights reserved. 5 5 ** Contact: Nokia Corporation (qt-info@nokia.com) -
trunk/src/gui/graphicsview/qgraphicsscenelinearindex.cpp
r651 r846 1 1 /**************************************************************************** 2 2 ** 3 ** Copyright (C) 201 0Nokia Corporation and/or its subsidiary(-ies).3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). 4 4 ** All rights reserved. 5 5 ** Contact: Nokia Corporation (qt-info@nokia.com) -
trunk/src/gui/graphicsview/qgraphicsscenelinearindex_p.h
r651 r846 1 1 /**************************************************************************** 2 2 ** 3 ** Copyright (C) 201 0Nokia Corporation and/or its subsidiary(-ies).3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). 4 4 ** All rights reserved. 5 5 ** Contact: Nokia Corporation (qt-info@nokia.com) -
trunk/src/gui/graphicsview/qgraphicstransform.cpp
r651 r846 1 1 /**************************************************************************** 2 2 ** 3 ** Copyright (C) 201 0Nokia Corporation and/or its subsidiary(-ies).3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). 4 4 ** All rights reserved. 5 5 ** Contact: Nokia Corporation (qt-info@nokia.com) … … 55 55 order, one at a time, to the QGraphicsItem it's assigned to. 56 56 57 QGraphicsTransform is particular ily useful for animations. Whereas57 QGraphicsTransform is particularly useful for animations. Whereas 58 58 QGraphicsItem::setTransform() lets you assign any transform directly to an 59 59 item, there is no direct way to interpolate between two different … … 268 268 d->xScale = scale; 269 269 update(); 270 emit xScaleChanged(); 270 271 emit scaleChanged(); 271 272 } … … 294 295 d->yScale = scale; 295 296 update(); 297 emit yScaleChanged(); 296 298 emit scaleChanged(); 297 299 } … … 320 322 d->zScale = scale; 321 323 update(); 324 emit zScaleChanged(); 322 325 emit scaleChanged(); 323 326 } … … 340 343 341 344 \sa QGraphicsScale::origin 345 */ 346 347 /*! 348 \fn QGraphicsScale::xScaleChanged() 349 \since 4.7 350 351 This signal is emitted whenever the \l xScale property changes. 352 */ 353 354 /*! 355 \fn QGraphicsScale::yScaleChanged() 356 \since 4.7 357 358 This signal is emitted whenever the \l yScale property changes. 359 */ 360 361 /*! 362 \fn QGraphicsScale::zScaleChanged() 363 \since 4.7 364 365 This signal is emitted whenever the \l zScale property changes. 342 366 */ 343 367 -
trunk/src/gui/graphicsview/qgraphicstransform.h
r651 r846 1 1 /**************************************************************************** 2 2 ** 3 ** Copyright (C) 201 0Nokia Corporation and/or its subsidiary(-ies).3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). 4 4 ** All rights reserved. 5 5 ** Contact: Nokia Corporation (qt-info@nokia.com) … … 86 86 87 87 Q_PROPERTY(QVector3D origin READ origin WRITE setOrigin NOTIFY originChanged) 88 Q_PROPERTY(qreal xScale READ xScale WRITE setXScale NOTIFY scaleChanged)89 Q_PROPERTY(qreal yScale READ yScale WRITE setYScale NOTIFY scaleChanged)90 Q_PROPERTY(qreal zScale READ zScale WRITE setZScale NOTIFY scaleChanged)88 Q_PROPERTY(qreal xScale READ xScale WRITE setXScale NOTIFY xScaleChanged) 89 Q_PROPERTY(qreal yScale READ yScale WRITE setYScale NOTIFY yScaleChanged) 90 Q_PROPERTY(qreal zScale READ zScale WRITE setZScale NOTIFY zScaleChanged) 91 91 public: 92 92 QGraphicsScale(QObject *parent = 0); … … 109 109 Q_SIGNALS: 110 110 void originChanged(); 111 void xScaleChanged(); 112 void yScaleChanged(); 113 void zScaleChanged(); 111 114 void scaleChanged(); 112 115 -
trunk/src/gui/graphicsview/qgraphicstransform_p.h
r651 r846 1 1 /**************************************************************************** 2 2 ** 3 ** Copyright (C) 201 0Nokia Corporation and/or its subsidiary(-ies).3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). 4 4 ** All rights reserved. 5 5 ** Contact: Nokia Corporation (qt-info@nokia.com) -
trunk/src/gui/graphicsview/qgraphicsview.cpp
r769 r846 1 1 /**************************************************************************** 2 2 ** 3 ** Copyright (C) 201 0Nokia Corporation and/or its subsidiary(-ies).3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). 4 4 ** All rights reserved. 5 5 ** Contact: Nokia Corporation (qt-info@nokia.com) … … 54 54 QGraphicsView visualizes the contents of a QGraphicsScene in a scrollable 55 55 viewport. To create a scene with geometrical items, see QGraphicsScene's 56 documentation. QGraphicsView is part of \l{TheGraphics View Framework}.56 documentation. QGraphicsView is part of the \l{Graphics View Framework}. 57 57 58 58 To visualize a scene, you start by constructing a QGraphicsView object, … … 328 328 sceneInteractionAllowed(true), hasSceneRect(false), 329 329 connectedToScene(false), 330 mousePressButton(Qt::NoButton),330 useLastMouseEvent(false), 331 331 identityMatrix(true), 332 332 dirtyScroll(true), 333 333 accelerateScrolling(true), 334 keepLastCenterPoint(true), 335 transforming(false), 336 handScrolling(false), 337 mustAllocateStyleOptions(false), 338 mustResizeBackgroundPixmap(true), 339 fullUpdatePending(true), 340 hasUpdateClip(false), 341 mousePressButton(Qt::NoButton), 334 342 leftIndent(0), topIndent(0), 335 343 lastMouseEvent(QEvent::None, QPoint(), Qt::NoButton, 0, 0), 336 useLastMouseEvent(false),337 keepLastCenterPoint(true),338 344 alignment(Qt::AlignCenter), 339 transforming(false),340 345 transformationAnchor(QGraphicsView::AnchorViewCenter), resizeAnchor(QGraphicsView::NoAnchor), 341 346 viewportUpdateMode(QGraphicsView::MinimalViewportUpdate), … … 346 351 rubberBandSelectionMode(Qt::IntersectsItemShape), 347 352 #endif 348 handScrolling(false), handScrollMotions(0), cacheMode(0), 349 mustAllocateStyleOptions(false), 350 mustResizeBackgroundPixmap(true), 353 handScrollMotions(0), cacheMode(0), 351 354 #ifndef QT_NO_CURSOR 352 355 hasStoredOriginalCursor(false), 353 356 #endif 354 357 lastDragDropEvent(0), 355 fullUpdatePending(true),356 358 updateSceneSlotReimplementedChecked(false) 357 359 { … … 734 736 735 737 // Restore the original viewport cursor. 736 hasStoredOriginalCursor = false; 737 if (dragMode == QGraphicsView::ScrollHandDrag) 738 viewport->setCursor(Qt::OpenHandCursor); 739 else 740 viewport->setCursor(originalCursor); 738 if (hasStoredOriginalCursor) { 739 hasStoredOriginalCursor = false; 740 if (dragMode == QGraphicsView::ScrollHandDrag) 741 viewport->setCursor(Qt::OpenHandCursor); 742 else 743 viewport->setCursor(originalCursor); 744 } 741 745 } 742 746 #endif … … 853 857 viewport->update(); 854 858 } else if (viewportUpdateMode == QGraphicsView::BoundingRectViewportUpdate) { 855 if (optimizationFlags & QGraphicsView::DontAdjustForAntialiasing) 856 viewport->update(dirtyBoundingRect.adjusted(-1, -1, 1, 1)); 857 else 858 viewport->update(dirtyBoundingRect.adjusted(-2, -2, 2, 2)); 859 viewport->update(dirtyBoundingRect); 859 860 } else { 860 861 viewport->update(dirtyRegion); // Already adjusted in updateRect/Region. … … 881 882 } 882 883 883 bool QGraphicsViewPrivate::updateRegion(const QRegion &r) 884 { 885 if (fullUpdatePending || viewportUpdateMode == QGraphicsView::NoViewportUpdate || r.isEmpty()) 884 /* 885 Calling this function results in update rects being clipped to the item's 886 bounding rect. Note that updates prior to this function call is not clipped. 887 The clip is removed by passing 0. 888 */ 889 void QGraphicsViewPrivate::setUpdateClip(QGraphicsItem *item) 890 { 891 Q_Q(QGraphicsView); 892 // We simply ignore the request if the update mode is either FullViewportUpdate 893 // or NoViewportUpdate; in that case there's no point in clipping anything. 894 if (!item || viewportUpdateMode == QGraphicsView::NoViewportUpdate 895 || viewportUpdateMode == QGraphicsView::FullViewportUpdate) { 896 hasUpdateClip = false; 897 return; 898 } 899 900 // Calculate the clip (item's bounding rect in view coordinates). 901 // Optimized version of: 902 // QRect clip = item->deviceTransform(q->viewportTransform()) 903 // .mapRect(item->boundingRect()).toAlignedRect(); 904 QRect clip; 905 if (item->d_ptr->itemIsUntransformable()) { 906 QTransform xform = item->deviceTransform(q->viewportTransform()); 907 clip = xform.mapRect(item->boundingRect()).toAlignedRect(); 908 } else if (item->d_ptr->sceneTransformTranslateOnly && identityMatrix) { 909 QRectF r(item->boundingRect()); 910 r.translate(item->d_ptr->sceneTransform.dx() - horizontalScroll(), 911 item->d_ptr->sceneTransform.dy() - verticalScroll()); 912 clip = r.toAlignedRect(); 913 } else if (!q->isTransformed()) { 914 clip = item->d_ptr->sceneTransform.mapRect(item->boundingRect()).toAlignedRect(); 915 } else { 916 QTransform xform = item->d_ptr->sceneTransform; 917 xform *= q->viewportTransform(); 918 clip = xform.mapRect(item->boundingRect()).toAlignedRect(); 919 } 920 921 if (hasUpdateClip) { 922 // Intersect with old clip. 923 updateClip &= clip; 924 } else { 925 updateClip = clip; 926 hasUpdateClip = true; 927 } 928 } 929 930 bool QGraphicsViewPrivate::updateRegion(const QRectF &rect, const QTransform &xform) 931 { 932 if (rect.isEmpty()) 886 933 return false; 887 934 888 const QRect boundingRect = r.boundingRect(); 889 if (!intersectsViewport(boundingRect, viewport->width(), viewport->height())) 890 return false; // Update region outside viewport. 935 if (viewportUpdateMode != QGraphicsView::MinimalViewportUpdate 936 && viewportUpdateMode != QGraphicsView::SmartViewportUpdate) { 937 // No point in updating with QRegion granularity; use the rect instead. 938 return updateRectF(xform.mapRect(rect)); 939 } 940 941 // Update mode is either Minimal or Smart, so we have to do a potentially slow operation, 942 // which is clearly documented here: QGraphicsItem::setBoundingRegionGranularity. 943 const QRegion region = xform.map(QRegion(rect.toAlignedRect())); 944 QRect viewRect = region.boundingRect(); 945 const bool dontAdjustForAntialiasing = optimizationFlags & QGraphicsView::DontAdjustForAntialiasing; 946 if (dontAdjustForAntialiasing) 947 viewRect.adjust(-1, -1, 1, 1); 948 else 949 viewRect.adjust(-2, -2, 2, 2); 950 if (!intersectsViewport(viewRect, viewport->width(), viewport->height())) 951 return false; // Update region for sure outside viewport. 952 953 const QVector<QRect> &rects = region.rects(); 954 for (int i = 0; i < rects.size(); ++i) { 955 viewRect = rects.at(i); 956 if (dontAdjustForAntialiasing) 957 viewRect.adjust(-1, -1, 1, 1); 958 else 959 viewRect.adjust(-2, -2, 2, 2); 960 if (hasUpdateClip) 961 viewRect &= updateClip; 962 dirtyRegion += viewRect; 963 } 964 965 return true; 966 } 967 968 // NB! Assumes the rect 'r' is already aligned and adjusted for antialiasing. 969 // For QRectF use updateRectF(const QRectF &) to ensure proper adjustments. 970 bool QGraphicsViewPrivate::updateRect(const QRect &r) 971 { 972 if (fullUpdatePending || viewportUpdateMode == QGraphicsView::NoViewportUpdate 973 || !intersectsViewport(r, viewport->width(), viewport->height())) { 974 return false; 975 } 891 976 892 977 switch (viewportUpdateMode) { … … 896 981 break; 897 982 case QGraphicsView::BoundingRectViewportUpdate: 898 QRect_unite(&dirtyBoundingRect, boundingRect); 983 if (hasUpdateClip) 984 QRect_unite(&dirtyBoundingRect, r & updateClip); 985 else 986 QRect_unite(&dirtyBoundingRect, r); 899 987 if (containsViewport(dirtyBoundingRect, viewport->width(), viewport->height())) { 900 988 fullUpdatePending = true; … … 904 992 case QGraphicsView::SmartViewportUpdate: // ### DEPRECATE 905 993 case QGraphicsView::MinimalViewportUpdate: 906 { 907 const QVector<QRect> &rects = r.rects(); 908 for (int i = 0; i < rects.size(); ++i) { 909 if (optimizationFlags & QGraphicsView::DontAdjustForAntialiasing) 910 dirtyRegion += rects.at(i).adjusted(-1, -1, 1, 1); 911 else 912 dirtyRegion += rects.at(i).adjusted(-2, -2, 2, 2); 913 } 914 break; 915 } 916 default: 917 break; 918 } 919 920 return true; 921 } 922 923 bool QGraphicsViewPrivate::updateRect(const QRect &r) 924 { 925 if (fullUpdatePending || viewportUpdateMode == QGraphicsView::NoViewportUpdate 926 || !intersectsViewport(r, viewport->width(), viewport->height())) { 927 return false; 928 } 929 930 switch (viewportUpdateMode) { 931 case QGraphicsView::FullViewportUpdate: 932 fullUpdatePending = true; 933 viewport->update(); 934 break; 935 case QGraphicsView::BoundingRectViewportUpdate: 936 QRect_unite(&dirtyBoundingRect, r); 937 if (containsViewport(dirtyBoundingRect, viewport->width(), viewport->height())) { 938 fullUpdatePending = true; 939 viewport->update(); 940 } 941 break; 942 case QGraphicsView::SmartViewportUpdate: // ### DEPRECATE 943 case QGraphicsView::MinimalViewportUpdate: 944 if (optimizationFlags & QGraphicsView::DontAdjustForAntialiasing) 945 dirtyRegion += r.adjusted(-1, -1, 1, 1); 994 if (hasUpdateClip) 995 dirtyRegion += r & updateClip; 946 996 else 947 dirtyRegion += r .adjusted(-2, -2, 2, 2);997 dirtyRegion += r; 948 998 break; 949 999 default: … … 1036 1086 { 1037 1087 Q_Q(QGraphicsView); 1038 bool enabled = scene && scene->focusItem() 1039 && (scene->focusItem()->flags() & QGraphicsItem::ItemAcceptsInputMethod); 1088 QGraphicsItem *focusItem = 0; 1089 bool enabled = scene && (focusItem = scene->focusItem()) 1090 && (focusItem->d_ptr->flags & QGraphicsItem::ItemAcceptsInputMethod); 1040 1091 q->setAttribute(Qt::WA_InputMethodEnabled, enabled); 1041 1092 q->viewport()->setAttribute(Qt::WA_InputMethodEnabled, enabled); 1093 1094 if (!enabled) { 1095 q->setInputMethodHints(0); 1096 return; 1097 } 1098 1099 QGraphicsProxyWidget *proxy = focusItem->d_ptr->isWidget && focusItem->d_ptr->isProxyWidget() 1100 ? static_cast<QGraphicsProxyWidget *>(focusItem) : 0; 1101 if (!proxy) { 1102 q->setInputMethodHints(focusItem->inputMethodHints()); 1103 } else if (QWidget *widget = proxy->widget()) { 1104 if (QWidget *fw = widget->focusWidget()) 1105 widget = fw; 1106 q->setInputMethodHints(widget->inputMethodHints()); 1107 } else { 1108 q->setInputMethodHints(0); 1109 } 1042 1110 } 1043 1111 … … 1808 1876 { 1809 1877 Q_D(QGraphicsView); 1810 Q_UNUSED(xmargin);1811 Q_UNUSED(ymargin);1812 1878 qreal width = viewport()->width(); 1813 1879 qreal height = viewport()->height(); … … 2429 2495 QVariant value = d->scene->inputMethodQuery(query); 2430 2496 if (value.type() == QVariant::RectF) 2431 value = mapFromScene(value.toRectF()).boundingRect();2497 value = d->mapRectFromScene(value.toRectF()); 2432 2498 else if (value.type() == QVariant::PointF) 2433 2499 value = mapFromScene(value.toPointF()); … … 2531 2597 // Convert scene rects to viewport rects. 2532 2598 foreach (const QRectF &rect, rects) { 2533 QRect xrect = transform.mapRect(rect).to Rect();2599 QRect xrect = transform.mapRect(rect).toAlignedRect(); 2534 2600 if (!(d->optimizationFlags & DontAdjustForAntialiasing)) 2535 2601 xrect.adjust(-2, -2, 2, 2); 2602 else 2603 xrect.adjust(-1, -1, 1, 1); 2536 2604 if (!viewportRect.intersects(xrect)) 2537 2605 continue; … … 2622 2690 if (d->scene && !d->scene->d_func()->allItemsIgnoreTouchEvents) 2623 2691 widget->setAttribute(Qt::WA_AcceptTouchEvents); 2692 2693 #ifndef QT_NO_GESTURES 2694 if (d->scene) { 2695 foreach (Qt::GestureType gesture, d->scene->d_func()->grabbedGestures.keys()) 2696 widget->grabGesture(gesture); 2697 } 2698 #endif 2624 2699 2625 2700 widget->setAcceptDrops(acceptDrops()); … … 2768 2843 return true; 2769 2844 } 2845 #ifndef QT_NO_GESTURES 2770 2846 case QEvent::Gesture: 2771 2847 case QEvent::GestureOverride: … … 2781 2857 return true; 2782 2858 } 2859 #endif // QT_NO_GESTURES 2783 2860 default: 2784 2861 break; … … 3384 3461 // Items 3385 3462 if (!(d->optimizationFlags & IndirectPainting)) { 3463 const quint32 oldRectAdjust = d->scene->d_func()->rectAdjust; 3464 if (d->optimizationFlags & QGraphicsView::DontAdjustForAntialiasing) 3465 d->scene->d_func()->rectAdjust = 1; 3466 else 3467 d->scene->d_func()->rectAdjust = 2; 3386 3468 d->scene->d_func()->drawItems(&painter, viewTransformed ? &viewTransform : 0, 3387 3469 &d->exposedRegion, viewport()); 3470 d->scene->d_func()->rectAdjust = oldRectAdjust; 3388 3471 // Make sure the painter's world transform is restored correctly when 3389 3472 // drawing without painter state protection (DontSavePainterState). … … 3393 3476 // and restore() in QGraphicsScene::drawItems(). 3394 3477 if (!d->scene->d_func()->painterStateProtection) 3395 painter.setWorldTransform(viewTransform); 3478 painter.setOpacity(1.0); 3479 painter.setWorldTransform(viewTransform); 3396 3480 } else { 3397 3481 // Make sure we don't have unpolished items before we draw -
trunk/src/gui/graphicsview/qgraphicsview.h
r651 r846 1 1 /**************************************************************************** 2 2 ** 3 ** Copyright (C) 201 0Nokia Corporation and/or its subsidiary(-ies).3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). 4 4 ** All rights reserved. 5 5 ** Contact: Nokia Corporation (qt-info@nokia.com) -
trunk/src/gui/graphicsview/qgraphicsview_p.h
r769 r846 1 1 /**************************************************************************** 2 2 ** 3 ** Copyright (C) 201 0Nokia Corporation and/or its subsidiary(-ies).3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). 4 4 ** All rights reserved. 5 5 ** Contact: Nokia Corporation (qt-info@nokia.com) … … 66 66 QT_BEGIN_NAMESPACE 67 67 68 class Q_ AUTOTEST_EXPORT QGraphicsViewPrivate : public QAbstractScrollAreaPrivate68 class Q_GUI_EXPORT QGraphicsViewPrivate : public QAbstractScrollAreaPrivate 69 69 { 70 70 Q_DECLARE_PUBLIC(QGraphicsView) … … 78 78 79 79 QGraphicsView::DragMode dragMode; 80 bool sceneInteractionAllowed; 80 81 quint32 sceneInteractionAllowed : 1; 82 quint32 hasSceneRect : 1; 83 quint32 connectedToScene : 1; 84 quint32 useLastMouseEvent : 1; 85 quint32 identityMatrix : 1; 86 quint32 dirtyScroll : 1; 87 quint32 accelerateScrolling : 1; 88 quint32 keepLastCenterPoint : 1; 89 quint32 transforming : 1; 90 quint32 handScrolling : 1; 91 quint32 mustAllocateStyleOptions : 1; 92 quint32 mustResizeBackgroundPixmap : 1; 93 quint32 fullUpdatePending : 1; 94 quint32 hasUpdateClip : 1; 95 quint32 padding : 18; 96 81 97 QRectF sceneRect; 82 bool hasSceneRect;83 98 void updateLastCenterPoint(); 84 bool connectedToScene;85 99 86 100 qint64 horizontalScroll() const; … … 90 104 QRectF mapRectFromScene(const QRectF &rect) const; 91 105 106 QRect updateClip; 92 107 QPointF mousePressItemPoint; 93 108 QPointF mousePressScenePoint; … … 99 114 Qt::MouseButton mousePressButton; 100 115 QTransform matrix; 101 bool identityMatrix;102 116 qint64 scrollX, scrollY; 103 bool dirtyScroll;104 117 void updateScroll(); 105 118 106 bool accelerateScrolling;107 119 qreal leftIndent; 108 120 qreal topIndent; … … 110 122 // Replaying mouse events 111 123 QMouseEvent lastMouseEvent; 112 bool useLastMouseEvent;113 124 void replayLastMouseEvent(); 114 125 void storeMouseEvent(QMouseEvent *event); … … 116 127 117 128 QPointF lastCenterPoint; 118 bool keepLastCenterPoint;119 129 Qt::Alignment alignment; 120 bool transforming;121 130 122 131 QGraphicsView::ViewportAnchor transformationAnchor; … … 132 141 Qt::ItemSelectionMode rubberBandSelectionMode; 133 142 #endif 134 bool handScrolling;135 143 int handScrollMotions; 136 144 … … 138 146 139 147 QVector<QStyleOptionGraphicsItem> styleOptions; 140 bool mustAllocateStyleOptions;141 148 QStyleOptionGraphicsItem *allocStyleOptionsArray(int numItems); 142 149 void freeStyleOptionsArray(QStyleOptionGraphicsItem *array); … … 145 152 QBrush foregroundBrush; 146 153 QPixmap backgroundPixmap; 147 bool mustResizeBackgroundPixmap;148 154 QRegion backgroundPixmapExposed; 149 155 … … 162 168 QRect mapToViewRect(const QGraphicsItem *item, const QRectF &rect) const; 163 169 QRegion mapToViewRegion(const QGraphicsItem *item, const QRectF &rect) const; 164 bool fullUpdatePending;165 170 QRegion dirtyRegion; 166 171 QRect dirtyBoundingRect; … … 193 198 } 194 199 200 void setUpdateClip(QGraphicsItem *); 201 202 inline bool updateRectF(const QRectF &rect) 203 { 204 if (rect.isEmpty()) 205 return false; 206 if (optimizationFlags & QGraphicsView::DontAdjustForAntialiasing) 207 return updateRect(rect.toAlignedRect().adjusted(-1, -1, 1, 1)); 208 return updateRect(rect.toAlignedRect().adjusted(-2, -2, 2, 2)); 209 } 210 195 211 bool updateRect(const QRect &rect); 196 bool updateRegion(const QRe gion ®ion);212 bool updateRegion(const QRectF &rect, const QTransform &xform); 197 213 bool updateSceneSlotReimplementedChecked; 198 214 QRegion exposedRegion; -
trunk/src/gui/graphicsview/qgraphicswidget.cpp
r769 r846 1 1 /**************************************************************************** 2 2 ** 3 ** Copyright (C) 201 0Nokia Corporation and/or its subsidiary(-ies).3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). 4 4 ** All rights reserved. 5 5 ** Contact: Nokia Corporation (qt-info@nokia.com) … … 325 325 326 326 /*! 327 \fn QGraphicsWidget::geometryChanged() 328 329 This signal gets emitted whenever the geometry is changed in setGeometry(). 330 */ 331 332 /*! 327 333 \property QGraphicsWidget::geometry 328 334 \brief the geometry of the widget … … 380 386 //set the new pos 381 387 d->geom.moveTopLeft(pos()); 388 emit geometryChanged(); 382 389 return; 383 390 } … … 385 392 QSizeF oldSize = size(); 386 393 QGraphicsLayoutItem::setGeometry(newGeom); 387 388 394 // Send resize event 389 395 bool resized = newGeom.size() != oldSize; … … 392 398 re.setOldSize(oldSize); 393 399 re.setNewSize(newGeom.size()); 400 if (oldSize.width() != newGeom.size().width()) 401 emit widthChanged(); 402 if (oldSize.height() != newGeom.size().height()) 403 emit heightChanged(); 394 404 QApplication::sendEvent(this, &re); 395 405 } 406 emit geometryChanged(); 396 407 } 397 408 … … 440 451 441 452 Contents margins are used by the assigned layout to define the placement 442 of subwidgets and layouts. Margins are particular ily useful for widgets453 of subwidgets and layouts. Margins are particularly useful for widgets 443 454 that constrain subwidgets to only a section of its own geometry. For 444 455 example, a group box with a layout will place subwidgets inside its frame, … … 738 749 739 750 /*! 751 \property QGraphicsWidget::layout 752 \brief The layout of the widget 753 754 Any existing layout manager is deleted before the new layout is assigned. If 755 \a layout is 0, the widget is left without a layout. Existing subwidgets' 756 geometries will remain unaffected. 757 758 QGraphicsWidget takes ownership of \a layout. 759 760 All widgets that are currently managed by \a layout or all of its 761 sublayouts, are automatically reparented to this item. The layout is then 762 invalidated, and the child widget geometries are adjusted according to 763 this item's geometry() and contentsMargins(). Children who are not 764 explicitly managed by \a layout remain unaffected by the layout after 765 it has been assigned to this widget. 766 767 If no layout is currently managing this widget, layout() will return 0. 768 769 */ 770 771 /*! 772 \fn void QGraphicsWidget::layoutChanged() 773 This signal gets emitted whenever the layout of the item changes 774 \internal 775 */ 776 777 /*! 740 778 Returns this widget's layout, or 0 if no layout is currently managing this 741 779 widget. … … 790 828 l->d_func()->reparentChildItems(this); 791 829 l->invalidate(); 830 emit layoutChanged(); 792 831 } 793 832 … … 915 954 { 916 955 Q_D(const QGraphicsWidget); 917 return d->font; 956 QFont fnt = d->font; 957 fnt.resolve(fnt.resolve() | d->inheritedFontResolveMask); 958 return fnt; 918 959 } 919 960 void QGraphicsWidget::setFont(const QFont &font) … … 965 1006 QPalette resolvedPalette = palette.resolve(naturalPalette); 966 1007 d->setPalette_helper(resolvedPalette); 1008 } 1009 1010 /*! 1011 \property QGraphicsWidget::autoFillBackground 1012 \brief whether the widget background is filled automatically 1013 \since 4.7 1014 1015 If enabled, this property will cause Qt to fill the background of the 1016 widget before invoking the paint() method. The color used is defined by the 1017 QPalette::Window color role from the widget's \l{QPalette}{palette}. 1018 1019 In addition, Windows are always filled with QPalette::Window, unless the 1020 WA_OpaquePaintEvent or WA_NoSystemBackground attributes are set. 1021 1022 By default, this property is false. 1023 1024 \sa Qt::WA_OpaquePaintEvent, Qt::WA_NoSystemBackground, 1025 */ 1026 bool QGraphicsWidget::autoFillBackground() const 1027 { 1028 Q_D(const QGraphicsWidget); 1029 return d->autoFillBackground; 1030 } 1031 void QGraphicsWidget::setAutoFillBackground(bool enabled) 1032 { 1033 Q_D(QGraphicsWidget); 1034 if (d->autoFillBackground != enabled) { 1035 d->autoFillBackground = enabled; 1036 update(); 1037 } 967 1038 } 968 1039 … … 1048 1119 break; 1049 1120 case ItemParentChange: { 1050 QGraphicsItem *parent = qVariantValue<QGraphicsItem *>(value);1051 d->fixFocusChainBeforeReparenting((parent && parent->isWidget()) ? static_cast<QGraphicsWidget *>(parent) : 0, scene());1052 1053 1121 // Deliver ParentAboutToChange. 1054 1122 QEvent event(QEvent::ParentAboutToChange); -
trunk/src/gui/graphicsview/qgraphicswidget.h
r651 r846 1 1 /**************************************************************************** 2 2 ** 3 ** Copyright (C) 201 0Nokia Corporation and/or its subsidiary(-ies).3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). 4 4 ** All rights reserved. 5 5 ** Contact: Nokia Corporation (qt-info@nokia.com) … … 74 74 Q_PROPERTY(QFont font READ font WRITE setFont) 75 75 Q_PROPERTY(Qt::LayoutDirection layoutDirection READ layoutDirection WRITE setLayoutDirection RESET unsetLayoutDirection) 76 Q_PROPERTY(QSizeF size READ size WRITE resize )76 Q_PROPERTY(QSizeF size READ size WRITE resize NOTIFY geometryChanged) 77 77 Q_PROPERTY(QSizeF minimumSize READ minimumSize WRITE setMinimumSize) 78 78 Q_PROPERTY(QSizeF preferredSize READ preferredSize WRITE setPreferredSize) … … 82 82 Q_PROPERTY(Qt::WindowFlags windowFlags READ windowFlags WRITE setWindowFlags) 83 83 Q_PROPERTY(QString windowTitle READ windowTitle WRITE setWindowTitle) 84 Q_PROPERTY(QRectF geometry READ geometry WRITE setGeometry) 84 Q_PROPERTY(QRectF geometry READ geometry WRITE setGeometry NOTIFY geometryChanged) 85 Q_PROPERTY(bool autoFillBackground READ autoFillBackground WRITE setAutoFillBackground) 86 Q_PROPERTY(QGraphicsLayout* layout READ layout WRITE setLayout NOTIFY layoutChanged) 85 87 public: 86 88 QGraphicsWidget(QGraphicsItem *parent = 0, Qt::WindowFlags wFlags = 0); 87 89 ~QGraphicsWidget(); 88 89 90 QGraphicsLayout *layout() const; 90 91 void setLayout(QGraphicsLayout *layout); … … 103 104 QPalette palette() const; 104 105 void setPalette(const QPalette &palette); 106 107 bool autoFillBackground() const; 108 void setAutoFillBackground(bool enabled); 105 109 106 110 void resize(const QSizeF &size); … … 175 179 using QObject::children; 176 180 #endif 181 182 Q_SIGNALS: 183 void geometryChanged(); 184 void layoutChanged(); 177 185 178 186 public Q_SLOTS: -
trunk/src/gui/graphicsview/qgraphicswidget_p.cpp
r769 r846 1 1 /**************************************************************************** 2 2 ** 3 ** Copyright (C) 201 0Nokia Corporation and/or its subsidiary(-ies).3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). 4 4 ** All rights reserved. 5 5 ** Contact: Nokia Corporation (qt-info@nokia.com) … … 45 45 46 46 #include <QtCore/qdebug.h> 47 #include <QtCore/qnumeric.h> 47 48 #include "qgraphicswidget_p.h" 48 49 #include "qgraphicslayout.h" … … 71 72 windowFlags = wFlags; 72 73 73 q->setParentItem(parentItem); 74 if (parentItem) 75 setParentItemHelper(parentItem, 0, 0); 76 74 77 q->setSizePolicy(QSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred, QSizePolicy::DefaultType)); 75 78 q->setGraphicsItem(q); … … 77 80 resolveLayoutDirection(); 78 81 q->unsetWindowFrameMargins(); 79 q->setFlag(QGraphicsItem::ItemUsesExtendedStyleOption); 80 q->setFlag(QGraphicsItem::ItemSendsGeometryChanges); 82 flags |= QGraphicsItem::ItemUsesExtendedStyleOption; 83 flags |= QGraphicsItem::ItemSendsGeometryChanges; 84 if (windowFlags & Qt::Window) 85 flags |= QGraphicsItem::ItemIsPanel; 81 86 } 82 87 … … 250 255 void QGraphicsWidgetPrivate::resolveFont(uint inheritedMask) 251 256 { 257 Q_Q(QGraphicsWidget); 252 258 inheritedFontResolveMask = inheritedMask; 259 if (QGraphicsWidget *p = q->parentWidget()) 260 inheritedFontResolveMask |= p->d_func()->inheritedFontResolveMask; 253 261 QFont naturalFont = naturalWidgetFont(); 254 262 QFont resolvedFont = font.resolve(naturalFont); … … 757 765 QGraphicsWidget *firstOld = 0; 758 766 bool wasPreviousNew = true; 759 767 760 768 while (w != q) { 761 769 bool isCurrentNew = q->isAncestorOf(w); … … 792 800 793 801 if (oldScene && newScene != oldScene) 794 oldScene->d_func()->tabFocusFirst = firstOld;802 oldScene->d_func()->tabFocusFirst = (firstOld && firstOld->scene() == oldScene) ? firstOld : 0; 795 803 796 804 QGraphicsItem *topLevelItem = newParent ? newParent->topLevelItem() : 0; … … 826 834 } 827 835 836 qreal QGraphicsWidgetPrivate::width() const 837 { 838 Q_Q(const QGraphicsWidget); 839 return q->geometry().width(); 840 } 841 842 void QGraphicsWidgetPrivate::setWidth(qreal w) 843 { 844 if (qIsNaN(w)) 845 return; 846 Q_Q(QGraphicsWidget); 847 if (q->geometry().width() == w) 848 return; 849 850 QRectF oldGeom = q->geometry(); 851 852 q->setGeometry(QRectF(q->x(), q->y(), w, height())); 853 } 854 855 void QGraphicsWidgetPrivate::resetWidth() 856 { 857 Q_Q(QGraphicsWidget); 858 q->setGeometry(QRectF(q->x(), q->y(), 0, height())); 859 } 860 861 qreal QGraphicsWidgetPrivate::height() const 862 { 863 Q_Q(const QGraphicsWidget); 864 return q->geometry().height(); 865 } 866 867 void QGraphicsWidgetPrivate::setHeight(qreal h) 868 { 869 if (qIsNaN(h)) 870 return; 871 Q_Q(QGraphicsWidget); 872 if (q->geometry().height() == h) 873 return; 874 875 QRectF oldGeom = q->geometry(); 876 877 q->setGeometry(QRectF(q->x(), q->y(), width(), h)); 878 } 879 880 void QGraphicsWidgetPrivate::resetHeight() 881 { 882 Q_Q(QGraphicsWidget); 883 q->setGeometry(QRectF(q->x(), q->y(), width(), 0)); 884 } 885 828 886 void QGraphicsWidgetPrivate::setGeometryFromSetPos() 829 887 { -
trunk/src/gui/graphicsview/qgraphicswidget_p.h
r769 r846 1 1 /**************************************************************************** 2 2 ** 3 ** Copyright (C) 201 0Nokia Corporation and/or its subsidiary(-ies).3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). 4 4 ** All rights reserved. 5 5 ** Contact: Nokia Corporation (qt-info@nokia.com) … … 81 81 polished(0), 82 82 inSetPos(0), 83 autoFillBackground(0), 83 84 focusPolicy(Qt::NoFocus), 84 85 focusNext(0), … … 131 132 bool hasDecoration() const; 132 133 134 // Private Properties 135 qreal width() const; 136 void setWidth(qreal); 137 void resetWidth(); 138 139 qreal height() const; 140 void setHeight(qreal); 141 void resetHeight(); 133 142 void setGeometryFromSetPos(); 134 143 … … 175 184 quint32 polished: 1; 176 185 quint32 inSetPos : 1; 186 quint32 autoFillBackground : 1; 177 187 178 188 // Focus -
trunk/src/gui/graphicsview/qgridlayoutengine.cpp
r651 r846 1 1 /**************************************************************************** 2 2 ** 3 ** Copyright (C) 201 0Nokia Corporation and/or its subsidiary(-ies).3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). 4 4 ** All rights reserved. 5 5 ** Contact: Nokia Corporation (qt-info@nokia.com) … … 167 167 } 168 168 169 void QGridLayoutRowData::distributeMultiCells( )169 void QGridLayoutRowData::distributeMultiCells(const QGridLayoutRowInfo &rowInfo) 170 170 { 171 171 MultiCellMap::const_iterator i = multiCellMap.constBegin(); … … 186 186 if (extra > 0.0) { 187 187 calculateGeometries(start, end, box.q_sizes(j), dummy.data(), newSizes.data(), 188 0, totalBox );188 0, totalBox, rowInfo); 189 189 190 190 for (int k = 0; k < span; ++k) … … 195 195 for (int k = 0; k < span; ++k) { 196 196 boxes[start + k].combine(extras[k]); 197 stretches[start + k] = qMax(stretches[start + k], stretch); 197 if (stretch != 0) 198 stretches[start + k] = qMax(stretches[start + k], stretch); 198 199 } 199 200 } … … 203 204 void QGridLayoutRowData::calculateGeometries(int start, int end, qreal targetSize, qreal *positions, 204 205 qreal *sizes, qreal *descents, 205 const QGridLayoutBox &totalBox) 206 const QGridLayoutBox &totalBox, 207 const QGridLayoutRowInfo &rowInfo) 206 208 { 207 209 Q_ASSERT(end > start); 208 210 209 targetSize = q Bound(totalBox.q_minimumSize, targetSize, totalBox.q_maximumSize);211 targetSize = qMax(totalBox.q_minimumSize, targetSize); 210 212 211 213 int n = end - start; … … 247 249 } 248 250 } else { 249 stealBox(start, end, PreferredSize, positions, sizes); 250 251 sumAvailable = targetSize - totalBox.q_preferredSize; 251 bool isLargerThanMaximum = (targetSize > totalBox.q_maximumSize); 252 if (isLargerThanMaximum) { 253 stealBox(start, end, MaximumSize, positions, sizes); 254 sumAvailable = targetSize - totalBox.q_maximumSize; 255 } else { 256 stealBox(start, end, PreferredSize, positions, sizes); 257 sumAvailable = targetSize - totalBox.q_preferredSize; 258 } 259 252 260 if (sumAvailable > 0.0) { 261 qreal sumCurrentAvailable = sumAvailable; 253 262 bool somethingHasAMaximumSize = false; 254 263 255 qreal sum PreferredSizes = 0.0;264 qreal sumSizes = 0.0; 256 265 for (int i = 0; i < n; ++i) 257 sum PreferredSizes += sizes[i];266 sumSizes += sizes[i]; 258 267 259 268 for (int i = 0; i < n; ++i) { … … 265 274 266 275 const QGridLayoutBox &box = boxes.at(start + i); 267 qreal desired = box.q_maximumSize - box.q_preferredSize; 276 qreal boxSize; 277 278 qreal desired; 279 if (isLargerThanMaximum) { 280 boxSize = box.q_maximumSize; 281 desired = rowInfo.boxes.value(start + i).q_maximumSize - boxSize; 282 } else { 283 boxSize = box.q_preferredSize; 284 desired = box.q_maximumSize - boxSize; 285 } 268 286 if (desired == 0.0) { 269 287 newSizes[i] = sizes[i]; … … 284 302 factors[i] = 0.0; 285 303 } else { 286 qreal ultimate PreferredSize;287 qreal ultimateSum PreferredSizes;288 qreal x = ((stretch * sum PreferredSizes)289 - (sumStretches * box .q_preferredSize))304 qreal ultimateSize; 305 qreal ultimateSumSizes; 306 qreal x = ((stretch * sumSizes) 307 - (sumStretches * boxSize)) 290 308 / (sumStretches - stretch); 291 309 if (x >= 0.0) { 292 ultimate PreferredSize = box.q_preferredSize + x;293 ultimateSum PreferredSizes = sumPreferredSizes + x;310 ultimateSize = boxSize + x; 311 ultimateSumSizes = sumSizes + x; 294 312 } else { 295 ultimate PreferredSize = box.q_preferredSize;296 ultimateSum PreferredSizes = (sumStretches * box.q_preferredSize)313 ultimateSize = boxSize; 314 ultimateSumSizes = (sumStretches * boxSize) 297 315 / stretch; 298 316 } … … 303 321 during the transition). 304 322 */ 305 ultimatePreferredSize = ultimatePreferredSize * 3 / 2; 306 ultimateSumPreferredSizes = ultimateSumPreferredSizes * 3 / 2; 307 308 qreal ultimateFactor = (stretch * ultimateSumPreferredSizes 309 / sumStretches) 310 - (box.q_preferredSize); 311 qreal transitionalFactor = sumAvailable 312 * (ultimatePreferredSize - box.q_preferredSize) 313 / (ultimateSumPreferredSizes 314 - sumPreferredSizes); 315 316 qreal alpha = qMin(sumAvailable, 317 ultimateSumPreferredSizes - sumPreferredSizes); 318 qreal beta = ultimateSumPreferredSizes - sumPreferredSizes; 319 320 factors[i] = ((alpha * ultimateFactor) 321 + ((beta - alpha) * transitionalFactor)) / beta; 323 ultimateSize = ultimateSize * 3 / 2; 324 ultimateSumSizes = ultimateSumSizes * 3 / 2; 325 326 qreal beta = ultimateSumSizes - sumSizes; 327 if (!beta) { 328 factors[i] = 1; 329 } else { 330 qreal alpha = qMin(sumCurrentAvailable, beta); 331 qreal ultimateFactor = (stretch * ultimateSumSizes / sumStretches) 332 - (boxSize); 333 qreal transitionalFactor = sumCurrentAvailable * (ultimateSize - boxSize) / beta; 334 335 factors[i] = ((alpha * ultimateFactor) 336 + ((beta - alpha) * transitionalFactor)) / beta; 337 } 338 322 339 } 323 340 sumFactors += factors[i]; 324 if (desired < sum Available)341 if (desired < sumCurrentAvailable) 325 342 somethingHasAMaximumSize = true; 326 343 … … 337 354 continue; 338 355 339 const QGridLayoutBox &box = boxes.at(start + i); 340 qreal avail = sumAvailable * factors[i] / sumFactors; 341 if (sizes[i] + avail >= box.q_maximumSize) { 342 newSizes[i] = box.q_maximumSize; 343 sumAvailable -= box.q_maximumSize - sizes[i]; 356 qreal maxBoxSize; 357 if (isLargerThanMaximum) 358 maxBoxSize = rowInfo.boxes.value(start + i).q_maximumSize; 359 else 360 maxBoxSize = boxes.at(start + i).q_maximumSize; 361 362 qreal avail = sumCurrentAvailable * factors[i] / sumFactors; 363 if (sizes[i] + avail >= maxBoxSize) { 364 newSizes[i] = maxBoxSize; 365 sumCurrentAvailable -= maxBoxSize - sizes[i]; 344 366 sumFactors -= factors[i]; 345 keepGoing = (sum Available > 0.0);367 keepGoing = (sumCurrentAvailable > 0.0); 346 368 if (!keepGoing) 347 369 break; … … 353 375 if (newSizes[i] < 0.0) { 354 376 qreal delta = (sumFactors == 0.0) ? 0.0 355 : sum Available * factors[i] / sumFactors;377 : sumCurrentAvailable * factors[i] / sumFactors; 356 378 newSizes[i] = sizes[i] + delta; 357 379 } … … 546 568 } 547 569 570 /* 571 returns true if the size policy returns true for either hasHeightForWidth() 572 or hasWidthForHeight() 573 */ 574 bool QGridLayoutItem::hasDynamicConstraint() const 575 { 576 return QGraphicsLayoutItemPrivate::get(q_layoutItem)->hasHeightForWidth() 577 || QGraphicsLayoutItemPrivate::get(q_layoutItem)->hasWidthForHeight(); 578 } 579 580 Qt::Orientation QGridLayoutItem::dynamicConstraintOrientation() const 581 { 582 if (QGraphicsLayoutItemPrivate::get(q_layoutItem)->hasHeightForWidth()) 583 return Qt::Vertical; 584 else //if (QGraphicsLayoutItemPrivate::get(q_layoutItem)->hasWidthForHeight()) 585 return Qt::Horizontal; 586 } 587 548 588 QSizePolicy::ControlTypes QGridLayoutItem::controlTypes(LayoutSide /* side */) const 549 589 { … … 614 654 qreal cellHeight = height; 615 655 616 QSizeF size = effectiveMaxSize().boundedTo(QSizeF(cellWidth, cellHeight)); 656 657 QSizeF size = effectiveMaxSize(QSizeF(-1,-1)); 658 if (hasDynamicConstraint()) { 659 if (dynamicConstraintOrientation() == Qt::Vertical) { 660 if (size.width() > cellWidth) 661 size = effectiveMaxSize(QSizeF(cellWidth, -1)); 662 } else if (size.height() > cellHeight) { 663 size = effectiveMaxSize(QSizeF(-1, cellHeight)); 664 } 665 } 666 size = size.boundedTo(QSizeF(cellWidth, cellHeight)); 617 667 width = size.width(); 618 668 height = size.height(); … … 676 726 (since it only evaluates the hints, as the name implies) 677 727 */ 678 QSizeF QGridLayoutItem::effectiveMaxSize( ) const679 { 680 QSizeF size ;728 QSizeF QGridLayoutItem::effectiveMaxSize(const QSizeF &constraint) const 729 { 730 QSizeF size = constraint; 681 731 bool vGrow = (sizePolicy(Qt::Vertical) & QSizePolicy::GrowFlag) == QSizePolicy::GrowFlag; 682 732 bool hGrow = (sizePolicy(Qt::Horizontal) & QSizePolicy::GrowFlag) == QSizePolicy::GrowFlag; 683 733 if (!vGrow || !hGrow) { 684 QSizeF pref = layoutItem()->effectiveSizeHint(Qt::PreferredSize );734 QSizeF pref = layoutItem()->effectiveSizeHint(Qt::PreferredSize, constraint); 685 735 if (!vGrow) 686 736 size.setHeight(pref.height()); … … 690 740 691 741 if (!size.isValid()) { 692 QSizeF maxSize = layoutItem()->effectiveSizeHint(Qt::MaximumSize );742 QSizeF maxSize = layoutItem()->effectiveSizeHint(Qt::MaximumSize, size); 693 743 if (size.width() == -1) 694 744 size.setWidth(maxSize.width()); … … 1011 1061 q_cachedDataForStyleInfo.invalidate(); 1012 1062 q_cachedSize = QSizeF(); 1063 q_cachedConstraintOrientation = UnknownConstraint; 1013 1064 } 1014 1065 … … 1075 1126 1076 1127 QSizeF QGridLayoutEngine::sizeHint(const QLayoutStyleInfo &styleInfo, Qt::SizeHint which, 1077 const QSizeF & /* constraint */) const 1078 { 1079 ensureColumnAndRowData(styleInfo); 1128 const QSizeF &constraint) const 1129 { 1130 QGridLayoutBox sizehint_totalBoxes[NOrientations]; 1131 1132 bool sizeHintCalculated = false; 1133 1134 if (hasDynamicConstraint() && rowCount() > 0 && columnCount() > 0) { 1135 if (constraintOrientation() == Qt::Vertical) { 1136 //We have items whose height depends on their width 1137 if (constraint.width() >= 0) { 1138 if (q_cachedDataForStyleInfo != styleInfo) 1139 ensureColumnAndRowData(&q_columnData, &sizehint_totalBoxes[Hor], styleInfo, NULL, NULL, Qt::Horizontal); 1140 else 1141 sizehint_totalBoxes[Hor] = q_totalBoxes[Hor]; 1142 QVector<qreal> sizehint_xx; 1143 QVector<qreal> sizehint_widths; 1144 1145 sizehint_xx.resize(columnCount()); 1146 sizehint_widths.resize(columnCount()); 1147 qreal width = constraint.width(); 1148 //Calculate column widths and positions, and put results in q_xx.data() and q_widths.data() so that we can use this information as 1149 //constraints to find the row heights 1150 q_columnData.calculateGeometries(0, columnCount(), width, sizehint_xx.data(), sizehint_widths.data(), 1151 0, sizehint_totalBoxes[Hor], q_infos[Hor]); 1152 ensureColumnAndRowData(&q_rowData, &sizehint_totalBoxes[Ver], styleInfo, sizehint_xx.data(), sizehint_widths.data(), Qt::Vertical); 1153 sizeHintCalculated = true; 1154 } 1155 } else { 1156 if (constraint.height() >= 0) { 1157 //We have items whose width depends on their height 1158 ensureColumnAndRowData(&q_rowData, &sizehint_totalBoxes[Ver], styleInfo, NULL, NULL, Qt::Vertical); 1159 QVector<qreal> sizehint_yy; 1160 QVector<qreal> sizehint_heights; 1161 1162 sizehint_yy.resize(rowCount()); 1163 sizehint_heights.resize(rowCount()); 1164 qreal height = constraint.height(); 1165 //Calculate row heights and positions, and put results in q_yy.data() and q_heights.data() so that we can use this information as 1166 //constraints to find the column widths 1167 q_rowData.calculateGeometries(0, rowCount(), height, sizehint_yy.data(), sizehint_heights.data(), 1168 0, sizehint_totalBoxes[Ver], q_infos[Ver]); 1169 ensureColumnAndRowData(&q_columnData, &sizehint_totalBoxes[Hor], styleInfo, sizehint_yy.data(), sizehint_heights.data(), Qt::Vertical); 1170 sizeHintCalculated = true; 1171 } 1172 } 1173 } 1174 1175 if (!sizeHintCalculated) { 1176 //No items with height for width, so it doesn't matter which order we do these in 1177 if (q_cachedDataForStyleInfo != styleInfo) { 1178 ensureColumnAndRowData(&q_columnData, &sizehint_totalBoxes[Hor], styleInfo, NULL, NULL, Qt::Horizontal); 1179 ensureColumnAndRowData(&q_rowData, &sizehint_totalBoxes[Ver], styleInfo, NULL, NULL, Qt::Vertical); 1180 } else { 1181 sizehint_totalBoxes[Hor] = q_totalBoxes[Hor]; 1182 sizehint_totalBoxes[Ver] = q_totalBoxes[Ver]; 1183 } 1184 } 1080 1185 1081 1186 switch (which) { 1082 1187 case Qt::MinimumSize: 1083 return QSizeF( q_totalBoxes[Hor].q_minimumSize, q_totalBoxes[Ver].q_minimumSize);1188 return QSizeF(sizehint_totalBoxes[Hor].q_minimumSize, sizehint_totalBoxes[Ver].q_minimumSize); 1084 1189 case Qt::PreferredSize: 1085 return QSizeF( q_totalBoxes[Hor].q_preferredSize, q_totalBoxes[Ver].q_preferredSize);1190 return QSizeF(sizehint_totalBoxes[Hor].q_preferredSize, sizehint_totalBoxes[Ver].q_preferredSize); 1086 1191 case Qt::MaximumSize: 1087 return QSizeF( q_totalBoxes[Hor].q_maximumSize, q_totalBoxes[Ver].q_maximumSize);1192 return QSizeF(sizehint_totalBoxes[Hor].q_maximumSize, sizehint_totalBoxes[Ver].q_maximumSize); 1088 1193 case Qt::MinimumDescent: 1089 return QSizeF(-1.0, q_totalBoxes[Hor].q_minimumDescent); // ### doesn't work1194 return QSizeF(-1.0, sizehint_totalBoxes[Hor].q_minimumDescent); // ### doesn't work 1090 1195 default: 1091 1196 break; … … 1263 1368 1264 1369 void QGridLayoutEngine::fillRowData(QGridLayoutRowData *rowData, const QLayoutStyleInfo &styleInfo, 1370 qreal *colPositions, qreal *colSizes, 1265 1371 Qt::Orientation orientation) const 1266 1372 { … … 1368 1474 if (effectiveRowSpan == 1) { 1369 1475 box = &rowBox; 1370 if (!userRowStretch )1476 if (!userRowStretch && itemStretch != 0) 1371 1477 rowStretch = qMax(rowStretch, itemStretch); 1372 1478 } else { … … 1376 1482 multiCell.q_stretch = itemStretch; 1377 1483 } 1378 box->combine(item->box(orientation)); 1484 // Items with constraints need to be passed the constraint 1485 if (colSizes && colPositions && item->hasDynamicConstraint() && orientation == item->dynamicConstraintOrientation()) { 1486 /* Get the width of the item by summing up the widths of the columns that it spans. 1487 * We need to have already calculated the widths of the columns by calling 1488 * q_columns->calculateGeometries() before hand and passing the value in the colSizes 1489 * and colPositions parameters. 1490 * The variable name is still colSizes even when it actually has the row sizes 1491 */ 1492 qreal length = colSizes[item->lastColumn(orientation)]; 1493 if (item->columnSpan(orientation) != 1) 1494 length += colPositions[item->lastColumn(orientation)] - colPositions[item->firstColumn(orientation)]; 1495 box->combine(item->box(orientation, length)); 1496 } else { 1497 box->combine(item->box(orientation)); 1498 } 1379 1499 1380 1500 if (effectiveRowSpan == 1) { … … 1513 1633 } 1514 1634 1515 void QGridLayoutEngine::ensureColumnAndRowData(const QLayoutStyleInfo &styleInfo) const 1516 { 1517 if (q_cachedDataForStyleInfo == styleInfo) 1518 return; 1519 1520 q_columnData.reset(columnCount()); 1521 q_rowData.reset(rowCount()); 1522 1523 fillRowData(&q_columnData, styleInfo, Qt::Horizontal); 1524 fillRowData(&q_rowData, styleInfo, Qt::Vertical); 1525 1526 q_columnData.distributeMultiCells(); 1527 q_rowData.distributeMultiCells(); 1528 1529 q_totalBoxes[Hor] = q_columnData.totalBox(0, columnCount()); 1530 q_totalBoxes[Ver] = q_rowData.totalBox(0, rowCount()); 1531 1532 q_cachedDataForStyleInfo = styleInfo; 1635 void QGridLayoutEngine::ensureColumnAndRowData(QGridLayoutRowData *rowData, QGridLayoutBox *totalBox, 1636 const QLayoutStyleInfo &styleInfo, 1637 qreal *colPositions, qreal *colSizes, 1638 Qt::Orientation orientation) const 1639 { 1640 rowData->reset(rowCount(orientation)); 1641 fillRowData(rowData, styleInfo, colPositions, colSizes, orientation); 1642 const QGridLayoutRowInfo &rowInfo = q_infos[orientation == Qt::Vertical]; 1643 rowData->distributeMultiCells(rowInfo); 1644 *totalBox = rowData->totalBox(0, rowCount(orientation)); 1645 //We have items whose width depends on their height 1646 } 1647 1648 /** 1649 returns false if the layout has contradicting constraints (i.e. some items with a horizontal 1650 constraint and other items with a vertical constraint) 1651 */ 1652 bool QGridLayoutEngine::ensureDynamicConstraint() const 1653 { 1654 if (q_cachedConstraintOrientation == UnknownConstraint) { 1655 for (int i = q_items.count() - 1; i >= 0; --i) { 1656 QGridLayoutItem *item = q_items.at(i); 1657 if (item->hasDynamicConstraint()) { 1658 Qt::Orientation itemConstraintOrientation = item->dynamicConstraintOrientation(); 1659 if (q_cachedConstraintOrientation == UnknownConstraint) { 1660 q_cachedConstraintOrientation = itemConstraintOrientation; 1661 } else if (q_cachedConstraintOrientation != itemConstraintOrientation) { 1662 q_cachedConstraintOrientation = UnfeasibleConstraint; 1663 qWarning("QGridLayoutEngine: Unfeasible, cannot mix horizontal and" 1664 " vertical constraint in the same layout"); 1665 return false; 1666 } 1667 } 1668 } 1669 if (q_cachedConstraintOrientation == UnknownConstraint) 1670 q_cachedConstraintOrientation = NoConstraint; 1671 } 1672 return true; 1673 } 1674 1675 bool QGridLayoutEngine::hasDynamicConstraint() const 1676 { 1677 if (!ensureDynamicConstraint()) 1678 return false; 1679 return q_cachedConstraintOrientation != NoConstraint; 1680 } 1681 1682 /* 1683 * return value is only valid if hasConstraint() returns true 1684 */ 1685 Qt::Orientation QGridLayoutEngine::constraintOrientation() const 1686 { 1687 (void)ensureDynamicConstraint(); 1688 return (Qt::Orientation)q_cachedConstraintOrientation; 1533 1689 } 1534 1690 … … 1536 1692 const QSizeF &size) const 1537 1693 { 1538 ensureColumnAndRowData(styleInfo); 1539 if (q_cachedSize == size) 1694 if (q_cachedDataForStyleInfo == styleInfo && q_cachedSize == size) 1540 1695 return; 1541 1696 1697 q_cachedDataForStyleInfo = styleInfo; 1698 q_cachedSize = size; 1699 1542 1700 q_xx.resize(columnCount()); 1701 q_widths.resize(columnCount()); 1543 1702 q_yy.resize(rowCount()); 1544 q_widths.resize(columnCount());1545 1703 q_heights.resize(rowCount()); 1546 1704 q_descents.resize(rowCount()); 1547 q_columnData.calculateGeometries(0, columnCount(), size.width(), q_xx.data(), q_widths.data(), 1548 0, q_totalBoxes[Hor]); 1549 q_rowData.calculateGeometries(0, rowCount(), size.height(), q_yy.data(), q_heights.data(), 1550 q_descents.data(), q_totalBoxes[Ver]); 1551 1552 q_cachedSize = size; 1705 1706 if (constraintOrientation() != Qt::Horizontal) { 1707 //We might have items whose width depends on their height 1708 ensureColumnAndRowData(&q_columnData, &q_totalBoxes[Hor], styleInfo, NULL, NULL, Qt::Horizontal); 1709 //Calculate column widths and positions, and put results in q_xx.data() and q_widths.data() so that we can use this information as 1710 //constraints to find the row heights 1711 q_columnData.calculateGeometries(0, columnCount(), size.width(), q_xx.data(), q_widths.data(), 1712 0, q_totalBoxes[Hor], q_infos[Hor] ); 1713 ensureColumnAndRowData(&q_rowData, &q_totalBoxes[Ver], styleInfo, q_xx.data(), q_widths.data(), Qt::Vertical); 1714 //Calculate row heights and positions, and put results in q_yy.data() and q_heights.data() 1715 q_rowData.calculateGeometries(0, rowCount(), size.height(), q_yy.data(), q_heights.data(), 1716 q_descents.data(), q_totalBoxes[Ver], q_infos[Ver]); 1717 } else { 1718 //We have items whose height depends on their width 1719 ensureColumnAndRowData(&q_rowData, &q_totalBoxes[Ver], styleInfo, NULL, NULL, Qt::Vertical); 1720 //Calculate row heights and positions, and put results in q_yy.data() and q_heights.data() so that we can use this information as 1721 //constraints to find the column widths 1722 q_rowData.calculateGeometries(0, rowCount(), size.height(), q_yy.data(), q_heights.data(), 1723 q_descents.data(), q_totalBoxes[Ver], q_infos[Ver]); 1724 ensureColumnAndRowData(&q_columnData, &q_totalBoxes[Hor], styleInfo, q_yy.data(), q_heights.data(), Qt::Horizontal); 1725 //Calculate row heights and positions, and put results in q_yy.data() and q_heights.data() 1726 q_columnData.calculateGeometries(0, columnCount(), size.width(), q_xx.data(), q_widths.data(), 1727 0, q_totalBoxes[Hor], q_infos[Hor]); 1728 } 1553 1729 } 1554 1730 -
trunk/src/gui/graphicsview/qgridlayoutengine_p.h
r651 r846 1 1 /**************************************************************************** 2 2 ** 3 ** Copyright (C) 201 0Nokia Corporation and/or its subsidiary(-ies).3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). 4 4 ** All rights reserved. 5 5 ** Contact: Nokia Corporation (qt-info@nokia.com) … … 90 90 Right, 91 91 Bottom 92 }; 93 94 enum { 95 NoConstraint, 96 HorizontalConstraint, // Width depends on the height 97 VerticalConstraint, // Height depends on the width 98 UnknownConstraint, // need to update cache 99 UnfeasibleConstraint // not feasible, it be has some items with Vertical and others with Horizontal constraints 92 100 }; 93 101 … … 217 225 typedef QMap<QPair<int, int>, QGridLayoutMultiCellData> MultiCellMap; 218 226 227 class QGridLayoutRowInfo; 228 219 229 class QGridLayoutRowData 220 230 { 221 231 public: 222 232 void reset(int count); 223 void distributeMultiCells( );233 void distributeMultiCells(const QGridLayoutRowInfo &rowInfo); 224 234 void calculateGeometries(int start, int end, qreal targetSize, qreal *positions, qreal *sizes, 225 qreal *descents, const QGridLayoutBox &totalBox); 235 qreal *descents, const QGridLayoutBox &totalBox, 236 const QGridLayoutRowInfo &rowInfo); 226 237 QGridLayoutBox totalBox(int start, int end) const; 227 238 void stealBox(int start, int end, int which, qreal *positions, qreal *sizes); … … 271 282 272 283 QSizePolicy::Policy sizePolicy(Qt::Orientation orientation) const; 284 285 bool hasDynamicConstraint() const; 286 Qt::Orientation dynamicConstraintOrientation() const; 287 273 288 QSizePolicy::ControlTypes controlTypes(LayoutSide side) const; 274 289 QSizeF sizeHint(Qt::SizeHint which, const QSizeF &constraint = QSizeF()) const; … … 281 296 void transpose(); 282 297 void insertOrRemoveRows(int row, int delta, Qt::Orientation orientation = Qt::Vertical); 283 QSizeF effectiveMaxSize( ) const;298 QSizeF effectiveMaxSize(const QSizeF &constraint) const; 284 299 285 300 #ifdef QT_DEBUG … … 364 379 inline void insertRow(int row, Qt::Orientation orientation = Qt::Vertical) 365 380 { insertOrRemoveRows(row, +1, orientation); } 366 inline void removeRow (int row, Qt::Orientation orientation = Qt::Vertical)367 { insertOrRemoveRows(row, - 1, orientation); }381 inline void removeRows(int row, int count, Qt::Orientation orientation) 382 { insertOrRemoveRows(row, -count, orientation); } 368 383 369 384 void invalidate(); … … 373 388 QSizeF sizeHint(const QLayoutStyleInfo &styleInfo, Qt::SizeHint which, 374 389 const QSizeF &constraint) const; 390 391 // heightForWidth / widthForHeight support 392 QSizeF dynamicallyConstrainedSizeHint(Qt::SizeHint which, const QSizeF &constraint) const; 393 bool ensureDynamicConstraint() const; 394 bool hasDynamicConstraint() const; 395 Qt::Orientation constraintOrientation() const; 396 397 375 398 QSizePolicy::ControlTypes controlTypes(LayoutSide side) const; 376 399 void transpose(); … … 391 414 void insertOrRemoveRows(int row, int delta, Qt::Orientation orientation = Qt::Vertical); 392 415 void fillRowData(QGridLayoutRowData *rowData, const QLayoutStyleInfo &styleInfo, 393 Qt::Orientation orientation = Qt::Vertical) const; 416 qreal *colPositions, qreal *colSizes, 417 Qt::Orientation orientation = Qt::Vertical) const; 394 418 void ensureEffectiveFirstAndLastRows() const; 395 void ensureColumnAndRowData(const QLayoutStyleInfo &styleInfo) const; 419 void ensureColumnAndRowData(QGridLayoutRowData *rowData, QGridLayoutBox *totalBox, 420 const QLayoutStyleInfo &styleInfo, 421 qreal *colPositions, qreal *colSizes, 422 Qt::Orientation orientation) const; 423 396 424 void ensureGeometries(const QLayoutStyleInfo &styleInfo, const QSizeF &size) const; 397 425 … … 406 434 mutable int q_cachedEffectiveFirstRows[NOrientations]; 407 435 mutable int q_cachedEffectiveLastRows[NOrientations]; 436 mutable quint8 q_cachedConstraintOrientation : 3; 408 437 409 438 // Layout item input -
trunk/src/gui/graphicsview/qsimplex_p.cpp
r651 r846 1 1 /**************************************************************************** 2 2 ** 3 ** Copyright (C) 201 0Nokia Corporation and/or its subsidiary(-ies).3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). 4 4 ** All rights reserved. 5 5 ** Contact: Nokia Corporation (qt-info@nokia.com) -
trunk/src/gui/graphicsview/qsimplex_p.h
r651 r846 1 1 /**************************************************************************** 2 2 ** 3 ** Copyright (C) 201 0Nokia Corporation and/or its subsidiary(-ies).3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). 4 4 ** All rights reserved. 5 5 ** Contact: Nokia Corporation (qt-info@nokia.com)
Note:
See TracChangeset
for help on using the changeset viewer.