summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/gui/graphicsview/qgraphicsscene.cpp33
-rw-r--r--src/gui/graphicsview/qgraphicsscene_p.h1
-rw-r--r--src/gui/graphicsview/qgraphicsscenebsptreeindex.cpp36
-rw-r--r--src/gui/graphicsview/qgraphicsscenebsptreeindex_p.h3
-rw-r--r--src/gui/graphicsview/qgraphicssceneindex.cpp23
-rw-r--r--src/gui/graphicsview/qgraphicssceneindex_p.h4
-rw-r--r--src/gui/graphicsview/qgraphicsscenelinearindex_p.h7
-rw-r--r--src/gui/graphicsview/qgraphicsview.cpp16
-rw-r--r--tests/auto/qgraphicsscene/tst_qgraphicsscene.cpp28
-rw-r--r--tests/auto/qgraphicsview/tst_qgraphicsview.cpp1
10 files changed, 71 insertions, 81 deletions
diff --git a/src/gui/graphicsview/qgraphicsscene.cpp b/src/gui/graphicsview/qgraphicsscene.cpp
index 2f7ae04..6f92629 100644
--- a/src/gui/graphicsview/qgraphicsscene.cpp
+++ b/src/gui/graphicsview/qgraphicsscene.cpp
@@ -273,6 +273,7 @@ QGraphicsScenePrivate::QGraphicsScenePrivate()
index(0),
lastItemCount(0),
hasSceneRect(false),
+ dirtyGrowingItemsBoundingRect(true),
updateAll(false),
calledEmitUpdated(false),
processDirtyItemsEmitted(false),
@@ -378,8 +379,9 @@ void QGraphicsScenePrivate::unregisterTopLevelItem(QGraphicsItem *item)
*/
void QGraphicsScenePrivate::_q_updateLater()
{
+ QRectF null;
foreach (QGraphicsItem *item, pendingUpdateItems)
- item->update();
+ markDirty(item, null);
pendingUpdateItems.clear();
}
@@ -409,8 +411,11 @@ void QGraphicsScenePrivate::_q_processDirtyItems()
const bool wasPendingSceneUpdate = calledEmitUpdated;
const QRectF oldGrowingItemsBoundingRect = growingItemsBoundingRect;
processDirtyItemsRecursive(0);
- if (!hasSceneRect && oldGrowingItemsBoundingRect != growingItemsBoundingRect)
+ dirtyGrowingItemsBoundingRect = false;
+ if (oldGrowingItemsBoundingRect != growingItemsBoundingRect) {
+ index->sceneRectChanged();
emit q_func()->sceneRectChanged(growingItemsBoundingRect);
+ }
if (wasPendingSceneUpdate)
return;
@@ -1250,9 +1255,18 @@ QGraphicsScene::~QGraphicsScene()
QRectF QGraphicsScene::sceneRect() const
{
Q_D(const QGraphicsScene);
- /// ### Remove? The growing items bounding rect might be managed
- // by the scene.
- return d->index->indexedRect();
+ if (!d->hasSceneRect && d->dirtyGrowingItemsBoundingRect) {
+ // Lazily update the growing items bounding rect
+ QGraphicsScenePrivate *thatd = const_cast<QGraphicsScenePrivate *>(d);
+ QRectF oldGrowingBoundingRect = thatd->growingItemsBoundingRect;
+ thatd->growingItemsBoundingRect |= itemsBoundingRect();
+ thatd->dirtyGrowingItemsBoundingRect = false;
+ if (oldGrowingBoundingRect != thatd->growingItemsBoundingRect) {
+ thatd->index->sceneRectChanged();
+ emit const_cast<QGraphicsScene *>(this)->sceneRectChanged(thatd->growingItemsBoundingRect);
+ }
+ }
+ return d->hasSceneRect ? d->sceneRect : d->growingItemsBoundingRect;
}
void QGraphicsScene::setSceneRect(const QRectF &rect)
{
@@ -1260,8 +1274,8 @@ void QGraphicsScene::setSceneRect(const QRectF &rect)
if (rect != d->sceneRect) {
d->hasSceneRect = !rect.isNull();
d->sceneRect = rect;
- d->index->sceneRectChanged(rect);
- emit sceneRectChanged(rect);
+ d->index->sceneRectChanged();
+ emit sceneRectChanged(d->hasSceneRect ? rect : d->growingItemsBoundingRect);
}
}
@@ -1411,8 +1425,6 @@ void QGraphicsScene::setItemIndexMethod(ItemIndexMethod method)
d->index = new QGraphicsSceneLinearIndex(this);
for (int i = oldItems.size() - 1; i >= 0; --i)
d->index->addItem(oldItems.at(i));
-
- d->index->sceneRectChanged(d->sceneRect);
}
/*!
@@ -2057,6 +2069,8 @@ void QGraphicsScene::addItem(QGraphicsItem *item)
if (d->pendingUpdateItems.isEmpty())
QMetaObject::invokeMethod(this, "_q_updateLater", Qt::QueuedConnection);
d->pendingUpdateItems << item;
+ } else {
+ d->dirtyGrowingItemsBoundingRect = true;
}
// Disable selectionChanged() for individual items
@@ -4235,6 +4249,7 @@ void QGraphicsScenePrivate::markDirty(QGraphicsItem *item, const QRectF &rect, b
bool removingItemFromScene)
{
Q_ASSERT(item);
+ dirtyGrowingItemsBoundingRect = true;
if (updateAll)
return;
diff --git a/src/gui/graphicsview/qgraphicsscene_p.h b/src/gui/graphicsview/qgraphicsscene_p.h
index ea65707..8c4b2d2 100644
--- a/src/gui/graphicsview/qgraphicsscene_p.h
+++ b/src/gui/graphicsview/qgraphicsscene_p.h
@@ -95,6 +95,7 @@ public:
QRectF sceneRect;
bool hasSceneRect;
+ bool dirtyGrowingItemsBoundingRect;
QRectF growingItemsBoundingRect;
void _q_emitUpdated();
diff --git a/src/gui/graphicsview/qgraphicsscenebsptreeindex.cpp b/src/gui/graphicsview/qgraphicsscenebsptreeindex.cpp
index 72636b8..aeee982 100644
--- a/src/gui/graphicsview/qgraphicsscenebsptreeindex.cpp
+++ b/src/gui/graphicsview/qgraphicsscenebsptreeindex.cpp
@@ -122,7 +122,6 @@ void QGraphicsSceneBspTreeIndexPrivate::_q_updateIndex()
if (!indexTimerId)
return;
- QGraphicsScenePrivate * scenePrivate = q->scene()->d_func();
q->killTimer(indexTimerId);
indexTimerId = 0;
@@ -144,10 +143,6 @@ void QGraphicsSceneBspTreeIndexPrivate::_q_updateIndex()
}
}
- // Update growing scene rect.
- QRectF oldGrowingItemsBoundingRect = scenePrivate->growingItemsBoundingRect;
- scenePrivate->growingItemsBoundingRect |= unindexedItemsBoundingRect;
-
// Determine whether we should regenerate the BSP tree.
if (bspTreeDepth == 0) {
int oldDepth = intmaxlog(lastItemCount);
@@ -165,7 +160,6 @@ void QGraphicsSceneBspTreeIndexPrivate::_q_updateIndex()
bsp.initialize(q->scene()->sceneRect(), bspTreeDepth);
unindexedItems = indexedItems;
lastItemCount = indexedItems.size();
- q->scene()->update();
}
// Insert all unindexed items into the tree.
@@ -179,10 +173,6 @@ void QGraphicsSceneBspTreeIndexPrivate::_q_updateIndex()
}
}
unindexedItems.clear();
-
- // Notify scene rect changes.
- if (!scenePrivate->hasSceneRect && scenePrivate->growingItemsBoundingRect != oldGrowingItemsBoundingRect)
- emit q->scene()->sceneRectChanged(scenePrivate->growingItemsBoundingRect);
}
@@ -248,7 +238,7 @@ void QGraphicsSceneBspTreeIndexPrivate::climbTree(QGraphicsItem *item, int *stac
{
if (!item->d_ptr->children.isEmpty()) {
QList<QGraphicsItem *> childList = item->d_ptr->children;
- qSort(childList.begin(), childList.end(), qt_closestLeaf);
+ qStableSort(childList.begin(), childList.end(), qt_closestLeaf);
for (int i = 0; i < childList.size(); ++i) {
QGraphicsItem *item = childList.at(i);
if (!(item->flags() & QGraphicsItem::ItemStacksBehindParent))
@@ -287,7 +277,7 @@ void QGraphicsSceneBspTreeIndexPrivate::_q_updateSortCache()
topLevels << item;
}
- qSort(topLevels.begin(), topLevels.end(), qt_closestLeaf);
+ qStableSort(topLevels.begin(), topLevels.end(), qt_closestLeaf);
for (int i = 0; i < topLevels.size(); ++i)
climbTree(topLevels.at(i), &stackingOrder);
}
@@ -379,15 +369,15 @@ void QGraphicsSceneBspTreeIndexPrivate::sortItems(QList<QGraphicsItem *> *itemLi
{
if (sortCacheEnabled) {
if (order == Qt::AscendingOrder) {
- qSort(itemList->begin(), itemList->end(), closestItemFirst_withCache);
+ qStableSort(itemList->begin(), itemList->end(), closestItemFirst_withCache);
} else if (order == Qt::DescendingOrder) {
- qSort(itemList->begin(), itemList->end(), closestItemLast_withCache);
+ qStableSort(itemList->begin(), itemList->end(), closestItemLast_withCache);
}
} else {
if (order == Qt::AscendingOrder) {
- qSort(itemList->begin(), itemList->end(), closestItemFirst_withoutCache);
+ qStableSort(itemList->begin(), itemList->end(), closestItemFirst_withoutCache);
} else if (order == Qt::DescendingOrder) {
- qSort(itemList->begin(), itemList->end(), closestItemLast_withoutCache);
+ qStableSort(itemList->begin(), itemList->end(), closestItemLast_withoutCache);
}
}
}
@@ -403,17 +393,6 @@ QGraphicsSceneBspTreeIndex::QGraphicsSceneBspTreeIndex(QGraphicsScene *scene)
/*!
\reimp
- Return the rect indexed by the BSP index.
-*/
-QRectF QGraphicsSceneBspTreeIndex::indexedRect() const
-{
- Q_D(const QGraphicsSceneBspTreeIndex);
- const_cast<QGraphicsSceneBspTreeIndexPrivate*>(d)->_q_updateIndex();
- return scene()->d_func()->hasSceneRect ? scene()->d_func()->sceneRect : scene()->d_func()->growingItemsBoundingRect;
-}
-
-/*!
- \reimp
Clear the all the BSP index.
*/
void QGraphicsSceneBspTreeIndex::clear()
@@ -705,10 +684,9 @@ void QGraphicsSceneBspTreeIndex::setBspTreeDepth(int depth)
This method react to the \a rect change of the scene and
reset the BSP tree index.
*/
-void QGraphicsSceneBspTreeIndex::sceneRectChanged(const QRectF &rect)
+void QGraphicsSceneBspTreeIndex::sceneRectChanged()
{
Q_D(QGraphicsSceneBspTreeIndex);
- d->sceneRect = rect;
d->resetIndex();
}
diff --git a/src/gui/graphicsview/qgraphicsscenebsptreeindex_p.h b/src/gui/graphicsview/qgraphicsscenebsptreeindex_p.h
index 1e4234e..715b22f 100644
--- a/src/gui/graphicsview/qgraphicsscenebsptreeindex_p.h
+++ b/src/gui/graphicsview/qgraphicsscenebsptreeindex_p.h
@@ -82,7 +82,6 @@ class Q_AUTOTEST_EXPORT QGraphicsSceneBspTreeIndex : public QGraphicsSceneIndex
Q_PROPERTY(int bspTreeDepth READ bspTreeDepth WRITE setBspTreeDepth)
public:
QGraphicsSceneBspTreeIndex(QGraphicsScene *scene = 0);
- QRectF indexedRect() const;
QList<QGraphicsItem *> estimateItems(const QRectF &rect, Qt::SortOrder order, const QTransform &deviceTransform) const;
@@ -100,7 +99,7 @@ protected:
void deleteItem(QGraphicsItem *item);
void prepareBoundingRectChange(const QGraphicsItem *item);
- void sceneRectChanged(const QRectF &rect);
+ void sceneRectChanged();
void itemChange(const QGraphicsItem *item, QGraphicsItem::GraphicsItemChange change, const QVariant &value);
private :
diff --git a/src/gui/graphicsview/qgraphicssceneindex.cpp b/src/gui/graphicsview/qgraphicssceneindex.cpp
index 8d7581f..4eaed2b 100644
--- a/src/gui/graphicsview/qgraphicssceneindex.cpp
+++ b/src/gui/graphicsview/qgraphicssceneindex.cpp
@@ -56,6 +56,7 @@
\sa QGraphicsScene, QGraphicsView
*/
+#include "qdebug.h"
#include "qgraphicsscene.h"
#include "qgraphicsitem_p.h"
#include "qgraphicsscene_p.h"
@@ -131,14 +132,10 @@ public:
keep = QGraphicsSceneIndexPrivate::itemCollidesWithPath(item, pointPath, mode);
}
} else {
- QRectF sceneBrect = transform.mapRect(brect);
- keep = sceneBrect.contains(scenePoint);
- if (keep && (mode == Qt::ContainsItemShape || mode == Qt::IntersectsItemShape)) {
- QPainterPath pointPath;
- pointPath.addRect(QRectF(transform.inverted().map(scenePoint), QSizeF(1, 1)));
- keep = QGraphicsSceneIndexPrivate::itemCollidesWithPath(item, pointPath, mode);
- }
+ QRectF sceneBoundingRect = transform.mapRect(brect);
+ keep = sceneBoundingRect.intersects(QRectF(scenePoint, QSizeF(1, 1))) && item->contains(transform.inverted().map(scenePoint));
}
+
return keep;
}
@@ -366,15 +363,6 @@ QGraphicsScene* QGraphicsSceneIndex::scene() const
}
/*!
- Returns the indexed area for the index
-*/
-QRectF QGraphicsSceneIndex::indexedRect() const
-{
- Q_D(const QGraphicsSceneIndex);
- return d->scene->d_func()->sceneRect;
-}
-
-/*!
\fn QList<QGraphicsItem *> QGraphicsSceneIndex::items(const QPointF &pos,
Qt::ItemSelectionMode mode, Qt::SortOrder order, const QTransform
&deviceTransform) const
@@ -613,9 +601,8 @@ void QGraphicsSceneIndex::prepareBoundingRectChange(const QGraphicsItem *item)
rectangle. \a rect is the new value of the scene rectangle.
\sa QGraphicsScene::sceneRect()
*/
-void QGraphicsSceneIndex::sceneRectChanged(const QRectF &rect)
+void QGraphicsSceneIndex::sceneRectChanged()
{
- Q_UNUSED(rect);
}
QT_END_NAMESPACE
diff --git a/src/gui/graphicsview/qgraphicssceneindex_p.h b/src/gui/graphicsview/qgraphicssceneindex_p.h
index 85a1140..60e9032 100644
--- a/src/gui/graphicsview/qgraphicssceneindex_p.h
+++ b/src/gui/graphicsview/qgraphicssceneindex_p.h
@@ -87,8 +87,6 @@ public:
QGraphicsScene *scene() const;
- virtual QRectF indexedRect() const;
-
virtual QList<QGraphicsItem *> items(Qt::SortOrder order = Qt::AscendingOrder) const = 0;
virtual QList<QGraphicsItem *> items(const QPointF &pos, Qt::ItemSelectionMode mode,
Qt::SortOrder order, const QTransform &deviceTransform = QTransform()) const;
@@ -111,7 +109,7 @@ protected:
virtual void itemChange(const QGraphicsItem *item, QGraphicsItem::GraphicsItemChange, const QVariant &value);
virtual void prepareBoundingRectChange(const QGraphicsItem *item);
- virtual void sceneRectChanged(const QRectF &rect);
+ virtual void sceneRectChanged();
QGraphicsSceneIndex(QObjectPrivate &dd, QGraphicsScene *scene);
diff --git a/src/gui/graphicsview/qgraphicsscenelinearindex_p.h b/src/gui/graphicsview/qgraphicsscenelinearindex_p.h
index 88e0e6a..9463487 100644
--- a/src/gui/graphicsview/qgraphicsscenelinearindex_p.h
+++ b/src/gui/graphicsview/qgraphicsscenelinearindex_p.h
@@ -87,13 +87,7 @@ public:
return m_items;
}
- virtual QRectF indexedRect() const
- { return m_sceneRect; }
-
protected :
- void sceneRectChanged(const QRectF &rect)
- { m_sceneRect = rect; }
-
virtual void clear()
{ m_items.clear(); }
@@ -104,7 +98,6 @@ protected :
{ m_items.removeOne(item); }
private:
- QRectF m_sceneRect;
QList<QGraphicsItem*> m_items;
};
diff --git a/src/gui/graphicsview/qgraphicsview.cpp b/src/gui/graphicsview/qgraphicsview.cpp
index ec1746a..640f85b 100644
--- a/src/gui/graphicsview/qgraphicsview.cpp
+++ b/src/gui/graphicsview/qgraphicsview.cpp
@@ -802,13 +802,15 @@ void QGraphicsViewPrivate::processPendingUpdates()
return;
}
+ if (optimizationFlags & QGraphicsView::DontAdjustForAntialiasing)
+ dirtyBoundingRect.adjust(-1, -1, 1, 1);
+ else
+ dirtyBoundingRect.adjust(-2, -2, 2, 2);
+
if (viewportUpdateMode == QGraphicsView::BoundingRectViewportUpdate) {
- if (optimizationFlags & QGraphicsView::DontAdjustForAntialiasing)
- viewport->update(dirtyBoundingRect.adjusted(-1, -1, 1, 1));
- else
- viewport->update(dirtyBoundingRect.adjusted(-2, -2, 2, 2));
+ viewport->update((dirtyRegion + dirtyBoundingRect).boundingRect());
} else {
- viewport->update(dirtyRegion); // Already adjusted in updateRect/Region.
+ viewport->update(dirtyRegion + dirtyBoundingRect); // Already adjusted in updateRect/Region.
}
dirtyBoundingRect = QRect();
@@ -2087,9 +2089,7 @@ QGraphicsItem *QGraphicsView::itemAt(const QPoint &pos) const
Q_D(const QGraphicsView);
if (!d->scene)
return 0;
- // ### Use QGraphicsScene::itemAt() instead.
- QList<QGraphicsItem *> itemsAtPos = d->scene->items(pos, Qt::IntersectsItemShape, Qt::AscendingOrder,
- viewportTransform());
+ QList<QGraphicsItem *> itemsAtPos = items(pos);
return itemsAtPos.isEmpty() ? 0 : itemsAtPos.first();
}
diff --git a/tests/auto/qgraphicsscene/tst_qgraphicsscene.cpp b/tests/auto/qgraphicsscene/tst_qgraphicsscene.cpp
index 1d03ef1..1a7a076 100644
--- a/tests/auto/qgraphicsscene/tst_qgraphicsscene.cpp
+++ b/tests/auto/qgraphicsscene/tst_qgraphicsscene.cpp
@@ -271,28 +271,46 @@ void tst_QGraphicsScene::construction()
void tst_QGraphicsScene::sceneRect()
{
QGraphicsScene scene;
+ QSignalSpy sceneRectChanged(&scene, SIGNAL(sceneRectChanged(QRectF)));
QCOMPARE(scene.sceneRect(), QRectF());
+ QCOMPARE(sceneRectChanged.count(), 0);
QGraphicsItem *item = scene.addRect(QRectF(0, 0, 10, 10));
- qApp->processEvents();
item->setPos(-5, -5);
- qApp->processEvents();
+ QCOMPARE(sceneRectChanged.count(), 0);
QCOMPARE(scene.itemAt(0, 0), item);
QCOMPARE(scene.itemAt(10, 10), (QGraphicsItem *)0);
+ QCOMPARE(sceneRectChanged.count(), 0);
+ QCOMPARE(scene.sceneRect(), QRectF(-5, -5, 10, 10));
+ QCOMPARE(sceneRectChanged.count(), 1);
+ QCOMPARE(sceneRectChanged.last().at(0).toRectF(), scene.sceneRect());
+
+ item->setPos(0, 0);
QCOMPARE(scene.sceneRect(), QRectF(-5, -5, 15, 15));
+ QCOMPARE(sceneRectChanged.count(), 2);
+ QCOMPARE(sceneRectChanged.last().at(0).toRectF(), scene.sceneRect());
scene.setSceneRect(-100, -100, 10, 10);
+ QCOMPARE(sceneRectChanged.count(), 3);
+ QCOMPARE(sceneRectChanged.last().at(0).toRectF(), scene.sceneRect());
QCOMPARE(scene.itemAt(0, 0), item);
QCOMPARE(scene.itemAt(10, 10), (QGraphicsItem *)0);
QCOMPARE(scene.sceneRect(), QRectF(-100, -100, 10, 10));
+ item->setPos(10, 10);
+ QCOMPARE(scene.sceneRect(), QRectF(-100, -100, 10, 10));
+ QCOMPARE(sceneRectChanged.count(), 3);
+ QCOMPARE(sceneRectChanged.last().at(0).toRectF(), scene.sceneRect());
scene.setSceneRect(QRectF());
- QCOMPARE(scene.itemAt(0, 0), item);
- QCOMPARE(scene.itemAt(10, 10), (QGraphicsItem *)0);
- QCOMPARE(scene.sceneRect(), QRectF(-5, -5, 15, 15));
+ QCOMPARE(scene.itemAt(10, 10), item);
+ QCOMPARE(scene.itemAt(20, 20), (QGraphicsItem *)0);
+ QCOMPARE(sceneRectChanged.count(), 4);
+ QCOMPARE(scene.sceneRect(), QRectF(-5, -5, 25, 25));
+ QCOMPARE(sceneRectChanged.count(), 5);
+ QCOMPARE(sceneRectChanged.last().at(0).toRectF(), scene.sceneRect());
}
void tst_QGraphicsScene::itemIndexMethod()
diff --git a/tests/auto/qgraphicsview/tst_qgraphicsview.cpp b/tests/auto/qgraphicsview/tst_qgraphicsview.cpp
index c8c032a..02e4046 100644
--- a/tests/auto/qgraphicsview/tst_qgraphicsview.cpp
+++ b/tests/auto/qgraphicsview/tst_qgraphicsview.cpp
@@ -371,6 +371,7 @@ void tst_QGraphicsView::interactive()
QCOMPARE(item->events.size(), 0);
QPoint itemPoint = view.mapFromScene(item->scenePos());
+
QVERIFY(view.itemAt(itemPoint));
for (int i = 0; i < 100; ++i) {