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 <QtTest/QtTest>
30#include <QtWidgets/qgraphicsanchorlayout.h>
31#include <private/qgraphicsanchorlayout_p.h>
32#include <QtWidgets/qgraphicswidget.h>
33#include <QtWidgets/qgraphicsproxywidget.h>
34#include <QtWidgets/qgraphicsview.h>
35#include <QtWidgets/qstylefactory.h>
36#include <QtWidgets/qproxystyle.h>
37
38
39class tst_QGraphicsAnchorLayout : public QObject {
40 Q_OBJECT
41
42public:
43 tst_QGraphicsAnchorLayout() : QObject() {
44 hasSimplification = qgetenv(varName: "QT_ANCHORLAYOUT_NO_SIMPLIFICATION").isEmpty();
45 }
46
47private:
48 bool hasSimplification;
49
50private slots:
51 void simple();
52 void simple_center();
53 void simple_semifloat();
54 void layoutDirection();
55 void diagonal();
56 void parallel();
57 void parallel2();
58 void snake();
59 void snakeOppositeDirections();
60 void fairDistribution();
61 void fairDistributionOppositeDirections();
62 void proportionalPreferred();
63 void example();
64 void setSpacing();
65 void styleDefaults();
66 void hardComplexS60();
67 void stability();
68 void delete_anchor();
69 void conflicts();
70 void sizePolicy();
71 void floatConflict();
72 void infiniteMaxSizes();
73 void simplifiableUnfeasible();
74 void simplificationVsOrder();
75 void parallelSimplificationOfCenter();
76 void simplificationVsRedundance();
77 void spacingPersistency();
78 void snakeParallelWithLayout();
79 void parallelToHalfLayout();
80 void globalSpacing();
81 void graphicsAnchorHandling();
82 void invalidHierarchyCheck();
83};
84
85class RectWidget : public QGraphicsWidget
86{
87public:
88 RectWidget(QGraphicsItem *parent = 0) : QGraphicsWidget(parent){}
89
90 void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
91 {
92 Q_UNUSED(option);
93 Q_UNUSED(widget);
94 painter->drawRoundedRect(rect: rect(), xRadius: 25, yRadius: 25, mode: Qt::RelativeSize);
95 painter->drawLine(p1: rect().topLeft(), p2: rect().bottomRight());
96 painter->drawLine(p1: rect().bottomLeft(), p2: rect().topRight());
97 }
98};
99
100static QGraphicsWidget *createItem(const QSizeF &minimum = QSizeF(100.0, 100.0),
101 const QSizeF &preferred = QSize(150.0, 100.0),
102 const QSizeF &maximum = QSizeF(200.0, 100.0),
103 const QString &name = QString())
104{
105 QGraphicsWidget *w = new RectWidget;
106 w->setMinimumSize(minimum);
107 w->setPreferredSize(preferred);
108 w->setMaximumSize(maximum);
109 w->setData(key: 0, value: name);
110 return w;
111}
112
113static void setAnchor(QGraphicsAnchorLayout *l,
114 QGraphicsLayoutItem *firstItem,
115 Qt::AnchorPoint firstEdge,
116 QGraphicsLayoutItem *secondItem,
117 Qt::AnchorPoint secondEdge,
118 qreal spacing = 0)
119{
120 QGraphicsAnchor *anchor = l->addAnchor(firstItem, firstEdge, secondItem, secondEdge);
121 anchor->setSpacing(spacing);
122}
123
124static bool checkReverseDirection(QGraphicsWidget *widget)
125{
126 QGraphicsLayout *layout = widget->layout();
127 qreal left, top, right, bottom;
128 layout->getContentsMargins(left: &left, top: &top, right: &right, bottom: &bottom);
129 widget->setLayoutDirection(Qt::LeftToRight);
130 QApplication::processEvents();
131 QMap<QGraphicsLayoutItem *, QRectF> geometries;
132 for (int i = 0; i < layout->count(); ++i) {
133 QGraphicsLayoutItem *item = layout->itemAt(i);
134 geometries.insert(key: item, value: item->geometry());
135 }
136 widget->setLayoutDirection(Qt::RightToLeft);
137 QApplication::processEvents();
138 const QRectF layoutGeometry = layout->geometry().adjusted(xp1: +right, yp1: +top, xp2: -left, yp2: -bottom);
139 for (int i = 0; i < layout->count(); ++i) {
140 QGraphicsLayoutItem *item = layout->itemAt(i);
141 const QRectF rightToLeftGeometry = item->geometry();
142 const QRectF leftToRightGeometry = geometries.value(akey: item);
143 QRectF expectedGeometry = leftToRightGeometry;
144 expectedGeometry.moveRight(pos: layoutGeometry.right() - leftToRightGeometry.left());
145 if (expectedGeometry != rightToLeftGeometry) {
146 qDebug() << "layout->geometry():" << layoutGeometry
147 << "expected:" << expectedGeometry
148 << "actual:" << rightToLeftGeometry;
149 return false;
150 }
151 }
152 return true;
153}
154
155static bool layoutHasConflict(QGraphicsAnchorLayout *l)
156{
157 return QGraphicsAnchorLayoutPrivate::get(q: l)->hasConflicts();
158}
159
160static bool usedSimplex(QGraphicsAnchorLayout *l, Qt::Orientation o)
161{
162 QGraphicsAnchorLayoutPrivate::Orientation oo = (o == Qt::Horizontal) ?
163 QGraphicsAnchorLayoutPrivate::Horizontal :
164 QGraphicsAnchorLayoutPrivate::Vertical;
165
166 return QGraphicsAnchorLayoutPrivate::get(q: l)->lastCalculationUsedSimplex[oo];
167}
168
169void tst_QGraphicsAnchorLayout::simple()
170{
171 QGraphicsWidget *w1 = createItem();
172 QGraphicsWidget *w2 = createItem();
173
174 QGraphicsAnchorLayout *l = new QGraphicsAnchorLayout;
175 l->setContentsMargins(left: 0, top: 0, right: 0, bottom: 0);
176
177 // Horizontal
178 l->addAnchor(firstItem: l, firstEdge: Qt::AnchorLeft, secondItem: w1, secondEdge: Qt::AnchorLeft);
179 l->addAnchor(firstItem: w1, firstEdge: Qt::AnchorRight, secondItem: w2, secondEdge: Qt::AnchorLeft);
180 l->addAnchor(firstItem: w2, firstEdge: Qt::AnchorRight, secondItem: l, secondEdge: Qt::AnchorRight);
181
182 // Vertical
183 l->addAnchors(firstItem: l, secondItem: w1, orientations: Qt::Vertical);
184 l->addAnchors(firstItem: l, secondItem: w2, orientations: Qt::Vertical);
185
186 QCOMPARE(l->count(), 2);
187
188 QGraphicsWidget p;
189 p.setLayout(l);
190 p.adjustSize();
191
192 if (hasSimplification) {
193 QVERIFY(!usedSimplex(l, Qt::Horizontal));
194 QVERIFY(!usedSimplex(l, Qt::Vertical));
195 }
196}
197
198void tst_QGraphicsAnchorLayout::simple_center()
199{
200 QSizeF minSize(10, 10);
201 QSizeF pref(50, 10);
202 QSizeF maxSize(100, 10);
203
204 QGraphicsWidget *a = createItem(minimum: minSize, preferred: pref, maximum: maxSize, name: "a");
205 QGraphicsWidget *b = createItem(minimum: minSize, preferred: pref, maximum: maxSize, name: "b");
206 QGraphicsWidget *c = createItem(minimum: minSize, preferred: pref, maximum: maxSize, name: "c");
207
208 QGraphicsAnchorLayout *l = new QGraphicsAnchorLayout;
209 l->setContentsMargins(left: 0, top: 0, right: 0, bottom: 0);
210 // horizontal
211 setAnchor(l, firstItem: l, firstEdge: Qt::AnchorLeft, secondItem: a, secondEdge: Qt::AnchorLeft, spacing: 0);
212 setAnchor(l, firstItem: a, firstEdge: Qt::AnchorRight, secondItem: b, secondEdge: Qt::AnchorLeft, spacing: 0);
213 setAnchor(l, firstItem: b, firstEdge: Qt::AnchorRight, secondItem: l, secondEdge: Qt::AnchorRight, spacing: 0);
214 setAnchor(l, firstItem: a, firstEdge: Qt::AnchorHorizontalCenter, secondItem: c, secondEdge: Qt::AnchorLeft, spacing: 0);
215 setAnchor(l, firstItem: c, firstEdge: Qt::AnchorRight, secondItem: b, secondEdge: Qt::AnchorHorizontalCenter, spacing: 0);
216
217 // vertical
218 setAnchor(l, firstItem: l, firstEdge: Qt::AnchorTop, secondItem: a, secondEdge: Qt::AnchorTop, spacing: 0);
219 setAnchor(l, firstItem: l, firstEdge: Qt::AnchorTop, secondItem: b, secondEdge: Qt::AnchorTop, spacing: 0);
220 setAnchor(l, firstItem: a, firstEdge: Qt::AnchorBottom, secondItem: c, secondEdge: Qt::AnchorTop, spacing: 0);
221 setAnchor(l, firstItem: b, firstEdge: Qt::AnchorBottom, secondItem: c, secondEdge: Qt::AnchorTop, spacing: 0);
222 setAnchor(l, firstItem: c, firstEdge: Qt::AnchorBottom, secondItem: l, secondEdge: Qt::AnchorBottom, spacing: 0);
223
224 QCOMPARE(l->count(), 3);
225
226 QGraphicsWidget *p = new QGraphicsWidget(0, Qt::Window);
227 p->setLayout(l);
228
229 QSizeF layoutMinimumSize = l->effectiveSizeHint(which: Qt::MinimumSize);
230 QCOMPARE(layoutMinimumSize, QSizeF(20, 20));
231
232 QSizeF layoutMaximumSize = l->effectiveSizeHint(which: Qt::MaximumSize);
233 QCOMPARE(layoutMaximumSize, QSizeF(200, 20));
234
235 if (hasSimplification) {
236 QVERIFY(usedSimplex(l, Qt::Horizontal));
237 QVERIFY(!usedSimplex(l, Qt::Vertical));
238 }
239
240 delete p;
241}
242
243void tst_QGraphicsAnchorLayout::simple_semifloat()
244{
245 // Useful for testing simplification between A_left and B_left.
246 // Unfortunately the only way to really test that now is to manually inspect the
247 // simplified graph.
248 QSizeF minSize(10, 10);
249 QSizeF pref(50, 10);
250 QSizeF maxSize(100, 10);
251
252 QGraphicsWidget *A = createItem(minimum: minSize, preferred: pref, maximum: maxSize, name: "A");
253 QGraphicsWidget *B = createItem(minimum: minSize, preferred: pref, maximum: maxSize, name: "B");
254 QGraphicsWidget *a = createItem(minimum: minSize, preferred: pref, maximum: maxSize, name: "a");
255 QGraphicsWidget *b = createItem(minimum: minSize, preferred: pref, maximum: maxSize, name: "b");
256
257 QGraphicsAnchorLayout *l = new QGraphicsAnchorLayout;
258 l->setContentsMargins(left: 0, top: 0, right: 0, bottom: 0);
259
260 // horizontal
261 setAnchor(l, firstItem: l, firstEdge: Qt::AnchorLeft, secondItem: A, secondEdge: Qt::AnchorLeft, spacing: 0);
262 setAnchor(l, firstItem: A, firstEdge: Qt::AnchorRight, secondItem: B, secondEdge: Qt::AnchorLeft, spacing: 0);
263 setAnchor(l, firstItem: B, firstEdge: Qt::AnchorRight, secondItem: l, secondEdge: Qt::AnchorRight, spacing: 0);
264
265 setAnchor(l, firstItem: A, firstEdge: Qt::AnchorLeft, secondItem: a, secondEdge: Qt::AnchorLeft, spacing: 0);
266 setAnchor(l, firstItem: B, firstEdge: Qt::AnchorLeft, secondItem: b, secondEdge: Qt::AnchorLeft, spacing: 0);
267
268 // vertical
269 setAnchor(l, firstItem: l, firstEdge: Qt::AnchorTop, secondItem: A, secondEdge: Qt::AnchorTop, spacing: 0);
270 setAnchor(l, firstItem: l, firstEdge: Qt::AnchorTop, secondItem: B, secondEdge: Qt::AnchorTop, spacing: 0);
271 setAnchor(l, firstItem: A, firstEdge: Qt::AnchorBottom, secondItem: a, secondEdge: Qt::AnchorTop, spacing: 0);
272 setAnchor(l, firstItem: B, firstEdge: Qt::AnchorBottom, secondItem: b, secondEdge: Qt::AnchorTop, spacing: 0);
273 setAnchor(l, firstItem: a, firstEdge: Qt::AnchorBottom, secondItem: l, secondEdge: Qt::AnchorBottom, spacing: 0);
274 setAnchor(l, firstItem: b, firstEdge: Qt::AnchorBottom, secondItem: l, secondEdge: Qt::AnchorBottom, spacing: 0);
275
276 QCOMPARE(l->count(), 4);
277
278 QGraphicsWidget *p = new QGraphicsWidget(0, Qt::Window);
279 p->setLayout(l);
280
281 QSizeF layoutMinimumSize = l->effectiveSizeHint(which: Qt::MinimumSize);
282 QCOMPARE(layoutMinimumSize, QSizeF(20, 20));
283
284 QCOMPARE(l->effectiveSizeHint(Qt::PreferredSize), QSizeF(100, 20));
285
286 QSizeF layoutMaximumSize = l->effectiveSizeHint(which: Qt::MaximumSize);
287 QCOMPARE(layoutMaximumSize, QSizeF(200, 20));
288
289 delete p;
290}
291
292void tst_QGraphicsAnchorLayout::layoutDirection()
293{
294 QSizeF minSize(10, 10);
295 QSizeF pref(50, 10);
296 QSizeF maxSize(100, 10);
297
298 QGraphicsWidget *a = createItem(minimum: minSize, preferred: pref, maximum: maxSize, name: "a");
299 QGraphicsWidget *b = createItem(minimum: minSize, preferred: pref, maximum: maxSize, name: "b");
300 QGraphicsWidget *c = createItem(minimum: minSize, preferred: pref, maximum: QSizeF(100, 20), name: "c");
301
302 a->setSizePolicy(hPolicy: QSizePolicy::Preferred, vPolicy: QSizePolicy::Preferred);
303 b->setSizePolicy(hPolicy: QSizePolicy::Preferred, vPolicy: QSizePolicy::Preferred);
304 c->setSizePolicy(hPolicy: QSizePolicy::Preferred, vPolicy: QSizePolicy::Preferred);
305
306
307 QGraphicsAnchorLayout *l = new QGraphicsAnchorLayout;
308 l->setContentsMargins(left: 0, top: 5, right: 10, bottom: 15);
309 // horizontal
310 setAnchor(l, firstItem: l, firstEdge: Qt::AnchorLeft, secondItem: a, secondEdge: Qt::AnchorLeft, spacing: 0);
311 setAnchor(l, firstItem: a, firstEdge: Qt::AnchorRight, secondItem: b, secondEdge: Qt::AnchorLeft, spacing: 0);
312 setAnchor(l, firstItem: b, firstEdge: Qt::AnchorRight, secondItem: l, secondEdge: Qt::AnchorRight, spacing: 0);
313 setAnchor(l, firstItem: a, firstEdge: Qt::AnchorHorizontalCenter, secondItem: c, secondEdge: Qt::AnchorLeft, spacing: 0);
314 setAnchor(l, firstItem: c, firstEdge: Qt::AnchorRight, secondItem: b, secondEdge: Qt::AnchorHorizontalCenter, spacing: 0);
315
316 // vertical
317 setAnchor(l, firstItem: l, firstEdge: Qt::AnchorTop, secondItem: a, secondEdge: Qt::AnchorTop, spacing: 0);
318 setAnchor(l, firstItem: l, firstEdge: Qt::AnchorTop, secondItem: b, secondEdge: Qt::AnchorTop, spacing: 0);
319 setAnchor(l, firstItem: a, firstEdge: Qt::AnchorBottom, secondItem: c, secondEdge: Qt::AnchorTop, spacing: 0);
320 setAnchor(l, firstItem: b, firstEdge: Qt::AnchorBottom, secondItem: c, secondEdge: Qt::AnchorTop, spacing: 0);
321 setAnchor(l, firstItem: c, firstEdge: Qt::AnchorBottom, secondItem: l, secondEdge: Qt::AnchorBottom, spacing: 0);
322
323 QCOMPARE(l->count(), 3);
324
325 QGraphicsWidget *p = new QGraphicsWidget(0, Qt::Window);
326 p->setLayoutDirection(Qt::LeftToRight);
327 p->setLayout(l);
328
329 QGraphicsScene scene;
330 QGraphicsView *view = new QGraphicsView(&scene);
331 scene.addItem(item: p);
332 p->show();
333 view->show();
334
335 QVERIFY(p->layout());
336 QCOMPARE(checkReverseDirection(p), true);
337
338 if (hasSimplification) {
339 QVERIFY(usedSimplex(l, Qt::Horizontal));
340 QVERIFY(!usedSimplex(l, Qt::Vertical));
341 }
342
343 delete p;
344 delete view;
345}
346
347void tst_QGraphicsAnchorLayout::diagonal()
348{
349 QSizeF minSize(10, 100);
350 QSizeF pref(70, 100);
351 QSizeF maxSize(100, 100);
352
353 QGraphicsWidget *a = createItem(minimum: minSize, preferred: pref, maximum: maxSize, name: "A");
354 QGraphicsWidget *b = createItem(minimum: minSize, preferred: pref, maximum: maxSize, name: "B");
355 QGraphicsWidget *c = createItem(minimum: minSize, preferred: pref, maximum: maxSize, name: "C");
356 QGraphicsWidget *d = createItem(minimum: minSize, preferred: pref, maximum: maxSize, name: "D");
357 QGraphicsWidget *e = createItem(minimum: minSize, preferred: pref, maximum: maxSize, name: "E");
358
359 QGraphicsAnchorLayout *l = new QGraphicsAnchorLayout;
360 l->setContentsMargins(left: 0, top: 0, right: 0, bottom: 0);
361 l->setSpacing(0);
362
363 // vertical
364 l->addAnchor(firstItem: a, firstEdge: Qt::AnchorTop, secondItem: l, secondEdge: Qt::AnchorTop);
365 l->addAnchor(firstItem: b, firstEdge: Qt::AnchorTop, secondItem: l, secondEdge: Qt::AnchorTop);
366 l->addAnchor(firstItem: c, firstEdge: Qt::AnchorTop, secondItem: a, secondEdge: Qt::AnchorBottom);
367 l->addAnchor(firstItem: c, firstEdge: Qt::AnchorTop, secondItem: b, secondEdge: Qt::AnchorBottom);
368 l->addAnchor(firstItem: c, firstEdge: Qt::AnchorBottom, secondItem: d, secondEdge: Qt::AnchorTop);
369 l->addAnchor(firstItem: c, firstEdge: Qt::AnchorBottom, secondItem: e, secondEdge: Qt::AnchorTop);
370 l->addAnchor(firstItem: d, firstEdge: Qt::AnchorBottom, secondItem: l, secondEdge: Qt::AnchorBottom);
371 l->addAnchor(firstItem: e, firstEdge: Qt::AnchorBottom, secondItem: l, secondEdge: Qt::AnchorBottom);
372
373 // horizontal
374 l->addAnchor(firstItem: l, firstEdge: Qt::AnchorLeft, secondItem: a, secondEdge: Qt::AnchorLeft);
375 l->addAnchor(firstItem: l, firstEdge: Qt::AnchorLeft, secondItem: d, secondEdge: Qt::AnchorLeft);
376 l->addAnchor(firstItem: a, firstEdge: Qt::AnchorRight, secondItem: b, secondEdge: Qt::AnchorLeft);
377
378 l->addAnchor(firstItem: a, firstEdge: Qt::AnchorRight, secondItem: c, secondEdge: Qt::AnchorLeft);
379 l->addAnchor(firstItem: c, firstEdge: Qt::AnchorRight, secondItem: e, secondEdge: Qt::AnchorLeft);
380
381 l->addAnchor(firstItem: b, firstEdge: Qt::AnchorRight, secondItem: l, secondEdge: Qt::AnchorRight);
382 l->addAnchor(firstItem: e, firstEdge: Qt::AnchorRight, secondItem: l, secondEdge: Qt::AnchorRight);
383 l->addAnchor(firstItem: d, firstEdge: Qt::AnchorRight, secondItem: e, secondEdge: Qt::AnchorLeft);
384
385 QCOMPARE(l->count(), 5);
386
387 QGraphicsWidget p;
388 p.setLayout(l);
389
390 QSizeF layoutMinimumSize = l->effectiveSizeHint(which: Qt::MinimumSize);
391 QSizeF layoutMaximumSize = l->effectiveSizeHint(which: Qt::MaximumSize);
392 QSizeF layoutPreferredSize = l->effectiveSizeHint(which: Qt::PreferredSize);
393
394 QCOMPARE(layoutMinimumSize, QSizeF(30.0, 300.0));
395 QCOMPARE(layoutPreferredSize, QSizeF(170.0, 300.0));
396 QCOMPARE(layoutMaximumSize, QSizeF(190.0, 300.0));
397
398 p.resize(size: layoutMinimumSize);
399 QCOMPARE(a->geometry(), QRectF(0.0, 0.0, 10.0, 100.0));
400 QCOMPARE(b->geometry(), QRectF(10.0, 0.0, 20.0, 100.0));
401 QCOMPARE(c->geometry(), QRectF(10.0, 100.0, 10.0, 100.0));
402 QCOMPARE(d->geometry(), QRectF(0.0, 200.0, 20.0, 100.0));
403 QCOMPARE(e->geometry(), QRectF(20.0, 200.0, 10.0, 100.0));
404 QCOMPARE(p.size(), layoutMinimumSize);
405
406 p.resize(size: layoutPreferredSize);
407 QCOMPARE(a->geometry(), QRectF(0.0, 0.0, 70.0, 100.0));
408 QCOMPARE(b->geometry(), QRectF(70.0, 0.0, 100.0, 100.0));
409 QCOMPARE(c->geometry(), QRectF(70.0, 100.0, 30.0, 100.0));
410 QCOMPARE(d->geometry(), QRectF(0.0, 200.0, 100.0, 100.0));
411 QCOMPARE(e->geometry(), QRectF(100.0, 200.0, 70.0, 100.0));
412 QCOMPARE(p.size(), layoutPreferredSize);
413
414 p.resize(size: layoutMaximumSize);
415 QCOMPARE(a->geometry(), QRectF(0.0, 0.0, 90.0, 100.0));
416 QCOMPARE(b->geometry(), QRectF(90.0, 0.0, 100.0, 100.0));
417 QCOMPARE(c->geometry(), QRectF(90.0, 100.0, 10.0, 100.0));
418 QCOMPARE(d->geometry(), QRectF(0.0, 200.0, 100.0, 100.0));
419 QCOMPARE(e->geometry(), QRectF(100.0, 200.0, 90.0, 100.0));
420 QCOMPARE(p.size(), layoutMaximumSize);
421
422 QSizeF testA(175.0, 300.0);
423 p.resize(size: testA);
424 QCOMPARE(a->geometry(), QRectF(0.0, 0.0, 75.0, 100.0));
425 QCOMPARE(b->geometry(), QRectF(75.0, 0.0, 100.0, 100.0));
426 QCOMPARE(c->geometry(), QRectF(75.0, 100.0, 25.0, 100.0));
427 QCOMPARE(d->geometry(), QRectF(0.0, 200.0, 100.0, 100.0));
428 QCOMPARE(e->geometry(), QRectF(100.0, 200.0, 75.0, 100.0));
429 QCOMPARE(p.size(), testA);
430
431 if (hasSimplification) {
432 QVERIFY(usedSimplex(l, Qt::Horizontal));
433 QVERIFY(!usedSimplex(l, Qt::Vertical));
434 }
435
436 QVERIFY(p.layout());
437 QCOMPARE(checkReverseDirection(&p), true);
438
439 c->setMinimumWidth(300);
440 QVERIFY(layoutHasConflict(l));
441}
442
443void tst_QGraphicsAnchorLayout::parallel()
444{
445 QGraphicsWidget *a = createItem(minimum: QSizeF(100, 100),
446 preferred: QSizeF(150, 100),
447 maximum: QSizeF(200, 100), name: "A");
448
449 QGraphicsWidget *b = createItem(minimum: QSizeF(100, 100),
450 preferred: QSizeF(150, 100),
451 maximum: QSizeF(300, 100), name: "B");
452
453 QGraphicsWidget *c = createItem(minimum: QSizeF(100, 100),
454 preferred: QSizeF(200, 100),
455 maximum: QSizeF(350, 100), name: "C");
456
457 QGraphicsWidget *d = createItem(minimum: QSizeF(100, 100),
458 preferred: QSizeF(170, 100),
459 maximum: QSizeF(200, 100), name: "D");
460
461 QGraphicsWidget *e = createItem(minimum: QSizeF(150, 100),
462 preferred: QSizeF(150, 100),
463 maximum: QSizeF(200, 100), name: "E");
464
465 QGraphicsWidget *f = createItem(minimum: QSizeF(100, 100),
466 preferred: QSizeF(150, 100),
467 maximum: QSizeF(200, 100), name: "F");
468
469 QGraphicsAnchorLayout *l = new QGraphicsAnchorLayout;
470 l->setContentsMargins(left: 0, top: 0, right: 0, bottom: 0);
471 l->setSpacing(0);
472
473 l->addAnchor(firstItem: l, firstEdge: Qt::AnchorTop, secondItem: a, secondEdge: Qt::AnchorTop);
474 l->addAnchor(firstItem: a, firstEdge: Qt::AnchorBottom, secondItem: b, secondEdge: Qt::AnchorTop);
475 l->addAnchor(firstItem: b, firstEdge: Qt::AnchorBottom, secondItem: c, secondEdge: Qt::AnchorTop);
476 l->addAnchor(firstItem: c, firstEdge: Qt::AnchorBottom, secondItem: d, secondEdge: Qt::AnchorTop);
477 l->addAnchor(firstItem: d, firstEdge: Qt::AnchorBottom, secondItem: e, secondEdge: Qt::AnchorTop);
478 l->addAnchor(firstItem: e, firstEdge: Qt::AnchorBottom, secondItem: f, secondEdge: Qt::AnchorTop);
479 l->addAnchor(firstItem: f, firstEdge: Qt::AnchorBottom, secondItem: l, secondEdge: Qt::AnchorBottom);
480
481 l->addAnchor(firstItem: l, firstEdge: Qt::AnchorLeft, secondItem: a, secondEdge: Qt::AnchorLeft);
482 l->addAnchor(firstItem: a, firstEdge: Qt::AnchorRight, secondItem: b, secondEdge: Qt::AnchorLeft);
483 l->addAnchor(firstItem: a, firstEdge: Qt::AnchorRight, secondItem: c, secondEdge: Qt::AnchorLeft);
484 l->addAnchor(firstItem: b, firstEdge: Qt::AnchorRight, secondItem: d, secondEdge: Qt::AnchorLeft);
485 l->addAnchor(firstItem: b, firstEdge: Qt::AnchorRight, secondItem: e, secondEdge: Qt::AnchorLeft);
486 l->addAnchor(firstItem: c, firstEdge: Qt::AnchorRight, secondItem: f, secondEdge: Qt::AnchorLeft);
487 l->addAnchor(firstItem: d, firstEdge: Qt::AnchorRight, secondItem: f, secondEdge: Qt::AnchorLeft);
488 l->addAnchor(firstItem: e, firstEdge: Qt::AnchorRight, secondItem: f, secondEdge: Qt::AnchorLeft);
489 l->addAnchor(firstItem: f, firstEdge: Qt::AnchorRight, secondItem: l, secondEdge: Qt::AnchorRight);
490
491 QCOMPARE(l->count(), 6);
492
493 QGraphicsWidget p;
494 p.setLayout(l);
495
496 QSizeF layoutMinimumSize = l->effectiveSizeHint(which: Qt::MinimumSize);
497 QSizeF layoutPreferredSize = l->effectiveSizeHint(which: Qt::PreferredSize);
498 QSizeF layoutMaximumSize = l->effectiveSizeHint(which: Qt::MaximumSize);
499
500 QCOMPARE(layoutMinimumSize, QSizeF(450, 600));
501 QCOMPARE(layoutPreferredSize, QSizeF(620, 600));
502 QCOMPARE(layoutMaximumSize, QSizeF(750, 600));
503
504 p.resize(size: layoutMinimumSize);
505 QCOMPARE(a->geometry(), QRectF(0, 0, 100, 100));
506 QCOMPARE(b->geometry(), QRectF(100, 100, 100, 100));
507 QCOMPARE(c->geometry(), QRectF(100, 200, 250, 100));
508 QCOMPARE(d->geometry(), QRectF(200, 300, 150, 100));
509 QCOMPARE(e->geometry(), QRectF(200, 400, 150, 100));
510 QCOMPARE(f->geometry(), QRectF(350, 500, 100, 100));
511 QCOMPARE(p.size(), layoutMinimumSize);
512
513 if (!hasSimplification)
514 return;
515
516 p.resize(size: layoutPreferredSize);
517 QCOMPARE(a->geometry(), QRectF(0, 0, 150, 100));
518 QCOMPARE(b->geometry(), QRectF(150, 100, 150, 100));
519 QCOMPARE(c->geometry(), QRectF(150, 200, 320, 100));
520 QCOMPARE(d->geometry(), QRectF(300, 300, 170, 100));
521 QCOMPARE(e->geometry(), QRectF(300, 400, 170, 100));
522 QCOMPARE(f->geometry(), QRectF(470, 500, 150, 100));
523 QCOMPARE(p.size(), layoutPreferredSize);
524
525 // Maximum size depends on simplification / fair distribution
526 // Without that, test may or may not pass, depending on the
527 // solution found by the solver at runtime.
528 p.resize(size: layoutMaximumSize);
529 QCOMPARE(a->geometry(), QRectF(0, 0, 200, 100));
530 QCOMPARE(b->geometry(), QRectF(200, 100, 175, 100));
531 QCOMPARE(c->geometry(), QRectF(200, 200, 350, 100));
532 QCOMPARE(d->geometry(), QRectF(375, 300, 175, 100));
533 QCOMPARE(e->geometry(), QRectF(375, 400, 175, 100));
534 QCOMPARE(f->geometry(), QRectF(550, 500, 200, 100));
535 QCOMPARE(p.size(), layoutMaximumSize);
536
537 QVERIFY(!usedSimplex(l, Qt::Horizontal));
538 QVERIFY(!usedSimplex(l, Qt::Vertical));
539}
540
541void tst_QGraphicsAnchorLayout::parallel2()
542{
543 QGraphicsWidget *a = createItem(minimum: QSizeF(70.0, 100.0),
544 preferred: QSizeF(100.0, 100.0),
545 maximum: QSizeF(200.0, 100.0), name: "A");
546
547 QGraphicsWidget *b = createItem(minimum: QSizeF(100.0, 100.0),
548 preferred: QSizeF(150.0, 100.0),
549 maximum: QSizeF(190.0, 100.0), name: "B");
550
551 QGraphicsAnchorLayout *l = new QGraphicsAnchorLayout;
552 l->setContentsMargins(left: 0, top: 0, right: 0, bottom: 0);
553 l->setSpacing(0);
554
555 l->addAnchor(firstItem: l, firstEdge: Qt::AnchorTop, secondItem: a, secondEdge: Qt::AnchorTop);
556 l->addAnchor(firstItem: a, firstEdge: Qt::AnchorBottom, secondItem: b, secondEdge: Qt::AnchorTop);
557 l->addAnchor(firstItem: b, firstEdge: Qt::AnchorBottom, secondItem: l, secondEdge: Qt::AnchorBottom);
558
559 l->addAnchors(firstItem: l, secondItem: a, orientations: Qt::Horizontal);
560 l->addAnchor(firstItem: l, firstEdge: Qt::AnchorLeft, secondItem: b, secondEdge: Qt::AnchorLeft);
561 l->addAnchor(firstItem: b, firstEdge: Qt::AnchorRight, secondItem: a, secondEdge: Qt::AnchorRight);
562
563 QCOMPARE(l->count(), 2);
564
565 QGraphicsWidget p;
566 p.setLayout(l);
567
568 QSizeF layoutMinimumSize = l->effectiveSizeHint(which: Qt::MinimumSize);
569 QSizeF layoutPreferredSize = l->effectiveSizeHint(which: Qt::PreferredSize);
570 QSizeF layoutMaximumSize = l->effectiveSizeHint(which: Qt::MaximumSize);
571
572 QCOMPARE(layoutMinimumSize, QSizeF(100.0, 200.0));
573 QCOMPARE(layoutPreferredSize, QSizeF(150.0, 200.0));
574 QCOMPARE(layoutMaximumSize, QSizeF(190.0, 200.0));
575
576 p.resize(size: layoutMinimumSize);
577 QCOMPARE(p.size(), layoutMinimumSize);
578
579 p.resize(size: layoutPreferredSize);
580 QCOMPARE(p.size(), layoutPreferredSize);
581
582 p.resize(size: layoutMaximumSize);
583 QCOMPARE(p.size(), layoutMaximumSize);
584
585 if (hasSimplification) {
586 QVERIFY(!usedSimplex(l, Qt::Horizontal));
587 QVERIFY(!usedSimplex(l, Qt::Vertical));
588 }
589}
590
591void tst_QGraphicsAnchorLayout::snake()
592{
593 QGraphicsWidget *a = createItem(minimum: QSizeF(50.0, 100.0),
594 preferred: QSizeF(70.0, 100.0),
595 maximum: QSizeF(100.0, 100.0), name: "A");
596
597 QGraphicsWidget *b = createItem(minimum: QSizeF(10.0, 100.0),
598 preferred: QSizeF(20.0, 100.0),
599 maximum: QSizeF(40.0, 100.0), name: "B");
600
601 QGraphicsWidget *c = createItem(minimum: QSizeF(50.0, 100.0),
602 preferred: QSizeF(70.0, 100.0),
603 maximum: QSizeF(100.0, 100.0), name: "C");
604
605 QGraphicsAnchorLayout *l = new QGraphicsAnchorLayout;
606 l->setContentsMargins(left: 0, top: 0, right: 0, bottom: 0);
607 l->setSpacing(0);
608
609 l->addAnchor(firstItem: l, firstEdge: Qt::AnchorTop, secondItem: a, secondEdge: Qt::AnchorTop);
610 l->addAnchor(firstItem: a, firstEdge: Qt::AnchorBottom, secondItem: b, secondEdge: Qt::AnchorTop);
611 l->addAnchor(firstItem: b, firstEdge: Qt::AnchorBottom, secondItem: c, secondEdge: Qt::AnchorTop);
612 l->addAnchor(firstItem: c, firstEdge: Qt::AnchorBottom, secondItem: l, secondEdge: Qt::AnchorBottom);
613
614 l->addAnchor(firstItem: l, firstEdge: Qt::AnchorLeft, secondItem: a, secondEdge: Qt::AnchorLeft);
615 l->addAnchor(firstItem: a, firstEdge: Qt::AnchorRight, secondItem: b, secondEdge: Qt::AnchorRight);
616 l->addAnchor(firstItem: b, firstEdge: Qt::AnchorLeft, secondItem: c, secondEdge: Qt::AnchorLeft);
617 l->addAnchor(firstItem: c, firstEdge: Qt::AnchorRight, secondItem: l, secondEdge: Qt::AnchorRight);
618
619 QCOMPARE(l->count(), 3);
620
621 QGraphicsWidget p;
622 p.setLayout(l);
623
624 QSizeF layoutMinimumSize = l->effectiveSizeHint(which: Qt::MinimumSize);
625 QSizeF layoutMaximumSize = l->effectiveSizeHint(which: Qt::MaximumSize);
626 QSizeF layoutPreferredSize = l->effectiveSizeHint(which: Qt::PreferredSize);
627
628 QCOMPARE(layoutMinimumSize, QSizeF(60.0, 300.0));
629 QCOMPARE(layoutPreferredSize, QSizeF(120.0, 300.0));
630 QCOMPARE(layoutMaximumSize, QSizeF(190.0, 300.0));
631
632 p.resize(size: layoutMinimumSize);
633 QCOMPARE(a->geometry(), QRectF(0.0, 0.0, 50.0, 100.0));
634 QCOMPARE(b->geometry(), QRectF(10.0, 100.0, 40.0, 100.0));
635 QCOMPARE(c->geometry(), QRectF(10.0, 200.0, 50.0, 100.0));
636 QCOMPARE(p.size(), layoutMinimumSize);
637
638 p.resize(size: layoutPreferredSize);
639 QCOMPARE(a->geometry(), QRectF(0.0, 0.0, 70.0, 100.0));
640 QCOMPARE(b->geometry(), QRectF(50.0, 100.0, 20.0, 100.0));
641 QCOMPARE(c->geometry(), QRectF(50.0, 200.0, 70.0, 100.0));
642 QCOMPARE(p.size(), layoutPreferredSize);
643
644 p.resize(size: layoutMaximumSize);
645 QCOMPARE(a->geometry(), QRectF(0.0, 0.0, 100.0, 100.0));
646 QCOMPARE(b->geometry(), QRectF(90.0, 100.0, 10.0, 100.0));
647 QCOMPARE(c->geometry(), QRectF(90.0, 200.0, 100.0, 100.0));
648 QCOMPARE(p.size(), layoutMaximumSize);
649
650 QVERIFY(!layoutHasConflict(l));
651
652 // Test QSizePolicy::ExpandFlag, it shouldn't change the extreme
653 // points of the layout...
654 b->setSizePolicy(hPolicy: QSizePolicy::Expanding, vPolicy: QSizePolicy::Preferred);
655
656 QSizeF newLayoutMinimumSize = l->effectiveSizeHint(which: Qt::MinimumSize);
657 QSizeF newLayoutMaximumSize = l->effectiveSizeHint(which: Qt::MaximumSize);
658 QSizeF newLayoutPreferredSize = l->effectiveSizeHint(which: Qt::PreferredSize);
659
660 QCOMPARE(layoutMinimumSize, newLayoutMinimumSize);
661 QCOMPARE(layoutMaximumSize, newLayoutMaximumSize);
662 QCOMPARE(layoutPreferredSize, newLayoutPreferredSize);
663}
664
665void tst_QGraphicsAnchorLayout::snakeOppositeDirections()
666{
667 QGraphicsWidget *a = createItem(minimum: QSizeF(50.0, 100.0),
668 preferred: QSizeF(70.0, 100.0),
669 maximum: QSizeF(100.0, 100.0), name: "A");
670
671 QGraphicsWidget *b = createItem(minimum: QSizeF(10.0, 100.0),
672 preferred: QSizeF(20.0, 100.0),
673 maximum: QSizeF(40.0, 100.0), name: "B");
674
675 QGraphicsWidget *c = createItem(minimum: QSizeF(50.0, 100.0),
676 preferred: QSizeF(70.0, 100.0),
677 maximum: QSizeF(100.0, 100.0), name: "C");
678
679 QGraphicsAnchorLayout *l = new QGraphicsAnchorLayout;
680 l->setContentsMargins(left: 0, top: 0, right: 0, bottom: 0);
681 l->setSpacing(0);
682
683 l->addAnchor(firstItem: l, firstEdge: Qt::AnchorTop, secondItem: a, secondEdge: Qt::AnchorTop);
684 l->addAnchor(firstItem: a, firstEdge: Qt::AnchorBottom, secondItem: b, secondEdge: Qt::AnchorTop);
685 l->addAnchor(firstItem: b, firstEdge: Qt::AnchorBottom, secondItem: c, secondEdge: Qt::AnchorTop);
686 l->addAnchor(firstItem: c, firstEdge: Qt::AnchorBottom, secondItem: l, secondEdge: Qt::AnchorBottom);
687
688 l->addAnchor(firstItem: l, firstEdge: Qt::AnchorLeft, secondItem: a, secondEdge: Qt::AnchorLeft);
689
690 // Both a and c are 'pointing' to b
691 l->addAnchor(firstItem: a, firstEdge: Qt::AnchorRight, secondItem: b, secondEdge: Qt::AnchorRight);
692 l->addAnchor(firstItem: c, firstEdge: Qt::AnchorLeft, secondItem: b, secondEdge: Qt::AnchorLeft);
693
694 l->addAnchor(firstItem: c, firstEdge: Qt::AnchorRight, secondItem: l, secondEdge: Qt::AnchorRight);
695
696 QCOMPARE(l->count(), 3);
697
698 QGraphicsWidget p;
699 p.setLayout(l);
700
701 QSizeF layoutMinimumSize = l->effectiveSizeHint(which: Qt::MinimumSize);
702 QSizeF layoutMaximumSize = l->effectiveSizeHint(which: Qt::MaximumSize);
703 QSizeF layoutPreferredSize = l->effectiveSizeHint(which: Qt::PreferredSize);
704
705 QCOMPARE(layoutMinimumSize, QSizeF(60.0, 300.0));
706 QCOMPARE(layoutPreferredSize, QSizeF(120.0, 300.0));
707 QCOMPARE(layoutMaximumSize, QSizeF(190.0, 300.0));
708
709 p.resize(size: layoutMinimumSize);
710 QCOMPARE(a->geometry(), QRectF(0.0, 0.0, 50.0, 100.0));
711 QCOMPARE(b->geometry(), QRectF(10.0, 100.0, 40.0, 100.0));
712 QCOMPARE(c->geometry(), QRectF(10.0, 200.0, 50.0, 100.0));
713 QCOMPARE(p.size(), layoutMinimumSize);
714
715 p.resize(size: layoutPreferredSize);
716 QCOMPARE(a->geometry(), QRectF(0.0, 0.0, 70.0, 100.0));
717 QCOMPARE(b->geometry(), QRectF(50.0, 100.0, 20.0, 100.0));
718 QCOMPARE(c->geometry(), QRectF(50.0, 200.0, 70.0, 100.0));
719 QCOMPARE(p.size(), layoutPreferredSize);
720
721 p.resize(size: layoutMaximumSize);
722 QCOMPARE(a->geometry(), QRectF(0.0, 0.0, 100.0, 100.0));
723 QCOMPARE(b->geometry(), QRectF(90.0, 100.0, 10.0, 100.0));
724 QCOMPARE(c->geometry(), QRectF(90.0, 200.0, 100.0, 100.0));
725 QCOMPARE(p.size(), layoutMaximumSize);
726
727 QVERIFY(p.layout());
728 QCOMPARE(checkReverseDirection(&p), true);
729}
730
731void tst_QGraphicsAnchorLayout::fairDistribution()
732{
733 QGraphicsWidget *a = createItem(minimum: QSizeF(10.0, 100.0),
734 preferred: QSizeF(50.0, 100.0),
735 maximum: QSizeF(100.0, 100.0), name: "A");
736
737 QGraphicsWidget *b = createItem(minimum: QSizeF(10.0, 100.0),
738 preferred: QSizeF(50.0, 100.0),
739 maximum: QSizeF(100.0, 100.0), name: "B");
740
741 QGraphicsWidget *c = createItem(minimum: QSizeF(10.0, 100.0),
742 preferred: QSizeF(50.0, 100.0),
743 maximum: QSizeF(100.0, 100.0), name: "C");
744
745 QGraphicsWidget *d = createItem(minimum: QSizeF(60.0, 100.0),
746 preferred: QSizeF(165.0, 100.0),
747 maximum: QSizeF(600.0, 100.0), name: "D");
748
749
750 QGraphicsAnchorLayout *l = new QGraphicsAnchorLayout;
751 l->setContentsMargins(left: 0, top: 0, right: 0, bottom: 0);
752 l->setSpacing(0);
753
754 l->addAnchor(firstItem: l, firstEdge: Qt::AnchorTop, secondItem: a, secondEdge: Qt::AnchorTop);
755 l->addAnchor(firstItem: a, firstEdge: Qt::AnchorBottom, secondItem: b, secondEdge: Qt::AnchorTop);
756 l->addAnchor(firstItem: b, firstEdge: Qt::AnchorBottom, secondItem: c, secondEdge: Qt::AnchorTop);
757 l->addAnchor(firstItem: c, firstEdge: Qt::AnchorBottom, secondItem: d, secondEdge: Qt::AnchorTop);
758 l->addAnchor(firstItem: d, firstEdge: Qt::AnchorBottom, secondItem: l, secondEdge: Qt::AnchorBottom);
759
760 l->addAnchor(firstItem: l, firstEdge: Qt::AnchorLeft, secondItem: a, secondEdge: Qt::AnchorLeft);
761 l->addAnchor(firstItem: a, firstEdge: Qt::AnchorRight, secondItem: b, secondEdge: Qt::AnchorLeft);
762 l->addAnchor(firstItem: b, firstEdge: Qt::AnchorRight, secondItem: c, secondEdge: Qt::AnchorLeft);
763 l->addAnchor(firstItem: c, firstEdge: Qt::AnchorRight, secondItem: l, secondEdge: Qt::AnchorRight);
764 l->addAnchor(firstItem: l, firstEdge: Qt::AnchorLeft, secondItem: d, secondEdge: Qt::AnchorLeft);
765 l->addAnchor(firstItem: d, firstEdge: Qt::AnchorRight, secondItem: l, secondEdge: Qt::AnchorRight);
766
767 QCOMPARE(l->count(), 4);
768
769 QGraphicsWidget p;
770 p.setLayout(l);
771
772 QSizeF layoutMinimumSize = l->effectiveSizeHint(which: Qt::MinimumSize);
773 QSizeF layoutMaximumSize = l->effectiveSizeHint(which: Qt::MaximumSize);
774 QSizeF layoutPreferredSize = l->effectiveSizeHint(which: Qt::PreferredSize);
775
776 QCOMPARE(layoutMinimumSize, QSizeF(60.0, 400.0));
777 QCOMPARE(layoutPreferredSize, QSizeF(165.0, 400.0));
778 QCOMPARE(layoutMaximumSize, QSizeF(300.0, 400.0));
779
780 p.resize(size: layoutMinimumSize);
781 if (!hasSimplification)
782 QEXPECT_FAIL("", "Without simplification there is no fair distribution.", Abort);
783 QCOMPARE(a->geometry(), QRectF(0.0, 0.0, 20.0, 100.0));
784 QCOMPARE(b->geometry(), QRectF(20.0, 100.0, 20.0, 100.0));
785 QCOMPARE(c->geometry(), QRectF(40.0, 200.0, 20.0, 100.0));
786 QCOMPARE(d->geometry(), QRectF(0.0, 300.0, 60.0, 100.0));
787 QCOMPARE(p.size(), layoutMinimumSize);
788
789 p.resize(size: layoutPreferredSize);
790 QCOMPARE(a->geometry(), QRectF(0.0, 0.0, 55.0, 100.0));
791 QCOMPARE(b->geometry(), QRectF(55.0, 100.0, 55.0, 100.0));
792 QCOMPARE(c->geometry(), QRectF(110.0, 200.0, 55.0, 100.0));
793 QCOMPARE(d->geometry(), QRectF(0.0, 300.0, 165.0, 100.0));
794 QCOMPARE(p.size(), layoutPreferredSize);
795
796 p.resize(size: layoutMaximumSize);
797 QCOMPARE(a->geometry(), QRectF(0.0, 0.0, 100.0, 100.0));
798 QCOMPARE(b->geometry(), QRectF(100.0, 100.0, 100.0, 100.0));
799 QCOMPARE(c->geometry(), QRectF(200.0, 200.0, 100.0, 100.0));
800 QCOMPARE(d->geometry(), QRectF(0.0, 300.0, 300.0, 100.0));
801 QCOMPARE(p.size(), layoutMaximumSize);
802
803 if (hasSimplification) {
804 QVERIFY(!usedSimplex(l, Qt::Horizontal));
805 QVERIFY(!usedSimplex(l, Qt::Vertical));
806 }
807}
808
809void tst_QGraphicsAnchorLayout::fairDistributionOppositeDirections()
810{
811 QGraphicsWidget *a = createItem(minimum: QSizeF(10.0, 100.0),
812 preferred: QSizeF(50.0, 100.0),
813 maximum: QSizeF(100.0, 100.0), name: "A");
814
815 QGraphicsWidget *b = createItem(minimum: QSizeF(10.0, 100.0),
816 preferred: QSizeF(50.0, 100.0),
817 maximum: QSizeF(100.0, 100.0), name: "B");
818
819 QGraphicsWidget *c = createItem(minimum: QSizeF(10.0, 100.0),
820 preferred: QSizeF(50.0, 100.0),
821 maximum: QSizeF(100.0, 100.0), name: "C");
822
823 QGraphicsWidget *d = createItem(minimum: QSizeF(10.0, 100.0),
824 preferred: QSizeF(50.0, 100.0),
825 maximum: QSizeF(100.0, 100.0), name: "D");
826
827 QGraphicsWidget *e = createItem(minimum: QSizeF(60.0, 100.0),
828 preferred: QSizeF(220.0, 100.0),
829 maximum: QSizeF(600.0, 100.0), name: "E");
830
831
832 QGraphicsAnchorLayout *l = new QGraphicsAnchorLayout;
833 l->setContentsMargins(left: 0, top: 0, right: 0, bottom: 0);
834 l->setSpacing(0);
835
836 l->addAnchor(firstItem: l, firstEdge: Qt::AnchorTop, secondItem: a, secondEdge: Qt::AnchorTop);
837 l->addAnchor(firstItem: a, firstEdge: Qt::AnchorBottom, secondItem: b, secondEdge: Qt::AnchorTop);
838 l->addAnchor(firstItem: b, firstEdge: Qt::AnchorBottom, secondItem: c, secondEdge: Qt::AnchorTop);
839 l->addAnchor(firstItem: c, firstEdge: Qt::AnchorBottom, secondItem: d, secondEdge: Qt::AnchorTop);
840 l->addAnchor(firstItem: d, firstEdge: Qt::AnchorBottom, secondItem: e, secondEdge: Qt::AnchorTop);
841 l->addAnchor(firstItem: e, firstEdge: Qt::AnchorBottom, secondItem: l, secondEdge: Qt::AnchorBottom);
842
843 l->addAnchor(firstItem: a, firstEdge: Qt::AnchorLeft, secondItem: l, secondEdge: Qt::AnchorLeft);
844 l->addAnchor(firstItem: b, firstEdge: Qt::AnchorLeft, secondItem: a, secondEdge: Qt::AnchorRight);
845 l->addAnchor(firstItem: c, firstEdge: Qt::AnchorLeft, secondItem: b, secondEdge: Qt::AnchorRight);
846 l->addAnchor(firstItem: d, firstEdge: Qt::AnchorLeft, secondItem: c, secondEdge: Qt::AnchorRight);
847 l->addAnchor(firstItem: d, firstEdge: Qt::AnchorRight, secondItem: l, secondEdge: Qt::AnchorRight);
848 l->addAnchors(firstItem: l, secondItem: e, orientations: Qt::Horizontal);
849
850 QCOMPARE(l->count(), 5);
851
852 QGraphicsWidget p;
853 p.setLayout(l);
854
855 QSizeF layoutMinimumSize = l->effectiveSizeHint(which: Qt::MinimumSize);
856 QSizeF layoutMaximumSize = l->effectiveSizeHint(which: Qt::MaximumSize);
857 QSizeF layoutPreferredSize = l->effectiveSizeHint(which: Qt::PreferredSize);
858
859 QCOMPARE(layoutMinimumSize, QSizeF(60.0, 500.0));
860 QCOMPARE(layoutPreferredSize, QSizeF(220.0, 500.0));
861 QCOMPARE(layoutMaximumSize, QSizeF(400.0, 500.0));
862
863 if (!hasSimplification)
864 return;
865
866 p.resize(size: layoutMinimumSize);
867 QCOMPARE(a->size(), b->size());
868 QCOMPARE(a->size(), c->size());
869 QCOMPARE(a->size(), d->size());
870 QCOMPARE(e->size().width(), 4 * a->size().width());
871 QCOMPARE(p.size(), layoutMinimumSize);
872
873 p.resize(size: layoutPreferredSize);
874 QCOMPARE(a->size(), b->size());
875 QCOMPARE(a->size(), c->size());
876 QCOMPARE(a->size(), d->size());
877 QCOMPARE(e->size().width(), 4 * a->size().width());
878 QCOMPARE(p.size(), layoutPreferredSize);
879
880 p.resize(size: layoutMaximumSize);
881 QCOMPARE(a->size(), b->size());
882 QCOMPARE(a->size(), c->size());
883 QCOMPARE(a->size(), d->size());
884 QCOMPARE(e->size().width(), 4 * a->size().width());
885 QCOMPARE(p.size(), layoutMaximumSize);
886
887 QVERIFY(!usedSimplex(l, Qt::Horizontal));
888 QVERIFY(!usedSimplex(l, Qt::Vertical));
889}
890
891void tst_QGraphicsAnchorLayout::proportionalPreferred()
892{
893 QSizeF minSize(0, 100);
894
895 QGraphicsWidget *a = createItem(minimum: minSize, preferred: QSizeF(10, 100), maximum: QSizeF(20, 100), name: "A");
896 QGraphicsWidget *b = createItem(minimum: minSize, preferred: QSizeF(20, 100), maximum: QSizeF(30, 100), name: "B");
897 QGraphicsWidget *c = createItem(minimum: minSize, preferred: QSizeF(14, 100), maximum: QSizeF(20, 100), name: "C");
898 QGraphicsWidget *d = createItem(minimum: minSize, preferred: QSizeF(10, 100), maximum: QSizeF(20, 100), name: "D");
899
900 QGraphicsAnchorLayout *l = new QGraphicsAnchorLayout;
901 l->setContentsMargins(left: 0, top: 0, right: 0, bottom: 0);
902 l->setSpacing(0);
903
904 l->addAnchor(firstItem: l, firstEdge: Qt::AnchorTop, secondItem: a, secondEdge: Qt::AnchorTop);
905 l->addAnchor(firstItem: a, firstEdge: Qt::AnchorBottom, secondItem: b, secondEdge: Qt::AnchorTop);
906 l->addAnchor(firstItem: b, firstEdge: Qt::AnchorBottom, secondItem: c, secondEdge: Qt::AnchorTop);
907 l->addAnchor(firstItem: c, firstEdge: Qt::AnchorBottom, secondItem: d, secondEdge: Qt::AnchorTop);
908 l->addAnchor(firstItem: d, firstEdge: Qt::AnchorBottom, secondItem: l, secondEdge: Qt::AnchorBottom);
909
910 l->addAnchor(firstItem: l, firstEdge: Qt::AnchorLeft, secondItem: a, secondEdge: Qt::AnchorLeft);
911 l->addAnchor(firstItem: l, firstEdge: Qt::AnchorLeft, secondItem: b, secondEdge: Qt::AnchorLeft);
912 l->addAnchor(firstItem: a, firstEdge: Qt::AnchorRight, secondItem: c, secondEdge: Qt::AnchorLeft);
913 l->addAnchor(firstItem: a, firstEdge: Qt::AnchorRight, secondItem: d, secondEdge: Qt::AnchorLeft);
914 l->addAnchor(firstItem: b, firstEdge: Qt::AnchorRight, secondItem: l, secondEdge: Qt::AnchorRight);
915 l->addAnchor(firstItem: c, firstEdge: Qt::AnchorRight, secondItem: l, secondEdge: Qt::AnchorRight);
916 l->addAnchor(firstItem: d, firstEdge: Qt::AnchorRight, secondItem: l, secondEdge: Qt::AnchorRight);
917
918 QCOMPARE(l->count(), 4);
919
920 QGraphicsWidget p;
921 p.setLayout(l);
922
923 QSizeF layoutMinimumSize = l->effectiveSizeHint(which: Qt::MinimumSize);
924 QSizeF layoutPreferredSize = l->effectiveSizeHint(which: Qt::PreferredSize);
925 QSizeF layoutMaximumSize = l->effectiveSizeHint(which: Qt::MaximumSize);
926
927 QCOMPARE(layoutMinimumSize, QSizeF(0, 400));
928 QCOMPARE(layoutPreferredSize, QSizeF(24, 400));
929 QCOMPARE(layoutMaximumSize, QSizeF(30, 400));
930
931 p.resize(size: layoutMinimumSize);
932 QCOMPARE(p.size(), layoutMinimumSize);
933
934 p.resize(size: layoutPreferredSize);
935 QCOMPARE(c->size().width(), d->size().width());
936 QCOMPARE(p.size(), layoutPreferredSize);
937
938 p.resize(size: layoutMaximumSize);
939 QCOMPARE(p.size(), layoutMaximumSize);
940
941 p.resize(size: QSizeF(12, 400));
942
943 // Proportionality between size given and preferred size, this
944 // should be respected in this graph for (a) and (b)|(c).
945 qreal factor = 12.0 / 24.0;
946
947 QCOMPARE(c->size().width(), d->size().width());
948 QCOMPARE(a->size().width(), 10 * factor);
949 QCOMPARE(c->size().width(), 14 * factor);
950 QCOMPARE(p.size(), QSizeF(12, 400));
951
952 if (hasSimplification) {
953 QVERIFY(!usedSimplex(l, Qt::Horizontal));
954 QVERIFY(!usedSimplex(l, Qt::Vertical));
955 }
956}
957
958void tst_QGraphicsAnchorLayout::example()
959{
960 QSizeF minSize(30, 100);
961 QSizeF pref(210, 100);
962 QSizeF maxSize(300, 100);
963
964 QGraphicsWidget *a = createItem(minimum: minSize, preferred: pref, maximum: maxSize, name: "A");
965 QGraphicsWidget *b = createItem(minimum: minSize, preferred: pref, maximum: maxSize, name: "B");
966 QGraphicsWidget *c = createItem(minimum: minSize, preferred: pref, maximum: maxSize, name: "C");
967 QGraphicsWidget *d = createItem(minimum: minSize, preferred: pref, maximum: maxSize, name: "D");
968 QGraphicsWidget *e = createItem(minimum: minSize, preferred: pref, maximum: maxSize, name: "E");
969 QGraphicsWidget *f = createItem(minimum: QSizeF(30, 50), preferred: QSizeF(150, 50), maximum: maxSize, name: "F");
970 QGraphicsWidget *g = createItem(minimum: QSizeF(30, 50), preferred: QSizeF(30, 100), maximum: maxSize, name: "G");
971
972 QGraphicsAnchorLayout *l = new QGraphicsAnchorLayout;
973 l->setContentsMargins(left: 0, top: 0, right: 0, bottom: 0);
974 l->setSpacing(0);
975
976 // vertical
977 l->addAnchor(firstItem: a, firstEdge: Qt::AnchorTop, secondItem: l, secondEdge: Qt::AnchorTop);
978 l->addAnchor(firstItem: b, firstEdge: Qt::AnchorTop, secondItem: l, secondEdge: Qt::AnchorTop);
979
980 l->addAnchor(firstItem: c, firstEdge: Qt::AnchorTop, secondItem: a, secondEdge: Qt::AnchorBottom);
981 l->addAnchor(firstItem: c, firstEdge: Qt::AnchorTop, secondItem: b, secondEdge: Qt::AnchorBottom);
982 l->addAnchor(firstItem: c, firstEdge: Qt::AnchorBottom, secondItem: d, secondEdge: Qt::AnchorTop);
983 l->addAnchor(firstItem: c, firstEdge: Qt::AnchorBottom, secondItem: e, secondEdge: Qt::AnchorTop);
984
985 l->addAnchor(firstItem: d, firstEdge: Qt::AnchorBottom, secondItem: l, secondEdge: Qt::AnchorBottom);
986 l->addAnchor(firstItem: e, firstEdge: Qt::AnchorBottom, secondItem: l, secondEdge: Qt::AnchorBottom);
987
988 l->addAnchor(firstItem: c, firstEdge: Qt::AnchorTop, secondItem: f, secondEdge: Qt::AnchorTop);
989 l->addAnchor(firstItem: c, firstEdge: Qt::AnchorVerticalCenter, secondItem: f, secondEdge: Qt::AnchorBottom);
990 l->addAnchor(firstItem: f, firstEdge: Qt::AnchorBottom, secondItem: g, secondEdge: Qt::AnchorTop);
991 l->addAnchor(firstItem: c, firstEdge: Qt::AnchorBottom, secondItem: g, secondEdge: Qt::AnchorBottom);
992
993 // horizontal
994 l->addAnchor(firstItem: l, firstEdge: Qt::AnchorLeft, secondItem: a, secondEdge: Qt::AnchorLeft);
995 l->addAnchor(firstItem: l, firstEdge: Qt::AnchorLeft, secondItem: d, secondEdge: Qt::AnchorLeft);
996 l->addAnchor(firstItem: a, firstEdge: Qt::AnchorRight, secondItem: b, secondEdge: Qt::AnchorLeft);
997
998 l->addAnchor(firstItem: a, firstEdge: Qt::AnchorRight, secondItem: c, secondEdge: Qt::AnchorLeft);
999 l->addAnchor(firstItem: c, firstEdge: Qt::AnchorRight, secondItem: e, secondEdge: Qt::AnchorLeft);
1000
1001 l->addAnchor(firstItem: b, firstEdge: Qt::AnchorRight, secondItem: l, secondEdge: Qt::AnchorRight);
1002 l->addAnchor(firstItem: e, firstEdge: Qt::AnchorRight, secondItem: l, secondEdge: Qt::AnchorRight);
1003 l->addAnchor(firstItem: d, firstEdge: Qt::AnchorRight, secondItem: e, secondEdge: Qt::AnchorLeft);
1004
1005 l->addAnchor(firstItem: l, firstEdge: Qt::AnchorLeft, secondItem: f, secondEdge: Qt::AnchorLeft);
1006 l->addAnchor(firstItem: l, firstEdge: Qt::AnchorLeft, secondItem: g, secondEdge: Qt::AnchorLeft);
1007 l->addAnchor(firstItem: f, firstEdge: Qt::AnchorRight, secondItem: g, secondEdge: Qt::AnchorRight);
1008
1009 QCOMPARE(l->count(), 7);
1010
1011 QGraphicsWidget p;
1012 p.setLayout(l);
1013
1014 QSizeF layoutMinimumSize = l->effectiveSizeHint(which: Qt::MinimumSize);
1015 QSizeF layoutMaximumSize = l->effectiveSizeHint(which: Qt::MaximumSize);
1016 QSizeF layoutPreferredSize = l->effectiveSizeHint(which: Qt::PreferredSize);
1017
1018 QCOMPARE(layoutMinimumSize, QSizeF(90.0, 300.0));
1019 QCOMPARE(layoutPreferredSize, QSizeF(510.0, 300.0));
1020 QCOMPARE(layoutMaximumSize, QSizeF(570.0, 300.0));
1021
1022 p.resize(size: layoutMinimumSize);
1023 QCOMPARE(p.size(), layoutMinimumSize);
1024 QCOMPARE(a->size(), e->size());
1025 QCOMPARE(b->size(), d->size());
1026 QCOMPARE(f->size(), g->size());
1027
1028 p.resize(size: layoutPreferredSize);
1029 QCOMPARE(p.size(), layoutPreferredSize);
1030 QCOMPARE(a->size(), e->size());
1031 QCOMPARE(b->size(), d->size());
1032 QCOMPARE(f->size(), g->size());
1033
1034 p.resize(size: layoutMaximumSize);
1035 QCOMPARE(p.size(), layoutMaximumSize);
1036 QCOMPARE(a->size(), e->size());
1037 QCOMPARE(b->size(), d->size());
1038 QCOMPARE(f->size(), g->size());
1039
1040 if (hasSimplification) {
1041 QVERIFY(usedSimplex(l, Qt::Horizontal));
1042 QVERIFY(usedSimplex(l, Qt::Vertical));
1043 }
1044}
1045
1046void tst_QGraphicsAnchorLayout::setSpacing()
1047{
1048 QSizeF minSize(10, 10);
1049 QSizeF pref(20, 20);
1050 QSizeF maxSize(50, 50);
1051
1052 QGraphicsWidget *a = createItem(minimum: minSize, preferred: pref, maximum: maxSize);
1053 QGraphicsWidget *b = createItem(minimum: minSize, preferred: pref, maximum: maxSize);
1054 QGraphicsWidget *c = createItem(minimum: minSize, preferred: pref, maximum: maxSize);
1055
1056 QGraphicsAnchorLayout *l = new QGraphicsAnchorLayout;
1057 l->addCornerAnchors(firstItem: l, firstCorner: Qt::TopLeftCorner, secondItem: a, secondCorner: Qt::TopLeftCorner);
1058 l->addCornerAnchors(firstItem: b, firstCorner: Qt::TopRightCorner, secondItem: l, secondCorner: Qt::TopRightCorner);
1059 l->addAnchor(firstItem: a, firstEdge: Qt::AnchorRight, secondItem: b, secondEdge: Qt::AnchorLeft);
1060
1061 l->addAnchors(firstItem: l, secondItem: c, orientations: Qt::Horizontal);
1062
1063 l->addAnchor(firstItem: a, firstEdge: Qt::AnchorBottom, secondItem: c, secondEdge: Qt::AnchorTop);
1064 l->addAnchor(firstItem: c, firstEdge: Qt::AnchorBottom, secondItem: l, secondEdge: Qt::AnchorBottom);
1065
1066 QGraphicsWidget *p = new QGraphicsWidget(0, Qt::Window);
1067
1068 p->setLayout(l);
1069 l->setSpacing(1);
1070
1071 // don't let the style influence the test.
1072 l->setContentsMargins(left: 0, top: 0, right: 0, bottom: 0);
1073
1074 QGraphicsScene scene;
1075 scene.addItem(item: p);
1076 QGraphicsView *view = new QGraphicsView(&scene);
1077 view->show();
1078 p->show();
1079
1080 QApplication::processEvents();
1081#ifdef Q_OS_MAC
1082 QTest::qWait(200);
1083#endif
1084
1085 // 21x21
1086 QCOMPARE(p->size(), QSizeF(41, 41));
1087 QCOMPARE(a->geometry(), QRectF(0, 0, 20, 20));
1088 QCOMPARE(b->geometry(), QRectF(21, 0, 20, 20));
1089 QCOMPARE(c->geometry(), QRectF(0, 21, 41, 20));
1090
1091 l->setHorizontalSpacing(4);
1092 QApplication::processEvents();
1093 p->adjustSize();
1094 QCOMPARE(a->geometry(), QRectF(0, 0, 20, 20));
1095 QCOMPARE(b->geometry(), QRectF(24, 0, 20, 20));
1096 QCOMPARE(c->geometry(), QRectF(0, 21, 44, 20));
1097
1098 l->setVerticalSpacing(0);
1099 QApplication::processEvents();
1100 p->adjustSize();
1101 QCOMPARE(a->geometry(), QRectF(0, 0, 20, 20));
1102 QCOMPARE(b->geometry(), QRectF(24, 0, 20, 20));
1103 QCOMPARE(c->geometry(), QRectF(0, 20, 44, 20));
1104
1105 delete p;
1106 delete view;
1107}
1108
1109class CustomLayoutStyle : public QProxyStyle
1110{
1111 Q_OBJECT
1112public:
1113 CustomLayoutStyle() : QProxyStyle(QStyleFactory::create("windows"))
1114 {
1115 hspacing = 5;
1116 vspacing = 10;
1117 }
1118
1119 virtual int pixelMetric(PixelMetric metric, const QStyleOption * option = 0,
1120 const QWidget * widget = 0 ) const;
1121
1122 int hspacing;
1123 int vspacing;
1124
1125 int layoutSpacing(QSizePolicy::ControlType control1,
1126 QSizePolicy::ControlType control2,
1127 Qt::Orientation orientation,
1128 const QStyleOption *option = 0,
1129 const QWidget *widget = 0) const;
1130
1131};
1132
1133#define CT1(c) CT2(c, c)
1134#define CT2(c1, c2) ((uint)c1 << 16) | (uint)c2
1135
1136int CustomLayoutStyle::layoutSpacing(QSizePolicy::ControlType control1,
1137 QSizePolicy::ControlType control2,
1138 Qt::Orientation orientation,
1139 const QStyleOption * /*option = 0*/,
1140 const QWidget * /*widget = 0*/) const
1141{
1142 if (orientation == Qt::Horizontal) {
1143 switch (CT2(control1, control2)) {
1144 case CT1(QSizePolicy::PushButton):
1145 return 2;
1146 break;
1147 }
1148 return 5;
1149 } else {
1150 switch (CT2(control1, control2)) {
1151 case CT1(QSizePolicy::RadioButton):
1152 return 2;
1153 break;
1154
1155 }
1156 return 10;
1157 }
1158}
1159
1160int CustomLayoutStyle::pixelMetric(PixelMetric metric, const QStyleOption * option /*= 0*/,
1161 const QWidget * widget /*= 0*/ ) const
1162{
1163 switch (metric) {
1164 case PM_LayoutLeftMargin:
1165 return 0;
1166 break;
1167 case PM_LayoutTopMargin:
1168 return 3;
1169 break;
1170 case PM_LayoutRightMargin:
1171 return 6;
1172 break;
1173 case PM_LayoutBottomMargin:
1174 return 9;
1175 break;
1176 case PM_LayoutHorizontalSpacing:
1177 return hspacing;
1178 case PM_LayoutVerticalSpacing:
1179 return vspacing;
1180 break;
1181 default:
1182 break;
1183 }
1184 return QProxyStyle::pixelMetric(metric, option, widget);
1185}
1186
1187void tst_QGraphicsAnchorLayout::styleDefaults()
1188{
1189 QSizeF minSize (10, 10);
1190 QSizeF pref(20, 20);
1191 QSizeF maxSize (50, 50);
1192
1193 /*
1194 create this layout, where a,b have controlType QSizePolicy::RadioButton
1195 c,d have controlType QSizePolicy::PushButton:
1196 +-------+
1197 |a |
1198 | b |
1199 | c |
1200 | d|
1201 +-------+
1202 */
1203 QGraphicsScene scene;
1204 QGraphicsWidget *a = createItem(minimum: minSize, preferred: pref, maximum: maxSize);
1205 QSizePolicy spRadioButton = a->sizePolicy();
1206 spRadioButton.setControlType(QSizePolicy::RadioButton);
1207 a->setSizePolicy(spRadioButton);
1208
1209 QGraphicsWidget *b = createItem(minimum: minSize, preferred: pref, maximum: maxSize);
1210 b->setSizePolicy(spRadioButton);
1211
1212 QGraphicsWidget *c = createItem(minimum: minSize, preferred: pref, maximum: maxSize);
1213 QSizePolicy spPushButton = c->sizePolicy();
1214 spPushButton.setControlType(QSizePolicy::PushButton);
1215 c->setSizePolicy(spPushButton);
1216
1217 QGraphicsWidget *d = createItem(minimum: minSize, preferred: pref, maximum: maxSize);
1218 d->setSizePolicy(spPushButton);
1219
1220 QGraphicsWidget *window = new QGraphicsWidget(0, Qt::Window);
1221
1222 // Test layoutSpacing
1223 CustomLayoutStyle *style = new CustomLayoutStyle;
1224 style->hspacing = -1;
1225 style->vspacing = -1;
1226 window->setStyle(style);
1227 QGraphicsAnchorLayout *l = new QGraphicsAnchorLayout;
1228
1229 l->addCornerAnchors(firstItem: l, firstCorner: Qt::TopLeftCorner, secondItem: a, secondCorner: Qt::TopLeftCorner);
1230 l->addCornerAnchors(firstItem: a, firstCorner: Qt::BottomRightCorner, secondItem: b, secondCorner: Qt::TopLeftCorner);
1231 l->addCornerAnchors(firstItem: b, firstCorner: Qt::BottomRightCorner, secondItem: c, secondCorner: Qt::TopLeftCorner);
1232 l->addCornerAnchors(firstItem: c, firstCorner: Qt::BottomRightCorner, secondItem: d, secondCorner: Qt::TopLeftCorner);
1233 l->addCornerAnchors(firstItem: d, firstCorner: Qt::BottomRightCorner, secondItem: l, secondCorner: Qt::BottomRightCorner);
1234
1235 window->setLayout(l);
1236
1237 scene.addItem(item: window);
1238
1239 window->show();
1240 QGraphicsView view(&scene);
1241 view.resize(w: 200, h: 200);
1242 view.show();
1243
1244 window->adjustSize();
1245 QCOMPARE(a->geometry(), QRectF(0, 3, 20, 20)); //radio
1246 QCOMPARE(b->geometry(), QRectF(25, 25, 20, 20)); //radio
1247 QCOMPARE(c->geometry(), QRectF(50, 55, 20, 20)); //push
1248 QCOMPARE(d->geometry(), QRectF(72, 85, 20, 20)); //push
1249 QCOMPARE(l->geometry(), QRectF(0, 0, 98, 114));
1250
1251
1252 // Test pixelMetric(PM_Layout{Horizontal|Vertical}Spacing
1253 window->setStyle(0);
1254
1255 style->hspacing = 1;
1256 style->vspacing = 2;
1257
1258 window->setStyle(style);
1259 window->adjustSize();
1260 QCOMPARE(a->geometry(), QRectF(0, 3, 20, 20));
1261 QCOMPARE(b->geometry(), QRectF(21, 25, 20, 20));
1262 QCOMPARE(c->geometry(), QRectF(42, 47, 20, 20));
1263 QCOMPARE(d->geometry(), QRectF(63, 69, 20, 20));
1264 QCOMPARE(l->geometry(), QRectF(0, 0, 89, 98));
1265
1266 window->setStyle(0);
1267 delete style;
1268}
1269
1270
1271/*!
1272 Taken from "hard" complex case, found at
1273 https://cwiki.nokia.com/S60QTUI/AnchorLayoutComplexCases
1274
1275 This layout has a special property, since it has two possible solutions for its minimum size.
1276
1277 For instance, when it is in its minimum size - the layout have two possible solutions:
1278 1. c.width == 10, e.width == 10 and g.width == 10
1279 (all others have width 0)
1280 2. d.width == 10 and g.width == 10
1281 (all others have width 0)
1282
1283 It also has several solutions for preferred size.
1284*/
1285static QGraphicsAnchorLayout *createAmbiguousS60Layout()
1286{
1287 QGraphicsAnchorLayout *l = new QGraphicsAnchorLayout;
1288 l->setContentsMargins(left: 0, top: 0, right: 0, bottom: 0);
1289 l->setSpacing(0);
1290
1291 QSizeF minSize(0, 10);
1292 QSizeF pref(50, 10);
1293 QSizeF maxSize(100, 10);
1294
1295 QGraphicsWidget *a = createItem(minimum: minSize, preferred: pref, maximum: maxSize, name: "a");
1296 QGraphicsWidget *b = createItem(minimum: minSize, preferred: pref, maximum: maxSize, name: "b");
1297 QGraphicsWidget *c = createItem(minimum: minSize, preferred: pref, maximum: maxSize, name: "c");
1298 QGraphicsWidget *d = createItem(minimum: minSize, preferred: pref, maximum: maxSize, name: "d");
1299 QGraphicsWidget *e = createItem(minimum: minSize, preferred: pref, maximum: maxSize, name: "e");
1300 QGraphicsWidget *f = createItem(minimum: minSize, preferred: pref, maximum: maxSize, name: "f");
1301 QGraphicsWidget *g = createItem(minimum: minSize, preferred: pref, maximum: maxSize, name: "g");
1302
1303 //<!-- Trunk -->
1304 setAnchor(l, firstItem: l, firstEdge: Qt::AnchorLeft, secondItem: a, secondEdge: Qt::AnchorLeft, spacing: 10);
1305 setAnchor(l, firstItem: a, firstEdge: Qt::AnchorRight, secondItem: b, secondEdge: Qt::AnchorLeft, spacing: 10);
1306 setAnchor(l, firstItem: b, firstEdge: Qt::AnchorRight, secondItem: c, secondEdge: Qt::AnchorLeft, spacing: 10);
1307 setAnchor(l, firstItem: c, firstEdge: Qt::AnchorRight, secondItem: d, secondEdge: Qt::AnchorLeft, spacing: 10);
1308 setAnchor(l, firstItem: d, firstEdge: Qt::AnchorRight, secondItem: l, secondEdge: Qt::AnchorRight, spacing: 10);
1309
1310 //<!-- Above trunk -->
1311 setAnchor(l, firstItem: b, firstEdge: Qt::AnchorLeft, secondItem: e, secondEdge: Qt::AnchorLeft, spacing: 10);
1312 setAnchor(l, firstItem: e, firstEdge: Qt::AnchorRight, secondItem: d, secondEdge: Qt::AnchorLeft, spacing: 10);
1313
1314 //<!-- Below trunk -->
1315 setAnchor(l, firstItem: a, firstEdge: Qt::AnchorHorizontalCenter, secondItem: g, secondEdge: Qt::AnchorLeft, spacing: 10);
1316 setAnchor(l, firstItem: g, firstEdge: Qt::AnchorRight, secondItem: f, secondEdge: Qt::AnchorHorizontalCenter, spacing: 10);
1317 setAnchor(l, firstItem: c, firstEdge: Qt::AnchorLeft, secondItem: f, secondEdge: Qt::AnchorLeft, spacing: 10);
1318 setAnchor(l, firstItem: f, firstEdge: Qt::AnchorRight, secondItem: d, secondEdge: Qt::AnchorRight, spacing: 10);
1319
1320 //<!-- vertical is simpler -->
1321 setAnchor(l, firstItem: l, firstEdge: Qt::AnchorTop, secondItem: e, secondEdge: Qt::AnchorTop, spacing: 0);
1322 setAnchor(l, firstItem: e, firstEdge: Qt::AnchorBottom, secondItem: a, secondEdge: Qt::AnchorTop, spacing: 0);
1323 setAnchor(l, firstItem: e, firstEdge: Qt::AnchorBottom, secondItem: b, secondEdge: Qt::AnchorTop, spacing: 0);
1324 setAnchor(l, firstItem: e, firstEdge: Qt::AnchorBottom, secondItem: c, secondEdge: Qt::AnchorTop, spacing: 0);
1325 setAnchor(l, firstItem: e, firstEdge: Qt::AnchorBottom, secondItem: d, secondEdge: Qt::AnchorTop, spacing: 0);
1326 setAnchor(l, firstItem: a, firstEdge: Qt::AnchorBottom, secondItem: f, secondEdge: Qt::AnchorTop, spacing: 0);
1327 setAnchor(l, firstItem: a, firstEdge: Qt::AnchorBottom, secondItem: b, secondEdge: Qt::AnchorBottom, spacing: 0);
1328 setAnchor(l, firstItem: a, firstEdge: Qt::AnchorBottom, secondItem: c, secondEdge: Qt::AnchorBottom, spacing: 0);
1329 setAnchor(l, firstItem: a, firstEdge: Qt::AnchorBottom, secondItem: d, secondEdge: Qt::AnchorBottom, spacing: 0);
1330 setAnchor(l, firstItem: f, firstEdge: Qt::AnchorBottom, secondItem: g, secondEdge: Qt::AnchorTop, spacing: 0);
1331 setAnchor(l, firstItem: g, firstEdge: Qt::AnchorBottom, secondItem: l, secondEdge: Qt::AnchorBottom, spacing: 0);
1332 return l;
1333}
1334
1335void tst_QGraphicsAnchorLayout::hardComplexS60()
1336{
1337 QGraphicsAnchorLayout *l = createAmbiguousS60Layout();
1338 QCOMPARE(l->count(), 7);
1339
1340 QGraphicsWidget *p = new QGraphicsWidget(0, Qt::Window);
1341 p->setLayout(l);
1342
1343 QSizeF layoutMinimumSize = l->effectiveSizeHint(which: Qt::MinimumSize);
1344 QCOMPARE(layoutMinimumSize, QSizeF(60, 40));
1345 // expected preferred might be wrong, (haven't manually verified it)
1346 QSizeF layoutPreferredSize = l->effectiveSizeHint(which: Qt::PreferredSize);
1347 QCOMPARE(layoutPreferredSize, QSizeF(220, 40));
1348 QSizeF layoutMaximumSize = l->effectiveSizeHint(which: Qt::MaximumSize);
1349 QCOMPARE(layoutMaximumSize, QSizeF(240, 40));
1350
1351 delete p;
1352}
1353
1354static inline QByteArray msgStability(const QRectF &actual, const QRectF &expected, int pass, int item)
1355{
1356 QString result;
1357 QDebug(&result)
1358 << "The layout has several solutions, but which solution it picks is not stable ("
1359 << actual << "!=" << expected << ", iteration" << pass << ", item" << item << ')';
1360 return result.toLocal8Bit();
1361}
1362
1363void tst_QGraphicsAnchorLayout::stability()
1364{
1365 QVector<QRectF> geometries;
1366 geometries.resize(size: 7);
1367 QGraphicsWidget p(0, Qt::Window);
1368 // it usually fails after 3-4 iterations
1369 for (int pass = 0; pass < 20; ++pass) {
1370 // In case we need to "scramble" the heap allocator to provoke this bug.
1371 //static const int primes[] = {2, 3, 5, 13, 89, 233, 1597, 28657, 514229}; // fibo primes
1372 //const int primeCount = sizeof(primes)/sizeof(int);
1373 //int alloc = primes[pass % primeCount] + pass;
1374 //void *mem = malloc(alloc);
1375 //free(mem);
1376 QGraphicsAnchorLayout *l = createAmbiguousS60Layout();
1377 p.setLayout(l);
1378 QSizeF layoutMinimumSize = l->effectiveSizeHint(which: Qt::MinimumSize);
1379 l->setGeometry(QRectF(QPointF(0,0), layoutMinimumSize));
1380 QApplication::processEvents();
1381 for (int i = l->count() - 1; i >=0; --i) {
1382 const QRectF actualGeom = l->itemAt(index: i)->geometry();
1383 if (pass != 0) {
1384 if (actualGeom != geometries[i])
1385 QEXPECT_FAIL("", msgStability(actualGeom, geometries[i], pass, i).constData(), Abort);
1386 QCOMPARE(actualGeom, geometries[i]);
1387 }
1388 geometries[i] = actualGeom;
1389 }
1390 p.setLayout(0); // uninstalls and deletes the layout
1391 QApplication::processEvents();
1392 }
1393}
1394
1395void tst_QGraphicsAnchorLayout::delete_anchor()
1396{
1397 QGraphicsScene scene;
1398 QSizeF minSize(0, 0);
1399 QSizeF prefSize(50, 50);
1400 QSizeF maxSize(100, 100);
1401 QGraphicsWidget *w1 = createItem(minimum: minSize, preferred: prefSize, maximum: maxSize, name: "w1");
1402 QGraphicsWidget *w2 = createItem(minimum: minSize, preferred: prefSize, maximum: maxSize, name: "w2");
1403 QGraphicsWidget *w3 = createItem(minimum: minSize, preferred: prefSize, maximum: maxSize, name: "w3");
1404
1405 QGraphicsAnchorLayout *l = new QGraphicsAnchorLayout;
1406 l->setSpacing(0);
1407 l->setContentsMargins(left: 0, top: 0, right: 0, bottom: 0);
1408
1409 // Horizontal
1410 l->addAnchor(firstItem: l, firstEdge: Qt::AnchorLeft, secondItem: w1, secondEdge: Qt::AnchorLeft);
1411 l->addAnchor(firstItem: w1, firstEdge: Qt::AnchorRight, secondItem: w2, secondEdge: Qt::AnchorLeft);
1412 l->addAnchor(firstItem: w2, firstEdge: Qt::AnchorRight, secondItem: l, secondEdge: Qt::AnchorRight);
1413 l->addAnchor(firstItem: w1, firstEdge: Qt::AnchorRight, secondItem: w3, secondEdge: Qt::AnchorLeft);
1414 l->addAnchor(firstItem: w3, firstEdge: Qt::AnchorRight, secondItem: l, secondEdge: Qt::AnchorRight);
1415
1416 // Vertical
1417 l->addAnchors(firstItem: l, secondItem: w1, orientations: Qt::Vertical);
1418 l->addAnchors(firstItem: l, secondItem: w2, orientations: Qt::Vertical);
1419 l->addAnchors(firstItem: l, secondItem: w3, orientations: Qt::Vertical);
1420
1421 QGraphicsAnchor *anchor = l->anchor(firstItem: w3, firstEdge: Qt::AnchorRight, secondItem: l, secondEdge: Qt::AnchorRight);
1422 anchor->setSpacing(10);
1423
1424 QGraphicsWidget *p = new QGraphicsWidget;
1425 p->setLayout(l);
1426
1427 QCOMPARE(l->count(), 3);
1428
1429 scene.addItem(item: p);
1430 QGraphicsView *view = new QGraphicsView(&scene);
1431 QApplication::processEvents();
1432 // Should now be simplified
1433 QCOMPARE(l->effectiveSizeHint(Qt::PreferredSize).width(), qreal(110));
1434 QGraphicsAnchor *anchor1 = l->anchor(firstItem: w3, firstEdge: Qt::AnchorRight, secondItem: l, secondEdge: Qt::AnchorRight);
1435 QVERIFY(anchor1);
1436 QGraphicsAnchor *anchor2 = l->anchor(firstItem: w3, firstEdge: Qt::AnchorRight, secondItem: l, secondEdge: Qt::AnchorRight);
1437 QVERIFY(anchor2);
1438 QGraphicsAnchor *anchor3 = l->anchor(firstItem: l, firstEdge: Qt::AnchorRight, secondItem: w3, secondEdge: Qt::AnchorRight);
1439 QVERIFY(anchor3);
1440 QGraphicsAnchor *anchor4 = l->anchor(firstItem: l, firstEdge: Qt::AnchorRight, secondItem: w3, secondEdge: Qt::AnchorRight);
1441 QVERIFY(anchor4);
1442
1443 // should all be the same object
1444 QCOMPARE(anchor1, anchor2);
1445 QCOMPARE(anchor2, anchor3);
1446 QCOMPARE(anchor3, anchor4);
1447
1448 // check if removal works
1449 delete anchor1;
1450
1451 QApplication::processEvents();
1452
1453 // it should also change the preferred size of the layout
1454 QCOMPARE(l->effectiveSizeHint(Qt::PreferredSize).width(), qreal(100));
1455
1456 delete p;
1457 delete view;
1458}
1459
1460void tst_QGraphicsAnchorLayout::sizePolicy()
1461{
1462 QGraphicsScene scene;
1463 QSizeF minSize(0, 0);
1464 QSizeF prefSize(50, 50);
1465 QSizeF maxSize(100, 100);
1466 QGraphicsWidget *w1 = createItem(minimum: minSize, preferred: prefSize, maximum: maxSize, name: "w1");
1467
1468 QGraphicsAnchorLayout *l = new QGraphicsAnchorLayout;
1469 l->setSpacing(0);
1470 l->setContentsMargins(left: 0, top: 0, right: 0, bottom: 0);
1471
1472 // horizontal and vertical
1473 l->addAnchors(firstItem: l, secondItem: w1);
1474
1475 QGraphicsWidget *p = new QGraphicsWidget;
1476 p->setLayout(l);
1477
1478 scene.addItem(item: p);
1479 QGraphicsView *view = new QGraphicsView(&scene);
1480
1481 // QSizePolicy::Minimum
1482 w1->setSizePolicy(hPolicy: QSizePolicy::Minimum, vPolicy: QSizePolicy::Minimum);
1483 QApplication::processEvents();
1484 w1->adjustSize();
1485
1486 QCOMPARE(l->effectiveSizeHint(Qt::MinimumSize), QSizeF(50, 50));
1487 QCOMPARE(l->effectiveSizeHint(Qt::PreferredSize), QSizeF(50, 50));
1488 QCOMPARE(l->effectiveSizeHint(Qt::MaximumSize), QSizeF(100, 100));
1489
1490 // QSizePolicy::Maximum
1491 w1->setSizePolicy(hPolicy: QSizePolicy::Maximum, vPolicy: QSizePolicy::Maximum);
1492 QApplication::processEvents();
1493 w1->adjustSize();
1494
1495 QCOMPARE(l->effectiveSizeHint(Qt::MinimumSize), QSizeF(0, 0));
1496 QCOMPARE(l->effectiveSizeHint(Qt::PreferredSize), QSizeF(50, 50));
1497 QCOMPARE(l->effectiveSizeHint(Qt::MaximumSize), QSizeF(50, 50));
1498
1499 // QSizePolicy::Fixed
1500 w1->setSizePolicy(hPolicy: QSizePolicy::Fixed, vPolicy: QSizePolicy::Fixed);
1501 QApplication::processEvents();
1502 w1->adjustSize();
1503
1504 QCOMPARE(l->effectiveSizeHint(Qt::MinimumSize), QSizeF(50, 50));
1505 QCOMPARE(l->effectiveSizeHint(Qt::PreferredSize), QSizeF(50, 50));
1506 QCOMPARE(l->effectiveSizeHint(Qt::MaximumSize), QSizeF(50, 50));
1507
1508 // QSizePolicy::Preferred
1509 w1->setSizePolicy(hPolicy: QSizePolicy::Preferred, vPolicy: QSizePolicy::Preferred);
1510 QApplication::processEvents();
1511 w1->adjustSize();
1512
1513 QCOMPARE(l->effectiveSizeHint(Qt::MinimumSize), QSizeF(0, 0));
1514 QCOMPARE(l->effectiveSizeHint(Qt::PreferredSize), QSizeF(50, 50));
1515 QCOMPARE(l->effectiveSizeHint(Qt::MaximumSize), QSizeF(100, 100));
1516
1517 // QSizePolicy::Ignored
1518 w1->setSizePolicy(hPolicy: QSizePolicy::Ignored, vPolicy: QSizePolicy::Ignored);
1519 QApplication::processEvents();
1520 w1->adjustSize();
1521
1522 QCOMPARE(l->effectiveSizeHint(Qt::MinimumSize), QSizeF(0, 0));
1523 QCOMPARE(l->effectiveSizeHint(Qt::PreferredSize), QSizeF(0, 0));
1524 QCOMPARE(l->effectiveSizeHint(Qt::MaximumSize), QSizeF(100, 100));
1525
1526 // Anchor size policies
1527 w1->setSizePolicy(hPolicy: QSizePolicy::Fixed, vPolicy: QSizePolicy::Fixed);
1528 QGraphicsAnchor *anchor = l->anchor(firstItem: l, firstEdge: Qt::AnchorLeft, secondItem: w1, secondEdge: Qt::AnchorLeft);
1529 anchor->setSpacing(10);
1530
1531 // QSizePolicy::Minimum
1532 anchor->setSizePolicy(QSizePolicy::Minimum);
1533 QApplication::processEvents();
1534
1535 QCOMPARE(l->effectiveSizeHint(Qt::MinimumSize), QSizeF(60, 50));
1536 QCOMPARE(l->effectiveSizeHint(Qt::PreferredSize), QSizeF(60, 50));
1537 // The layout has a maximum size of QWIDGETSIZE_MAX, so the result won't exceed that value.
1538 QCOMPARE(l->effectiveSizeHint(Qt::MaximumSize), QSizeF(QWIDGETSIZE_MAX, 50));
1539
1540 // QSizePolicy::Preferred
1541 anchor->setSizePolicy(QSizePolicy::Preferred);
1542 QApplication::processEvents();
1543
1544 QCOMPARE(l->effectiveSizeHint(Qt::MinimumSize), QSizeF(50, 50));
1545 QCOMPARE(l->effectiveSizeHint(Qt::PreferredSize), QSizeF(60, 50));
1546 // The layout has a maximum size of QWIDGETSIZE_MAX, so the result won't exceed that value.
1547 QCOMPARE(l->effectiveSizeHint(Qt::MaximumSize), QSizeF(QWIDGETSIZE_MAX, 50));
1548
1549 // QSizePolicy::Maximum
1550 anchor->setSizePolicy(QSizePolicy::Maximum);
1551 QApplication::processEvents();
1552
1553 QCOMPARE(l->effectiveSizeHint(Qt::MinimumSize), QSizeF(50, 50));
1554 QCOMPARE(l->effectiveSizeHint(Qt::PreferredSize), QSizeF(60, 50));
1555 QCOMPARE(l->effectiveSizeHint(Qt::MaximumSize), QSizeF(60, 50));
1556
1557 // QSizePolicy::Ignored
1558 anchor->setSizePolicy(QSizePolicy::Ignored);
1559 QApplication::processEvents();
1560
1561 QCOMPARE(l->effectiveSizeHint(Qt::MinimumSize), QSizeF(50, 50));
1562 QCOMPARE(l->effectiveSizeHint(Qt::PreferredSize), QSizeF(50, 50));
1563 QCOMPARE(l->effectiveSizeHint(Qt::MaximumSize), QSizeF(QWIDGETSIZE_MAX, 50));
1564
1565 if (hasSimplification) {
1566 QVERIFY(!usedSimplex(l, Qt::Horizontal));
1567 QVERIFY(!usedSimplex(l, Qt::Vertical));
1568 }
1569
1570 delete p;
1571 delete view;
1572}
1573
1574/*!
1575 \internal
1576
1577 Uses private API. (We have decided to pull hasConflicts() out of the API). However, it also
1578 tests some tight conditions (almost-in-conflict) that we really want to test.
1579*/
1580void tst_QGraphicsAnchorLayout::conflicts()
1581{
1582 QGraphicsWidget *a = createItem(minimum: QSizeF(80,10), preferred: QSizeF(90,10), maximum: QSizeF(100,10), name: "a");
1583 QGraphicsWidget *b = createItem(minimum: QSizeF(10,10), preferred: QSizeF(20,10), maximum: QSizeF(30,10), name: "b");
1584 QGraphicsWidget *c = createItem(minimum: QSizeF(10,10), preferred: QSizeF(20,10), maximum: QSizeF(30,10), name: "c");
1585
1586 QGraphicsAnchorLayout *l;
1587 QGraphicsWidget *p = new QGraphicsWidget(0, Qt::Window);
1588
1589 l = new QGraphicsAnchorLayout;
1590 l->setContentsMargins(left: 0, top: 0, right: 0, bottom: 0);
1591
1592 // with the following setup, 'a' cannot be larger than 30 we will first have a Simplex conflict
1593
1594 // horizontal
1595 setAnchor(l, firstItem: l, firstEdge: Qt::AnchorLeft, secondItem: b, secondEdge: Qt::AnchorLeft);
1596 setAnchor(l, firstItem: b, firstEdge: Qt::AnchorRight, secondItem: c, secondEdge: Qt::AnchorLeft);
1597 setAnchor(l, firstItem: c, firstEdge: Qt::AnchorRight, secondItem: l, secondEdge: Qt::AnchorRight);
1598 setAnchor(l, firstItem: b, firstEdge: Qt::AnchorHorizontalCenter, secondItem: a, secondEdge: Qt::AnchorLeft);
1599 setAnchor(l, firstItem: a, firstEdge: Qt::AnchorRight, secondItem: c, secondEdge: Qt::AnchorHorizontalCenter);
1600
1601 // vertical
1602 setAnchor(l, firstItem: l, firstEdge: Qt::AnchorTop, secondItem: a, secondEdge: Qt::AnchorTop);
1603 setAnchor(l, firstItem: a, firstEdge: Qt::AnchorBottom, secondItem: b, secondEdge: Qt::AnchorTop);
1604 setAnchor(l, firstItem: a, firstEdge: Qt::AnchorBottom, secondItem: c, secondEdge: Qt::AnchorTop);
1605 setAnchor(l, firstItem: b, firstEdge: Qt::AnchorBottom, secondItem: l, secondEdge: Qt::AnchorBottom);
1606 setAnchor(l, firstItem: c, firstEdge: Qt::AnchorBottom, secondItem: l, secondEdge: Qt::AnchorBottom);
1607
1608 p->setLayout(l);
1609
1610 QCOMPARE(layoutHasConflict(l), true);
1611
1612 a->setMinimumSize(QSizeF(29,10));
1613 QCOMPARE(layoutHasConflict(l), false);
1614
1615 a->setMinimumSize(QSizeF(30,10));
1616 QCOMPARE(layoutHasConflict(l), false);
1617
1618 delete p;
1619}
1620
1621void tst_QGraphicsAnchorLayout::floatConflict()
1622{
1623 QGraphicsWidget *a = createItem(minimum: QSizeF(80,10), preferred: QSizeF(90,10), maximum: QSizeF(100,10), name: "a");
1624 QGraphicsWidget *b = createItem(minimum: QSizeF(80,10), preferred: QSizeF(90,10), maximum: QSizeF(100,10), name: "b");
1625
1626 QGraphicsAnchorLayout *l;
1627 QGraphicsWidget *p = new QGraphicsWidget(0, Qt::Window);
1628
1629 l = new QGraphicsAnchorLayout;
1630 l->setContentsMargins(left: 0, top: 0, right: 0, bottom: 0);
1631
1632 p->setLayout(l);
1633
1634 // horizontal
1635 // with this anchor we have two floating items
1636 setAnchor(l, firstItem: a, firstEdge: Qt::AnchorRight, secondItem: b, secondEdge: Qt::AnchorLeft);
1637
1638 // Just checking if the layout is handling well the removal of floating items
1639 delete l->anchor(firstItem: a, firstEdge: Qt::AnchorRight, secondItem: b, secondEdge: Qt::AnchorLeft);
1640 QCOMPARE(l->count(), 0);
1641 QCOMPARE(layoutHasConflict(l), false);
1642
1643 // setting back the same anchor
1644 setAnchor(l, firstItem: a, firstEdge: Qt::AnchorRight, secondItem: b, secondEdge: Qt::AnchorLeft);
1645
1646 // We don't support floating items but they should be counted as if they are in the layout
1647 QCOMPARE(l->count(), 2);
1648 // Although, we have an invalid situation
1649 QCOMPARE(layoutHasConflict(l), true);
1650
1651 // Semi-floats are supported
1652 setAnchor(l, firstItem: a, firstEdge: Qt::AnchorLeft, secondItem: l, secondEdge: Qt::AnchorLeft);
1653 QCOMPARE(l->count(), 2);
1654
1655 // Vertically the layout has floating items. Therefore, we have a conflict
1656 QCOMPARE(layoutHasConflict(l), true);
1657
1658 // No more floating items
1659 setAnchor(l, firstItem: b, firstEdge: Qt::AnchorRight, secondItem: l, secondEdge: Qt::AnchorRight);
1660 setAnchor(l, firstItem: a, firstEdge: Qt::AnchorTop, secondItem: l, secondEdge: Qt::AnchorTop);
1661 setAnchor(l, firstItem: a, firstEdge: Qt::AnchorBottom, secondItem: l, secondEdge: Qt::AnchorBottom);
1662 setAnchor(l, firstItem: b, firstEdge: Qt::AnchorTop, secondItem: l, secondEdge: Qt::AnchorTop);
1663 setAnchor(l, firstItem: b, firstEdge: Qt::AnchorBottom, secondItem: l, secondEdge: Qt::AnchorBottom);
1664 QCOMPARE(layoutHasConflict(l), false);
1665
1666 delete p;
1667}
1668
1669void tst_QGraphicsAnchorLayout::infiniteMaxSizes()
1670{
1671 if (sizeof(qreal) <= 4)
1672 QSKIP("qreal has too little precision, result will be wrong");
1673 QGraphicsAnchorLayout *l = new QGraphicsAnchorLayout;
1674 l->setContentsMargins(left: 0, top: 0, right: 0, bottom: 0);
1675 l->setSpacing(0);
1676
1677 QSizeF minSize(10, 10);
1678 QSizeF pref(50, 10);
1679 QSizeF maxSize(QWIDGETSIZE_MAX, 10);
1680
1681 QGraphicsWidget *a = createItem(minimum: minSize, preferred: pref, maximum: maxSize, name: "a");
1682 QGraphicsWidget *b = createItem(minimum: minSize, preferred: pref, maximum: maxSize, name: "b");
1683 QGraphicsWidget *c = createItem(minimum: minSize, preferred: pref, maximum: maxSize, name: "c");
1684 QGraphicsWidget *d = createItem(minimum: minSize, preferred: pref, maximum: maxSize, name: "d");
1685 QGraphicsWidget *e = createItem(minimum: minSize, preferred: pref, maximum: maxSize, name: "e");
1686
1687 //<!-- Trunk -->
1688 setAnchor(l, firstItem: l, firstEdge: Qt::AnchorLeft, secondItem: a, secondEdge: Qt::AnchorLeft, spacing: 0);
1689 setAnchor(l, firstItem: a, firstEdge: Qt::AnchorRight, secondItem: b, secondEdge: Qt::AnchorLeft, spacing: 0);
1690 setAnchor(l, firstItem: b, firstEdge: Qt::AnchorRight, secondItem: c, secondEdge: Qt::AnchorLeft, spacing: 0);
1691 setAnchor(l, firstItem: c, firstEdge: Qt::AnchorRight, secondItem: d, secondEdge: Qt::AnchorLeft, spacing: 0);
1692 setAnchor(l, firstItem: d, firstEdge: Qt::AnchorRight, secondItem: l, secondEdge: Qt::AnchorRight, spacing: 0);
1693 setAnchor(l, firstItem: b, firstEdge: Qt::AnchorHorizontalCenter, secondItem: e, secondEdge: Qt::AnchorLeft, spacing: 0);
1694 setAnchor(l, firstItem: e, firstEdge: Qt::AnchorRight, secondItem: c, secondEdge: Qt::AnchorHorizontalCenter, spacing: 0);
1695
1696 QGraphicsWidget p;
1697 p.setLayout(l);
1698
1699 QCOMPARE(int(p.effectiveSizeHint(Qt::MaximumSize).width()),
1700 QWIDGETSIZE_MAX);
1701
1702 p.resize(w: 200, h: 10);
1703 QCOMPARE(a->geometry(), QRectF(0, 0, 50, 10));
1704 QCOMPARE(b->geometry(), QRectF(50, 0, 50, 10));
1705 QCOMPARE(c->geometry(), QRectF(100, 0, 50, 10));
1706 QCOMPARE(d->geometry(), QRectF(150, 0, 50, 10));
1707
1708 p.resize(w: 1000, h: 10);
1709 QCOMPARE(a->geometry(), QRectF(0, 0, 250, 10));
1710 QCOMPARE(b->geometry(), QRectF(250, 0, 250, 10));
1711 QCOMPARE(c->geometry(), QRectF(500, 0, 250, 10));
1712 QCOMPARE(d->geometry(), QRectF(750, 0, 250, 10));
1713
1714 p.resize(w: 40000, h: 10);
1715 QCOMPARE(a->geometry(), QRectF(0, 0, 10000, 10));
1716 QCOMPARE(b->geometry(), QRectF(10000, 0, 10000, 10));
1717 QCOMPARE(c->geometry(), QRectF(20000, 0, 10000, 10));
1718 QCOMPARE(d->geometry(), QRectF(30000, 0, 10000, 10));
1719}
1720
1721void tst_QGraphicsAnchorLayout::simplifiableUnfeasible()
1722{
1723 QGraphicsWidget *a = createItem(minimum: QSizeF(70.0, 100.0),
1724 preferred: QSizeF(100.0, 100.0),
1725 maximum: QSizeF(100.0, 100.0), name: "A");
1726
1727 QGraphicsWidget *b = createItem(minimum: QSizeF(110.0, 100.0),
1728 preferred: QSizeF(150.0, 100.0),
1729 maximum: QSizeF(190.0, 100.0), name: "B");
1730
1731 QGraphicsAnchorLayout *l = new QGraphicsAnchorLayout;
1732 l->setContentsMargins(left: 0, top: 0, right: 0, bottom: 0);
1733 l->setSpacing(0);
1734
1735 l->addAnchor(firstItem: l, firstEdge: Qt::AnchorTop, secondItem: a, secondEdge: Qt::AnchorTop);
1736 l->addAnchor(firstItem: a, firstEdge: Qt::AnchorBottom, secondItem: b, secondEdge: Qt::AnchorTop);
1737 l->addAnchor(firstItem: b, firstEdge: Qt::AnchorBottom, secondItem: l, secondEdge: Qt::AnchorBottom);
1738
1739 l->addAnchors(firstItem: l, secondItem: a, orientations: Qt::Horizontal);
1740 l->addAnchor(firstItem: l, firstEdge: Qt::AnchorLeft, secondItem: b, secondEdge: Qt::AnchorLeft);
1741 l->addAnchor(firstItem: b, firstEdge: Qt::AnchorRight, secondItem: a, secondEdge: Qt::AnchorRight);
1742
1743 QCOMPARE(l->count(), 2);
1744
1745 QGraphicsWidget p;
1746 p.setLayout(l);
1747
1748 l->invalidate();
1749 QVERIFY(layoutHasConflict(l));
1750 if (hasSimplification)
1751 QVERIFY(!usedSimplex(l, Qt::Horizontal));
1752
1753 // Now we make it valid
1754 b->setMinimumWidth(100);
1755
1756 l->invalidate();
1757 QVERIFY(!layoutHasConflict(l));
1758 if (hasSimplification)
1759 QVERIFY(!usedSimplex(l, Qt::Horizontal));
1760
1761 // And make it invalid again
1762 a->setPreferredWidth(70);
1763 a->setMaximumWidth(70);
1764
1765 l->invalidate();
1766 QVERIFY(layoutHasConflict(l));
1767 if (hasSimplification)
1768 QVERIFY(!usedSimplex(l, Qt::Horizontal));
1769}
1770
1771/*
1772 Test whether the anchor direction can prevent it from
1773 being simplificated
1774*/
1775void tst_QGraphicsAnchorLayout::simplificationVsOrder()
1776{
1777 QSizeF minSize(10, 10);
1778 QSizeF pref(20, 10);
1779 QSizeF maxSize(50, 10);
1780
1781 QGraphicsWidget *a = createItem(minimum: minSize, preferred: pref, maximum: maxSize, name: "A");
1782 QGraphicsWidget *b = createItem(minimum: minSize, preferred: pref, maximum: maxSize, name: "B");
1783 QGraphicsWidget *c = createItem(minimum: minSize, preferred: pref, maximum: maxSize, name: "C");
1784
1785 QGraphicsWidget frame;
1786 QGraphicsAnchorLayout *l = new QGraphicsAnchorLayout(&frame);
1787
1788 // Bulk anchors
1789 l->addAnchor(firstItem: l, firstEdge: Qt::AnchorLeft, secondItem: a, secondEdge: Qt::AnchorLeft);
1790 l->addAnchor(firstItem: a, firstEdge: Qt::AnchorRight, secondItem: b, secondEdge: Qt::AnchorLeft);
1791 l->addAnchor(firstItem: b, firstEdge: Qt::AnchorLeft, secondItem: c, secondEdge: Qt::AnchorLeft);
1792 l->addAnchor(firstItem: c, firstEdge: Qt::AnchorRight, secondItem: l, secondEdge: Qt::AnchorRight);
1793
1794 // Problematic anchor, direction b->c
1795 QGraphicsAnchor *anchor = l->addAnchor(firstItem: b, firstEdge: Qt::AnchorRight, secondItem: c, secondEdge: Qt::AnchorRight);
1796 anchor->setSpacing(5);
1797
1798 l->effectiveSizeHint(which: Qt::MinimumSize);
1799 if (hasSimplification) {
1800 QCOMPARE(usedSimplex(l, Qt::Horizontal), false);
1801 QCOMPARE(usedSimplex(l, Qt::Vertical), false);
1802 }
1803
1804 // Problematic anchor, direction c->b
1805 delete anchor;
1806 anchor = l->addAnchor(firstItem: c, firstEdge: Qt::AnchorRight, secondItem: b, secondEdge: Qt::AnchorRight);
1807 anchor->setSpacing(5);
1808
1809 l->effectiveSizeHint(which: Qt::MinimumSize);
1810 if (hasSimplification) {
1811 QCOMPARE(usedSimplex(l, Qt::Horizontal), false);
1812 QCOMPARE(usedSimplex(l, Qt::Vertical), false);
1813 }
1814}
1815
1816void tst_QGraphicsAnchorLayout::parallelSimplificationOfCenter()
1817{
1818 QSizeF minSize(10, 10);
1819 QSizeF pref(20, 10);
1820 QSizeF maxSize(50, 10);
1821
1822 QGraphicsWidget *a = createItem(minimum: minSize, preferred: pref, maximum: maxSize, name: "A");
1823 QGraphicsWidget *b = createItem(minimum: minSize, preferred: pref, maximum: maxSize, name: "B");
1824
1825 QGraphicsWidget parent;
1826 QGraphicsAnchorLayout *l = new QGraphicsAnchorLayout(&parent);
1827 l->setContentsMargins(left: 0, top: 0, right: 0, bottom: 0);
1828
1829 l->addAnchor(firstItem: l, firstEdge: Qt::AnchorLeft, secondItem: a, secondEdge: Qt::AnchorLeft);
1830 l->addAnchor(firstItem: l, firstEdge: Qt::AnchorRight, secondItem: a, secondEdge: Qt::AnchorRight);
1831
1832 l->addAnchor(firstItem: a, firstEdge: Qt::AnchorHorizontalCenter, secondItem: b, secondEdge: Qt::AnchorLeft);
1833 l->addAnchor(firstItem: b, firstEdge: Qt::AnchorRight, secondItem: a, secondEdge: Qt::AnchorRight);
1834
1835 parent.resize(size: l->effectiveSizeHint(which: Qt::PreferredSize));
1836
1837 QCOMPARE(a->geometry(), QRectF(0, 0, 40, 10));
1838 QCOMPARE(b->geometry(), QRectF(20, 0, 20, 10));
1839}
1840
1841/*
1842 Test whether redundance of anchors (in this case by using addCornerAnchors), will
1843 prevent simplification to take place when it should.
1844*/
1845void tst_QGraphicsAnchorLayout::simplificationVsRedundance()
1846{
1847 QSizeF minSize(10, 10);
1848 QSizeF pref(20, 10);
1849 QSizeF maxSize(50, 30);
1850
1851 QGraphicsWidget *a = createItem(minimum: minSize, preferred: pref, maximum: maxSize, name: "A");
1852 QGraphicsWidget *b = createItem(minimum: minSize, preferred: pref, maximum: maxSize, name: "B");
1853 QGraphicsWidget *c = createItem(minimum: minSize, preferred: pref, maximum: maxSize, name: "C");
1854
1855 QGraphicsWidget frame;
1856 QGraphicsAnchorLayout *l = new QGraphicsAnchorLayout(&frame);
1857
1858 l->addCornerAnchors(firstItem: a, firstCorner: Qt::TopLeftCorner, secondItem: l, secondCorner: Qt::TopLeftCorner);
1859 l->addCornerAnchors(firstItem: a, firstCorner: Qt::BottomLeftCorner, secondItem: l, secondCorner: Qt::BottomLeftCorner);
1860
1861 l->addCornerAnchors(firstItem: b, firstCorner: Qt::TopLeftCorner, secondItem: a, secondCorner: Qt::TopRightCorner);
1862 l->addCornerAnchors(firstItem: b, firstCorner: Qt::TopRightCorner, secondItem: l, secondCorner: Qt::TopRightCorner);
1863
1864 l->addCornerAnchors(firstItem: c, firstCorner: Qt::TopLeftCorner, secondItem: b, secondCorner: Qt::BottomLeftCorner);
1865 l->addCornerAnchors(firstItem: c, firstCorner: Qt::BottomLeftCorner, secondItem: a, secondCorner: Qt::BottomRightCorner);
1866 l->addCornerAnchors(firstItem: c, firstCorner: Qt::TopRightCorner, secondItem: b, secondCorner: Qt::BottomRightCorner);
1867 l->addCornerAnchors(firstItem: c, firstCorner: Qt::BottomRightCorner, secondItem: l, secondCorner: Qt::BottomRightCorner);
1868
1869 l->effectiveSizeHint(which: Qt::MinimumSize);
1870
1871 QCOMPARE(layoutHasConflict(l), false);
1872
1873 if (!hasSimplification)
1874 QEXPECT_FAIL("", "Test depends on simplification.", Abort);
1875
1876 QCOMPARE(usedSimplex(l, Qt::Horizontal), false);
1877 QCOMPARE(usedSimplex(l, Qt::Vertical), false);
1878}
1879
1880/*
1881 Avoid regression where the saved prefSize would be lost. This was
1882 solved by saving the original spacing in the QGraphicsAnchorPrivate class
1883*/
1884void tst_QGraphicsAnchorLayout::spacingPersistency()
1885{
1886 QGraphicsWidget w;
1887 QGraphicsWidget *a = createItem();
1888 QGraphicsAnchorLayout *l = new QGraphicsAnchorLayout(&w);
1889
1890 l->addAnchors(firstItem: l, secondItem: a, orientations: Qt::Horizontal);
1891 QGraphicsAnchor *anchor = l->anchor(firstItem: l, firstEdge: Qt::AnchorLeft, secondItem: a, secondEdge: Qt::AnchorLeft);
1892
1893 anchor->setSpacing(-30);
1894 QCOMPARE(anchor->spacing(), -30.0);
1895
1896 anchor->setSpacing(30);
1897 QCOMPARE(anchor->spacing(), 30.0);
1898
1899 anchor->setSizePolicy(QSizePolicy::Ignored);
1900 w.effectiveSizeHint(which: Qt::PreferredSize);
1901
1902 QCOMPARE(anchor->spacing(), 30.0);
1903}
1904
1905/*
1906 Test whether a correct preferred size is set when a "snake" sequence is in parallel with the
1907 layout or half of the layout. The tricky thing here is that all items on the snake should
1908 keep their preferred sizes.
1909*/
1910void tst_QGraphicsAnchorLayout::snakeParallelWithLayout()
1911{
1912 QSizeF minSize(10, 20);
1913 QSizeF pref(50, 20);
1914 QSizeF maxSize(100, 20);
1915
1916 QGraphicsWidget *a = createItem(minimum: maxSize, preferred: maxSize, maximum: maxSize, name: "A");
1917 QGraphicsWidget *b = createItem(minimum: minSize, preferred: pref, maximum: maxSize, name: "B");
1918 QGraphicsWidget *c = createItem(minimum: maxSize, preferred: maxSize, maximum: maxSize, name: "C");
1919
1920 QGraphicsWidget parent;
1921 QGraphicsAnchorLayout *l = new QGraphicsAnchorLayout(&parent);
1922 l->setContentsMargins(left: 0, top: 0, right: 0, bottom: 0);
1923 l->setSpacing(0);
1924
1925 // First we'll do the case in parallel with the entire layout...
1926 l->addAnchor(firstItem: l, firstEdge: Qt::AnchorLeft, secondItem: a, secondEdge: Qt::AnchorLeft);
1927 l->addAnchor(firstItem: a, firstEdge: Qt::AnchorRight, secondItem: b, secondEdge: Qt::AnchorRight);
1928 l->addAnchor(firstItem: b, firstEdge: Qt::AnchorLeft, secondItem: c, secondEdge: Qt::AnchorLeft);
1929 l->addAnchor(firstItem: c, firstEdge: Qt::AnchorRight, secondItem: l, secondEdge: Qt::AnchorRight);
1930
1931 l->addAnchor(firstItem: l, firstEdge: Qt::AnchorTop, secondItem: a, secondEdge: Qt::AnchorTop);
1932 l->addAnchor(firstItem: a, firstEdge: Qt::AnchorBottom, secondItem: b, secondEdge: Qt::AnchorTop);
1933 l->addAnchor(firstItem: b, firstEdge: Qt::AnchorBottom, secondItem: c, secondEdge: Qt::AnchorTop);
1934 l->addAnchor(firstItem: c, firstEdge: Qt::AnchorBottom, secondItem: l, secondEdge: Qt::AnchorBottom);
1935
1936 parent.resize(size: l->effectiveSizeHint(which: Qt::PreferredSize));
1937
1938 // Note that A and C are fixed in the maximum size
1939 QCOMPARE(l->geometry(), QRectF(QPointF(0, 0), QSizeF(150, 60)));
1940 QCOMPARE(a->geometry(), QRectF(QPointF(0, 0), maxSize));
1941 QCOMPARE(b->geometry(), QRectF(QPointF(50, 20), pref));
1942 QCOMPARE(c->geometry(), QRectF(QPointF(50, 40), maxSize));
1943
1944 // Then, we change the "snake" to be in parallel with half of the layout
1945 delete l->anchor(firstItem: c, firstEdge: Qt::AnchorRight, secondItem: l, secondEdge: Qt::AnchorRight);
1946 l->addAnchor(firstItem: c, firstEdge: Qt::AnchorRight, secondItem: l, secondEdge: Qt::AnchorHorizontalCenter);
1947
1948 parent.resize(size: l->effectiveSizeHint(which: Qt::PreferredSize));
1949
1950 QCOMPARE(l->geometry(), QRectF(QPointF(0, 0), QSizeF(300, 60)));
1951 QCOMPARE(a->geometry(), QRectF(QPointF(0, 0), maxSize));
1952 QCOMPARE(b->geometry(), QRectF(QPointF(50, 20), pref));
1953 QCOMPARE(c->geometry(), QRectF(QPointF(50, 40), maxSize));
1954}
1955
1956/*
1957 Avoid regression where the sizeHint constraints would not be
1958 created for a parallel anchor that included the first layout half
1959*/
1960void tst_QGraphicsAnchorLayout::parallelToHalfLayout()
1961{
1962 QGraphicsWidget *a = createItem();
1963
1964 QGraphicsWidget w;
1965 QGraphicsAnchorLayout *l = new QGraphicsAnchorLayout(&w);
1966 l->setContentsMargins(left: 10, top: 10, right: 10, bottom: 10);
1967
1968 l->addAnchors(firstItem: l, secondItem: a, orientations: Qt::Vertical);
1969
1970 QGraphicsAnchor *anchor;
1971 anchor = l->addAnchor(firstItem: l, firstEdge: Qt::AnchorLeft, secondItem: a, secondEdge: Qt::AnchorLeft);
1972 anchor->setSpacing(5);
1973 anchor = l->addAnchor(firstItem: l, firstEdge: Qt::AnchorHorizontalCenter, secondItem: a, secondEdge: Qt::AnchorRight);
1974 anchor->setSpacing(-5);
1975
1976 const QSizeF minimumSizeHint = w.effectiveSizeHint(which: Qt::MinimumSize);
1977 const QSizeF preferredSizeHint = w.effectiveSizeHint(which: Qt::PreferredSize);
1978 const QSizeF maximumSizeHint = w.effectiveSizeHint(which: Qt::MaximumSize);
1979
1980 const QSizeF overhead = QSizeF(10 + 5 + 5, 10) * 2;
1981
1982 QCOMPARE(minimumSizeHint, QSizeF(200, 100) + overhead);
1983 QCOMPARE(preferredSizeHint, QSizeF(300, 100) + overhead);
1984 QCOMPARE(maximumSizeHint, QSizeF(400, 100) + overhead);
1985}
1986
1987void tst_QGraphicsAnchorLayout::globalSpacing()
1988{
1989 QGraphicsWidget *a = createItem();
1990 QGraphicsWidget *b = createItem();
1991
1992 QGraphicsWidget w;
1993 QGraphicsAnchorLayout *l = new QGraphicsAnchorLayout(&w);
1994
1995 l->addCornerAnchors(firstItem: l, firstCorner: Qt::TopLeftCorner, secondItem: a, secondCorner: Qt::TopLeftCorner);
1996 l->addCornerAnchors(firstItem: a, firstCorner: Qt::BottomRightCorner, secondItem: b, secondCorner: Qt::TopLeftCorner);
1997 l->addCornerAnchors(firstItem: b, firstCorner: Qt::BottomRightCorner, secondItem: l, secondCorner: Qt::BottomRightCorner);
1998
1999 w.resize(size: w.effectiveSizeHint(which: Qt::PreferredSize));
2000 qreal vSpacing = b->geometry().top() - a->geometry().bottom();
2001 qreal hSpacing = b->geometry().left() - a->geometry().right();
2002
2003 // Set spacings manually
2004 l->setVerticalSpacing(vSpacing + 10);
2005 l->setHorizontalSpacing(hSpacing + 5);
2006
2007 w.resize(size: w.effectiveSizeHint(which: Qt::PreferredSize));
2008 qreal newVSpacing = b->geometry().top() - a->geometry().bottom();
2009 qreal newHSpacing = b->geometry().left() - a->geometry().right();
2010
2011 QCOMPARE(newVSpacing, vSpacing + 10);
2012 QCOMPARE(newHSpacing, hSpacing + 5);
2013
2014 // Set a negative spacing. This will unset the previous spacing and
2015 // bring back the widget-defined spacing.
2016 l->setSpacing(-1);
2017
2018 w.resize(size: w.effectiveSizeHint(which: Qt::PreferredSize));
2019 newVSpacing = b->geometry().top() - a->geometry().bottom();
2020 newHSpacing = b->geometry().left() - a->geometry().right();
2021
2022 QCOMPARE(newVSpacing, vSpacing);
2023 QCOMPARE(newHSpacing, hSpacing);
2024}
2025
2026void tst_QGraphicsAnchorLayout::graphicsAnchorHandling()
2027{
2028 QGraphicsAnchorLayout *l = new QGraphicsAnchorLayout();
2029 QGraphicsWidget *a = createItem();
2030
2031 l->addAnchors(firstItem: l, secondItem: a);
2032
2033 QGraphicsAnchor *layoutAnchor = l->anchor(firstItem: l, firstEdge: Qt::AnchorTop, secondItem: l, secondEdge: Qt::AnchorBottom);
2034 QGraphicsAnchor *itemAnchor = l->anchor(firstItem: a, firstEdge: Qt::AnchorTop, secondItem: a, secondEdge: Qt::AnchorBottom);
2035 QGraphicsAnchor *invalidAnchor = l->anchor(firstItem: a, firstEdge: Qt::AnchorTop, secondItem: l, secondEdge: Qt::AnchorBottom);
2036
2037 // Ensure none of these anchors are accessible.
2038 QVERIFY(!layoutAnchor);
2039 QVERIFY(!itemAnchor);
2040 QVERIFY(!invalidAnchor);
2041
2042 // Hook the anchors to a QObject
2043 QObject object;
2044 QGraphicsAnchor *userAnchor = l->anchor(firstItem: l, firstEdge: Qt::AnchorTop, secondItem: a, secondEdge: Qt::AnchorTop);
2045 userAnchor->setParent(&object);
2046 userAnchor = l->anchor(firstItem: l, firstEdge: Qt::AnchorBottom, secondItem: a, secondEdge: Qt::AnchorBottom);
2047 userAnchor->setParent(&object);
2048 userAnchor = l->anchor(firstItem: l, firstEdge: Qt::AnchorRight, secondItem: a, secondEdge: Qt::AnchorRight);
2049 userAnchor->setParent(&object);
2050 userAnchor = l->anchor(firstItem: l, firstEdge: Qt::AnchorLeft, secondItem: a, secondEdge: Qt::AnchorLeft);
2051 userAnchor->setParent(&object);
2052
2053 QCOMPARE(object.children().size(), 4);
2054
2055 // Delete layout, this will cause all anchors to be deleted internally.
2056 // We expect the public QGraphicsAnchor instances to be deleted too.
2057 delete l;
2058 QCOMPARE(object.children().size(), 0);
2059
2060 delete a;
2061}
2062
2063void tst_QGraphicsAnchorLayout::invalidHierarchyCheck()
2064{
2065 QGraphicsWidget window(0, Qt::Window);
2066 QGraphicsAnchorLayout *l = new QGraphicsAnchorLayout;
2067 window.setLayout(l);
2068
2069 QCOMPARE(l->count(), 0);
2070 QTest::ignoreMessage(type: QtWarningMsg, message: "QGraphicsAnchorLayout::addAnchor(): "
2071 "You cannot add the parent of the layout to the layout.");
2072 QVERIFY(!l->addAnchor(l, Qt::AnchorLeft, &window, Qt::AnchorLeft));
2073 QTest::ignoreMessage(type: QtWarningMsg, message: "QGraphicsAnchorLayout::addAnchor(): "
2074 "You cannot add the parent of the layout to the layout.");
2075 l->addAnchors(firstItem: l, secondItem: &window);
2076 QTest::ignoreMessage(type: QtWarningMsg, message: "QGraphicsAnchorLayout::addAnchor(): "
2077 "You cannot add the parent of the layout to the layout.");
2078 l->addCornerAnchors(firstItem: l, firstCorner: Qt::TopLeftCorner, secondItem: &window, secondCorner: Qt::TopLeftCorner);
2079 QCOMPARE(l->count(), 0);
2080}
2081
2082QTEST_MAIN(tst_QGraphicsAnchorLayout)
2083#include "tst_qgraphicsanchorlayout.moc"
2084

source code of qtbase/tests/auto/widgets/graphicsview/qgraphicsanchorlayout/tst_qgraphicsanchorlayout.cpp