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