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

source code of qtbase/tests/auto/widgets/graphicsview/qgraphicsanchorlayout1/tst_qgraphicsanchorlayout1.cpp