1 /**************************************************************************** |
1 /**************************************************************************** |
2 ** |
2 ** |
3 ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). |
3 ** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). |
4 ** All rights reserved. |
4 ** All rights reserved. |
5 ** Contact: Nokia Corporation (qt-info@nokia.com) |
5 ** Contact: Nokia Corporation (qt-info@nokia.com) |
6 ** |
6 ** |
7 ** This file is part of the QtGui module of the Qt Toolkit. |
7 ** This file is part of the QtGui module of the Qt Toolkit. |
8 ** |
8 ** |
290 updateAll(false), |
290 updateAll(false), |
291 calledEmitUpdated(false), |
291 calledEmitUpdated(false), |
292 processDirtyItemsEmitted(false), |
292 processDirtyItemsEmitted(false), |
293 selectionChanging(0), |
293 selectionChanging(0), |
294 needSortTopLevelItems(true), |
294 needSortTopLevelItems(true), |
|
295 unpolishedItemsModified(true), |
295 holesInTopLevelSiblingIndex(false), |
296 holesInTopLevelSiblingIndex(false), |
296 topLevelSequentialOrdering(true), |
297 topLevelSequentialOrdering(true), |
297 scenePosDescendantsUpdatePending(false), |
298 scenePosDescendantsUpdatePending(false), |
298 stickyFocus(false), |
299 stickyFocus(false), |
299 hasFocus(false), |
300 hasFocus(false), |
426 /*! |
427 /*! |
427 \internal |
428 \internal |
428 */ |
429 */ |
429 void QGraphicsScenePrivate::_q_polishItems() |
430 void QGraphicsScenePrivate::_q_polishItems() |
430 { |
431 { |
431 QSet<QGraphicsItem *>::Iterator it; |
432 QSet<QGraphicsItem *>::Iterator it = unpolishedItems.begin(); |
432 const QVariant booleanTrueVariant(true); |
433 const QVariant booleanTrueVariant(true); |
433 while (!unpolishedItems.isEmpty()) { |
434 while (!unpolishedItems.isEmpty()) { |
434 it = unpolishedItems.begin(); |
|
435 QGraphicsItem *item = *it; |
435 QGraphicsItem *item = *it; |
436 unpolishedItems.erase(it); |
436 it = unpolishedItems.erase(it); |
|
437 unpolishedItemsModified = false; |
437 if (!item->d_ptr->explicitlyHidden) { |
438 if (!item->d_ptr->explicitlyHidden) { |
438 item->itemChange(QGraphicsItem::ItemVisibleChange, booleanTrueVariant); |
439 item->itemChange(QGraphicsItem::ItemVisibleChange, booleanTrueVariant); |
439 item->itemChange(QGraphicsItem::ItemVisibleHasChanged, booleanTrueVariant); |
440 item->itemChange(QGraphicsItem::ItemVisibleHasChanged, booleanTrueVariant); |
440 } |
441 } |
441 if (item->isWidget()) { |
442 if (item->isWidget()) { |
442 QEvent event(QEvent::Polish); |
443 QEvent event(QEvent::Polish); |
443 QApplication::sendEvent((QGraphicsWidget *)item, &event); |
444 QApplication::sendEvent((QGraphicsWidget *)item, &event); |
444 } |
445 } |
|
446 if (unpolishedItemsModified) |
|
447 it = unpolishedItems.begin(); |
445 } |
448 } |
446 } |
449 } |
447 |
450 |
448 void QGraphicsScenePrivate::_q_processDirtyItems() |
451 void QGraphicsScenePrivate::_q_processDirtyItems() |
449 { |
452 { |
634 // Update selected & hovered item bookkeeping |
637 // Update selected & hovered item bookkeeping |
635 selectedItems.remove(item); |
638 selectedItems.remove(item); |
636 hoverItems.removeAll(item); |
639 hoverItems.removeAll(item); |
637 cachedItemsUnderMouse.removeAll(item); |
640 cachedItemsUnderMouse.removeAll(item); |
638 unpolishedItems.remove(item); |
641 unpolishedItems.remove(item); |
|
642 unpolishedItemsModified = true; |
639 resetDirtyItem(item); |
643 resetDirtyItem(item); |
640 |
644 |
641 //We remove all references of item from the sceneEventFilter arrays |
645 //We remove all references of item from the sceneEventFilter arrays |
642 QMultiMap<QGraphicsItem*, QGraphicsItem*>::iterator iterator = sceneEventFilters.begin(); |
646 QMultiMap<QGraphicsItem*, QGraphicsItem*>::iterator iterator = sceneEventFilters.begin(); |
643 while (iterator != sceneEventFilters.end()) { |
647 while (iterator != sceneEventFilters.end()) { |
1130 enabled, the event is sent; otherwise it is stopped. |
1134 enabled, the event is sent; otherwise it is stopped. |
1131 */ |
1135 */ |
1132 bool QGraphicsScenePrivate::sendEvent(QGraphicsItem *item, QEvent *event) |
1136 bool QGraphicsScenePrivate::sendEvent(QGraphicsItem *item, QEvent *event) |
1133 { |
1137 { |
1134 if (QGraphicsObject *object = item->toGraphicsObject()) { |
1138 if (QGraphicsObject *object = item->toGraphicsObject()) { |
1135 if (qt_gestureManager) { |
1139 QGestureManager *gestureManager = QApplicationPrivate::instance()->gestureManager; |
1136 if (qt_gestureManager->filterEvent(object, event)) |
1140 if (gestureManager) { |
|
1141 if (gestureManager->filterEvent(object, event)) |
1137 return true; |
1142 return true; |
1138 } |
1143 } |
1139 } |
1144 } |
1140 |
1145 |
1141 if (filterEvent(item, event)) |
1146 if (filterEvent(item, event)) |
1559 d_func()->init(); |
1564 d_func()->init(); |
1560 setSceneRect(x, y, width, height); |
1565 setSceneRect(x, y, width, height); |
1561 } |
1566 } |
1562 |
1567 |
1563 /*! |
1568 /*! |
1564 Destroys the QGraphicsScene object. |
1569 Removes and deletes all items from the scene object |
|
1570 before destroying the scene object. The scene object |
|
1571 is removed from the application's global scene list, |
|
1572 and it is removed from all associated views. |
1565 */ |
1573 */ |
1566 QGraphicsScene::~QGraphicsScene() |
1574 QGraphicsScene::~QGraphicsScene() |
1567 { |
1575 { |
1568 Q_D(QGraphicsScene); |
1576 Q_D(QGraphicsScene); |
1569 |
1577 |
2441 removeItem(group); |
2449 removeItem(group); |
2442 delete group; |
2450 delete group; |
2443 } |
2451 } |
2444 |
2452 |
2445 /*! |
2453 /*! |
2446 Adds or moves the item \a item and all its childen to the scene. |
2454 Adds or moves the \a item and all its childen to this scene. |
|
2455 This scene takes ownership of the \a item. |
2447 |
2456 |
2448 If the item is visible (i.e., QGraphicsItem::isVisible() returns |
2457 If the item is visible (i.e., QGraphicsItem::isVisible() returns |
2449 true), QGraphicsScene will emit changed() once control goes back |
2458 true), QGraphicsScene will emit changed() once control goes back |
2450 to the event loop. |
2459 to the event loop. |
2451 |
2460 |
2452 If the item is already in a different scene, it will first be removed from |
2461 If the item is already in a different scene, it will first be |
2453 its old scene, and then added to this scene as a top-level. |
2462 removed from its old scene, and then added to this scene as a |
2454 |
2463 top-level. |
2455 QGraphicsScene will send ItemSceneChange notifications to \a item while |
2464 |
2456 it is added to the scene. If item does not currently belong to a scene, only one |
2465 QGraphicsScene will send ItemSceneChange notifications to \a item |
2457 notification is sent. If it does belong to scene already (i.e., it is |
2466 while it is added to the scene. If item does not currently belong |
2458 moved to this scene), QGraphicsScene will send an addition notification as |
2467 to a scene, only one notification is sent. If it does belong to |
2459 the item is removed from its previous scene. |
2468 scene already (i.e., it is moved to this scene), QGraphicsScene |
2460 |
2469 will send an addition notification as the item is removed from its |
2461 If the item is a panel, the scene is active, and there is no active panel |
2470 previous scene. |
2462 in the scene, then the item will be activated. |
2471 |
|
2472 If the item is a panel, the scene is active, and there is no |
|
2473 active panel in the scene, then the item will be activated. |
2463 |
2474 |
2464 \sa removeItem(), addEllipse(), addLine(), addPath(), addPixmap(), |
2475 \sa removeItem(), addEllipse(), addLine(), addPath(), addPixmap(), |
2465 addRect(), addText(), addWidget(), {QGraphicsItem#Sorting}{Sorting} |
2476 addRect(), addText(), addWidget(), {QGraphicsItem#Sorting}{Sorting} |
2466 */ |
2477 */ |
2467 void QGraphicsScene::addItem(QGraphicsItem *item) |
2478 void QGraphicsScene::addItem(QGraphicsItem *item) |
2569 |
2580 |
2570 // Resolve font and palette. |
2581 // Resolve font and palette. |
2571 item->d_ptr->resolveFont(d->font.resolve()); |
2582 item->d_ptr->resolveFont(d->font.resolve()); |
2572 item->d_ptr->resolvePalette(d->palette.resolve()); |
2583 item->d_ptr->resolvePalette(d->palette.resolve()); |
2573 |
2584 |
2574 if (d->unpolishedItems.isEmpty()) |
2585 if (d->unpolishedItems.isEmpty()) |
2575 QMetaObject::invokeMethod(this, "_q_polishItems", Qt::QueuedConnection); |
2586 QMetaObject::invokeMethod(this, "_q_polishItems", Qt::QueuedConnection); |
2576 d->unpolishedItems.insert(item); |
2587 d->unpolishedItems.insert(item); |
|
2588 d->unpolishedItemsModified = true; |
2577 |
2589 |
2578 // Reenable selectionChanged() for individual items |
2590 // Reenable selectionChanged() for individual items |
2579 --d->selectionChanging; |
2591 --d->selectionChanging; |
2580 if (!d->selectionChanging && d->selectedItems.size() != oldSelectedItemSize) |
2592 if (!d->selectionChanging && d->selectedItems.size() != oldSelectedItemSize) |
2581 emit selectionChanged(); |
2593 emit selectionChanged(); |
4672 painter->setOpacity(opacity); |
4684 painter->setOpacity(opacity); |
4673 |
4685 |
4674 if (sourced->currentCachedSystem() != Qt::LogicalCoordinates |
4686 if (sourced->currentCachedSystem() != Qt::LogicalCoordinates |
4675 && sourced->lastEffectTransform != painter->worldTransform()) |
4687 && sourced->lastEffectTransform != painter->worldTransform()) |
4676 { |
4688 { |
|
4689 bool unclipped = false; |
|
4690 if (sourced->lastEffectTransform.type() <= QTransform::TxTranslate |
|
4691 && painter->worldTransform().type() <= QTransform::TxTranslate) |
|
4692 { |
|
4693 QRectF itemRect = item->boundingRect(); |
|
4694 if (!item->d_ptr->children.isEmpty()) |
|
4695 itemRect |= item->childrenBoundingRect(); |
|
4696 |
|
4697 QRectF oldSourceRect = sourced->lastEffectTransform.mapRect(itemRect); |
|
4698 QRectF newSourceRect = painter->worldTransform().mapRect(itemRect); |
|
4699 |
|
4700 QRect oldEffectRect = sourced->paddedEffectRect(sourced->currentCachedSystem(), sourced->currentCachedMode(), oldSourceRect); |
|
4701 QRect newEffectRect = sourced->paddedEffectRect(sourced->currentCachedSystem(), sourced->currentCachedMode(), newSourceRect); |
|
4702 |
|
4703 QRect deviceRect(0, 0, painter->device()->width(), painter->device()->height()); |
|
4704 if (deviceRect.contains(oldEffectRect) && deviceRect.contains(newEffectRect)) { |
|
4705 sourced->setCachedOffset(newEffectRect.topLeft()); |
|
4706 unclipped = true; |
|
4707 } |
|
4708 } |
|
4709 |
4677 sourced->lastEffectTransform = painter->worldTransform(); |
4710 sourced->lastEffectTransform = painter->worldTransform(); |
4678 sourced->invalidateCache(QGraphicsEffectSourcePrivate::TransformChanged); |
4711 |
|
4712 if (!unclipped) |
|
4713 sourced->invalidateCache(QGraphicsEffectSourcePrivate::TransformChanged); |
4679 } |
4714 } |
4680 |
4715 |
4681 item->d_ptr->graphicsEffect->draw(painter); |
4716 item->d_ptr->graphicsEffect->draw(painter); |
4682 painter->setWorldTransform(restoreTransform); |
4717 painter->setWorldTransform(restoreTransform); |
4683 sourced->info = 0; |
4718 sourced->info = 0; |
5086 can increase drawing performance significantly. |
5121 can increase drawing performance significantly. |
5087 |
5122 |
5088 Example: |
5123 Example: |
5089 |
5124 |
5090 \snippet doc/src/snippets/graphicssceneadditemsnippet.cpp 0 |
5125 \snippet doc/src/snippets/graphicssceneadditemsnippet.cpp 0 |
|
5126 |
|
5127 \obsolete Since Qt 4.6, this function is not called anymore unless |
|
5128 the QGraphicsView::IndirectPainting flag is given as an Optimization |
|
5129 flag. |
5091 |
5130 |
5092 \sa drawBackground(), drawForeground() |
5131 \sa drawBackground(), drawForeground() |
5093 */ |
5132 */ |
5094 void QGraphicsScene::drawItems(QPainter *painter, |
5133 void QGraphicsScene::drawItems(QPainter *painter, |
5095 int numItems, |
5134 int numItems, |