1 /****************************************************************************
3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
4 ** All rights reserved.
5 ** Contact: Nokia Corporation (qt-info@nokia.com)
7 ** This file is part of the test suite of the Qt Toolkit.
9 ** $QT_BEGIN_LICENSE:LGPL$
10 ** GNU Lesser General Public License Usage
11 ** This file may be used under the terms of the GNU Lesser General Public
12 ** License version 2.1 as published by the Free Software Foundation and
13 ** appearing in the file LICENSE.LGPL included in the packaging of this
14 ** file. Please review the following information to ensure the GNU Lesser
15 ** General Public License version 2.1 requirements will be met:
16 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
18 ** In addition, as a special exception, Nokia gives you certain additional
19 ** rights. These rights are described in the Nokia Qt LGPL Exception
20 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
22 ** GNU General Public License Usage
23 ** Alternatively, this file may be used under the terms of the GNU General
24 ** Public License version 3.0 as published by the Free Software Foundation
25 ** and appearing in the file LICENSE.GPL included in the packaging of this
26 ** file. Please review the following information to ensure the GNU General
27 ** Public License version 3.0 requirements will be met:
28 ** http://www.gnu.org/copyleft/gpl.html.
31 ** Alternatively, this file may be used in accordance with the terms and
32 ** conditions contained in a signed written agreement between you and Nokia.
40 ****************************************************************************/
43 #include <QtTest/QtTest>
44 #include <QtWidgets/qgraphicsscene.h>
45 #include <private/qgraphicsscenebsptreeindex_p.h>
46 #include <private/qgraphicssceneindex_p.h>
47 #include <private/qgraphicsscenelinearindex_p.h>
52 class tst_QGraphicsSceneIndex : public QObject
59 void scatteredItems_data();
60 void scatteredItems();
61 void overlappedItems_data();
62 void overlappedItems();
63 void movingItems_data();
65 void connectedToSceneRectChanged();
72 QGraphicsSceneIndex *createIndex(const QString &name);
75 void tst_QGraphicsSceneIndex::initTestCase()
79 void tst_QGraphicsSceneIndex::common_data()
81 QTest::addColumn<QString>("indexMethod");
83 QTest::newRow("BSP") << QString("bsp");
84 QTest::newRow("Linear") << QString("linear");
87 QGraphicsSceneIndex *tst_QGraphicsSceneIndex::createIndex(const QString &indexMethod)
89 QGraphicsSceneIndex *index = 0;
90 QGraphicsScene *scene = new QGraphicsScene();
91 if (indexMethod == "bsp")
92 index = new QGraphicsSceneBspTreeIndex(scene);
94 if (indexMethod == "linear")
95 index = new QGraphicsSceneLinearIndex(scene);
100 void tst_QGraphicsSceneIndex::scatteredItems_data()
105 void tst_QGraphicsSceneIndex::scatteredItems()
107 QFETCH(QString, indexMethod);
109 QGraphicsScene scene;
110 scene.setItemIndexMethod(indexMethod == "linear" ? QGraphicsScene::NoIndex : QGraphicsScene::BspTreeIndex);
112 for (int i = 0; i < 10; ++i)
113 scene.addRect(i*50, i*50, 40, 35);
115 QCOMPARE(scene.items(QPointF(5, 5)).count(), 1);
116 QCOMPARE(scene.items(QPointF(55, 55)).count(), 1);
117 QCOMPARE(scene.items(QPointF(-100, -100)).count(), 0);
119 QCOMPARE(scene.items(QRectF(0, 0, 10, 10)).count(), 1);
120 QCOMPARE(scene.items(QRectF(0, 0, 1000, 1000)).count(), 10);
121 QCOMPARE(scene.items(QRectF(-100, -1000, 0, 0)).count(), 0);
124 void tst_QGraphicsSceneIndex::overlappedItems_data()
129 void tst_QGraphicsSceneIndex::overlappedItems()
131 QFETCH(QString, indexMethod);
133 QGraphicsScene scene;
134 scene.setItemIndexMethod(indexMethod == "linear" ? QGraphicsScene::NoIndex : QGraphicsScene::BspTreeIndex);
136 for (int i = 0; i < 10; ++i)
137 for (int j = 0; j < 10; ++j)
138 scene.addRect(i*50, j*50, 200, 200);
140 QCOMPARE(scene.items(QPointF(5, 5)).count(), 1);
141 QCOMPARE(scene.items(QPointF(55, 55)).count(), 4);
142 QCOMPARE(scene.items(QPointF(105, 105)).count(), 9);
143 QCOMPARE(scene.items(QPointF(-100, -100)).count(), 0);
145 QCOMPARE(scene.items(QRectF(0, 0, 1000, 1000)).count(), 100);
146 QCOMPARE(scene.items(QRectF(-100, -1000, 0, 0)).count(), 0);
147 QCOMPARE(scene.items(QRectF(0, 0, 200, 200)).count(), 16);
148 QCOMPARE(scene.items(QRectF(0, 0, 100, 100)).count(), 4);
149 QCOMPARE(scene.items(QRectF(0, 0, 1, 100)).count(), 2);
150 QCOMPARE(scene.items(QRectF(0, 0, 1, 1000)).count(), 10);
153 void tst_QGraphicsSceneIndex::movingItems_data()
158 void tst_QGraphicsSceneIndex::movingItems()
160 QFETCH(QString, indexMethod);
162 QGraphicsScene scene;
163 scene.setItemIndexMethod(indexMethod == "linear" ? QGraphicsScene::NoIndex : QGraphicsScene::BspTreeIndex);
165 for (int i = 0; i < 10; ++i)
166 scene.addRect(i*50, i*50, 40, 35);
168 QGraphicsRectItem *box = scene.addRect(0, 0, 10, 10);
169 QCOMPARE(scene.items(QPointF(5, 5)).count(), 2);
170 QCOMPARE(scene.items(QPointF(-1, -1)).count(), 0);
171 QCOMPARE(scene.items(QRectF(0, 0, 5, 5)).count(), 2);
174 QCOMPARE(scene.items(QPointF(9, 9)).count(), 1);
175 QCOMPARE(scene.items(QPointF(15, 15)).count(), 2);
176 QCOMPARE(scene.items(QRectF(0, 0, 1, 1)).count(), 1);
179 QCOMPARE(scene.items(QPointF(-1, -1)).count(), 1);
180 QCOMPARE(scene.items(QRectF(0, 0, 1, 1)).count(), 2);
182 QCOMPARE(scene.items(QRectF(0, 0, 1000, 1000)).count(), 11);
185 void tst_QGraphicsSceneIndex::connectedToSceneRectChanged()
188 class MyScene : public QGraphicsScene
191 using QGraphicsScene::receivers;
194 MyScene scene; // Uses QGraphicsSceneBspTreeIndex by default.
195 QCOMPARE(scene.receivers(SIGNAL(sceneRectChanged(const QRectF&))), 1);
197 scene.setItemIndexMethod(QGraphicsScene::NoIndex); // QGraphicsSceneLinearIndex
198 QCOMPARE(scene.receivers(SIGNAL(sceneRectChanged(const QRectF&))), 1);
201 void tst_QGraphicsSceneIndex::items()
203 QGraphicsScene scene;
204 QGraphicsItem *item1 = scene.addRect(0, 0, 10, 10);
205 QGraphicsItem *item2 = scene.addRect(10, 10, 10, 10);
206 QCOMPARE(scene.items().size(), 2);
208 // Move from unindexed items into bsp tree.
210 QCOMPARE(scene.items().size(), 2);
212 // Add untransformable item.
213 QGraphicsItem *item3 = new QGraphicsRectItem(QRectF(20, 20, 10, 10));
214 item3->setFlag(QGraphicsItem::ItemIgnoresTransformations);
215 scene.addItem(item3);
216 QCOMPARE(scene.items().size(), 3);
218 // Move from unindexed items into untransformable items.
220 QCOMPARE(scene.items().size(), 3);
222 // Move from untransformable items into unindexed items.
223 item3->setFlag(QGraphicsItem::ItemIgnoresTransformations, false);
224 QCOMPARE(scene.items().size(), 3);
226 QCOMPARE(scene.items().size(), 3);
228 // Make all items untransformable.
229 item1->setFlag(QGraphicsItem::ItemIgnoresTransformations);
230 item2->setParentItem(item1);
231 item3->setParentItem(item2);
232 QCOMPARE(scene.items().size(), 3);
234 // Move from unindexed items into untransformable items.
236 QCOMPARE(scene.items().size(), 3);
239 class RectWidget : public QGraphicsWidget
243 RectWidget(QGraphicsItem *parent = 0) : QGraphicsWidget(parent)
247 void paint(QPainter *painter, const QStyleOptionGraphicsItem * /* option */, QWidget * /* widget */)
249 painter->setBrush(brush);
250 painter->drawRect(boundingRect());
256 void tst_QGraphicsSceneIndex::removeItems()
258 QGraphicsScene scene;
260 RectWidget *parent = new RectWidget;
261 parent->brush = QBrush(QColor(Qt::magenta));
262 parent->setGeometry(250, 250, 400, 400);
264 RectWidget *widget = new RectWidget(parent);
265 widget->brush = QBrush(QColor(Qt::blue));
266 widget->setGeometry(10, 10, 200, 200);
268 RectWidget *widgetChild1 = new RectWidget(widget);
269 widgetChild1->brush = QBrush(QColor(Qt::green));
270 widgetChild1->setGeometry(20, 20, 100, 100);
272 RectWidget *widgetChild2 = new RectWidget(widgetChild1);
273 widgetChild2->brush = QBrush(QColor(Qt::yellow));
274 widgetChild2->setGeometry(25, 25, 50, 50);
276 scene.addItem(parent);
278 QGraphicsView view(&scene);
279 view.resize(600, 600);
281 QApplication::setActiveWindow(&view);
282 QTest::qWaitForWindowShown(&view);
284 QApplication::processEvents();
286 scene.removeItem(widgetChild1);
291 scene.items(295, 295, 50, 50);
293 //This should not crash
296 void tst_QGraphicsSceneIndex::clear()
298 class MyItem : public QGraphicsItem
301 MyItem(QGraphicsItem *parent = 0) : QGraphicsItem(parent), numPaints(0) {}
304 QRectF boundingRect() const { return QRectF(0, 0, 10, 10); }
305 void paint(QPainter * /* painter */, const QStyleOptionGraphicsItem *, QWidget *)
309 QGraphicsScene scene;
310 scene.setSceneRect(0, 0, 100, 100);
311 scene.addItem(new MyItem);
313 QGraphicsView view(&scene);
316 qt_x11_wait_for_window_manager(&view);
321 // Make sure the index is re-generated after QGraphicsScene::clear();
322 // otherwise no items will be painted.
323 MyItem *item = new MyItem;
325 qApp->processEvents();
326 QTRY_COMPARE(item->numPaints, 1);
329 QTEST_MAIN(tst_QGraphicsSceneIndex)
330 #include "tst_qgraphicssceneindex.moc"