1 /****************************************************************************
2 **
3 ** Copyright (C) 2015 The Qt Company Ltd.
4 ** Contact: http://www.qt.io/licensing/
5 **
6 ** This file is part of the test suite of the Qt Toolkit.
7 **
8 ** $QT_BEGIN_LICENSE:LGPL$
9 ** Commercial License Usage
10 ** Licensees holding valid commercial Qt licenses may use this file in
11 ** accordance with the commercial license agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and The Qt Company. For licensing terms
14 ** and conditions see http://www.qt.io/terms-conditions. For further
15 ** information use the contact form at http://www.qt.io/contact-us.
16 **
17 ** GNU Lesser General Public License Usage
18 ** Alternatively, this file may be used under the terms of the GNU Lesser
19 ** General Public License version 2.1 or version 3 as published by the Free
20 ** Software Foundation and appearing in the file LICENSE.LGPLv21 and
21 ** LICENSE.LGPLv3 included in the packaging of this file. Please review the
22 ** following information to ensure the GNU Lesser General Public License
23 ** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
24 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
25 **
26 ** As a special exception, The Qt Company gives you certain additional
27 ** rights. These rights are described in The Qt Company LGPL Exception
28 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
29 **
30 ** GNU General Public License Usage
31 ** Alternatively, this file may be used under the terms of the GNU
32 ** General Public License version 3.0 as published by the Free Software
33 ** Foundation and appearing in the file LICENSE.GPL included in the
34 ** packaging of this file. Please review the following information to
35 ** ensure the GNU General Public License version 3.0 requirements will be
36 ** met: http://www.gnu.org/copyleft/gpl.html.
37 **
38 ** $QT_END_LICENSE$
39 **
40 ****************************************************************************/
41
42 #include <QtGui>
43 #include <QtTest/QtTest>
44 #include <QTest>
45 #include <QMetaType>
46 #include <QtGui/qgraphicsanchorlayout.h>
47 #include <private/qgraphicsanchorlayout_p.h>
48
49 #define TEST_COMPLEX_CASES
50
51
52 //---------------------- AnchorLayout helper class ----------------------------
53 class TheAnchorLayout : public QGraphicsAnchorLayout
54 {
55 public:
TheAnchorLayout()56 TheAnchorLayout() : QGraphicsAnchorLayout()
57 {
58 setContentsMargins( 0,0,0,0 );
59 setSpacing( 0 );
60 }
61
isValid()62 bool isValid()
63 {
64 return !QGraphicsAnchorLayoutPrivate::get(this)->hasConflicts();
65 }
66
setAnchor(QGraphicsLayoutItem * startItem,Qt::AnchorPoint startEdge,QGraphicsLayoutItem * endItem,Qt::AnchorPoint endEdge,qreal value)67 void setAnchor(
68 QGraphicsLayoutItem *startItem,
69 Qt::AnchorPoint startEdge,
70 QGraphicsLayoutItem *endItem,
71 Qt::AnchorPoint endEdge,
72 qreal value)
73 {
74 QGraphicsAnchor *anchor = addAnchor( startItem, startEdge, endItem, endEdge);
75 if (anchor)
76 anchor->setSpacing(value);
77 }
78
indexOf(const QGraphicsLayoutItem * item) const79 int indexOf(const QGraphicsLayoutItem* item) const
80 {
81 for ( int i=0; i< count(); i++) {
82 if ( itemAt(i) == item ) {
83 return i;
84 }
85 }
86 return -1;
87 }
88
removeItem(QGraphicsLayoutItem * item)89 void removeItem(QGraphicsLayoutItem* item)
90 {
91 removeAt(indexOf(item));
92 }
93
removeAnchor(QGraphicsLayoutItem * startItem,Qt::AnchorPoint startEdge,QGraphicsLayoutItem * endItem,Qt::AnchorPoint endEdge)94 void removeAnchor(
95 QGraphicsLayoutItem *startItem,
96 Qt::AnchorPoint startEdge,
97 QGraphicsLayoutItem *endItem,
98 Qt::AnchorPoint endEdge)
99 {
100 delete QGraphicsAnchorLayout::anchor(startItem, startEdge, endItem, endEdge);
101 }
102 };
103 //-----------------------------------------------------------------------------
104
105
106 struct BasicLayoutTestData
107 {
BasicLayoutTestDataBasicLayoutTestData108 inline BasicLayoutTestData(
109 int index1, Qt::AnchorPoint edge1,
110 int index2, Qt::AnchorPoint edge2,
111 qreal distance)
112 : firstIndex(index1), firstEdge(edge1),
113 secondIndex(index2), secondEdge(edge2),
114 spacing(distance)
115 {
116 }
117
118 int firstIndex;
119 Qt::AnchorPoint firstEdge;
120 int secondIndex;
121 Qt::AnchorPoint secondEdge;
122 qreal spacing;
123 };
124
125 struct AnchorItemSizeHint
126 {
AnchorItemSizeHintAnchorItemSizeHint127 inline AnchorItemSizeHint(
128 qreal hmin, qreal hpref, qreal hmax,
129 qreal vmin, qreal vpref, qreal vmax )
130 : hmin(hmin), hpref(hpref), hmax(hmax), vmin(vmin), vpref(vpref), vmax(vmax)
131 {
132 }
133 qreal hmin, hpref, hmax;
134 qreal vmin, vpref, vmax;
135 };
136
137 // some test results
138
139 struct BasicLayoutTestResult
140 {
BasicLayoutTestResultBasicLayoutTestResult141 inline BasicLayoutTestResult(
142 int resultIndex, const QRectF& resultRect )
143 : index(resultIndex), rect(resultRect)
144 {
145 }
146
147 int index;
148 QRectF rect;
149 };
150
151 typedef QList<BasicLayoutTestData> BasicLayoutTestDataList;
152 Q_DECLARE_METATYPE(BasicLayoutTestDataList)
153
154 typedef QList<BasicLayoutTestResult> BasicLayoutTestResultList;
155 Q_DECLARE_METATYPE(BasicLayoutTestResultList)
156
157 typedef QList<AnchorItemSizeHint> AnchorItemSizeHintList;
158 Q_DECLARE_METATYPE(AnchorItemSizeHintList)
159
160
161 //---------------------- Test Widget used on all tests ------------------------
162 class TestWidget : public QGraphicsWidget
163 {
164 public:
TestWidget(QGraphicsItem * parent=0,const QString & name=QString ())165 inline TestWidget(QGraphicsItem *parent = 0, const QString &name = QString())
166 : QGraphicsWidget(parent)
167 {
168 setContentsMargins( 0,0,0,0 );
169 if (name.isEmpty())
170 setData(0, QString::fromAscii("w%1").arg(quintptr(this)));
171 else
172 setData(0, name);
173 }
~TestWidget()174 ~TestWidget()
175 {
176 }
177
178 protected:
179 QSizeF sizeHint(Qt::SizeHint which, const QSizeF &constraint = QSizeF()) const;
180 };
181
sizeHint(Qt::SizeHint which,const QSizeF & constraint) const182 QSizeF TestWidget::sizeHint(Qt::SizeHint which, const QSizeF &constraint) const
183 {
184 Q_UNUSED( constraint );
185 if (which == Qt::MinimumSize) {
186 return QSizeF(5,5);
187 }
188
189 if (which == Qt::PreferredSize) {
190 return QSizeF(50,50);
191 }
192
193 return QSizeF(500,500);
194 }
195 //-----------------------------------------------------------------------------
196
197
198
199 //----------------------------- Test class ------------------------------------
200 class tst_QGraphicsAnchorLayout1 : public QObject
201 {
202 Q_OBJECT
203
204 private slots:
205 void testCount();
206
207 void testRemoveAt();
208 void testRemoveItem();
209
210 void testItemAt();
211 void testIndexOf();
212
213 void testAddAndRemoveAnchor();
214 void testIsValid();
215 void testSpecialCases();
216
217 void testBasicLayout_data();
218 void testBasicLayout();
219
220 void testNegativeSpacing_data();
221 void testNegativeSpacing();
222
223 void testMixedSpacing_data();
224 void testMixedSpacing();
225
226 void testMulti_data();
227 void testMulti();
228
229 void testCenterAnchors_data();
230 void testCenterAnchors();
231
232 void testRemoveCenterAnchor_data();
233 void testRemoveCenterAnchor();
234
235 void testSingleSizePolicy_data();
236 void testSingleSizePolicy();
237
238 void testDoubleSizePolicy_data();
239 void testDoubleSizePolicy();
240
241 void testSizeDistribution_data();
242 void testSizeDistribution();
243
244 void testSizeHint();
245
246 #ifdef TEST_COMPLEX_CASES
247 void testComplexCases_data();
248 void testComplexCases();
249 #endif
250 };
251
252
testCount()253 void tst_QGraphicsAnchorLayout1::testCount()
254 {
255 QGraphicsWidget *widget = new QGraphicsWidget;
256
257 TheAnchorLayout *layout = new TheAnchorLayout();
258 QVERIFY( layout->count() == 0 );
259
260 TestWidget *widget1 = new TestWidget();
261 layout->setAnchor(layout, Qt::AnchorLeft, widget1, Qt::AnchorLeft, 1);
262 QCOMPARE( layout->count(), 1 );
263
264 // adding one more anchor for already added widget should not increase the count
265 layout->setAnchor(layout, Qt::AnchorRight, widget1, Qt::AnchorRight, 1);
266 QCOMPARE( layout->count(), 1 );
267
268 // create one more widget and attach with anchor layout
269 TestWidget *widget2 = new TestWidget();
270 layout->setAnchor(layout, Qt::AnchorLeft, widget2, Qt::AnchorLeft, 1);
271 QCOMPARE( layout->count(), 2 );
272
273 widget->setLayout(layout);
274 delete widget;
275 }
276
testRemoveAt()277 void tst_QGraphicsAnchorLayout1::testRemoveAt()
278 {
279 TheAnchorLayout *layout = new TheAnchorLayout();
280 QVERIFY( layout->count() == 0 );
281
282 TestWidget *widget1 = new TestWidget();
283 layout->setAnchor(layout, Qt::AnchorLeft, widget1, Qt::AnchorLeft, 2);
284 QVERIFY( layout->count() == 1 );
285
286 TestWidget *widget2 = new TestWidget();
287 layout->setAnchor(widget2, Qt::AnchorLeft, layout, Qt::AnchorLeft, 0.1);
288 QVERIFY( layout->count() == 2 );
289
290 layout->removeAt(0);
291 QVERIFY( layout->count() == 1 );
292
293 layout->removeAt(-55);
294 layout->removeAt(55);
295 QVERIFY( layout->count() == 1 );
296
297 layout->removeAt(0);
298 QVERIFY( layout->count() == 0 );
299
300 delete layout;
301 delete widget1;
302 delete widget2;
303 }
304
testRemoveItem()305 void tst_QGraphicsAnchorLayout1::testRemoveItem()
306 {
307 TheAnchorLayout *layout = new TheAnchorLayout();
308 QCOMPARE( layout->count(), 0 );
309
310 TestWidget *widget1 = new TestWidget();
311 layout->setAnchor(layout, Qt::AnchorLeft, widget1, Qt::AnchorLeft, 2);
312 QCOMPARE( layout->count(), 1 );
313
314 TestWidget *widget2 = new TestWidget();
315 layout->setAnchor(layout, Qt::AnchorLeft, widget2, Qt::AnchorLeft, 0.1);
316 QCOMPARE( layout->count(), 2 );
317
318 layout->removeItem(0);
319 QCOMPARE( layout->count(), 2 );
320
321 layout->removeItem(widget1);
322 QCOMPARE( layout->count(), 1 );
323 QCOMPARE( layout->indexOf(widget1), -1 );
324 QCOMPARE( layout->indexOf(widget2), 0 );
325
326 layout->removeItem(widget1);
327 QCOMPARE( layout->count(), 1 );
328
329 layout->removeItem(widget2);
330 QVERIFY( layout->count() == 0 );
331
332 delete layout;
333 delete widget1;
334 delete widget2;
335 }
336
testItemAt()337 void tst_QGraphicsAnchorLayout1::testItemAt()
338 {
339 QGraphicsWidget *widget = new QGraphicsWidget;
340
341 TheAnchorLayout *layout = new TheAnchorLayout();
342
343 TestWidget *widget1 = new TestWidget();
344 TestWidget *widget2 = new TestWidget();
345 TestWidget *widget3 = new TestWidget();
346 TestWidget *widget4 = new TestWidget();
347
348 layout->setAnchor(layout, Qt::AnchorLeft, widget1, Qt::AnchorLeft, 0.1);
349 layout->setAnchor(layout, Qt::AnchorLeft, widget2, Qt::AnchorLeft, 0.1);
350 layout->setAnchor(layout, Qt::AnchorLeft, widget3, Qt::AnchorLeft, 0.1);
351 layout->setAnchor(layout, Qt::AnchorLeft, widget4, Qt::AnchorLeft, 0.1);
352
353 QVERIFY( layout->itemAt(0) == widget1 );
354
355 layout->removeAt(0);
356
357 QVERIFY( layout->itemAt(0) == widget2 );
358
359 delete widget1;
360
361 widget->setLayout(layout);
362 delete widget;
363 }
364
testIndexOf()365 void tst_QGraphicsAnchorLayout1::testIndexOf()
366 {
367 QGraphicsWidget *widget = new QGraphicsWidget;
368
369 TheAnchorLayout *layout = new TheAnchorLayout();
370
371 TestWidget *widget1 = new TestWidget();
372 TestWidget *widget2 = new TestWidget();
373 TestWidget *widget3 = new TestWidget();
374 TestWidget *widget4 = new TestWidget();
375
376 QCOMPARE( layout->indexOf(widget1), -1 );
377
378 layout->setAnchor(layout, Qt::AnchorLeft, widget1, Qt::AnchorLeft, 0.1);
379 layout->setAnchor(layout, Qt::AnchorLeft, widget2, Qt::AnchorLeft, 0.1);
380 layout->setAnchor(layout, Qt::AnchorLeft, widget3, Qt::AnchorLeft, 0.1);
381
382 QCOMPARE( layout->indexOf(widget4), -1 );
383 layout->setAnchor(layout, Qt::AnchorLeft, widget4, Qt::AnchorLeft, 0.1);
384
385 QCOMPARE( layout->count(), 4 );
386 for (int i = 0; i < layout->count(); ++i) {
387 QCOMPARE(layout->indexOf(layout->itemAt(i)), i);
388 }
389
390 QCOMPARE( layout->indexOf(0), -1 );
391 widget->setLayout(layout);
392 delete widget;
393 }
394
testAddAndRemoveAnchor()395 void tst_QGraphicsAnchorLayout1::testAddAndRemoveAnchor()
396 {
397 QGraphicsWidget *widget = new QGraphicsWidget;
398
399 TheAnchorLayout *layout = new TheAnchorLayout();
400
401 TestWidget *widget1 = new TestWidget();
402 TestWidget *widget2 = new TestWidget();
403 TestWidget *widget3 = new TestWidget();
404 TestWidget *widget4 = new TestWidget();
405 TestWidget *widget5 = new TestWidget();
406
407 layout->setAnchor(layout, Qt::AnchorLeft, widget1, Qt::AnchorLeft, 0.1);
408 layout->setAnchor(layout, Qt::AnchorLeft, widget2, Qt::AnchorLeft, 0.5);
409 layout->setAnchor(layout, Qt::AnchorLeft, widget3, Qt::AnchorLeft, 10);
410 layout->setAnchor(layout, Qt::AnchorLeft, widget4, Qt::AnchorLeft, 0.1);
411 QCOMPARE( layout->count(), 4 );
412
413 // test setting invalid anchors
414 QTest::ignoreMessage(QtWarningMsg, "QGraphicsAnchorLayout::addAnchor(): Cannot anchor NULL items");
415 layout->setAnchor(0, Qt::AnchorLeft, widget1, Qt::AnchorLeft, 1);
416 QTest::ignoreMessage(QtWarningMsg, "QGraphicsAnchorLayout::addAnchor(): Cannot anchor NULL items");
417 layout->setAnchor(layout, Qt::AnchorLeft, 0, Qt::AnchorLeft, 1);
418 QCOMPARE( layout->count(), 4 );
419
420 // test removing invalid anchors
421 layout->removeAnchor(widget4, Qt::AnchorRight, widget1, Qt::AnchorRight);
422
423 // anchor one horizontal edge with vertical edge. it should not add this widget as a child
424 QTest::ignoreMessage(QtWarningMsg, "QGraphicsAnchorLayout::addAnchor(): Cannot anchor edges of different orientations");
425 layout->setAnchor(layout, Qt::AnchorLeft, widget5, Qt::AnchorTop, 10);
426 QCOMPARE( layout->count(), 4 );
427
428 // anchor two edges of a widget (to define width / height)
429 QTest::ignoreMessage(QtWarningMsg, "QGraphicsAnchorLayout::addAnchor(): Cannot anchor the item to itself");
430 layout->setAnchor(widget5, Qt::AnchorLeft, widget5, Qt::AnchorRight, 10);
431 // QCOMPARE( layout->count(), 5 );
432 QCOMPARE( layout->count(), 4 );
433
434 // anchor yet new widget properly
435 layout->setAnchor(layout, Qt::AnchorRight, widget5, Qt::AnchorRight, 20 );
436 QCOMPARE( layout->count(), 5 );
437
438 // remove anchor for widget1. widget1 should be removed from layout since the
439 // last anchor was removed.
440 layout->removeAnchor(layout, Qt::AnchorLeft, widget1, Qt::AnchorLeft);
441
442 QCOMPARE( layout->count(), 4 );
443 QVERIFY( !widget1->parentLayoutItem() );
444
445 // test that item is not removed from layout if other anchors remain set
446 layout->setAnchor(widget2, Qt::AnchorLeft, widget3, Qt::AnchorRight, 10);
447 layout->removeAnchor(layout, Qt::AnchorLeft, widget2, Qt::AnchorLeft);
448 QCOMPARE( layout->count(), 4 );
449
450 // remove all the anchors
451 layout->removeAnchor(widget2, Qt::AnchorLeft, widget3, Qt::AnchorRight);
452 layout->removeAnchor(layout, Qt::AnchorLeft, widget3, Qt::AnchorLeft);
453 layout->removeAnchor(layout, Qt::AnchorLeft, widget4, Qt::AnchorLeft);
454 layout->removeAnchor(widget5, Qt::AnchorLeft, widget5, Qt::AnchorRight);
455 layout->removeAnchor(layout, Qt::AnchorRight, widget5, Qt::AnchorRight);
456
457 QCOMPARE( layout->count(), 0 );
458
459 // set one anchor "another way round" to get full coverage for "removeAnchor"
460 layout->setAnchor(widget1, Qt::AnchorLeft, layout, Qt::AnchorLeft, 0.1);
461 layout->removeAnchor(widget1, Qt::AnchorLeft, layout, Qt::AnchorLeft);
462
463 QCOMPARE( layout->count(), 0 );
464
465 delete widget1;
466 delete widget2;
467 delete widget3;
468 delete widget4;
469 delete widget5;
470
471 widget->setLayout(layout);
472 delete widget;
473 }
474
testIsValid()475 void tst_QGraphicsAnchorLayout1::testIsValid()
476 {
477 // Empty, valid
478 {
479 QGraphicsWidget *widget = new QGraphicsWidget;
480 TheAnchorLayout *layout = new TheAnchorLayout();
481 widget->setLayout(layout);
482 widget->setGeometry(QRectF(0,0,100,100));
483
484 QCOMPARE(layout->isValid(), true);
485 delete widget;
486 }
487
488 // One widget, valid
489 {
490 QGraphicsWidget *widget = new QGraphicsWidget;
491 TheAnchorLayout *layout = new TheAnchorLayout();
492
493 TestWidget *widget1 = new TestWidget();
494
495 layout->setAnchor(layout, Qt::AnchorLeft, widget1, Qt::AnchorLeft, 0.1);
496 layout->setAnchor(layout, Qt::AnchorTop, widget1, Qt::AnchorTop, 0.1);
497 layout->setAnchor(widget1, Qt::AnchorRight, layout, Qt::AnchorRight, 0.1);
498 layout->setAnchor(widget1, Qt::AnchorBottom, layout, Qt::AnchorBottom, 0.1);
499
500 widget->setLayout(layout);
501
502 widget->setGeometry(QRectF(0,0,100,100));
503 QCOMPARE(layout->isValid(), true);
504 delete widget;
505 }
506
507 // Overconstrained one widget, invalid
508 // ### Our understanding is that this case is valid. What happens though,
509 // is that the layout minimum and maximum vertical size hints become
510 // the same, 10.1. That means its height is fixed.
511 // What will "fail" then is the "setGeometry(0, 0, 100, 100)" call,
512 // after which the layout geometry will be (0, 0, 100, 10.1).
513
514 {
515 QGraphicsWidget *widget = new QGraphicsWidget;
516 TheAnchorLayout *layout = new TheAnchorLayout();
517
518 TestWidget *widget1 = new TestWidget();
519
520 layout->setAnchor(layout, Qt::AnchorLeft, widget1, Qt::AnchorLeft, 0.1);
521 layout->setAnchor(layout, Qt::AnchorTop, widget1, Qt::AnchorTop, 0.1);
522 layout->setAnchor(widget1, Qt::AnchorRight, layout, Qt::AnchorRight, 0.1);
523 layout->setAnchor(widget1, Qt::AnchorBottom, layout, Qt::AnchorBottom, 0.1);
524
525 layout->setAnchor(widget1, Qt::AnchorTop, layout, Qt::AnchorBottom, 10);
526
527 widget->setLayout(layout);
528
529 widget->setGeometry(QRectF(0,0,100,100));
530 QCOMPARE(layout->isValid(), true);
531 delete widget;
532 }
533
534 // Underconstrained two widgets, valid
535 {
536 QGraphicsWidget *widget = new QGraphicsWidget;
537 TheAnchorLayout *layout = new TheAnchorLayout();
538
539 TestWidget *widget1 = new TestWidget();
540 TestWidget *widget2 = new TestWidget();
541
542 // Vertically the layout has floating items. Therefore, we have a conflict
543 layout->setAnchor(layout, Qt::AnchorLeft, widget1, Qt::AnchorLeft, 0.1);
544 layout->setAnchor(layout, Qt::AnchorRight, widget1, Qt::AnchorRight, -0.1);
545
546 // Horizontally the layout has floating items. Therefore, we have a conflict
547 layout->setAnchor(layout, Qt::AnchorTop, widget2, Qt::AnchorTop, 0.1);
548 layout->setAnchor(layout, Qt::AnchorBottom, widget2, Qt::AnchorBottom, -0.1);
549
550 widget->setLayout(layout);
551
552 widget->setGeometry(QRectF(0,0,100,100));
553 QCOMPARE(layout->isValid(), false);
554 delete widget;
555 }
556 }
557
testSpecialCases()558 void tst_QGraphicsAnchorLayout1::testSpecialCases()
559 {
560 // One widget, setLayout before defining layouts
561 {
562 #ifdef QT_DEBUG
563 QTest::ignoreMessage(QtWarningMsg, "QGraphicsLayout::addChildLayoutItem: QGraphicsWidget \"\""
564 " in wrong parent; moved to correct parent");
565 #endif
566 QGraphicsWidget *widget = new QGraphicsWidget;
567 TheAnchorLayout *layout = new TheAnchorLayout();
568 widget->setLayout(layout);
569
570 TestWidget *widget1 = new TestWidget();
571
572 layout->setAnchor(layout, Qt::AnchorLeft, widget1, Qt::AnchorLeft, 1);
573 layout->setAnchor(layout, Qt::AnchorTop, widget1, Qt::AnchorTop, 1);
574 layout->setAnchor(widget1, Qt::AnchorRight, layout, Qt::AnchorRight, 1);
575 layout->setAnchor(widget1, Qt::AnchorBottom, layout, Qt::AnchorBottom, 1);
576 widget->setGeometry(QRectF(0,0,100,100));
577 QCOMPARE(widget1->geometry(), QRectF(1,1,98,98));
578 delete widget1;
579 delete widget;
580 }
581
582 // One widget, layout inside layout, layout inside layout inside layout
583 {
584 #ifdef QT_DEBUG
585 QTest::ignoreMessage(QtWarningMsg, "QGraphicsLayout::addChildLayoutItem: QGraphicsWidget \"\""
586 " in wrong parent; moved to correct parent");
587 #endif
588 QGraphicsWidget *widget = new QGraphicsWidget;
589 TheAnchorLayout *layout = new TheAnchorLayout();
590 widget->setLayout(layout);
591
592 TheAnchorLayout *layout1 = new TheAnchorLayout();
593 TestWidget *widget1 = new TestWidget();
594 layout1->setAnchor(layout1, Qt::AnchorLeft, widget1, Qt::AnchorLeft, 1);
595 layout1->setAnchor(layout1, Qt::AnchorTop, widget1, Qt::AnchorTop, 1);
596 layout1->setAnchor(widget1, Qt::AnchorRight, layout1, Qt::AnchorRight, 1);
597 layout1->setAnchor(widget1, Qt::AnchorBottom, layout1, Qt::AnchorBottom, 1);
598
599 TheAnchorLayout *layout2 = new TheAnchorLayout();
600 TestWidget *widget2 = new TestWidget();
601 layout2->setAnchor(layout2, Qt::AnchorLeft, widget2, Qt::AnchorLeft, 1);
602 layout2->setAnchor(layout2, Qt::AnchorTop, widget2, Qt::AnchorTop, 1);
603 layout2->setAnchor(widget2, Qt::AnchorRight, layout2, Qt::AnchorRight, 1);
604 layout2->setAnchor(widget2, Qt::AnchorBottom, layout2, Qt::AnchorBottom, 1);
605
606 layout1->setAnchor(layout1, Qt::AnchorLeft, layout2, Qt::AnchorLeft, 1);
607 layout1->setAnchor(layout1, Qt::AnchorTop, layout2, Qt::AnchorTop, 1);
608 layout1->setAnchor(layout2, Qt::AnchorRight, layout1, Qt::AnchorRight, 1);
609 layout1->setAnchor(layout2, Qt::AnchorBottom, layout1, Qt::AnchorBottom, 1);
610
611 layout->setAnchor(layout, Qt::AnchorLeft, layout1, Qt::AnchorLeft, 1);
612 layout->setAnchor(layout, Qt::AnchorTop, layout1, Qt::AnchorTop, 1);
613 layout->setAnchor(layout1, Qt::AnchorRight, layout, Qt::AnchorRight, 1);
614 layout->setAnchor(layout1, Qt::AnchorBottom, layout, Qt::AnchorBottom, 1);
615
616 // remove and add again to improve test coverage.
617 layout->removeItem(layout1);
618
619 layout->setAnchor(layout, Qt::AnchorLeft, layout1, Qt::AnchorLeft, 1);
620 layout->setAnchor(layout, Qt::AnchorTop, layout1, Qt::AnchorTop, 1);
621 layout->setAnchor(layout1, Qt::AnchorRight, layout, Qt::AnchorRight, 1);
622 layout->setAnchor(layout1, Qt::AnchorBottom, layout, Qt::AnchorBottom, 1);
623
624 widget->setGeometry(QRectF(0,0,100,100));
625 QCOMPARE(widget1->geometry(), QRectF(2,2,96,96));
626 QCOMPARE(widget2->geometry(), QRectF(3,3,94,94));
627 delete widget;
628 }
629
630 // One widget, layout inside layout, setLayout after layout definition
631 {
632 QGraphicsWidget *widget = new QGraphicsWidget;
633 TheAnchorLayout *layout = new TheAnchorLayout();
634
635 TheAnchorLayout *layout1 = new TheAnchorLayout();
636
637 TestWidget *widget1 = new TestWidget();
638 layout1->setAnchor(layout1, Qt::AnchorLeft, widget1, Qt::AnchorLeft, 1);
639 layout1->setAnchor(layout1, Qt::AnchorTop, widget1, Qt::AnchorTop, 1);
640 layout1->setAnchor(widget1, Qt::AnchorRight, layout1, Qt::AnchorRight, 1);
641 layout1->setAnchor(widget1, Qt::AnchorBottom, layout1, Qt::AnchorBottom, 1);
642
643 layout->setAnchor(layout, Qt::AnchorLeft, layout1, Qt::AnchorLeft, 1);
644 layout->setAnchor(layout, Qt::AnchorTop, layout1, Qt::AnchorTop, 1);
645 layout->setAnchor(layout1, Qt::AnchorRight, layout, Qt::AnchorRight, 1);
646 layout->setAnchor(layout1, Qt::AnchorBottom, layout, Qt::AnchorBottom, 1);
647
648 widget->setLayout(layout);
649 widget->setGeometry(QRectF(0,0,100,100));
650 QCOMPARE(widget1->geometry(), QRectF(2,2,96,96));
651 delete widget;
652 }
653
654 // One widget, layout inside layout, setLayout after layout definition, widget transferred from
655 // one layout to another
656 {
657 QGraphicsWidget *widget = new QGraphicsWidget;
658 TheAnchorLayout *layout = new TheAnchorLayout();
659 widget->setLayout(layout);
660
661 TheAnchorLayout *layout1 = new TheAnchorLayout();
662 TestWidget *widget1 = new TestWidget();
663
664 // Additional layout + widget to improve coverage.
665 TheAnchorLayout *layout0 = new TheAnchorLayout();
666 TestWidget *widget0 = new TestWidget();
667
668 // widget0 to layout0
669 layout0->setAnchor(layout0, Qt::AnchorLeft, widget0, Qt::AnchorLeft, 1);
670 layout0->setAnchor(layout0, Qt::AnchorTop, widget0, Qt::AnchorTop, 1);
671 layout0->setAnchor(widget0, Qt::AnchorRight, layout0, Qt::AnchorRight, 1);
672 layout0->setAnchor(widget0, Qt::AnchorBottom, layout0, Qt::AnchorBottom, 1);
673
674 // layout0 to layout
675 layout->setAnchor(layout, Qt::AnchorLeft, layout0, Qt::AnchorLeft, 1);
676 layout->setAnchor(layout, Qt::AnchorTop, layout0, Qt::AnchorTop, 1);
677 layout->setAnchor(layout0, Qt::AnchorRight, layout, Qt::AnchorRight, 50);
678 layout->setAnchor(layout0, Qt::AnchorBottom, layout, Qt::AnchorBottom, 1);
679
680 // widget1 to layout1
681 layout1->setAnchor(layout1, Qt::AnchorLeft, widget1, Qt::AnchorLeft, 1);
682 layout1->setAnchor(layout1, Qt::AnchorTop, widget1, Qt::AnchorTop, 1);
683 layout1->setAnchor(widget1, Qt::AnchorRight, layout1, Qt::AnchorRight, 1);
684 layout1->setAnchor(widget1, Qt::AnchorBottom, layout1, Qt::AnchorBottom, 1);
685
686 // layout1 to layout
687 layout->setAnchor(layout, Qt::AnchorLeft, layout1, Qt::AnchorLeft, 1);
688 layout->setAnchor(layout, Qt::AnchorTop, layout1, Qt::AnchorTop, 1);
689 layout->setAnchor(layout1, Qt::AnchorRight, layout, Qt::AnchorRight, 50);
690 layout->setAnchor(layout1, Qt::AnchorBottom, layout, Qt::AnchorBottom, 1);
691
692 TheAnchorLayout *layout2 = new TheAnchorLayout();
693
694 // layout2 to layout
695 layout->setAnchor(layout, Qt::AnchorLeft, layout2, Qt::AnchorLeft, 50);
696 layout->setAnchor(layout, Qt::AnchorTop, layout2, Qt::AnchorTop, 1);
697 layout->setAnchor(layout2, Qt::AnchorRight, layout, Qt::AnchorRight, 1);
698 layout->setAnchor(layout2, Qt::AnchorBottom, layout, Qt::AnchorBottom, 1);
699
700 // transfer widget1 to layout2
701 layout2->setAnchor(layout2, Qt::AnchorLeft, widget1, Qt::AnchorLeft, 1);
702 layout2->setAnchor(layout2, Qt::AnchorTop, widget1, Qt::AnchorTop, 1);
703 layout2->setAnchor(widget1, Qt::AnchorRight, layout2, Qt::AnchorRight, 1);
704 layout2->setAnchor(widget1, Qt::AnchorBottom, layout2, Qt::AnchorBottom, 1);
705
706 widget->setGeometry(QRectF(0,0,100,100));
707 QCOMPARE(widget1->geometry(), QRectF(51,2,47,96));
708 delete widget;
709 }
710
711 // One widget, set first to one layout then to another. Child reparented.
712 // In addition widget as a direct child of another widget. Child reparented.
713 {
714 QGraphicsWidget *widget1 = new QGraphicsWidget;
715 TheAnchorLayout *layout1 = new TheAnchorLayout();
716 widget1->setLayout(layout1);
717
718 TestWidget *childWidget = new TestWidget();
719
720 // childWidget to layout1
721 layout1->setAnchor(layout1, Qt::AnchorLeft, childWidget, Qt::AnchorLeft, 1);
722 layout1->setAnchor(layout1, Qt::AnchorTop, childWidget, Qt::AnchorTop, 1);
723 layout1->setAnchor(childWidget, Qt::AnchorRight, layout1, Qt::AnchorRight, 1);
724 layout1->setAnchor(childWidget, Qt::AnchorBottom, layout1, Qt::AnchorBottom, 1);
725
726 widget1->setGeometry(QRectF(0,0,100,100));
727 QCOMPARE(childWidget->geometry(), QRectF(1,1,98,98));
728 QVERIFY(childWidget->parentLayoutItem() == layout1);
729 QGraphicsWidget *widget2 = new QGraphicsWidget;
730 TheAnchorLayout *layout2 = new TheAnchorLayout();
731 widget2->setLayout(layout2);
732
733 // childWidget to layout2
734 layout2->setAnchor(layout2, Qt::AnchorLeft, childWidget, Qt::AnchorLeft, 1);
735 layout2->setAnchor(layout2, Qt::AnchorTop, childWidget, Qt::AnchorTop, 1);
736 layout2->setAnchor(childWidget, Qt::AnchorRight, layout2, Qt::AnchorRight, 1);
737 layout2->setAnchor(childWidget, Qt::AnchorBottom, layout2, Qt::AnchorBottom, 1);
738
739 QGraphicsWidget *widget3 = new QGraphicsWidget;
740 QGraphicsWidget *widget4 = new QGraphicsWidget;
741 // widget4 is a direct child of widget3 (i.e. not in any layout)
742 widget4->setParentItem(widget3);
743
744 // widget4 to layout2
745 layout2->setAnchor(layout2, Qt::AnchorLeft, widget4, Qt::AnchorLeft, 1);
746 layout2->setAnchor(layout2, Qt::AnchorTop, widget4, Qt::AnchorTop, 1);
747 layout2->setAnchor(widget4, Qt::AnchorRight, layout2, Qt::AnchorRight, 1);
748 layout2->setAnchor(widget4, Qt::AnchorBottom, layout2, Qt::AnchorBottom, 1);
749
750 widget2->setGeometry(QRectF(0,0,100,100));
751 QCOMPARE(childWidget->geometry(), QRectF(1,1,98,98));
752 QVERIFY(childWidget->parentLayoutItem() == layout2);
753 QCOMPARE(widget4->geometry(), QRectF(1,1,98,98));
754 QVERIFY(widget4->parentLayoutItem() == layout2);
755 QVERIFY(widget4->parentItem() == widget2);
756
757 delete widget4;
758 delete widget3;
759 delete widget1;
760 delete childWidget;
761 delete widget2;
762 }
763 }
764
testBasicLayout_data()765 void tst_QGraphicsAnchorLayout1::testBasicLayout_data()
766 {
767 QTest::addColumn<QSizeF>("size");
768 QTest::addColumn<BasicLayoutTestDataList>("data");
769 QTest::addColumn<BasicLayoutTestResultList>("result");
770
771 typedef BasicLayoutTestData BasicData;
772 typedef BasicLayoutTestResult BasicResult;
773
774 // One widget, basic
775 {
776 BasicLayoutTestDataList theData;
777 BasicLayoutTestResultList theResult;
778
779 theData
780 << BasicData(-1, Qt::AnchorTop, 0, Qt::AnchorTop, 10)
781 << BasicData(-1, Qt::AnchorLeft, 0, Qt::AnchorLeft, 20)
782 << BasicData(0, Qt::AnchorRight, -1, Qt::AnchorRight, 30)
783 << BasicData(0, Qt::AnchorBottom, -1, Qt::AnchorBottom, 40)
784 ;
785
786 theResult
787 << BasicResult(0, QRectF(20, 10, 150, 50) )
788 ;
789
790 QTest::newRow("One, simple") << QSizeF(200, 100) << theData << theResult;
791 }
792
793 // One widget, duplicates
794 {
795 BasicLayoutTestDataList theData;
796 BasicLayoutTestResultList theResult;
797
798 theData
799 << BasicData(-1, Qt::AnchorTop, 0, Qt::AnchorTop, 10)
800 << BasicData(-1, Qt::AnchorLeft, 0, Qt::AnchorLeft, 20)
801 << BasicData(0, Qt::AnchorRight, -1, Qt::AnchorRight, 30)
802 << BasicData(0, Qt::AnchorBottom, -1, Qt::AnchorBottom, 40)
803
804 << BasicData(0, Qt::AnchorTop, -1, Qt::AnchorTop, 0)
805 << BasicData(-1, Qt::AnchorLeft, 0, Qt::AnchorLeft, 0)
806 << BasicData(-1, Qt::AnchorRight, 0, Qt::AnchorRight, 0)
807 << BasicData(0, Qt::AnchorBottom, -1, Qt::AnchorBottom, 0)
808 ;
809
810 theResult
811 << BasicResult(0, QRectF(0, 0, 200, 100) )
812 ;
813
814 QTest::newRow("One, duplicates") << QSizeF(200, 100) << theData << theResult;
815 }
816
817 // One widget, mixed
818 {
819 BasicLayoutTestDataList theData;
820 BasicLayoutTestResultList theResult;
821
822 theData
823 << BasicData(-1, Qt::AnchorTop, 0, Qt::AnchorBottom, 80)
824 << BasicData(-1, Qt::AnchorLeft, 0, Qt::AnchorRight, 150)
825 << BasicData(0, Qt::AnchorLeft, -1, Qt::AnchorRight, 150)
826 << BasicData(0, Qt::AnchorTop, -1, Qt::AnchorBottom, 80)
827 ;
828
829 theResult
830 << BasicResult(0, QRectF(50, 20, 100, 60) )
831 ;
832
833 QTest::newRow("One, mixed") << QSizeF(200, 100) << theData << theResult;
834 }
835
836 // Basic case - two widgets (same layout), different ordering
837 {
838 BasicLayoutTestDataList theData;
839 BasicLayoutTestResultList theResult;
840
841 theData
842 << BasicData(-1, Qt::AnchorTop, 0, Qt::AnchorTop, 10)
843 << BasicData(-1, Qt::AnchorLeft, 0, Qt::AnchorLeft, 10)
844 << BasicData(0, Qt::AnchorRight, -1, Qt::AnchorRight, 10)
845 << BasicData(0, Qt::AnchorBottom, -1, Qt::AnchorBottom, 10)
846
847 << BasicData(1, Qt::AnchorBottom, -1, Qt::AnchorBottom, 10)
848 << BasicData(-1, Qt::AnchorLeft, 1, Qt::AnchorLeft, 10)
849 << BasicData(-1, Qt::AnchorTop, 1, Qt::AnchorTop, 10)
850 << BasicData(1, Qt::AnchorRight, -1, Qt::AnchorRight, 10)
851 ;
852
853 theResult
854 << BasicResult(0, QRectF(10, 10, 180, 80) )
855 << BasicResult(1, QRectF(10, 10, 180, 80) )
856 ;
857
858 QTest::newRow("Two, orderings") << QSizeF(200, 100) << theData << theResult;
859 }
860
861 // Basic case - two widgets, duplicate anchors
862 {
863 BasicLayoutTestDataList theData;
864 BasicLayoutTestResultList theResult;
865
866 theData
867 << BasicData(-1, Qt::AnchorTop, 0, Qt::AnchorTop, 10)
868 << BasicData(-1, Qt::AnchorLeft, 0, Qt::AnchorLeft, 10)
869 << BasicData(0, Qt::AnchorRight, -1, Qt::AnchorRight, 10)
870 << BasicData(0, Qt::AnchorBottom, -1, Qt::AnchorBottom, 10)
871 << BasicData(-1, Qt::AnchorLeft, 0, Qt::AnchorLeft, 30)
872 << BasicData(0, Qt::AnchorBottom, -1, Qt::AnchorBottom, 20)
873
874 << BasicData(1, Qt::AnchorBottom, -1, Qt::AnchorBottom, 10)
875 << BasicData(-1, Qt::AnchorLeft, 1, Qt::AnchorLeft, 10)
876 << BasicData(-1, Qt::AnchorTop, 1, Qt::AnchorTop, 10)
877 << BasicData(1, Qt::AnchorRight, -1, Qt::AnchorRight, 10)
878 << BasicData(1, Qt::AnchorTop, -1, Qt::AnchorTop, 0)
879 << BasicData(-1, Qt::AnchorRight, 1, Qt::AnchorRight, 0)
880 ;
881
882 theResult
883 << BasicResult(0, QRectF(30, 10, 160, 70) )
884 << BasicResult(1, QRectF(10, 0, 190, 90) )
885 ;
886
887 QTest::newRow("Two, duplicates") << QSizeF(200, 100) << theData << theResult;
888 }
889
890 // Basic case - two widgets, mixed
891 {
892 BasicLayoutTestDataList theData;
893 BasicLayoutTestResultList theResult;
894
895 theData
896 << BasicData(-1, Qt::AnchorTop, 0, Qt::AnchorBottom, 90)
897 << BasicData(-1, Qt::AnchorLeft, 0, Qt::AnchorRight, 190)
898 << BasicData(0, Qt::AnchorLeft, -1, Qt::AnchorRight, 190)
899 << BasicData(0, Qt::AnchorTop, -1, Qt::AnchorBottom, 90)
900
901 << BasicData(1, Qt::AnchorTop, -1, Qt::AnchorBottom, 20)
902 << BasicData(1, Qt::AnchorBottom, -1, Qt::AnchorBottom, 10)
903 << BasicData(-1, Qt::AnchorLeft, 1, Qt::AnchorLeft, 10)
904 << BasicData(-1, Qt::AnchorLeft, 1, Qt::AnchorRight, 20)
905 ;
906
907 theResult
908 << BasicResult(0, QRectF(10, 10, 180, 80) )
909 << BasicResult(1, QRectF(10, 80, 10, 10) )
910 ;
911
912 QTest::newRow("Two, mixed") << QSizeF(200, 100) << theData << theResult;
913 }
914
915 // Basic case - two widgets, 1 horizontal connection, first completely defined
916 {
917 BasicLayoutTestDataList theData;
918 BasicLayoutTestResultList theResult;
919
920 theData
921 << BasicData(-1, Qt::AnchorTop, 0, Qt::AnchorTop, 10)
922 << BasicData(0, Qt::AnchorBottom, -1, Qt::AnchorBottom, 10)
923 << BasicData(-1, Qt::AnchorLeft, 0, Qt::AnchorLeft, 10)
924 << BasicData(0, Qt::AnchorRight, -1, Qt::AnchorRight, 180)
925
926 << BasicData(0, Qt::AnchorRight, 1, Qt::AnchorLeft, 10)
927 << BasicData(1, Qt::AnchorRight, -1, Qt::AnchorRight, 10)
928 << BasicData(-1, Qt::AnchorTop, 1, Qt::AnchorTop, 10)
929 << BasicData(1, Qt::AnchorBottom, -1, Qt::AnchorBottom, 20)
930 ;
931
932 theResult
933 << BasicResult(0, QRectF(10, 10, 10, 80) )
934 << BasicResult(1, QRectF(30, 10, 160, 70) )
935 ;
936
937 QTest::newRow("Two, 1h connected") << QSizeF(200, 100) << theData << theResult;
938 }
939
940 // Basic case - two widgets, 2 horizontal connections, first completely defined
941 {
942 BasicLayoutTestDataList theData;
943 BasicLayoutTestResultList theResult;
944
945 theData
946 << BasicData(-1, Qt::AnchorTop, 0, Qt::AnchorTop, 10)
947 << BasicData(0, Qt::AnchorBottom, -1, Qt::AnchorBottom, 10)
948 << BasicData(-1, Qt::AnchorLeft, 0, Qt::AnchorLeft, 10)
949 << BasicData(0, Qt::AnchorRight, -1, Qt::AnchorRight, 180)
950
951 // ### QGAL is not sensible to the argument order in this case
952 // To achieve the desired result we must explicitly set a negative
953 // spacing.
954 // << BasicData(0, Qt::AnchorLeft, 1, Qt::AnchorRight, 100)
955 << BasicData(0, Qt::AnchorLeft, 1, Qt::AnchorRight, -100)
956
957 << BasicData(0, Qt::AnchorRight, 1, Qt::AnchorLeft, 30)
958 << BasicData(-1, Qt::AnchorTop, 1, Qt::AnchorTop, 10)
959 << BasicData(1, Qt::AnchorBottom, -1, Qt::AnchorBottom, 20)
960 ;
961
962 theResult
963 << BasicResult(0, QRectF(10, 10, 10, 80) )
964 << BasicResult(1, QRectF(50, 10, 60, 70) )
965 ;
966
967 QTest::newRow("Two, 2h connected") << QSizeF(200, 100) << theData << theResult;
968 }
969
970 // Basic case - two widgets, 1 vertical connection, first completely defined
971 {
972 BasicLayoutTestDataList theData;
973 BasicLayoutTestResultList theResult;
974
975 theData
976 << BasicData(-1, Qt::AnchorTop, 0, Qt::AnchorTop, 10)
977 << BasicData(0, Qt::AnchorBottom, -1, Qt::AnchorBottom, 10)
978 << BasicData(-1, Qt::AnchorLeft, 0, Qt::AnchorLeft, 10)
979 << BasicData(0, Qt::AnchorRight, -1, Qt::AnchorRight, 180)
980
981 << BasicData(-1, Qt::AnchorLeft, 1, Qt::AnchorLeft, 30)
982 << BasicData(1, Qt::AnchorRight, -1, Qt::AnchorRight, 10)
983 << BasicData(0, Qt::AnchorTop, 1, Qt::AnchorTop, 10)
984 << BasicData(1, Qt::AnchorBottom, -1, Qt::AnchorBottom, 20)
985 ;
986
987 theResult
988 << BasicResult(0, QRectF(10, 10, 10, 80) )
989 << BasicResult(1, QRectF(30, 20, 160, 60) )
990 ;
991
992 QTest::newRow("Two, 1v connected") << QSizeF(200, 100) << theData << theResult;
993 }
994
995 // Basic case - two widgets, 2 vertical connections, first completely defined
996 {
997 BasicLayoutTestDataList theData;
998 BasicLayoutTestResultList theResult;
999
1000 theData
1001 << BasicData(-1, Qt::AnchorTop, 0, Qt::AnchorTop, 10)
1002 << BasicData(0, Qt::AnchorBottom, -1, Qt::AnchorBottom, 10)
1003 << BasicData(-1, Qt::AnchorLeft, 0, Qt::AnchorLeft, 10)
1004 << BasicData(0, Qt::AnchorRight, -1, Qt::AnchorRight, 180)
1005
1006 << BasicData(-1, Qt::AnchorLeft, 1, Qt::AnchorLeft, 30)
1007 << BasicData(1, Qt::AnchorRight, -1, Qt::AnchorRight, 10)
1008 << BasicData(0, Qt::AnchorTop, 1, Qt::AnchorTop, 10)
1009 << BasicData(1, Qt::AnchorBottom, 0, Qt::AnchorBottom, 20)
1010 ;
1011
1012 theResult
1013 << BasicResult(0, QRectF(10, 10, 10, 80) )
1014 << BasicResult(1, QRectF(30, 20, 160, 50) )
1015 ;
1016
1017 QTest::newRow("Two, 2v connected") << QSizeF(200, 100) << theData << theResult;
1018 }
1019
1020 // Basic case - two widgets, 1 horizontal and 1 vertical connection, first completely defined
1021 {
1022 BasicLayoutTestDataList theData;
1023 BasicLayoutTestResultList theResult;
1024
1025 theData
1026 << BasicData(-1, Qt::AnchorTop, 0, Qt::AnchorTop, 10)
1027 << BasicData(0, Qt::AnchorBottom, -1, Qt::AnchorBottom, 10)
1028 << BasicData(-1, Qt::AnchorLeft, 0, Qt::AnchorLeft, 10)
1029 << BasicData(0, Qt::AnchorRight, -1, Qt::AnchorRight, 180)
1030
1031 << BasicData(-1, Qt::AnchorLeft, 1, Qt::AnchorLeft, 80)
1032 << BasicData(0, Qt::AnchorRight, 1, Qt::AnchorRight, 100)
1033 << BasicData(-1, Qt::AnchorTop, 1, Qt::AnchorTop, 10)
1034 << BasicData(1, Qt::AnchorBottom, 0, Qt::AnchorBottom, 10)
1035 ;
1036
1037 theResult
1038 << BasicResult(0, QRectF(10, 10, 10, 80) )
1039 << BasicResult(1, QRectF(80, 10, 40, 70) )
1040 ;
1041
1042 QTest::newRow("Two, 1h+1v connected") << QSizeF(200, 100) << theData << theResult;
1043 }
1044
1045 // Basic case - two widgets, 2 horizontal and 2 vertical connections, first completely defined
1046 {
1047 BasicLayoutTestDataList theData;
1048 BasicLayoutTestResultList theResult;
1049
1050 theData
1051 << BasicData(-1, Qt::AnchorTop, 0, Qt::AnchorTop, 10)
1052 << BasicData(0, Qt::AnchorBottom, -1, Qt::AnchorBottom, 10)
1053 << BasicData(-1, Qt::AnchorLeft, 0, Qt::AnchorLeft, 10)
1054 << BasicData(0, Qt::AnchorRight, -1, Qt::AnchorRight, 180)
1055
1056 << BasicData(0, Qt::AnchorLeft, 1, Qt::AnchorLeft, 80)
1057 << BasicData(0, Qt::AnchorRight, 1, Qt::AnchorRight, 100)
1058 << BasicData(0, Qt::AnchorTop, 1, Qt::AnchorTop, 10)
1059 << BasicData(1, Qt::AnchorBottom, 0, Qt::AnchorBottom, 10)
1060 ;
1061
1062 theResult
1063 << BasicResult(0, QRectF(10, 10, 10, 80) )
1064 << BasicResult(1, QRectF(90, 20, 30, 60) )
1065 ;
1066
1067 QTest::newRow("Two, 2h+2v connected") << QSizeF(200, 100) << theData << theResult;
1068 }
1069
1070 // Basic case - two widgets, 2 horizontal and 2 vertical connections, dependent on each other.
1071 {
1072 BasicLayoutTestDataList theData;
1073 BasicLayoutTestResultList theResult;
1074
1075 theData
1076 << BasicData(-1, Qt::AnchorLeft, 0, Qt::AnchorLeft, 10)
1077 << BasicData(0, Qt::AnchorRight, 1, Qt::AnchorRight, 150)
1078 << BasicData(-1, Qt::AnchorTop, 0, Qt::AnchorTop, 10)
1079 << BasicData(0, Qt::AnchorBottom, 1, Qt::AnchorBottom, 10)
1080
1081 << BasicData(0, Qt::AnchorLeft, 1, Qt::AnchorLeft, 90)
1082 << BasicData(1, Qt::AnchorRight, -1, Qt::AnchorRight, 10)
1083 << BasicData(0, Qt::AnchorTop, 1, Qt::AnchorTop, 10)
1084 << BasicData(1, Qt::AnchorBottom, -1, Qt::AnchorBottom, 20)
1085 ;
1086
1087 theResult
1088 << BasicResult(0, QRectF(10, 10, 30, 60) )
1089 << BasicResult(1, QRectF(100, 20, 90, 60) )
1090 ;
1091
1092 QTest::newRow("Two, 2h+2v connected2") << QSizeF(200, 100) << theData << theResult;
1093 }
1094
1095 // Basic case - two widgets, connected, overlapping
1096 {
1097 BasicLayoutTestDataList theData;
1098 BasicLayoutTestResultList theResult;
1099
1100 theData
1101 << BasicData(-1, Qt::AnchorLeft, 0, Qt::AnchorLeft, 10)
1102 << BasicData(-1, Qt::AnchorTop, 0, Qt::AnchorTop, 10)
1103 // << BasicData(1, Qt::AnchorLeft, 0, Qt::AnchorRight, 30)
1104 // ### QGAL has different semantics and assumes right edges are always
1105 // to the left of left edges. Thus we need the minus sign here.
1106 << BasicData(1, Qt::AnchorLeft, 0, Qt::AnchorRight, -30)
1107 << BasicData(0, Qt::AnchorBottom, 1, Qt::AnchorBottom, 40)
1108
1109 << BasicData(-1, Qt::AnchorLeft, 1, Qt::AnchorLeft, 40)
1110 << BasicData(-1, Qt::AnchorTop, 1, Qt::AnchorTop, 20)
1111 << BasicData(1, Qt::AnchorRight, -1, Qt::AnchorRight, 10)
1112 << BasicData(1, Qt::AnchorBottom, -1, Qt::AnchorBottom, 10)
1113 ;
1114
1115 theResult
1116 << BasicResult(0, QRectF(10, 10, 60, 40) )
1117 << BasicResult(1, QRectF(40, 20, 150, 70) )
1118 ;
1119
1120 QTest::newRow("Two, connected overlapping") << QSizeF(200, 100) << theData << theResult;
1121 }
1122 }
1123
testNegativeSpacing_data()1124 void tst_QGraphicsAnchorLayout1::testNegativeSpacing_data()
1125 {
1126 QTest::addColumn<QSizeF>("size");
1127 QTest::addColumn<BasicLayoutTestDataList>("data");
1128 QTest::addColumn<BasicLayoutTestResultList>("result");
1129
1130 typedef BasicLayoutTestData BasicData;
1131 typedef BasicLayoutTestResult BasicResult;
1132
1133 // One widget, negative spacing
1134 {
1135 BasicLayoutTestDataList theData;
1136 BasicLayoutTestResultList theResult;
1137
1138 /// ### QGAL assumes items are always inside the layout.
1139 // In this case, the negative spacing would make the item
1140 // grow beyond the layout edges, which is OK, but gives a
1141 // different result.
1142 // Changing the direction of anchors (-1 to 0 or vice-versa)
1143 // has no effect in this case.
1144
1145 theData
1146 // << BasicData(0, Qt::AnchorTop, -1, Qt::AnchorTop, -10)
1147 // << BasicData(0, Qt::AnchorLeft, -1, Qt::AnchorLeft, -20)
1148 // << BasicData(-1, Qt::AnchorRight, 0, Qt::AnchorRight, -30)
1149 // << BasicData(-1, Qt::AnchorBottom, 0, Qt::AnchorBottom, -40)
1150
1151 << BasicData(-1, Qt::AnchorTop, 0, Qt::AnchorTop, -10)
1152 << BasicData(-1, Qt::AnchorLeft, 0, Qt::AnchorLeft, -20)
1153 << BasicData(0, Qt::AnchorRight, -1, Qt::AnchorRight, -30)
1154 << BasicData(0, Qt::AnchorBottom, -1, Qt::AnchorBottom, -40)
1155
1156 ;
1157
1158 theResult
1159 // << BasicResult(0, QRectF(20, 10, 150, 50) )
1160 << BasicResult(0, QRectF(-20, -10, 250, 150) )
1161 ;
1162
1163 QTest::newRow("One, simple (n)") << QSizeF(200, 100) << theData << theResult;
1164 }
1165
1166 // One widget, duplicates, negative spacing
1167 {
1168 BasicLayoutTestDataList theData;
1169 BasicLayoutTestResultList theResult;
1170
1171 theData
1172 << BasicData(0, Qt::AnchorTop, -1, Qt::AnchorTop, -20)
1173 << BasicData(0, Qt::AnchorLeft, -1, Qt::AnchorLeft, -20)
1174 << BasicData(-1, Qt::AnchorRight, 0, Qt::AnchorRight, -30)
1175 << BasicData(-1, Qt::AnchorBottom, 0, Qt::AnchorBottom, -40)
1176
1177 << BasicData(0, Qt::AnchorTop, -1, Qt::AnchorTop, -10)
1178 << BasicData(0, Qt::AnchorLeft, -1, Qt::AnchorLeft, -10)
1179 << BasicData(-1, Qt::AnchorRight, 0, Qt::AnchorRight, -10)
1180 << BasicData(-1, Qt::AnchorBottom, 0, Qt::AnchorBottom, -10)
1181 ;
1182
1183 theResult
1184 // ### Same as above...
1185 // << BasicResult(0, QRectF(10, 10, 180, 80) )
1186 << BasicResult(0, QRectF(-10, -10, 220, 120) )
1187 ;
1188
1189 QTest::newRow("One, duplicates (n)") << QSizeF(200, 100) << theData << theResult;
1190 }
1191
1192 // One widget, mixed, negative spacing
1193 {
1194 BasicLayoutTestDataList theData;
1195 BasicLayoutTestResultList theResult;
1196
1197 theData
1198 // ### All anchors of negative spacing between the layout and an
1199 // item are handled as to make sure the item is _outside_ the
1200 // layout.
1201 // To keep it inside, one _must_ use positive spacings.
1202 // << BasicData(0, Qt::AnchorBottom, -1, Qt::AnchorTop, -80)
1203 // << BasicData(0, Qt::AnchorRight, -1, Qt::AnchorLeft, -150)
1204 // << BasicData(-1, Qt::AnchorRight, 0, Qt::AnchorLeft, -150)
1205 // << BasicData(-1, Qt::AnchorBottom, 0, Qt::AnchorTop, -80)
1206
1207 << BasicData(0, Qt::AnchorBottom, -1, Qt::AnchorTop, 80)
1208 << BasicData(0, Qt::AnchorRight, -1, Qt::AnchorLeft, 150)
1209 << BasicData(-1, Qt::AnchorRight, 0, Qt::AnchorLeft, 150)
1210 << BasicData(-1, Qt::AnchorBottom, 0, Qt::AnchorTop, 80)
1211 ;
1212
1213 theResult
1214 << BasicResult(0, QRectF(50, 20, 100, 60) )
1215 ;
1216
1217 QTest::newRow("One, mixed (n)") << QSizeF(200, 100) << theData << theResult;
1218 }
1219
1220 // Basic case - two widgets, 1 horizontal connection, first completely defined, negative spacing
1221 {
1222 BasicLayoutTestDataList theData;
1223 BasicLayoutTestResultList theResult;
1224
1225 theData
1226 // << BasicData(0, Qt::AnchorTop, -1, Qt::AnchorTop, -10)
1227 // << BasicData(-1, Qt::AnchorBottom, 0, Qt::AnchorBottom, -10)
1228 // << BasicData(0, Qt::AnchorLeft, -1, Qt::AnchorLeft, -10)
1229 // << BasicData(-1, Qt::AnchorRight, 0, Qt::AnchorRight, -180)
1230
1231 // << BasicData(1, Qt::AnchorLeft, 0, Qt::AnchorRight, -10)
1232 // << BasicData(-1, Qt::AnchorRight, 1, Qt::AnchorRight, -10)
1233 // << BasicData(1, Qt::AnchorTop, -1, Qt::AnchorTop, -10)
1234 // << BasicData(-1, Qt::AnchorBottom, 1, Qt::AnchorBottom, -20)
1235
1236 << BasicData(0, Qt::AnchorTop, -1, Qt::AnchorTop, -10)
1237 << BasicData(-1, Qt::AnchorBottom, 0, Qt::AnchorBottom, -10)
1238 << BasicData(0, Qt::AnchorLeft, -1, Qt::AnchorLeft, -10)
1239 << BasicData(-1, Qt::AnchorRight, 0, Qt::AnchorRight, 180)
1240
1241 << BasicData(1, Qt::AnchorLeft, 0, Qt::AnchorRight, -10)
1242 << BasicData(-1, Qt::AnchorRight, 1, Qt::AnchorRight, -10)
1243 << BasicData(1, Qt::AnchorTop, -1, Qt::AnchorTop, -10)
1244 << BasicData(-1, Qt::AnchorBottom, 1, Qt::AnchorBottom, -20)
1245
1246 ;
1247
1248 theResult
1249 // << BasicResult(0, QRectF(10, 10, 10, 80) )
1250 // << BasicResult(1, QRectF(30, 10, 160, 70) )
1251
1252 << BasicResult(0, QRectF(-10, -10, 30, 120) )
1253 << BasicResult(1, QRectF(10, -10, 200, 130) )
1254 ;
1255
1256 QTest::newRow("Two, 1h connected (n)") << QSizeF(200, 100) << theData << theResult;
1257 }
1258
1259 // Basic case - two widgets, 2 horizontal and 2 vertical connections, dependent on each other, negative spacing
1260 {
1261 BasicLayoutTestDataList theData;
1262 BasicLayoutTestResultList theResult;
1263
1264 theData
1265 << BasicData(0, Qt::AnchorLeft, -1, Qt::AnchorLeft, -10)
1266 << BasicData(1, Qt::AnchorRight, 0, Qt::AnchorRight, -150)
1267 << BasicData(0, Qt::AnchorTop, -1, Qt::AnchorTop, -10)
1268 << BasicData(1, Qt::AnchorBottom, 0, Qt::AnchorBottom, -10)
1269
1270 << BasicData(1, Qt::AnchorLeft, 0, Qt::AnchorLeft, -90)
1271 << BasicData(-1, Qt::AnchorRight, 1, Qt::AnchorRight, -10)
1272 << BasicData(1, Qt::AnchorTop, 0, Qt::AnchorTop, -10)
1273 << BasicData(-1, Qt::AnchorBottom, 1, Qt::AnchorBottom, -20)
1274 ;
1275
1276 theResult
1277 // << BasicResult(0, QRectF(10, 10, 30, 60) )
1278 // << BasicResult(1, QRectF(100, 20, 90, 60) )
1279 << BasicResult(0, QRectF(-10, -10, 70, 120) )
1280 << BasicResult(1, QRectF(80, 0, 130, 120) )
1281 ;
1282
1283 QTest::newRow("Two, 2h+2v connected2 (n)") << QSizeF(200, 100) << theData << theResult;
1284 }
1285 }
1286
testMixedSpacing_data()1287 void tst_QGraphicsAnchorLayout1::testMixedSpacing_data()
1288 {
1289 QTest::addColumn<QSizeF>("size");
1290 QTest::addColumn<BasicLayoutTestDataList>("data");
1291 QTest::addColumn<BasicLayoutTestResultList>("result");
1292
1293 typedef BasicLayoutTestData BasicData;
1294 typedef BasicLayoutTestResult BasicResult;
1295
1296 // Two widgets, partial overlapping
1297 {
1298 BasicLayoutTestDataList theData;
1299 BasicLayoutTestResultList theResult;
1300
1301 theData
1302 << BasicData(-1, Qt::AnchorTop, 0, Qt::AnchorTop, 10)
1303 << BasicData(0, Qt::AnchorLeft, -1, Qt::AnchorLeft, -50)
1304 << BasicData(0, Qt::AnchorBottom, -1, Qt::AnchorBottom, 50)
1305 << BasicData(1, Qt::AnchorRight, 0, Qt::AnchorRight, 15)
1306
1307 // << BasicData(1, Qt::AnchorTop, 0, Qt::AnchorBottom, 5)
1308 << BasicData(1, Qt::AnchorTop, 0, Qt::AnchorBottom, -5)
1309 << BasicData(0, Qt::AnchorLeft, 1, Qt::AnchorLeft, -10)
1310 << BasicData(1, Qt::AnchorRight, -1, Qt::AnchorRight, 20)
1311 << BasicData(-1, Qt::AnchorBottom, 1, Qt::AnchorBottom, -5)
1312 ;
1313
1314 theResult
1315 // << BasicResult(0, QRectF(50, 10, 45, 40) )
1316 // << BasicResult(1, QRectF(40, 45, 40, 50) )
1317 << BasicResult(0, QRectF(-50, 10, 145, 40) )
1318 << BasicResult(1, QRectF(-60, 45, 140, 60) )
1319 ;
1320
1321 QTest::newRow("Two, partial overlap") << QSizeF(100, 100) << theData << theResult;
1322 }
1323
1324 // Two widgets, complete overlapping
1325 {
1326 BasicLayoutTestDataList theData;
1327 BasicLayoutTestResultList theResult;
1328
1329 theData
1330 << BasicData(-1, Qt::AnchorTop, 0, Qt::AnchorTop, 5)
1331 << BasicData(0, Qt::AnchorRight, 1, Qt::AnchorRight, 0)
1332 << BasicData(0, Qt::AnchorTop, 1, Qt::AnchorTop, 0)
1333 << BasicData(1, Qt::AnchorLeft, 0, Qt::AnchorLeft, 25)
1334
1335 << BasicData(1, Qt::AnchorBottom, 0, Qt::AnchorBottom, 0)
1336 << BasicData(1, Qt::AnchorBottom, -1, Qt::AnchorBottom, 5)
1337 << BasicData(1, Qt::AnchorLeft, -1, Qt::AnchorRight, 50)
1338 << BasicData(-1, Qt::AnchorRight, 1, Qt::AnchorRight, -10)
1339 ;
1340
1341 theResult
1342 << BasicResult(0, QRectF(65, 5, 35, 35) )
1343 << BasicResult(1, QRectF(40, 5, 60, 35) )
1344 ;
1345
1346 QTest::newRow("Two, complete overlap") << QSizeF(90, 45) << theData << theResult;
1347 }
1348
1349 // Five widgets, v shaped, edges shared
1350 {
1351 BasicLayoutTestDataList theData;
1352 BasicLayoutTestResultList theResult;
1353
1354 theData
1355 // edges shared
1356 << BasicData(0, Qt::AnchorRight, 1, Qt::AnchorLeft, 0)
1357 << BasicData(1, Qt::AnchorRight, 2, Qt::AnchorLeft, 0)
1358 << BasicData(2, Qt::AnchorRight, 3, Qt::AnchorLeft, 0)
1359 << BasicData(3, Qt::AnchorRight, 4, Qt::AnchorLeft, 0)
1360 << BasicData(1, Qt::AnchorBottom, 2, Qt::AnchorTop, 0)
1361 << BasicData(0, Qt::AnchorBottom, 1, Qt::AnchorTop, 0)
1362 << BasicData(3, Qt::AnchorBottom, 2, Qt::AnchorTop, 0)
1363 << BasicData(4, Qt::AnchorBottom, 3, Qt::AnchorTop, 0)
1364 << BasicData(0, Qt::AnchorBottom, 4, Qt::AnchorBottom, 0)
1365 << BasicData(1, Qt::AnchorBottom, 3, Qt::AnchorBottom, 0)
1366 << BasicData(0, Qt::AnchorTop, 4, Qt::AnchorTop, 0)
1367 << BasicData(1, Qt::AnchorTop, 3, Qt::AnchorTop, 0)
1368
1369 // margins
1370 << BasicData(-1, Qt::AnchorLeft, 0, Qt::AnchorLeft, 5)
1371 << BasicData(-1, Qt::AnchorTop, 0, Qt::AnchorTop, 5)
1372 << BasicData(2, Qt::AnchorBottom, -1, Qt::AnchorBottom, 5)
1373 // << BasicData(-1, Qt::AnchorRight, 4, Qt::AnchorRight, -5)
1374 << BasicData(-1, Qt::AnchorRight, 4, Qt::AnchorRight, 5)
1375
1376 // additional details for exact size determination easily
1377 << BasicData(-1, Qt::AnchorLeft, 1, Qt::AnchorLeft, 25)
1378 << BasicData(-1, Qt::AnchorLeft, 1, Qt::AnchorRight, 50)
1379 // << BasicData(-1, Qt::AnchorRight, 3, Qt::AnchorRight, -25)
1380 // << BasicData(-1, Qt::AnchorRight, 2, Qt::AnchorRight, -50)
1381 << BasicData(-1, Qt::AnchorRight, 3, Qt::AnchorRight, 25)
1382 << BasicData(-1, Qt::AnchorRight, 2, Qt::AnchorRight, 50)
1383 << BasicData(-1, Qt::AnchorTop, 3, Qt::AnchorBottom, 50)
1384 // << BasicData(-1, Qt::AnchorBottom, 3, Qt::AnchorTop, -50)
1385 << BasicData(-1, Qt::AnchorBottom, 3, Qt::AnchorTop, 50)
1386
1387 ;
1388
1389 theResult
1390 << BasicResult(0, QRectF(5,5,20,20))
1391 << BasicResult(1, QRectF(25,25,25,25))
1392 << BasicResult(2, QRectF(50,50,25,20))
1393 << BasicResult(3, QRectF(75,25,25,25))
1394 << BasicResult(4, QRectF(100,5,20,20))
1395 ;
1396
1397 QTest::newRow("Five, V shape") << QSizeF(125, 75) << theData << theResult;
1398 }
1399
1400 // ### The behavior is different in QGraphicsAnchorLayout. What happens here is
1401 // that when the above anchors are set, the layout size hints are changed.
1402 // In the example, the minimum item width is 5, thus the minimum layout width
1403 // becomes 105 (50 + 5 + 50). Once that size hint is set, trying to set
1404 // the widget size to (10, 10) is not possible because
1405 // QGraphicsWidget::setGeometry() will enforce the minimum is respected.
1406 if (0)
1407 // One widget, unsolvable
1408 {
1409 BasicLayoutTestDataList theData;
1410 BasicLayoutTestResultList theResult;
1411
1412 theData
1413 << BasicData(-1, Qt::AnchorLeft, 0, Qt::AnchorLeft, 50)
1414 << BasicData(0, Qt::AnchorRight, -1, Qt::AnchorRight, 50)
1415 ;
1416 theResult
1417 << BasicResult(0, QRectF(0,0,0,0))
1418 ;
1419
1420 QTest::newRow("One widget, unsolvable") << QSizeF(10, 10) << theData << theResult;
1421 }
1422
1423 // Two widgets, one has fixed size
1424 {
1425 BasicLayoutTestDataList theData;
1426 BasicLayoutTestResultList theResult;
1427
1428 theData
1429 << BasicData(-1, Qt::AnchorLeft, 0, Qt::AnchorLeft, 50)
1430 << BasicData(0, Qt::AnchorRight, -1, Qt::AnchorRight, 50)
1431 // not supported, use sizePolicy instead
1432 // << BasicData(0, Qt::AnchorLeft, 0, Qt::AnchorRight, 50)
1433
1434 << BasicData(-1, Qt::AnchorLeft, 1, Qt::AnchorLeft, 50)
1435 << BasicData(1, Qt::AnchorRight, -1, Qt::AnchorRight, 50)
1436 ;
1437 theResult
1438 << BasicResult(0, QRectF(50,0,50,50))
1439 << BasicResult(1, QRectF(50,0,50,50))
1440 ;
1441
1442 QTest::newRow("Two widgets, one has fixed size") << QSizeF(150, 150) << theData << theResult;
1443 }
1444 }
1445
testMulti_data()1446 void tst_QGraphicsAnchorLayout1::testMulti_data()
1447 {
1448 QTest::addColumn<QSizeF>("size");
1449 QTest::addColumn<BasicLayoutTestDataList>("data");
1450 QTest::addColumn<BasicLayoutTestResultList>("result");
1451
1452 typedef BasicLayoutTestData BasicData;
1453 typedef BasicLayoutTestResult BasicResult;
1454
1455 // Multiple widgets, all overllapping
1456 {
1457 BasicLayoutTestDataList theData;
1458 BasicLayoutTestResultList theResult;
1459
1460 const int n = 30;
1461 for ( int i = 0 ; i < n; i++ ) {
1462 theData
1463 << BasicData(-1, Qt::AnchorTop, i, Qt::AnchorTop, 20)
1464 << BasicData(-1, Qt::AnchorLeft, i, Qt::AnchorLeft, 10)
1465 // << BasicData(-1, Qt::AnchorBottom, i, Qt::AnchorBottom, -40)
1466 // << BasicData(-1, Qt::AnchorRight, i, Qt::AnchorRight, -30);
1467 << BasicData(-1, Qt::AnchorBottom, i, Qt::AnchorBottom, 40)
1468 << BasicData(-1, Qt::AnchorRight, i, Qt::AnchorRight, 30);
1469
1470 theResult
1471 << BasicResult(i, QRectF(10, 20, 160, 40) );
1472 }
1473
1474
1475 QTest::newRow("Overlapping multi") << QSizeF(200, 100) << theData << theResult;
1476 }
1477
1478 // Multiple widgets, linear order
1479 {
1480 BasicLayoutTestDataList theData;
1481 BasicLayoutTestResultList theResult;
1482
1483 const qreal height = 1000.f;
1484 const qreal width = 2000.f;
1485
1486 const int n = 30;
1487
1488 const qreal verticalStep = height/qreal(n+2);
1489 const qreal horizontalStep = width/qreal(n+2);
1490
1491 for ( int i = 0 ; i < n; i++ ) {
1492
1493 if ( i == 0 ) {
1494 // First item
1495 theData
1496 << BasicData(-1, Qt::AnchorTop, i, Qt::AnchorTop, verticalStep)
1497 << BasicData(-1, Qt::AnchorLeft, i, Qt::AnchorLeft, horizontalStep)
1498 << BasicData(i+1, Qt::AnchorBottom, i, Qt::AnchorBottom, -verticalStep)
1499 << BasicData(i+1, Qt::AnchorRight, i, Qt::AnchorRight, -horizontalStep);
1500
1501 } else if ( i == n-1 ) {
1502 // Last item
1503 theData
1504 << BasicData(i-1, Qt::AnchorTop, i, Qt::AnchorTop, verticalStep)
1505 << BasicData(i-1, Qt::AnchorLeft, i, Qt::AnchorLeft, horizontalStep)
1506 << BasicData(-1, Qt::AnchorBottom, i, Qt::AnchorBottom, verticalStep)
1507 << BasicData(-1, Qt::AnchorRight, i, Qt::AnchorRight, horizontalStep);
1508 // << BasicData(-1, Qt::AnchorBottom, i, Qt::AnchorBottom, -verticalStep)
1509 // << BasicData(-1, Qt::AnchorRight, i, Qt::AnchorRight, -horizontalStep);
1510
1511 } else {
1512 // items in the middle
1513 theData
1514 << BasicData(i-1, Qt::AnchorTop, i, Qt::AnchorTop, verticalStep)
1515 << BasicData(i-1, Qt::AnchorLeft, i, Qt::AnchorLeft, horizontalStep)
1516 << BasicData(i+1, Qt::AnchorBottom, i, Qt::AnchorBottom, -verticalStep)
1517 << BasicData(i+1, Qt::AnchorRight, i, Qt::AnchorRight, -horizontalStep);
1518 // << BasicData(i+1, Qt::AnchorBottom, i, Qt::AnchorBottom, -verticalStep)
1519 // << BasicData(i+1, Qt::AnchorRight, i, Qt::AnchorRight, -horizontalStep);
1520
1521 }
1522
1523 theResult
1524 << BasicResult(i, QRectF((i+1)*horizontalStep, (i+1)*verticalStep, horizontalStep, verticalStep) );
1525 }
1526
1527
1528 if (sizeof(qreal) == 4) {
1529 qDebug("Linear multi: Skipping! (qreal has too little precision, result will be wrong)");
1530 } else {
1531 QTest::newRow("Linear multi") << QSizeF(width, height) << theData << theResult;
1532 }
1533 }
1534
1535 // Multiple widgets, V shape
1536 {
1537 BasicLayoutTestDataList theData;
1538 BasicLayoutTestResultList theResult;
1539
1540 const qreal height = 100.f;
1541 const qreal width = 200.f;
1542
1543 const int n = 31; // odd number please (3,5,7... )
1544
1545 const qreal verticalStep = height/(2.f+(n+1)/2.f);
1546 const qreal horizontalStep = width/(n+2.f);
1547
1548 for ( int i = 0 ; i < n; i++ ) {
1549
1550 if ( i == 0 ) {
1551 // First item
1552 theData
1553 << BasicData(-1, Qt::AnchorTop, i, Qt::AnchorTop, verticalStep)
1554 << BasicData(-1, Qt::AnchorLeft, i, Qt::AnchorLeft, horizontalStep)
1555 << BasicData(i+1, Qt::AnchorBottom, i, Qt::AnchorBottom, -verticalStep)
1556 << BasicData(i, Qt::AnchorRight, i+1, Qt::AnchorRight, horizontalStep);
1557
1558 } else if ( i == n-1 ) {
1559 // Last item
1560 theData
1561 << BasicData(i-1, Qt::AnchorTop, i, Qt::AnchorTop, -verticalStep)
1562 << BasicData(i-1, Qt::AnchorLeft, i, Qt::AnchorLeft, horizontalStep)
1563 << BasicData(i-1, Qt::AnchorBottom, i, Qt::AnchorBottom, -verticalStep)
1564 << BasicData(i, Qt::AnchorRight, -1, Qt::AnchorRight, horizontalStep);
1565 } else if ( i == ((n-1)/2) ) {
1566 // midway
1567 theData
1568 << BasicData(i-1, Qt::AnchorTop, i, Qt::AnchorTop, verticalStep)
1569 << BasicData(i-1, Qt::AnchorLeft, i, Qt::AnchorLeft, horizontalStep)
1570 // << BasicData(-1, Qt::AnchorBottom, i, Qt::AnchorBottom, -verticalStep)
1571 << BasicData(-1, Qt::AnchorBottom, i, Qt::AnchorBottom, verticalStep)
1572 << BasicData(i, Qt::AnchorRight, i+1, Qt::AnchorRight, horizontalStep);
1573 } else if ( i < ((n-1)/2) ) {
1574 // before midway - going down
1575 theData
1576 << BasicData(i-1, Qt::AnchorTop, i, Qt::AnchorTop, verticalStep)
1577 << BasicData(i-1, Qt::AnchorLeft, i, Qt::AnchorLeft, horizontalStep)
1578 << BasicData(i+1, Qt::AnchorBottom, i, Qt::AnchorBottom, -verticalStep)
1579 << BasicData(i, Qt::AnchorRight, i+1, Qt::AnchorRight, horizontalStep);
1580
1581 } else {
1582 // after midway - going up
1583 theData
1584 << BasicData(i-1, Qt::AnchorTop, i, Qt::AnchorTop, -verticalStep)
1585 << BasicData(i-1, Qt::AnchorLeft, i, Qt::AnchorLeft, horizontalStep)
1586 << BasicData(i-1, Qt::AnchorBottom, i, Qt::AnchorBottom, -verticalStep)
1587 << BasicData(i, Qt::AnchorRight, i+1, Qt::AnchorRight, horizontalStep);
1588
1589 }
1590
1591 if ( i <= ((n-1)/2) ) {
1592 // until midway
1593 theResult
1594 << BasicResult(i, QRectF((i+1)*horizontalStep, (i+1)*verticalStep, horizontalStep, verticalStep) );
1595 } else {
1596 // after midway
1597 theResult
1598 << BasicResult(i, QRectF((i+1)*horizontalStep, (n-i)*verticalStep, horizontalStep, verticalStep) );
1599 }
1600
1601 }
1602 if (sizeof(qreal) == 4) {
1603 qDebug("V multi: Skipping! (qreal has too little precision, result will be wrong)");
1604 } else {
1605 QTest::newRow("V multi") << QSizeF(width, height) << theData << theResult;
1606 }
1607 }
1608
1609 // Multiple widgets, grid
1610 {
1611 BasicLayoutTestDataList theData;
1612 BasicLayoutTestResultList theResult;
1613
1614 const qreal height = 100.f;
1615 const qreal width = 200.f;
1616
1617 const int d = 10; // items per dimension
1618 const int n = d*d;
1619
1620 const qreal verticalStep = height/(d+2.f);
1621 const qreal horizontalStep = width/(d+2.f);
1622
1623 for ( int i = 0 ; i < n; i++ ) {
1624 if ( i%d == 0 ) {
1625 // left side item
1626 theData
1627 << BasicData(-1, Qt::AnchorLeft, i, Qt::AnchorLeft, horizontalStep)
1628 << BasicData(i+1, Qt::AnchorRight, i, Qt::AnchorRight, -horizontalStep);
1629 } else if ( (i+1)%d == 0 ) {
1630 // rigth side item
1631 theData
1632 << BasicData(i-1, Qt::AnchorLeft, i, Qt::AnchorLeft, horizontalStep)
1633 // << BasicData(-1, Qt::AnchorRight, i, Qt::AnchorRight, -horizontalStep);
1634 << BasicData(-1, Qt::AnchorRight, i, Qt::AnchorRight, horizontalStep);
1635 } else {
1636 // horizontal middle
1637 theData
1638 << BasicData(i-1, Qt::AnchorLeft, i, Qt::AnchorLeft, horizontalStep)
1639 << BasicData(i+1, Qt::AnchorRight, i, Qt::AnchorRight, -horizontalStep);
1640 }
1641
1642 if ( i < d ) {
1643 // top line
1644 theData
1645 << BasicData(-1, Qt::AnchorTop, i, Qt::AnchorTop, verticalStep)
1646 << BasicData(i+d, Qt::AnchorBottom, i, Qt::AnchorBottom, -verticalStep);
1647 } else if ( i >= (d-1)*d ){
1648 // bottom line
1649 theData
1650 << BasicData(i-d, Qt::AnchorTop, i, Qt::AnchorTop, verticalStep)
1651 // << BasicData(-1, Qt::AnchorBottom, i, Qt::AnchorBottom, -verticalStep)
1652 << BasicData(-1, Qt::AnchorBottom, i, Qt::AnchorBottom, verticalStep);
1653 } else {
1654 // vertical middle
1655 theData
1656 << BasicData(i-d, Qt::AnchorTop, i, Qt::AnchorTop, verticalStep)
1657 << BasicData(i+d, Qt::AnchorBottom, i, Qt::AnchorBottom, -verticalStep);
1658 }
1659
1660 theResult
1661 << BasicResult(i, QRectF(((i%d)+1)*horizontalStep, ((i/d)+1)*verticalStep, horizontalStep, verticalStep) );
1662 }
1663
1664 if (sizeof(qreal) == 4) {
1665 qDebug("Grid multi: Skipping! (qreal has too little precision, result will be wrong)");
1666 } else {
1667 QTest::newRow("Grid multi") << QSizeF(200, 100) << theData << theResult;
1668 }
1669 }
1670 }
1671
getItem(int index,const QList<QGraphicsWidget * > & widgets,QGraphicsLayoutItem * defaultItem)1672 inline QGraphicsLayoutItem *getItem(
1673 int index,
1674 const QList<QGraphicsWidget *>& widgets,
1675 QGraphicsLayoutItem *defaultItem)
1676 {
1677 if (index < 0) {
1678 return defaultItem;
1679 }
1680
1681 return widgets[index];
1682 }
1683
fuzzierCompare(qreal a,qreal b)1684 static bool fuzzierCompare(qreal a, qreal b)
1685 {
1686 return qAbs(a - b) <= qreal(0.0001);
1687 }
1688
fuzzierCompare(const QRectF & r1,const QRectF & r2)1689 static bool fuzzierCompare(const QRectF &r1, const QRectF &r2)
1690 {
1691
1692 return fuzzierCompare(r1.x(), r2.x()) && fuzzierCompare(r1.y(), r2.y())
1693 && fuzzierCompare(r1.width(), r2.width()) && fuzzierCompare(r1.height(), r2.height());
1694 }
1695
testBasicLayout()1696 void tst_QGraphicsAnchorLayout1::testBasicLayout()
1697 {
1698 QFETCH(QSizeF, size);
1699 QFETCH(BasicLayoutTestDataList, data);
1700 QFETCH(BasicLayoutTestResultList, result);
1701
1702 QGraphicsWidget *widget = new QGraphicsWidget;
1703
1704 // Determine amount of widgets to add.
1705 int widgetCount = -1;
1706 for (int i = 0; i < data.count(); ++i) {
1707 const BasicLayoutTestData item = data[i];
1708 widgetCount = qMax(widgetCount, item.firstIndex);
1709 widgetCount = qMax(widgetCount, item.secondIndex);
1710 }
1711 ++widgetCount; // widgetCount is max of indices.
1712
1713 // Create dummy widgets
1714 QList<QGraphicsWidget *> widgets;
1715 for (int i = 0; i < widgetCount; ++i) {
1716 TestWidget *w = new TestWidget(0, QString::fromAscii("W%1").arg(i));
1717 widgets << w;
1718 }
1719
1720 // Setup anchor layout
1721 TheAnchorLayout *layout = new TheAnchorLayout;
1722
1723 for (int i = 0; i < data.count(); ++i) {
1724 const BasicLayoutTestData item = data[i];
1725 layout->setAnchor(
1726 getItem(item.firstIndex, widgets, layout),
1727 item.firstEdge,
1728 getItem(item.secondIndex, widgets, layout),
1729 item.secondEdge,
1730 item.spacing );
1731 }
1732
1733 widget->setLayout(layout);
1734 widget->setContentsMargins(0,0,0,0);
1735
1736 widget->resize(size);
1737 QCOMPARE(widget->size(), size);
1738
1739 // Validate
1740 for (int i = 0; i < result.count(); ++i) {
1741 const BasicLayoutTestResult item = result[i];
1742 QRectF expected = item.rect;
1743 QRectF actual = widgets[item.index]->geometry();
1744
1745 QVERIFY(fuzzierCompare(actual, expected));
1746 }
1747
1748 // Test mirrored mode
1749 widget->setLayoutDirection(Qt::RightToLeft);
1750 layout->activate();
1751 // Validate
1752 for (int j = 0; j < result.count(); ++j) {
1753 const BasicLayoutTestResult item = result[j];
1754 QRectF mirroredRect(item.rect);
1755 // only valid cases are mirrored
1756 if (mirroredRect.isValid()){
1757 mirroredRect.moveLeft(size.width()-item.rect.width()-item.rect.left());
1758 }
1759 QRectF expected = mirroredRect;
1760 QRectF actual = widgets[item.index]->geometry();
1761
1762 QVERIFY(fuzzierCompare(actual, expected));
1763 }
1764
1765 qDeleteAll(widgets);
1766 delete widget;
1767 }
1768
testNegativeSpacing()1769 void tst_QGraphicsAnchorLayout1::testNegativeSpacing()
1770 {
1771 // use the same frame
1772 testBasicLayout();
1773 }
1774
testMixedSpacing()1775 void tst_QGraphicsAnchorLayout1::testMixedSpacing()
1776 {
1777 // use the same frame
1778 testBasicLayout();
1779 }
1780
testMulti()1781 void tst_QGraphicsAnchorLayout1::testMulti()
1782 {
1783 // use the same frame
1784 testBasicLayout();
1785 }
1786
testCenterAnchors_data()1787 void tst_QGraphicsAnchorLayout1::testCenterAnchors_data()
1788 {
1789 QTest::addColumn<QSizeF>("size");
1790 QTest::addColumn<BasicLayoutTestDataList>("data");
1791 QTest::addColumn<BasicLayoutTestResultList>("result");
1792
1793 typedef BasicLayoutTestData BasicData;
1794 typedef BasicLayoutTestResult BasicResult;
1795
1796 // Basic center case
1797 {
1798 BasicLayoutTestDataList theData;
1799 BasicLayoutTestResultList theResult;
1800
1801 theData
1802 // << BasicData(-1, Qt::AnchorRight, 0, Qt::AnchorHorizontalCenter, -10)
1803 << BasicData(-1, Qt::AnchorRight, 0, Qt::AnchorHorizontalCenter, 10)
1804 << BasicData(-1, Qt::AnchorLeft, 0, Qt::AnchorRight, 15)
1805 << BasicData(-1, Qt::AnchorTop, 0, Qt::AnchorVerticalCenter, 10)
1806 << BasicData(0, Qt::AnchorBottom, -1, Qt::AnchorBottom, 5);
1807
1808 theResult
1809 << BasicResult(0, QRectF(5, 5, 10, 10) );
1810
1811 QTest::newRow("center, basic") << QSizeF(20, 20) << theData << theResult;
1812 }
1813
1814 // Basic center case, with invalid (shouldn't affect on result)
1815 {
1816 BasicLayoutTestDataList theData;
1817 BasicLayoutTestResultList theResult;
1818
1819 theData
1820 // << BasicData(-1, Qt::AnchorRight, 0, Qt::AnchorHorizontalCenter, -10)
1821 << BasicData(-1, Qt::AnchorRight, 0, Qt::AnchorHorizontalCenter, 10)
1822 << BasicData(-1, Qt::AnchorLeft, 0, Qt::AnchorRight, 15)
1823 << BasicData(-1, Qt::AnchorTop, 0, Qt::AnchorVerticalCenter, 10)
1824 << BasicData(0, Qt::AnchorBottom, -1, Qt::AnchorBottom, 5)
1825
1826 // bogus definitions
1827 << BasicData(0, Qt::AnchorHorizontalCenter, -1, Qt::AnchorBottom, 5)
1828 << BasicData(0, Qt::AnchorHorizontalCenter, 1, Qt::AnchorVerticalCenter, 5)
1829 << BasicData(0, Qt::AnchorVerticalCenter, -1, Qt::AnchorRight, 5)
1830 << BasicData(0, Qt::AnchorVerticalCenter, 0, Qt::AnchorVerticalCenter, 666)
1831 << BasicData(0, Qt::AnchorHorizontalCenter, 0, Qt::AnchorHorizontalCenter, 999)
1832 << BasicData(0, Qt::AnchorLeft, 0, Qt::AnchorLeft, 333)
1833 << BasicData(-1, Qt::AnchorRight, -1, Qt::AnchorRight, 222)
1834 << BasicData(0, Qt::AnchorTop, 0, Qt::AnchorTop, 111)
1835 << BasicData(0, Qt::AnchorBottom, 0, Qt::AnchorBottom, 444);
1836
1837 theResult
1838 << BasicResult(0, QRectF(5, 5, 10, 10) );
1839
1840 QTest::ignoreMessage(QtWarningMsg, "QGraphicsAnchorLayout::addAnchor(): Cannot anchor edges of different orientations");
1841 QTest::ignoreMessage(QtWarningMsg, "QGraphicsAnchorLayout::addAnchor(): Cannot anchor edges of different orientations");
1842 QTest::ignoreMessage(QtWarningMsg, "QGraphicsAnchorLayout::addAnchor(): Cannot anchor edges of different orientations");
1843 QTest::ignoreMessage(QtWarningMsg, "QGraphicsAnchorLayout::addAnchor(): Cannot anchor the item to itself");
1844 QTest::ignoreMessage(QtWarningMsg, "QGraphicsAnchorLayout::addAnchor(): Cannot anchor the item to itself");
1845 QTest::ignoreMessage(QtWarningMsg, "QGraphicsAnchorLayout::addAnchor(): Cannot anchor the item to itself");
1846 QTest::ignoreMessage(QtWarningMsg, "QGraphicsAnchorLayout::addAnchor(): Cannot anchor the item to itself");
1847 QTest::ignoreMessage(QtWarningMsg, "QGraphicsAnchorLayout::addAnchor(): Cannot anchor the item to itself");
1848 QTest::ignoreMessage(QtWarningMsg, "QGraphicsAnchorLayout::addAnchor(): Cannot anchor the item to itself");
1849 QTest::newRow("center, basic with invalid") << QSizeF(20, 20) << theData << theResult;
1850 }
1851
1852 // Basic center case 2
1853 {
1854 BasicLayoutTestDataList theData;
1855 BasicLayoutTestResultList theResult;
1856
1857 theData
1858 << BasicData(-1, Qt::AnchorHorizontalCenter, 0, Qt::AnchorHorizontalCenter, 0)
1859 // Not supported << BasicData(0, Qt::AnchorHorizontalCenter, 0, Qt::AnchorRight, 5)
1860 << BasicData(-1, Qt::AnchorHorizontalCenter, 0, Qt::AnchorRight, 5)
1861 << BasicData(-1, Qt::AnchorVerticalCenter, 0, Qt::AnchorVerticalCenter, 0)
1862 << BasicData(-1, Qt::AnchorVerticalCenter, 0, Qt::AnchorTop, -5);
1863
1864 theResult
1865 << BasicResult(0, QRectF(5, 5, 10, 10) );
1866
1867 QTest::newRow("center, basic 2") << QSizeF(20, 20) << theData << theResult;
1868 }
1869
1870 // Basic center case, overrides
1871 {
1872 BasicLayoutTestDataList theData;
1873 BasicLayoutTestResultList theResult;
1874
1875 theData
1876 << BasicData(-1, Qt::AnchorHorizontalCenter, 0, Qt::AnchorHorizontalCenter, 10)
1877 << BasicData(-1, Qt::AnchorVerticalCenter, 0, Qt::AnchorVerticalCenter, 20)
1878 << BasicData(0, Qt::AnchorHorizontalCenter, -1, Qt::AnchorHorizontalCenter, 30)
1879 << BasicData(0, Qt::AnchorVerticalCenter, -1, Qt::AnchorVerticalCenter, 40)
1880 // actual data:
1881 << BasicData(-1, Qt::AnchorHorizontalCenter, 0, Qt::AnchorHorizontalCenter, 0)
1882 << BasicData(-1, Qt::AnchorVerticalCenter, 0, Qt::AnchorVerticalCenter, 0)
1883 // << BasicData(0, Qt::AnchorHorizontalCenter, 0, Qt::AnchorRight, 5)
1884 << BasicData(-1, Qt::AnchorHorizontalCenter, 0, Qt::AnchorRight, 5)
1885 << BasicData(-1, Qt::AnchorVerticalCenter, 0, Qt::AnchorTop, -5);
1886
1887 theResult
1888 << BasicResult(0, QRectF(5, 5, 10, 10) );
1889
1890 QTest::newRow("center, overrides") << QSizeF(20, 20) << theData << theResult;
1891 }
1892
1893 // Two nested
1894 {
1895 BasicLayoutTestDataList theData;
1896 BasicLayoutTestResultList theResult;
1897
1898 theData
1899 << BasicData(-1, Qt::AnchorHorizontalCenter, 0, Qt::AnchorLeft, 0)
1900 << BasicData(-1, Qt::AnchorTop, 0, Qt::AnchorTop, 0)
1901 << BasicData(-1, Qt::AnchorBottom, 0, Qt::AnchorBottom, 0)
1902 << BasicData(-1, Qt::AnchorRight, 0, Qt::AnchorRight, 0)
1903 << BasicData(0, Qt::AnchorVerticalCenter, 1, Qt::AnchorTop, 0)
1904 << BasicData(0, Qt::AnchorLeft, 1, Qt::AnchorLeft, 0)
1905 << BasicData(0, Qt::AnchorRight, 1, Qt::AnchorRight, 0)
1906 << BasicData(0, Qt::AnchorBottom, 1, Qt::AnchorBottom, 0);
1907
1908 theResult
1909 << BasicResult(0, QRectF(20, 0, 20, 40))
1910 << BasicResult(1, QRectF(20, 20, 20, 20));
1911
1912 QTest::newRow("center, two nested") << QSizeF(40, 40) << theData << theResult;
1913 }
1914
1915 // Two overlap
1916 {
1917 BasicLayoutTestDataList theData;
1918 BasicLayoutTestResultList theResult;
1919
1920 // theData
1921 // // horizontal
1922 // << BasicData(-1, Qt::AnchorLeft, 0, Qt::AnchorLeft, 20)
1923 // << BasicData(0, Qt::AnchorHorizontalCenter, 1, Qt::AnchorLeft, 0)
1924 // << BasicData(1, Qt::AnchorHorizontalCenter, 0, Qt::AnchorRight, -5)
1925 // << BasicData(1, Qt::AnchorRight, -1, Qt::AnchorRight, 10)
1926 // << BasicData(0, Qt::AnchorHorizontalCenter, 0, Qt::AnchorRight, 10)
1927 // // vertical is pretty much same as horizontal, just roles swapped
1928 // << BasicData(-1, Qt::AnchorTop, 1, Qt::AnchorTop, 20)
1929 // << BasicData(1, Qt::AnchorVerticalCenter, 0, Qt::AnchorTop, 0)
1930 // << BasicData(0, Qt::AnchorVerticalCenter, 1, Qt::AnchorBottom, -5)
1931 // << BasicData(0, Qt::AnchorBottom, -1, Qt::AnchorBottom, 10)
1932 // << BasicData(1, Qt::AnchorVerticalCenter, 1, Qt::AnchorBottom, 10);
1933
1934 theData
1935 // horizontal
1936 << BasicData(-1, Qt::AnchorLeft, 0, Qt::AnchorLeft, 20)
1937 << BasicData(0, Qt::AnchorHorizontalCenter, 1, Qt::AnchorLeft, 0)
1938 << BasicData(0, Qt::AnchorRight, 1, Qt::AnchorHorizontalCenter, 5)
1939 << BasicData(0, Qt::AnchorRight, 1, Qt::AnchorRight, 20)
1940 // vertical
1941 << BasicData(-1, Qt::AnchorTop, 1, Qt::AnchorTop, 20)
1942 << BasicData(1, Qt::AnchorVerticalCenter, 0, Qt::AnchorTop, 0)
1943 << BasicData(1, Qt::AnchorBottom, 0, Qt::AnchorVerticalCenter, 5)
1944 << BasicData(1, Qt::AnchorBottom, 0, Qt::AnchorBottom, 20);
1945
1946 theResult
1947 << BasicResult(0, QRectF(20, 30, 20, 30))
1948 << BasicResult(1, QRectF(30, 20, 30, 20));
1949
1950 QTest::newRow("center, two overlap") << QSizeF(70, 70) << theData << theResult;
1951 }
1952
1953 // Three
1954 {
1955 BasicLayoutTestDataList theData;
1956 BasicLayoutTestResultList theResult;
1957
1958 theData
1959 << BasicData(-1, Qt::AnchorLeft, 0, Qt::AnchorLeft, 0)
1960 << BasicData(0, Qt::AnchorHorizontalCenter, 2, Qt::AnchorHorizontalCenter, 75)
1961 << BasicData(1, Qt::AnchorRight, 2, Qt::AnchorLeft, 10)
1962 << BasicData(1, Qt::AnchorHorizontalCenter, 0, Qt::AnchorHorizontalCenter, -30)
1963 << BasicData(2, Qt::AnchorRight, -1, Qt::AnchorRight, 0)
1964 << BasicData(1, Qt::AnchorLeft, 1, Qt::AnchorRight, 30)
1965 << BasicData(0, Qt::AnchorRight, 1, Qt::AnchorLeft, 10)
1966
1967 << BasicData(1, Qt::AnchorTop, -1, Qt::AnchorTop, 0)
1968 << BasicData(1, Qt::AnchorVerticalCenter, 0, Qt::AnchorVerticalCenter, 35)
1969 << BasicData(1, Qt::AnchorVerticalCenter, 2, Qt::AnchorVerticalCenter, 15)
1970 << BasicData(1, Qt::AnchorBottom, 2, Qt::AnchorTop, 5)
1971 << BasicData(0, Qt::AnchorBottom, -1, Qt::AnchorBottom, 0)
1972 << BasicData(2, Qt::AnchorBottom, 0, Qt::AnchorTop, 5)
1973 << BasicData(0, Qt::AnchorTop, 0, Qt::AnchorBottom, 20);
1974
1975 theResult
1976 << BasicResult(0, QRectF(0, 30, 10, 20))
1977 << BasicResult(1, QRectF(20, 0, 30, 10))
1978 << BasicResult(2, QRectF(60, 15, 40, 10));
1979
1980 QTest::ignoreMessage(QtWarningMsg, "QGraphicsAnchorLayout::addAnchor(): Cannot anchor the item to itself");
1981 QTest::ignoreMessage(QtWarningMsg, "QGraphicsAnchorLayout::addAnchor(): Cannot anchor the item to itself");
1982
1983 QTest::newRow("center, three") << QSizeF(100, 50) << theData << theResult;
1984 }
1985
1986 // Two, parent center
1987 {
1988 BasicLayoutTestDataList theData;
1989 BasicLayoutTestResultList theResult;
1990
1991 theData
1992 // vertical is pretty much same as horizontal, just roles swapped
1993 << BasicData(-1, Qt::AnchorVerticalCenter, 1, Qt::AnchorVerticalCenter, -15)
1994 << BasicData(-1, Qt::AnchorVerticalCenter, 0, Qt::AnchorVerticalCenter, 10)
1995 << BasicData(-1, Qt::AnchorBottom, 0, Qt::AnchorBottom, 0)
1996 << BasicData(1, Qt::AnchorTop, 0, Qt::AnchorTop, 0)
1997 // horizontal
1998 << BasicData(-1, Qt::AnchorHorizontalCenter, 0, Qt::AnchorHorizontalCenter, -15)
1999 << BasicData(-1, Qt::AnchorHorizontalCenter, 1, Qt::AnchorHorizontalCenter, 10)
2000 << BasicData(-1, Qt::AnchorRight, 1, Qt::AnchorRight, 0)
2001 << BasicData(0, Qt::AnchorLeft, 1, Qt::AnchorLeft, 0);
2002
2003 theResult
2004 << BasicResult(0, QRectF(20, 20, 30, 80))
2005 << BasicResult(1, QRectF(20, 20, 80, 30));
2006
2007 QTest::newRow("center, parent") << QSizeF(100, 100) << theData << theResult;
2008 }
2009
2010 // Two, parent center 2
2011 {
2012 BasicLayoutTestDataList theData;
2013 BasicLayoutTestResultList theResult;
2014
2015 theData
2016 // << BasicData(1, Qt::AnchorLeft, -1, Qt::AnchorHorizontalCenter, 15)
2017 << BasicData(1, Qt::AnchorLeft, -1, Qt::AnchorHorizontalCenter, -15)
2018 << BasicData(1, Qt::AnchorRight, 0, Qt::AnchorLeft, 10)
2019 << BasicData(0, Qt::AnchorRight, -1, Qt::AnchorRight, 5)
2020 << BasicData(-1, Qt::AnchorHorizontalCenter, 1, Qt::AnchorRight, -5)
2021 // vertical
2022 << BasicData(0, Qt::AnchorVerticalCenter, 1, Qt::AnchorVerticalCenter, 20)
2023 << BasicData(-1, Qt::AnchorTop, 0, Qt::AnchorTop, 10)
2024 << BasicData(0, Qt::AnchorBottom, 1, Qt::AnchorBottom, 20)
2025 << BasicData(0, Qt::AnchorTop, 1, Qt::AnchorTop, 20)
2026 << BasicData(0, Qt::AnchorBottom, 1, Qt::AnchorTop, 10);
2027
2028 theResult
2029 << BasicResult(0, QRectF(30, 10, 15, 10))
2030 << BasicResult(1, QRectF(10, 30, 10, 10));
2031
2032 QTest::newRow("center, parent 2") << QSizeF(50, 50) << theData << theResult;
2033 }
2034
2035 // Two, parent center 3
2036 {
2037 BasicLayoutTestDataList theData;
2038 BasicLayoutTestResultList theResult;
2039
2040 theData
2041 << BasicData(-1, Qt::AnchorHorizontalCenter, 0, Qt::AnchorRight, -5)
2042 << BasicData(-1, Qt::AnchorHorizontalCenter, 1, Qt::AnchorLeft, 5)
2043 // << BasicData(0, Qt::AnchorLeft, 1, Qt::AnchorRight, 100)
2044 << BasicData(0, Qt::AnchorLeft, 1, Qt::AnchorRight, -100)
2045 << BasicData(0, Qt::AnchorLeft, -1, Qt::AnchorLeft, 0)
2046
2047 // vertical
2048 << BasicData(0, Qt::AnchorVerticalCenter, 1, Qt::AnchorVerticalCenter, 55)
2049 << BasicData(0, Qt::AnchorTop, -1, Qt::AnchorTop, 0)
2050 << BasicData(1, Qt::AnchorBottom, -1, Qt::AnchorBottom, 0)
2051 << BasicData(0, Qt::AnchorBottom, 1, Qt::AnchorTop, 10)
2052 // << BasicData(0, Qt::AnchorTop, 0, Qt::AnchorBottom, 45)
2053 << BasicData(-1, Qt::AnchorTop, 0, Qt::AnchorBottom, 45)
2054 ;
2055
2056 theResult
2057 << BasicResult(0, QRectF(0, 0, 45, 45))
2058 << BasicResult(1, QRectF(55, 55, 45, 45));
2059
2060 QTest::newRow("center, parent 3") << QSizeF(100, 100) << theData << theResult;
2061 }
2062
2063 }
2064
testCenterAnchors()2065 void tst_QGraphicsAnchorLayout1::testCenterAnchors()
2066 {
2067 // use the same frame
2068 testBasicLayout();
2069 }
2070
testRemoveCenterAnchor_data()2071 void tst_QGraphicsAnchorLayout1::testRemoveCenterAnchor_data()
2072 {
2073 QTest::addColumn<QSizeF>("size");
2074 QTest::addColumn<BasicLayoutTestDataList>("data");
2075 QTest::addColumn<BasicLayoutTestDataList>("removeData");
2076 QTest::addColumn<BasicLayoutTestResultList>("result");
2077
2078 typedef BasicLayoutTestData BasicData;
2079 typedef BasicLayoutTestResult BasicResult;
2080
2081 {
2082 BasicLayoutTestDataList theData;
2083 BasicLayoutTestDataList theRemoveData;
2084 BasicLayoutTestResultList theResult;
2085
2086 theData
2087 // << BasicData(-1, Qt::AnchorRight, 0, Qt::AnchorHorizontalCenter, -10)
2088 << BasicData(-1, Qt::AnchorRight, 0, Qt::AnchorHorizontalCenter, 10)
2089 << BasicData(-1, Qt::AnchorLeft, 0, Qt::AnchorRight, 15)
2090 << BasicData(-1, Qt::AnchorTop, 0, Qt::AnchorVerticalCenter, 10)
2091 << BasicData(0, Qt::AnchorBottom, -1, Qt::AnchorBottom, 5)
2092
2093 << BasicData(-1, Qt::AnchorHorizontalCenter, 1, Qt::AnchorHorizontalCenter, 66)
2094 << BasicData(1, Qt::AnchorVerticalCenter, -1, Qt::AnchorVerticalCenter, 99)
2095 << BasicData(0, Qt::AnchorHorizontalCenter, 1, Qt::AnchorHorizontalCenter, 33)
2096 ;
2097
2098 theRemoveData
2099 << BasicData(-1, Qt::AnchorHorizontalCenter, 1, Qt::AnchorHorizontalCenter, 0)
2100 << BasicData(1, Qt::AnchorVerticalCenter, -1, Qt::AnchorVerticalCenter, 0)
2101 << BasicData(0, Qt::AnchorHorizontalCenter, 1, Qt::AnchorHorizontalCenter, 0);
2102
2103 theResult
2104 << BasicResult(0, QRectF(5, 5, 10, 10) );
2105
2106 QTest::newRow("remove, center, basic") << QSizeF(20, 20) << theData
2107 << theRemoveData << theResult;
2108 }
2109
2110 {
2111 BasicLayoutTestDataList theData;
2112 BasicLayoutTestDataList theRemoveData;
2113 BasicLayoutTestResultList theResult;
2114
2115 theData
2116 << BasicData(-1, Qt::AnchorLeft, 0, Qt::AnchorLeft, 0)
2117 << BasicData(0, Qt::AnchorHorizontalCenter, 2, Qt::AnchorHorizontalCenter, 75)
2118 << BasicData(1, Qt::AnchorRight, 2, Qt::AnchorLeft, 10)
2119 << BasicData(1, Qt::AnchorHorizontalCenter, 0, Qt::AnchorHorizontalCenter, -30)
2120 << BasicData(2, Qt::AnchorRight, -1, Qt::AnchorRight, 0)
2121 << BasicData(1, Qt::AnchorLeft, 1, Qt::AnchorRight, 30)
2122 << BasicData(0, Qt::AnchorRight, 1, Qt::AnchorLeft, 10)
2123
2124 // extra:
2125 << BasicData(-1, Qt::AnchorVerticalCenter, 0, Qt::AnchorVerticalCenter, 66)
2126 << BasicData(-1, Qt::AnchorHorizontalCenter, 0, Qt::AnchorHorizontalCenter, 33)
2127 << BasicData(0, Qt::AnchorHorizontalCenter, 0, Qt::AnchorHorizontalCenter, 55)
2128 << BasicData(1, Qt::AnchorVerticalCenter, 1, Qt::AnchorVerticalCenter, 55)
2129
2130 << BasicData(1, Qt::AnchorTop, -1, Qt::AnchorTop, 0)
2131 << BasicData(1, Qt::AnchorVerticalCenter, 0, Qt::AnchorVerticalCenter, 35)
2132 << BasicData(1, Qt::AnchorVerticalCenter, 2, Qt::AnchorVerticalCenter, 15)
2133 << BasicData(1, Qt::AnchorBottom, 2, Qt::AnchorTop, 5)
2134 << BasicData(0, Qt::AnchorBottom, -1, Qt::AnchorBottom, 0)
2135 << BasicData(2, Qt::AnchorBottom, 0, Qt::AnchorTop, 5)
2136 << BasicData(0, Qt::AnchorTop, 0, Qt::AnchorBottom, 20);
2137
2138 theRemoveData
2139 << BasicData(-1, Qt::AnchorVerticalCenter, 0, Qt::AnchorVerticalCenter, 66)
2140 << BasicData(-1, Qt::AnchorHorizontalCenter, 0, Qt::AnchorHorizontalCenter, 33)
2141 << BasicData(0, Qt::AnchorHorizontalCenter, 0, Qt::AnchorHorizontalCenter, 55)
2142 << BasicData(1, Qt::AnchorVerticalCenter, 1, Qt::AnchorVerticalCenter, 55);
2143
2144 theResult
2145 << BasicResult(0, QRectF(0, 30, 10, 20))
2146 << BasicResult(1, QRectF(20, 0, 30, 10))
2147 << BasicResult(2, QRectF(60, 15, 40, 10));
2148
2149 QTest::ignoreMessage(QtWarningMsg, "QGraphicsAnchorLayout::addAnchor(): Cannot anchor the item to itself");
2150 QTest::ignoreMessage(QtWarningMsg, "QGraphicsAnchorLayout::addAnchor(): Cannot anchor the item to itself");
2151 QTest::ignoreMessage(QtWarningMsg, "QGraphicsAnchorLayout::addAnchor(): Cannot anchor the item to itself");
2152 QTest::ignoreMessage(QtWarningMsg, "QGraphicsAnchorLayout::addAnchor(): Cannot anchor the item to itself");
2153
2154 QTest::newRow("remove, center, three") << QSizeF(100, 50) << theData << theRemoveData << theResult;
2155 }
2156
2157 // add edge (item0,edge0,item1,edge1), remove (item1,edge1,item0,edge0)
2158 {
2159 BasicLayoutTestDataList theData;
2160 BasicLayoutTestDataList theRemoveData;
2161 BasicLayoutTestResultList theResult;
2162
2163 theData
2164 // << BasicData(-1, Qt::AnchorRight, 0, Qt::AnchorHorizontalCenter, -10)
2165 << BasicData(-1, Qt::AnchorRight, 0, Qt::AnchorHorizontalCenter, 10)
2166 << BasicData(-1, Qt::AnchorLeft, 0, Qt::AnchorRight, 15)
2167 << BasicData(-1, Qt::AnchorTop, 0, Qt::AnchorVerticalCenter, 10)
2168 << BasicData(0, Qt::AnchorBottom, -1, Qt::AnchorBottom, 5)
2169
2170 << BasicData(-1, Qt::AnchorHorizontalCenter, 1, Qt::AnchorHorizontalCenter, 66)
2171 << BasicData(1, Qt::AnchorVerticalCenter, -1, Qt::AnchorVerticalCenter, 99)
2172 << BasicData(0, Qt::AnchorHorizontalCenter, 1, Qt::AnchorHorizontalCenter, 33)
2173 << BasicData(0, Qt::AnchorLeft, 0, Qt::AnchorRight, 22)
2174 << BasicData(0, Qt::AnchorTop, 0, Qt::AnchorBottom, 11)
2175 ;
2176
2177 theRemoveData
2178 << BasicData(1, Qt::AnchorHorizontalCenter, -1, Qt::AnchorHorizontalCenter, 0)
2179 << BasicData(-1, Qt::AnchorVerticalCenter, 1, Qt::AnchorVerticalCenter, 0)
2180 << BasicData(1, Qt::AnchorHorizontalCenter, 0, Qt::AnchorHorizontalCenter, 0)
2181 << BasicData(0, Qt::AnchorRight, 0, Qt::AnchorLeft, 0)
2182 << BasicData(0, Qt::AnchorBottom, 0, Qt::AnchorTop, 0)
2183 ;
2184
2185 theResult
2186 << BasicResult(0, QRectF(5, 5, 10, 10) );
2187
2188 QTest::ignoreMessage(QtWarningMsg, "QGraphicsAnchorLayout::addAnchor(): Cannot anchor the item to itself");
2189 QTest::ignoreMessage(QtWarningMsg, "QGraphicsAnchorLayout::addAnchor(): Cannot anchor the item to itself");
2190 QTest::newRow("remove, center, basic 2") << QSizeF(20, 20) << theData
2191 << theRemoveData << theResult;
2192 }
2193
2194 }
2195
testRemoveCenterAnchor()2196 void tst_QGraphicsAnchorLayout1::testRemoveCenterAnchor()
2197 {
2198 QFETCH(QSizeF, size);
2199 QFETCH(BasicLayoutTestDataList, data);
2200 QFETCH(BasicLayoutTestDataList, removeData);
2201 QFETCH(BasicLayoutTestResultList, result);
2202
2203 QGraphicsWidget *widget = new QGraphicsWidget;
2204
2205 // Determine amount of widgets to add.
2206 int widgetCount = -1;
2207 for (int i = 0; i < data.count(); ++i) {
2208 const BasicLayoutTestData item = data[i];
2209 widgetCount = qMax(widgetCount, item.firstIndex);
2210 widgetCount = qMax(widgetCount, item.secondIndex);
2211 }
2212 ++widgetCount; // widgetCount is max of indices.
2213
2214 // Create dummy widgets
2215 QList<QGraphicsWidget *> widgets;
2216 for (int i = 0; i < widgetCount; ++i) {
2217 TestWidget *w = new TestWidget;
2218 widgets << w;
2219 }
2220
2221 // Setup anchor layout
2222 TheAnchorLayout *layout = new TheAnchorLayout;
2223
2224 for (int i = 0; i < data.count(); ++i) {
2225 const BasicLayoutTestData item = data[i];
2226 layout->setAnchor(
2227 getItem(item.firstIndex, widgets, layout),
2228 item.firstEdge,
2229 getItem(item.secondIndex, widgets, layout),
2230 item.secondEdge,
2231 item.spacing );
2232 }
2233
2234 for (int i = 0; i < removeData.count(); ++i) {
2235 const BasicLayoutTestData item = removeData[i];
2236 layout->removeAnchor(
2237 getItem(item.firstIndex, widgets, layout),
2238 item.firstEdge,
2239 getItem(item.secondIndex, widgets, layout),
2240 item.secondEdge);
2241 }
2242
2243 widget->setLayout(layout);
2244 widget->setContentsMargins(0,0,0,0);
2245
2246 widget->resize(size);
2247 QCOMPARE(widget->size(), size);
2248
2249 // Validate
2250 for (int i = 0; i < result.count(); ++i) {
2251 const BasicLayoutTestResult item = result[i];
2252
2253 QCOMPARE(widgets[item.index]->geometry(), item.rect);
2254 }
2255
2256 qDeleteAll(widgets);
2257 delete widget;
2258 }
2259
testSingleSizePolicy_data()2260 void tst_QGraphicsAnchorLayout1::testSingleSizePolicy_data()
2261 {
2262 QTest::addColumn<QSizeF>("size");
2263 QTest::addColumn<QSizePolicy>("policy");
2264 QTest::addColumn<bool>("valid");
2265
2266 // FIXED
2267 {
2268 QSizePolicy sizePolicy( QSizePolicy::Fixed, QSizePolicy::Fixed );
2269 QTest::newRow("single size policy: fixed ok") << QSizeF(70, 70) << sizePolicy << true;
2270 }
2271 /*
2272 {
2273 QSizePolicy sizePolicy( QSizePolicy::Fixed, QSizePolicy::Fixed );
2274 QTest::newRow("single size policy: fixed too big") << QSizeF(100, 100) << sizePolicy << false;
2275 }
2276
2277 {
2278 QSizePolicy sizePolicy( QSizePolicy::Fixed, QSizePolicy::Fixed );
2279 QTest::newRow("single size policy: fixed too small") << QSizeF(50, 50) << sizePolicy << false;
2280 }
2281 */
2282 // MINIMUM
2283 {
2284 QSizePolicy sizePolicy( QSizePolicy::Minimum, QSizePolicy::Minimum );
2285 QTest::newRow("single size policy: minimum bigger ok") << QSizeF(100, 100) << sizePolicy << true;
2286 }
2287
2288 {
2289 QSizePolicy sizePolicy( QSizePolicy::Minimum, QSizePolicy::Minimum );
2290 QTest::newRow("single size policy: minimum limit ok") << QSizeF(70, 70) << sizePolicy << true;
2291 }
2292 /*
2293 {
2294 QSizePolicy sizePolicy( QSizePolicy::Minimum, QSizePolicy::Minimum );
2295 QTest::newRow("single size policy: minimum too small") << QSizeF(50, 50) << sizePolicy << false;
2296 }
2297 */
2298 // MAXIMUM
2299 {
2300 QSizePolicy sizePolicy( QSizePolicy::Maximum, QSizePolicy::Maximum );
2301 QTest::newRow("single size policy: maximum small ok") << QSizeF(50, 50) << sizePolicy << true;
2302 }
2303
2304 {
2305 QSizePolicy sizePolicy( QSizePolicy::Maximum, QSizePolicy::Maximum );
2306 QTest::newRow("single size policy: maximum limit ok") << QSizeF(70, 70) << sizePolicy << true;
2307 }
2308 /*
2309 {
2310 QSizePolicy sizePolicy( QSizePolicy::Maximum, QSizePolicy::Maximum );
2311 QTest::newRow("single size policy: maximum bigger fail") << QSizeF(100, 100) << sizePolicy << false;
2312 }
2313 */
2314 // PREFERRED
2315 {
2316 QSizePolicy sizePolicy( QSizePolicy::Preferred, QSizePolicy::Preferred );
2317 QTest::newRow("single size policy: preferred bigger ok") << QSizeF(100, 100) << sizePolicy << true;
2318 }
2319
2320 {
2321 QSizePolicy sizePolicy( QSizePolicy::Preferred, QSizePolicy::Preferred );
2322 QTest::newRow("single size policy: preferred smaller ok") << QSizeF(50, 50) << sizePolicy << true;
2323 }
2324 /*
2325 {
2326 QSizePolicy sizePolicy( QSizePolicy::Preferred, QSizePolicy::Preferred );
2327 QTest::newRow("single size policy: preferred too big") << QSizeF(700, 700) << sizePolicy << false;
2328 }
2329
2330 {
2331 QSizePolicy sizePolicy( QSizePolicy::Preferred, QSizePolicy::Preferred );
2332 QTest::newRow("single size policy: preferred too small") << QSizeF(21, 21) << sizePolicy << false;
2333 }
2334 */
2335 // MINIMUMEXPANDING
2336
2337 {
2338 QSizePolicy sizePolicy( QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding );
2339 QTest::newRow("single size policy: min.expanding bigger ok") << QSizeF(100, 100) << sizePolicy << true;
2340 }
2341
2342 {
2343 QSizePolicy sizePolicy( QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding );
2344 QTest::newRow("single size policy: min.expanding limit ok") << QSizeF(70, 70) << sizePolicy << true;
2345 }
2346
2347 /*{
2348 QSizePolicy sizePolicy( QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding );
2349 QTest::newRow("single size policy: min.expanding too small") << QSizeF(50, 50) << sizePolicy << false;
2350 }*/
2351
2352 // EXPANDING
2353
2354 {
2355 QSizePolicy sizePolicy( QSizePolicy::Expanding, QSizePolicy::Expanding );
2356 QTest::newRow("single size policy: expanding bigger ok") << QSizeF(100, 100) << sizePolicy << true;
2357 }
2358
2359 {
2360 QSizePolicy sizePolicy( QSizePolicy::Expanding, QSizePolicy::Expanding );
2361 QTest::newRow("single size policy: expanding smaller ok") << QSizeF(50, 50) << sizePolicy << true;
2362 }
2363
2364 // IGNORED
2365
2366 {
2367 QSizePolicy sizePolicy( QSizePolicy::Ignored, QSizePolicy::Ignored );
2368 QTest::newRow("single size policy: ignored bigger ok") << QSizeF(100, 100) << sizePolicy << true;
2369 }
2370
2371 {
2372 QSizePolicy sizePolicy( QSizePolicy::Ignored, QSizePolicy::Ignored );
2373 QTest::newRow("single size policy: ignored smaller ok") << QSizeF(50, 50) << sizePolicy << true;
2374 }
2375 }
2376
testSingleSizePolicy()2377 void tst_QGraphicsAnchorLayout1::testSingleSizePolicy()
2378 {
2379 QFETCH(QSizeF, size);
2380 QFETCH(QSizePolicy, policy);
2381 QFETCH(bool, valid);
2382
2383 // create objects
2384 QGraphicsWidget widget;
2385 TheAnchorLayout *layout = new TheAnchorLayout;
2386 TestWidget *childWidget = new TestWidget;
2387
2388 // set anchors
2389 layout->setAnchor( layout, Qt::AnchorLeft, childWidget, Qt::AnchorLeft, 10 );
2390 layout->setAnchor( childWidget, Qt::AnchorRight, layout, Qt::AnchorRight, 10 );
2391 layout->setAnchor( layout, Qt::AnchorTop, childWidget, Qt::AnchorTop, 10 );
2392 layout->setAnchor( childWidget, Qt::AnchorBottom, layout, Qt::AnchorBottom, 10 );
2393
2394 widget.setLayout( layout );
2395
2396 // set test case specific: policy and size
2397 childWidget->setSizePolicy( policy );
2398 widget.setGeometry( QRectF( QPoint(0,0), size ) );
2399
2400 QCOMPARE( layout->isValid() , valid );
2401
2402 const QRectF childRect = childWidget->geometry();
2403 Q_UNUSED( childRect );
2404 }
2405
testDoubleSizePolicy_data()2406 void tst_QGraphicsAnchorLayout1::testDoubleSizePolicy_data()
2407 {
2408 // tests only horizontal direction
2409 QTest::addColumn<QSizePolicy>("policy1");
2410 QTest::addColumn<QSizePolicy>("policy2");
2411 QTest::addColumn<qreal>("width1");
2412 QTest::addColumn<qreal>("width2");
2413
2414 // layout size always 100x100 and size hints for items are 5<50<500
2415 // gabs: 10-item1-10-item2-10
2416
2417 {
2418 QSizePolicy sizePolicy1( QSizePolicy::Fixed, QSizePolicy::Fixed );
2419 QSizePolicy sizePolicy2( QSizePolicy::Preferred, QSizePolicy::Preferred );
2420 const qreal width1 = 50;
2421 const qreal width2 = 100-10-10-10-width1;
2422 QTest::newRow("double size policy: fixed-preferred") << sizePolicy1 << sizePolicy2 << width1 << width2;
2423 }
2424
2425 {
2426 QSizePolicy sizePolicy1( QSizePolicy::Minimum, QSizePolicy::Minimum );
2427 QSizePolicy sizePolicy2( QSizePolicy::Preferred, QSizePolicy::Preferred );
2428 const qreal width1 = 50;
2429 const qreal width2 = 100-10-10-10-width1;
2430 QTest::newRow("double size policy: minimum-preferred") << sizePolicy1 << sizePolicy2 << width1 << width2;
2431 }
2432
2433 {
2434 QSizePolicy sizePolicy1( QSizePolicy::Maximum, QSizePolicy::Maximum );
2435 QSizePolicy sizePolicy2( QSizePolicy::Preferred, QSizePolicy::Preferred );
2436 const qreal width1 = 35;
2437 const qreal width2 = 100-10-10-10-width1;
2438 QTest::newRow("double size policy: maximum-preferred") << sizePolicy1 << sizePolicy2 << width1 << width2;
2439 }
2440
2441 {
2442 QSizePolicy sizePolicy1( QSizePolicy::Preferred, QSizePolicy::Preferred );
2443 QSizePolicy sizePolicy2( QSizePolicy::Preferred, QSizePolicy::Preferred );
2444 const qreal width1 = 35;
2445 const qreal width2 = 100-10-10-10-width1;
2446 QTest::newRow("double size policy: preferred-preferred") << sizePolicy1 << sizePolicy2 << width1 << width2;
2447 }
2448
2449 {
2450 QSizePolicy sizePolicy1( QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding );
2451 QSizePolicy sizePolicy2( QSizePolicy::Preferred, QSizePolicy::Preferred );
2452 const qreal width1 = 50;
2453 const qreal width2 = 100-10-10-10-width1;
2454 QTest::newRow("double size policy: min.expanding-preferred") << sizePolicy1 << sizePolicy2 << width1 << width2;
2455 }
2456
2457 {
2458 QSizePolicy sizePolicy1( QSizePolicy::Expanding, QSizePolicy::Expanding );
2459 QSizePolicy sizePolicy2( QSizePolicy::Preferred, QSizePolicy::Preferred );
2460 const qreal width1 = 35;
2461 const qreal width2 = 100-10-10-10-width1;
2462 QTest::newRow("double size policy: expanding-preferred") << sizePolicy1 << sizePolicy2 << width1 << width2;
2463 }
2464
2465 // QGAL handling of ignored flag is different
2466 if (0)
2467 {
2468 QSizePolicy sizePolicy1( QSizePolicy::Ignored, QSizePolicy::Ignored );
2469 QSizePolicy sizePolicy2( QSizePolicy::Preferred, QSizePolicy::Preferred );
2470 const qreal width1 = 35;
2471 const qreal width2 = 100-10-10-10-width1;
2472 QTest::newRow("double size policy: ignored-preferred") << sizePolicy1 << sizePolicy2 << width1 << width2;
2473 }
2474
2475 /*{
2476 QSizePolicy sizePolicy1( QSizePolicy::Fixed, QSizePolicy::Fixed );
2477 QSizePolicy sizePolicy2( QSizePolicy::Fixed, QSizePolicy::Fixed );
2478 const qreal width1 = -1;
2479 const qreal width2 = 100-10-10-10-width1;
2480 QTest::newRow("double size policy: fixed-fixed invalid") << sizePolicy1 << sizePolicy2 << width1 << width2;
2481 }*/
2482
2483 /*{
2484 QSizePolicy sizePolicy1( QSizePolicy::Minimum, QSizePolicy::Minimum );
2485 QSizePolicy sizePolicy2( QSizePolicy::Fixed, QSizePolicy::Fixed );
2486 const qreal width1 = -1;
2487 const qreal width2 = 100-10-10-10-width1;
2488 QTest::newRow("double size policy: minimum-fixed invalid") << sizePolicy1 << sizePolicy2 << width1 << width2;
2489 }*/
2490
2491 {
2492 QSizePolicy sizePolicy1( QSizePolicy::Maximum, QSizePolicy::Maximum );
2493 QSizePolicy sizePolicy2( QSizePolicy::Fixed, QSizePolicy::Fixed );
2494 const qreal width1 = 20;
2495 const qreal width2 = 100-10-10-10-width1;
2496 QTest::newRow("double size policy: maximum-fixed") << sizePolicy1 << sizePolicy2 << width1 << width2;
2497 }
2498
2499 {
2500 QSizePolicy sizePolicy1( QSizePolicy::Preferred, QSizePolicy::Preferred );
2501 QSizePolicy sizePolicy2( QSizePolicy::Fixed, QSizePolicy::Fixed );
2502 const qreal width1 = 20;
2503 const qreal width2 = 100-10-10-10-width1;
2504 QTest::newRow("double size policy: preferred-fixed") << sizePolicy1 << sizePolicy2 << width1 << width2;
2505 }
2506
2507 /*{
2508 QSizePolicy sizePolicy1( QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding );
2509 QSizePolicy sizePolicy2( QSizePolicy::Fixed, QSizePolicy::Fixed );
2510 const qreal width1 = -1;
2511 const qreal width2 = 100-10-10-10-width1;
2512 QTest::newRow("double size policy: min.expanding-fixed invalid") << sizePolicy1 << sizePolicy2 << width1 << width2;
2513 }*/
2514
2515 {
2516 QSizePolicy sizePolicy1( QSizePolicy::Expanding, QSizePolicy::Expanding );
2517 QSizePolicy sizePolicy2( QSizePolicy::Fixed, QSizePolicy::Fixed );
2518 const qreal width1 = 20;
2519 const qreal width2 = 100-10-10-10-width1;
2520 QTest::newRow("double size policy: expanding-fixed") << sizePolicy1 << sizePolicy2 << width1 << width2;
2521 }
2522
2523 {
2524 QSizePolicy sizePolicy1( QSizePolicy::Ignored, QSizePolicy::Ignored );
2525 QSizePolicy sizePolicy2( QSizePolicy::Fixed, QSizePolicy::Fixed );
2526 const qreal width1 = 20;
2527 const qreal width2 = 100-10-10-10-width1;
2528 QTest::newRow("double size policy: ignored-fixed") << sizePolicy1 << sizePolicy2 << width1 << width2;
2529 }
2530 }
2531
testDoubleSizePolicy()2532 void tst_QGraphicsAnchorLayout1::testDoubleSizePolicy()
2533 {
2534 QFETCH(QSizePolicy, policy1);
2535 QFETCH(QSizePolicy, policy2);
2536 QFETCH(qreal, width1);
2537 QFETCH(qreal, width2);
2538
2539 // create objects
2540 QGraphicsWidget widget;
2541 TheAnchorLayout *layout = new TheAnchorLayout;
2542 TestWidget *childWidget1 = new TestWidget;
2543 TestWidget *childWidget2 = new TestWidget;
2544
2545 // set anchors
2546 layout->setAnchor( layout, Qt::AnchorLeft, childWidget1, Qt::AnchorLeft, 10 );
2547 layout->setAnchor( childWidget1, Qt::AnchorRight, childWidget2, Qt::AnchorLeft, 10 );
2548 layout->setAnchor( childWidget2, Qt::AnchorRight, layout, Qt::AnchorRight, 10 );
2549
2550 widget.setLayout( layout );
2551
2552 // set test case specific: policy
2553 childWidget1->setSizePolicy( policy1 );
2554 childWidget2->setSizePolicy( policy2 );
2555
2556 widget.setGeometry( QRectF( QPoint(0,0), QSize( 100,100 ) ) );
2557
2558 // check results:
2559 if ( width1 == -1.0f ) {
2560 // invalid
2561 QCOMPARE( layout->isValid() , false );
2562 } else {
2563 // valid
2564 QCOMPARE( childWidget1->geometry().width(), width1 );
2565 QCOMPARE( childWidget2->geometry().width(), width2 );
2566 }
2567 }
2568
2569 typedef QMap<int,qreal> SizeHintArray;
Q_DECLARE_METATYPE(SizeHintArray)2570 Q_DECLARE_METATYPE(SizeHintArray)
2571
2572 void tst_QGraphicsAnchorLayout1::testSizeDistribution_data()
2573 {
2574 // tests only horizontal direction
2575 QTest::addColumn<SizeHintArray>("sizeHints1");
2576 QTest::addColumn<SizeHintArray>("sizeHints2");
2577 QTest::addColumn<qreal>("width1");
2578 QTest::addColumn<qreal>("width2");
2579
2580 // layout size always 100x100 and size policy for items is preferred-preferred
2581 // gabs: 10-item1-10-item2-10
2582
2583 {
2584 SizeHintArray sizeHints1;
2585 sizeHints1.insert( Qt::MinimumSize, 30 );
2586 sizeHints1.insert( Qt::PreferredSize, 35 );
2587 sizeHints1.insert( Qt::MaximumSize, 40 );
2588
2589 SizeHintArray sizeHints2;
2590 sizeHints2.insert( Qt::MinimumSize, 5 );
2591 sizeHints2.insert( Qt::PreferredSize, 35 );
2592 sizeHints2.insert( Qt::MaximumSize, 300 );
2593
2594 const qreal width1 = 35;
2595 const qreal width2 = 100-10-10-10-width1;
2596 QTest::newRow("size distribution: preferred equal") << sizeHints1 << sizeHints2 << width1 << width2;
2597 }
2598
2599 {
2600 SizeHintArray sizeHints1;
2601 sizeHints1.insert( Qt::MinimumSize, 0 );
2602 sizeHints1.insert( Qt::PreferredSize, 20 );
2603 sizeHints1.insert( Qt::MaximumSize, 100 );
2604
2605 SizeHintArray sizeHints2;
2606 sizeHints2.insert( Qt::MinimumSize, 0 );
2607 sizeHints2.insert( Qt::PreferredSize, 50 );
2608 sizeHints2.insert( Qt::MaximumSize, 100 );
2609
2610 const qreal width1 = 20;
2611 const qreal width2 = 100-10-10-10-width1;
2612 QTest::newRow("size distribution: preferred non-equal") << sizeHints1 << sizeHints2 << width1 << width2;
2613 }
2614
2615 {
2616 SizeHintArray sizeHints1;
2617 sizeHints1.insert( Qt::MinimumSize, 0 );
2618 sizeHints1.insert( Qt::PreferredSize, 40 );
2619 sizeHints1.insert( Qt::MaximumSize, 100 );
2620
2621 SizeHintArray sizeHints2;
2622 sizeHints2.insert( Qt::MinimumSize, 0 );
2623 sizeHints2.insert( Qt::PreferredSize, 60 );
2624 sizeHints2.insert( Qt::MaximumSize, 100 );
2625
2626 const qreal width1 = 28; // got from manual calculation
2627 const qreal width2 = 100-10-10-10-width1;
2628 QTest::newRow("size distribution: below preferred") << sizeHints1 << sizeHints2 << width1 << width2;
2629 }
2630
2631 {
2632 SizeHintArray sizeHints1;
2633 sizeHints1.insert( Qt::MinimumSize, 0 );
2634 sizeHints1.insert( Qt::PreferredSize, 10 );
2635 sizeHints1.insert( Qt::MaximumSize, 100 );
2636
2637 SizeHintArray sizeHints2;
2638 sizeHints2.insert( Qt::MinimumSize, 0 );
2639 sizeHints2.insert( Qt::PreferredSize, 40 );
2640 sizeHints2.insert( Qt::MaximumSize, 100 );
2641
2642 const qreal width1 = 22; // got from manual calculation
2643 const qreal width2 = 100-10-10-10-width1;
2644 QTest::newRow("size distribution: above preferred") << sizeHints1 << sizeHints2 << width1 << width2;
2645 }
2646
2647 }
2648
testSizeDistribution()2649 void tst_QGraphicsAnchorLayout1::testSizeDistribution()
2650 {
2651 QFETCH(SizeHintArray, sizeHints1);
2652 QFETCH(SizeHintArray, sizeHints2);
2653 QFETCH(qreal, width1);
2654 QFETCH(qreal, width2);
2655
2656 // sanity-check the test data - MinimumSize <= PreferredSize <= MaximumSize
2657 QVERIFY( sizeHints1.value( Qt::MinimumSize ) <= sizeHints1.value( Qt::PreferredSize ) );
2658 QVERIFY( sizeHints1.value( Qt::PreferredSize ) <= sizeHints1.value( Qt::MaximumSize ) );
2659 QVERIFY( sizeHints2.value( Qt::MinimumSize ) <= sizeHints2.value( Qt::PreferredSize ) );
2660 QVERIFY( sizeHints2.value( Qt::PreferredSize ) <= sizeHints2.value( Qt::MaximumSize ) );
2661
2662 // create objects
2663 QGraphicsWidget widget;
2664 TheAnchorLayout *layout = new TheAnchorLayout;
2665 TestWidget *childWidget1 = new TestWidget;
2666 TestWidget *childWidget2 = new TestWidget;
2667
2668 // set anchors
2669 layout->setAnchor( layout, Qt::AnchorLeft, childWidget1, Qt::AnchorLeft, 10 );
2670 layout->setAnchor( childWidget1, Qt::AnchorRight, childWidget2, Qt::AnchorLeft, 10 );
2671 layout->setAnchor( childWidget2, Qt::AnchorRight, layout, Qt::AnchorRight, 10 );
2672
2673 widget.setLayout( layout );
2674
2675 // set test case specific: size hints
2676 childWidget1->setMinimumWidth( sizeHints1.value( Qt::MinimumSize ) );
2677 childWidget1->setPreferredWidth( sizeHints1.value( Qt::PreferredSize ) );
2678 childWidget1->setMaximumWidth( sizeHints1.value( Qt::MaximumSize ) );
2679
2680 childWidget2->setMinimumWidth( sizeHints2.value( Qt::MinimumSize ) );
2681 childWidget2->setPreferredWidth( sizeHints2.value( Qt::PreferredSize ) );
2682 childWidget2->setMaximumWidth( sizeHints2.value( Qt::MaximumSize ) );
2683
2684 widget.setGeometry( QRectF( QPoint(0,0), QSize( 100,100 ) ) );
2685
2686 // check results:
2687 if ( width1 == -1.0f ) {
2688 // invalid
2689 QCOMPARE( layout->isValid() , false );
2690 } else {
2691 // valid
2692 QCOMPARE( float(childWidget1->geometry().width()), float(width1) );
2693 QCOMPARE( float(childWidget2->geometry().width()), float(width2) );
2694 }
2695 }
2696
testSizeHint()2697 void tst_QGraphicsAnchorLayout1::testSizeHint()
2698 {
2699 QGraphicsWidget *widget[5];
2700
2701 for( int i = 0; i < 5; i++ ) {
2702 widget[i] = new QGraphicsWidget;
2703 widget[i]->setMinimumSize( 10, 10 );
2704 widget[i]->setPreferredSize( 20, 20 );
2705 widget[i]->setMaximumSize( 40, 40 );
2706 }
2707
2708 // one, basic
2709 {
2710 TheAnchorLayout *layout = new TheAnchorLayout();
2711
2712
2713 layout->setAnchor(layout, Qt::AnchorLeft, widget[0], Qt::AnchorLeft, 0 );
2714 layout->setAnchor(layout, Qt::AnchorRight, widget[0], Qt::AnchorRight, 0 );
2715
2716 layout->setAnchor(layout, Qt::AnchorTop, widget[0], Qt::AnchorTop, 0 );
2717 layout->setAnchor(layout, Qt::AnchorBottom, widget[0], Qt::AnchorBottom, 0 );
2718
2719 QCOMPARE( layout->minimumSize(), widget[0]->minimumSize() );
2720 QCOMPARE( layout->preferredSize(), widget[0]->preferredSize() );
2721 QCOMPARE( layout->maximumSize(), widget[0]->maximumSize() );
2722
2723
2724 delete layout;
2725 }
2726
2727 // one, basic again
2728 {
2729 TheAnchorLayout *layout = new TheAnchorLayout();
2730
2731
2732 layout->setAnchor(layout, Qt::AnchorLeft, widget[0], Qt::AnchorLeft, 10 );
2733 // layout->setAnchor(layout, Qt::AnchorRight, widget[0], Qt::AnchorRight, -10 );
2734 layout->setAnchor(layout, Qt::AnchorRight, widget[0], Qt::AnchorRight, 10 );
2735
2736 layout->setAnchor(layout, Qt::AnchorTop, widget[0], Qt::AnchorTop, 10 );
2737 // layout->setAnchor(layout, Qt::AnchorBottom, widget[0], Qt::AnchorBottom, -10 );
2738 layout->setAnchor(layout, Qt::AnchorBottom, widget[0], Qt::AnchorBottom, 10 );
2739
2740 QCOMPARE( layout->minimumSize(), widget[0]->minimumSize() + QSizeF( 20, 20 ) );
2741 QCOMPARE( layout->preferredSize(), widget[0]->preferredSize() + QSizeF( 20, 20 ) );
2742 QCOMPARE( layout->maximumSize(), widget[0]->maximumSize() + QSizeF( 20, 20 ) );
2743
2744 delete layout;
2745 }
2746
2747 // two, serial
2748 {
2749 TheAnchorLayout *layout = new TheAnchorLayout();
2750
2751
2752 layout->setAnchor(layout, Qt::AnchorLeft, widget[0], Qt::AnchorLeft, 0 );
2753 layout->setAnchor(layout, Qt::AnchorTop, widget[0], Qt::AnchorTop, 0 );
2754 layout->setAnchor(layout, Qt::AnchorBottom, widget[0], Qt::AnchorBottom, 0 );
2755
2756 layout->setAnchor(widget[0], Qt::AnchorRight, widget[1], Qt::AnchorLeft, 0 );
2757 layout->setAnchor(widget[1], Qt::AnchorRight, layout, Qt::AnchorRight, 0 );
2758
2759
2760 QCOMPARE( layout->minimumSize(), widget[0]->minimumSize() + QSizeF( widget[1]->minimumWidth(), 0 ) );
2761 QCOMPARE( layout->preferredSize(), widget[0]->preferredSize() + QSizeF( widget[1]->preferredWidth(), 0 ) );
2762 QCOMPARE( layout->maximumSize(), widget[0]->maximumSize() + QSizeF( widget[1]->maximumWidth(), 0 ) );
2763
2764 delete layout;
2765 }
2766
2767 // two, parallel
2768 {
2769 TheAnchorLayout *layout = new TheAnchorLayout();
2770
2771
2772 layout->setAnchor(layout, Qt::AnchorLeft, widget[0], Qt::AnchorLeft, 0 );
2773 layout->setAnchor(layout, Qt::AnchorTop, widget[0], Qt::AnchorTop, 0 );
2774 layout->setAnchor(layout, Qt::AnchorBottom, widget[0], Qt::AnchorBottom, 0 );
2775 layout->setAnchor(layout, Qt::AnchorRight, widget[0], Qt::AnchorRight, 0 );
2776
2777 layout->setAnchor(layout, Qt::AnchorLeft, widget[1], Qt::AnchorLeft, 0 );
2778 layout->setAnchor(layout, Qt::AnchorTop, widget[1], Qt::AnchorTop, 0 );
2779 layout->setAnchor(layout, Qt::AnchorBottom, widget[1], Qt::AnchorBottom, 0 );
2780 layout->setAnchor(layout, Qt::AnchorRight, widget[1], Qt::AnchorRight, 0 );
2781
2782 QCOMPARE( layout->minimumSize(), widget[0]->minimumSize() );
2783 QCOMPARE( layout->preferredSize(), widget[0]->preferredSize() );
2784 QCOMPARE( layout->maximumSize(), widget[0]->maximumSize() );
2785
2786 delete layout;
2787 }
2788
2789 // five, serial
2790 {
2791 TheAnchorLayout *layout = new TheAnchorLayout();
2792
2793
2794 layout->setAnchor(layout, Qt::AnchorLeft, widget[0], Qt::AnchorLeft, 0 );
2795 layout->setAnchor(layout, Qt::AnchorTop, widget[0], Qt::AnchorTop, 0 );
2796 layout->setAnchor(layout, Qt::AnchorBottom, widget[0], Qt::AnchorBottom, 0 );
2797
2798 layout->setAnchor(widget[0], Qt::AnchorRight, widget[1], Qt::AnchorLeft, 0 );
2799 layout->setAnchor(widget[1], Qt::AnchorRight, widget[2], Qt::AnchorLeft, 0 );
2800 layout->setAnchor(widget[2], Qt::AnchorRight, widget[3], Qt::AnchorLeft, 0 );
2801 layout->setAnchor(widget[3], Qt::AnchorRight, widget[4], Qt::AnchorLeft, 0 );
2802 layout->setAnchor(widget[4], Qt::AnchorRight, layout, Qt::AnchorRight, 0 );
2803
2804
2805 QCOMPARE( layout->minimumSize(), widget[0]->minimumSize() +
2806 QSizeF( widget[1]->minimumWidth() +
2807 widget[2]->minimumWidth() +
2808 widget[3]->minimumWidth() +
2809 widget[4]->minimumWidth(), 0 ) );
2810
2811 QCOMPARE( layout->preferredSize(), widget[0]->preferredSize() +
2812 QSizeF( widget[1]->preferredWidth() +
2813 widget[2]->preferredWidth() +
2814 widget[3]->preferredWidth() +
2815 widget[4]->preferredWidth(), 0 ) );
2816
2817 QCOMPARE( layout->maximumSize(), widget[0]->maximumSize() +
2818 QSizeF( widget[1]->maximumWidth() +
2819 widget[2]->maximumWidth() +
2820 widget[3]->maximumWidth() +
2821 widget[4]->maximumWidth(), 0 ) );
2822
2823 delete layout;
2824 }
2825
2826
2827 for( int i = 0; i < 5; i++ ) {
2828 delete widget[i];
2829 }
2830 }
2831
2832 #ifdef TEST_COMPLEX_CASES
2833
testComplexCases_data()2834 void tst_QGraphicsAnchorLayout1::testComplexCases_data()
2835 {
2836 QTest::addColumn<QSizeF>("size");
2837 QTest::addColumn<BasicLayoutTestDataList>("data");
2838 QTest::addColumn<AnchorItemSizeHintList>("sizehint");
2839 QTest::addColumn<BasicLayoutTestResultList>("result");
2840
2841 typedef BasicLayoutTestData BasicData;
2842 typedef BasicLayoutTestResult BasicResult;
2843
2844 // Three widgets, the same sizehint
2845 {
2846 BasicLayoutTestDataList theData;
2847 AnchorItemSizeHintList theSizeHint;
2848 BasicLayoutTestResultList theResult1;
2849 BasicLayoutTestResultList theResult2;
2850
2851 theData
2852 << BasicData(-1, Qt::AnchorLeft, 0, Qt::AnchorLeft, 10)
2853 << BasicData(0, Qt::AnchorRight, 1, Qt::AnchorLeft, 10)
2854 << BasicData(0, Qt::AnchorRight, 2, Qt::AnchorLeft, 10)
2855
2856 << BasicData(1, Qt::AnchorRight, -1, Qt::AnchorRight, 10)
2857 << BasicData(2, Qt::AnchorRight, -1, Qt::AnchorRight, 10)
2858
2859 << BasicData(-1, Qt::AnchorTop, 0, Qt::AnchorTop, 0)
2860 << BasicData(-1, Qt::AnchorTop, 1, Qt::AnchorTop, 0)
2861 << BasicData(-1, Qt::AnchorTop, 2, Qt::AnchorTop, 0)
2862 ;
2863
2864 theSizeHint
2865 << AnchorItemSizeHint( 0, 50, 100, 0, 50, 100 )
2866 << AnchorItemSizeHint( 0, 50, 100, 0, 50, 100 )
2867 << AnchorItemSizeHint( 0, 50, 100, 0, 50, 100 )
2868 ;
2869 theResult1
2870 << BasicResult(0, QRectF(10, 0, 30, 50) )
2871 << BasicResult(1, QRectF(50, 0, 30, 50) )
2872 << BasicResult(2, QRectF(50, 0, 30, 50) )
2873 ;
2874
2875 theResult2
2876 << BasicResult(0, QRectF(10, 0, 60, 50) )
2877 << BasicResult(1, QRectF(80, 0, 60, 50) )
2878 << BasicResult(2, QRectF(80, 0, 60, 50) )
2879 ;
2880
2881 QTest::newRow("Three, the same sizehint(1)") << QSizeF(90, 50) << theData << theSizeHint << theResult1;
2882 QTest::newRow("Three, the same sizehint(2)") << QSizeF(150, 50) << theData << theSizeHint << theResult2;
2883 }
2884
2885 // Three widgets, serial is bigger
2886 {
2887 BasicLayoutTestDataList theData;
2888 AnchorItemSizeHintList theSizeHint;
2889 BasicLayoutTestResultList theResult;
2890
2891 theData
2892 << BasicData(-1, Qt::AnchorLeft, 0, Qt::AnchorLeft, 10)
2893 << BasicData(0, Qt::AnchorRight, 1, Qt::AnchorLeft, 10)
2894 << BasicData(0, Qt::AnchorRight, 2, Qt::AnchorLeft, 10)
2895
2896 << BasicData(1, Qt::AnchorRight, -1, Qt::AnchorRight, 10)
2897 << BasicData(2, Qt::AnchorRight, -1, Qt::AnchorRight, 10)
2898
2899 << BasicData(-1, Qt::AnchorTop, 0, Qt::AnchorTop, 0)
2900 << BasicData(-1, Qt::AnchorTop, 1, Qt::AnchorTop, 0)
2901 << BasicData(-1, Qt::AnchorTop, 2, Qt::AnchorTop, 0)
2902 ;
2903
2904 theSizeHint
2905 << AnchorItemSizeHint( 0, 100, 200, 0, 50, 100 )
2906 << AnchorItemSizeHint( 0, 50, 100, 0, 50, 100 )
2907 << AnchorItemSizeHint( 0, 50, 100, 0, 50, 100 )
2908 ;
2909
2910 theResult
2911 << BasicResult(0, QRectF(10, 0, 70, 50) )
2912 << BasicResult(1, QRectF(90, 0, 35, 50) )
2913 << BasicResult(2, QRectF(90, 0, 35, 50) );
2914
2915 QTest::newRow("Three, serial is bigger") << QSizeF(135, 50) << theData << theSizeHint << theResult;
2916
2917 // theResult
2918 // << BasicResult(0, QRectF(10, 0, 80, 50) )
2919 // << BasicResult(1, QRectF(100, 0, 60, 50) )
2920 // << BasicResult(2, QRectF(100, 0, 60, 50) )
2921 // ;
2922
2923 // QTest::newRow("Three, serial is bigger") << QSizeF(170, 50) << theData << theSizeHint << theResult;
2924 }
2925
2926
2927 // Three widgets, parallel is bigger
2928 {
2929 BasicLayoutTestDataList theData;
2930 AnchorItemSizeHintList theSizeHint;
2931 BasicLayoutTestResultList theResult;
2932
2933 theData
2934 << BasicData(-1, Qt::AnchorLeft, 0, Qt::AnchorLeft, 10)
2935 << BasicData(0, Qt::AnchorRight, 1, Qt::AnchorLeft, 10)
2936 << BasicData(0, Qt::AnchorRight, 2, Qt::AnchorLeft, 10)
2937
2938 << BasicData(1, Qt::AnchorRight, -1, Qt::AnchorRight, 10)
2939 << BasicData(2, Qt::AnchorRight, -1, Qt::AnchorRight, 10)
2940
2941 << BasicData(-1, Qt::AnchorTop, 0, Qt::AnchorTop, 0)
2942 << BasicData(-1, Qt::AnchorTop, 1, Qt::AnchorTop, 0)
2943 << BasicData(-1, Qt::AnchorTop, 2, Qt::AnchorTop, 0)
2944 ;
2945
2946 theSizeHint
2947 << AnchorItemSizeHint( 0, 50, 100, 0, 50, 100 )
2948 << AnchorItemSizeHint( 0, 100, 200, 0, 50, 100 )
2949 << AnchorItemSizeHint( 0, 50, 100, 0, 50, 100 )
2950 ;
2951
2952 // ### QGAL uses a different preferred size calculation algorithm.
2953 // This algorithm was discussed with Jan-Arve and tries to grow
2954 // items instead of shrinking them.
2955 // In this case, the preferred size of each item becomes:
2956 // Item 0: 50
2957 // Item 1: 100 (grows to avoid shrinking item 2)
2958 // Item 2: 100
2959 // Therefore, the preferred size of the parent widget becomes
2960 // 180 == (10 + 50 + 10 + 100 + 10)
2961 // As we set its size to 150, each widget is shrinked in the same
2962 // ratio, in order to achieve the width of 150 == (10 + 40 + 10 + 80 + 10)
2963
2964 theResult
2965 << BasicResult(0, QRectF(10, 0, 40, 50) )
2966 << BasicResult(1, QRectF(60, 0, 80, 50) )
2967 << BasicResult(2, QRectF(60, 0, 80, 50) )
2968 ;
2969
2970 QTest::newRow("Three, parallel is bigger") << QSizeF(150, 50) << theData << theSizeHint << theResult;
2971
2972 // #ifdef PREFERRED_IS_AVERAGE
2973 // theResult
2974 // << BasicResult(0, QRectF(10, 0, 50, 50) )
2975 // << BasicResult(1, QRectF(70, 0, 75, 50) )
2976 // << BasicResult(2, QRectF(70, 0, 75, 50) )
2977 // ;
2978
2979 // QTest::newRow("Three, parallel is bigger") << QSizeF(155, 50) << theData << theSizeHint << theResult;
2980 // #else
2981 // theResult
2982 // << BasicResult(0, QRectF(10, 0, 50, 50) )
2983 // << BasicResult(1, QRectF(70, 0, 66.66666666666666, 50) )
2984 // << BasicResult(2, QRectF(70, 0, 60.66666666666666, 50) )
2985 // ;
2986
2987 // QTest::newRow("Three, parallel is bigger") << QSizeF(146.66666666666666, 50) << theData << theSizeHint << theResult;
2988 // #endif
2989 }
2990
2991 // Three widgets, the same sizehint, one center anchor
2992 {
2993 BasicLayoutTestDataList theData;
2994 AnchorItemSizeHintList theSizeHint;
2995 BasicLayoutTestResultList theResult;
2996
2997 theData
2998 << BasicData(-1, Qt::AnchorLeft, 0, Qt::AnchorLeft, 10)
2999 << BasicData(0, Qt::AnchorRight, 1, Qt::AnchorLeft, 10)
3000 << BasicData(0, Qt::AnchorHorizontalCenter, 2, Qt::AnchorLeft, 10)
3001
3002 << BasicData(1, Qt::AnchorRight, -1, Qt::AnchorRight, 10)
3003 << BasicData(2, Qt::AnchorRight, -1, Qt::AnchorRight, 10)
3004
3005 << BasicData(-1, Qt::AnchorTop, 0, Qt::AnchorTop, 0)
3006 << BasicData(-1, Qt::AnchorTop, 1, Qt::AnchorTop, 0)
3007 << BasicData(-1, Qt::AnchorTop, 2, Qt::AnchorTop, 0)
3008 ;
3009
3010 theSizeHint
3011 << AnchorItemSizeHint( 0, 50, 100, 0, 50, 100 )
3012 << AnchorItemSizeHint( 0, 50, 100, 0, 50, 100 )
3013 << AnchorItemSizeHint( 0, 50, 100, 0, 50, 100 )
3014 ;
3015 theResult
3016 << BasicResult(0, QRectF(10, 0, 40, 50) )
3017 << BasicResult(1, QRectF(60, 0, 40, 50) )
3018 << BasicResult(2, QRectF(40, 0, 60, 50) )
3019 ;
3020
3021 ;
3022
3023 QTest::newRow("Three, the same sizehint, one center anchor") << QSizeF(110, 50) << theData << theSizeHint << theResult;
3024 }
3025 }
3026
testComplexCases()3027 void tst_QGraphicsAnchorLayout1::testComplexCases()
3028 {
3029 QFETCH(QSizeF, size);
3030 QFETCH(BasicLayoutTestDataList, data);
3031 QFETCH(AnchorItemSizeHintList, sizehint);
3032 QFETCH(BasicLayoutTestResultList, result);
3033
3034 QGraphicsWidget *widget = new QGraphicsWidget;
3035
3036 // Determine amount of widgets to add.
3037 int widgetCount = -1;
3038 for (int i = 0; i < data.count(); ++i) {
3039 const BasicLayoutTestData item = data[i];
3040 widgetCount = qMax(widgetCount, item.firstIndex);
3041 widgetCount = qMax(widgetCount, item.secondIndex);
3042 }
3043 ++widgetCount; // widgetCount is max of indices.
3044
3045 // Create dummy widgets
3046 QList<QGraphicsWidget *> widgets;
3047 for (int i = 0; i < widgetCount; ++i) {
3048 TestWidget *w = new TestWidget;
3049
3050 w->setMinimumWidth( sizehint[i].hmin );
3051 w->setPreferredWidth( sizehint[i].hpref );
3052 w->setMaximumWidth( sizehint[i].hmax );
3053
3054 w->setMinimumHeight( sizehint[i].vmin );
3055 w->setPreferredHeight( sizehint[i].vpref );
3056 w->setMaximumHeight( sizehint[i].vmax );
3057
3058 widgets << w;
3059 }
3060
3061 // Setup anchor layout
3062 TheAnchorLayout *layout = new TheAnchorLayout;
3063
3064 for (int i = 0; i < data.count(); ++i) {
3065 const BasicLayoutTestData item = data[i];
3066 layout->setAnchor(
3067 getItem(item.firstIndex, widgets, layout),
3068 item.firstEdge,
3069 getItem(item.secondIndex, widgets, layout),
3070 item.secondEdge,
3071 item.spacing );
3072 }
3073
3074 widget->setLayout(layout);
3075 widget->setContentsMargins(0,0,0,0);
3076
3077 widget->resize(size);
3078 QCOMPARE(widget->size(), size);
3079
3080 // QTest::qWait(500); // layouting is asynchronous..
3081
3082 // Validate
3083 for (int i = 0; i < result.count(); ++i) {
3084 const BasicLayoutTestResult item = result[i];
3085 QCOMPARE(widgets[item.index]->geometry(), item.rect);
3086 }
3087
3088 // Test mirrored mode
3089 widget->setLayoutDirection(Qt::RightToLeft);
3090 layout->activate();
3091 // Validate
3092 for (int j = 0; j < result.count(); ++j) {
3093 const BasicLayoutTestResult item = result[j];
3094 QRectF mirroredRect(item.rect);
3095 // only valid cases are mirrored
3096 if (mirroredRect.isValid()){
3097 mirroredRect.moveLeft(size.width()-item.rect.width()-item.rect.left());
3098 }
3099 QCOMPARE(widgets[item.index]->geometry(), mirroredRect);
3100 delete widgets[item.index];
3101 }
3102
3103 delete widget;
3104 }
3105 #endif //TEST_COMPLEX_CASES
3106
3107
3108 QTEST_MAIN(tst_QGraphicsAnchorLayout1)
3109 #include "tst_qgraphicsanchorlayout1.moc"
3110 //-----------------------------------------------------------------------------
3111
3112