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
30#include <QtTest/QtTest>
31#include <qgraphicslinearlayout.h>
32#include <qgraphicsproxywidget.h>
33#include <qgraphicswidget.h>
34#include <qgraphicsscene.h>
35#include <qgraphicsview.h>
36#include <qapplication.h>
37#include <QtWidgets/qstyle.h>
38#include <QtWidgets/qproxystyle.h>
39
40class tst_QGraphicsLinearLayout : public QObject {
41Q_OBJECT
42
43private slots:
44 void initTestCase();
45 void qgraphicslinearlayout_data();
46 void qgraphicslinearlayout();
47
48 void alignment_data();
49 void alignment();
50 void count_data();
51 void count();
52 void dump_data();
53 void dump();
54 void geometry_data();
55 void geometry();
56 void insertItem_data();
57 void insertItem();
58 void insertStretch_data();
59 void insertStretch();
60 void invalidate_data();
61 void invalidate();
62 void itemAt_data();
63 void itemAt();
64 void itemAt_visualOrder();
65 void orientation_data();
66 void orientation();
67 void removeAt_data();
68 void removeAt();
69 void removeItem_data();
70 void removeItem();
71 void setGeometry_data();
72 void setGeometry();
73 void defaultSpacing();
74 void setSpacing_data();
75 void setSpacing();
76 void setItemSpacing_data();
77 void setItemSpacing();
78 void itemSpacing();
79 void setStretchFactor_data();
80 void setStretchFactor();
81 void testStretch();
82 void defaultStretchFactors_data();
83 void defaultStretchFactors();
84 void sizeHint_data();
85 void sizeHint();
86 void updateGeometry();
87 void layoutDirection();
88 void removeLayout();
89 void avoidRecursionInInsertItem();
90 void styleInfoLeak();
91 void testAlignmentInLargerLayout();
92 void testOffByOneInLargerLayout();
93 void testDefaultAlignment();
94 void combineSizePolicies();
95 void hiddenItems();
96
97 // Task specific tests
98 void task218400_insertStretchCrash();
99};
100
101// Subclass that exposes the protected functions.
102class SubQGraphicsLinearLayout : public QGraphicsLinearLayout {
103public:
104 SubQGraphicsLinearLayout(Qt::Orientation orientation = Qt::Horizontal) : QGraphicsLinearLayout(orientation),
105 graphicsSceneResize(0),
106 layoutRequest(0),
107 layoutDirectionChange(0)
108 { }
109
110 void widgetEvent(QEvent *e)
111 {
112 switch (e->type()) {
113 case QEvent::GraphicsSceneResize:
114 graphicsSceneResize++;
115 break;
116 case QEvent::LayoutRequest:
117 layoutRequest++;
118 break;
119 case QEvent::LayoutDirectionChange:
120 layoutDirectionChange++;
121 break;
122 default:
123 break;
124 }
125
126 QGraphicsLinearLayout::widgetEvent(e);
127 }
128
129 int graphicsSceneResize;
130 int layoutRequest;
131 int layoutDirectionChange;
132};
133
134// This will be called before the first test function is executed.
135// It is only called once.
136void tst_QGraphicsLinearLayout::initTestCase()
137{
138 // since the style will influence the results, we have to ensure
139 // that the tests are run using the same style on all platforms
140 QApplication::setStyle("windows");
141}
142
143class RectWidget : public QGraphicsWidget
144{
145public:
146 RectWidget(QGraphicsItem *parent = 0, const QBrush &brush = QBrush()) : QGraphicsWidget(parent){ m_brush = brush;}
147
148 void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
149 {
150 Q_UNUSED(option);
151 Q_UNUSED(widget);
152 painter->setBrush(m_brush);
153 painter->drawRoundedRect(rect: rect(), xRadius: 25, yRadius: 25, mode: Qt::RelativeSize);
154 }
155
156 void setSizeHint(Qt::SizeHint which, const QSizeF &size) {
157 m_sizeHints[which] = size;
158 updateGeometry();
159 }
160
161 virtual QSizeF sizeHint(Qt::SizeHint which, const QSizeF &constraint = QSizeF()) const {
162 if (m_sizeHints[which].isValid()) {
163 return m_sizeHints[which];
164 }
165 return QGraphicsWidget::sizeHint(which, constraint);
166 }
167
168 // Initializer {} is a workaround for gcc bug 68949
169 QSizeF m_sizeHints[Qt::NSizeHints] {};
170 QBrush m_brush;
171};
172
173
174Q_DECLARE_METATYPE(Qt::Orientation)
175void tst_QGraphicsLinearLayout::qgraphicslinearlayout_data()
176{
177 QTest::addColumn<Qt::Orientation>(name: "orientation");
178 QTest::newRow(dataTag: "vertical") << Qt::Vertical;
179 QTest::newRow(dataTag: "horizontal") << Qt::Horizontal;
180}
181
182void tst_QGraphicsLinearLayout::qgraphicslinearlayout()
183{
184 QFETCH(Qt::Orientation, orientation);
185 SubQGraphicsLinearLayout layout(orientation);
186 QVERIFY(layout.isLayout());
187
188 qApp->processEvents();
189 QCOMPARE(layout.graphicsSceneResize, 0);
190 QCOMPARE(layout.layoutRequest, 0);
191 QCOMPARE(layout.layoutDirectionChange, 0);
192
193 layout.setOrientation(Qt::Vertical);
194 layout.orientation();
195 QTest::ignoreMessage(type: QtWarningMsg, message: "QGraphicsLinearLayout::insertItem: cannot insert null item");
196 QCOMPARE(layout.count(), 0);
197 layout.addItem(item: 0);
198 QCOMPARE(layout.count(), 0);
199 layout.addStretch(stretch: 0);
200 QCOMPARE(layout.count(), 0);
201 QTest::ignoreMessage(type: QtWarningMsg, message: "QGraphicsLinearLayout::insertItem: cannot insert null item");
202 layout.insertItem(index: 0, item: 0);
203 layout.insertStretch(index: 0, stretch: 0);
204 layout.removeItem(item: 0);
205 QCOMPARE(layout.count(), 0);
206 layout.setSpacing(0);
207 layout.spacing();
208 QTest::ignoreMessage(type: QtWarningMsg, message: "QGraphicsLinearLayout::setStretchFactor: cannot assign a stretch factor to a null item");
209 layout.setStretchFactor(item: 0, stretch: 0);
210 QTest::ignoreMessage(type: QtWarningMsg, message: "QGraphicsLinearLayout::setStretchFactor: cannot return a stretch factor for a null item");
211 layout.stretchFactor(item: 0);
212 layout.setAlignment(item: 0, alignment: Qt::AlignHCenter);
213 QCOMPARE(layout.alignment(0), 0);
214 layout.setGeometry(QRectF());
215 layout.geometry();
216 QCOMPARE(layout.count(), 0);
217 layout.invalidate();
218 layout.sizeHint(which: Qt::MinimumSize, constraint: QSizeF());
219}
220
221Q_DECLARE_METATYPE(Qt::AlignmentFlag)
222void tst_QGraphicsLinearLayout::alignment_data()
223{
224 QTest::addColumn<Qt::Orientation>(name: "orientation");
225 QTest::addColumn<QSize>(name: "newSize");
226 QTest::newRow(dataTag: "h-defaultsize") << Qt::Horizontal << QSize();
227 QTest::newRow(dataTag: "v-defaultsize") << Qt::Vertical << QSize();
228 QTest::newRow(dataTag: "h-300") << Qt::Horizontal << QSize(300,100);
229 QTest::newRow(dataTag: "v-300") << Qt::Vertical << QSize(100, 300);
230}
231
232void tst_QGraphicsLinearLayout::alignment()
233{
234 QFETCH(Qt::Orientation, orientation);
235 QFETCH(QSize, newSize);
236
237 //if (alignment == Qt::AlignAbsolute)
238 // QApplication::setLayoutDirection(Qt::RightToLeft);
239 QGraphicsScene scene;
240 QGraphicsView view(&scene);
241 view.setSceneRect(ax: 0, ay: 0, aw: 320, ah: 240);
242 QGraphicsWidget *widget = new QGraphicsWidget(0, Qt::Window);
243 SubQGraphicsLinearLayout &layout = *(new SubQGraphicsLinearLayout(orientation));
244 scene.addItem(item: widget);
245 widget->setLayout(&layout);
246
247 static const Qt::Alignment alignmentsToTest[] = {
248 Qt::Alignment{},
249 Qt::AlignLeft,
250 Qt::AlignRight,
251 Qt::AlignHCenter,
252 Qt::AlignTop,
253 Qt::AlignBottom,
254 Qt::AlignVCenter,
255 Qt::AlignCenter,
256 Qt::Alignment{},
257 Qt::AlignLeft,
258 Qt::AlignRight,
259 Qt::AlignHCenter,
260 Qt::AlignTop,
261 Qt::AlignBottom,
262 Qt::AlignVCenter,
263 Qt::AlignCenter
264 };
265
266 int i;
267 bool addWidget = true;
268 for (size_t i = 0; i < sizeof(alignmentsToTest)/sizeof(Qt::Alignment); ++i) {
269 QGraphicsLayoutItem *loutItem;
270 Qt::Alignment align = alignmentsToTest[i];
271 if (!align && i > 0)
272 addWidget = false;
273 if (addWidget)
274 loutItem = new RectWidget(widget, QBrush(Qt::blue));
275 else {
276 SubQGraphicsLinearLayout *lay = new SubQGraphicsLinearLayout(Qt::Vertical);
277 lay->setSizePolicy(hPolicy: QSizePolicy::Preferred, vPolicy: QSizePolicy::Preferred, controlType: QSizePolicy::DefaultType);
278 lay->setContentsMargins(left: 0,top: 0,right: 0,bottom: 0);
279 QGraphicsWidget *w = new RectWidget(widget, QBrush(Qt::red));
280 if (align) {
281 w->setMinimumSize(QSizeF(10,10));
282 w->setMaximumSize(QSizeF(10,10));
283 } else {
284 w->setMinimumSize(QSizeF(50,50));
285 w->setMaximumSize(QSizeF(50,50));
286 }
287 lay->addItem(item: w);
288 loutItem = lay;
289 }
290 if (align) {
291 loutItem->setMinimumSize(QSizeF(10,10));
292 loutItem->setMaximumSize(QSizeF(10,10));
293 } else {
294 loutItem->setMinimumSize(QSizeF(50,50));
295 loutItem->setMaximumSize(QSizeF(50,50));
296 }
297 layout.addItem(item: loutItem);
298 layout.setAlignment(item: loutItem, alignment: align);
299
300 }
301 layout.setContentsMargins(left: 0,top: 0,right: 0,bottom: 0);
302 int spacing = 1;
303 layout.setSpacing(spacing);
304 if (newSize.isValid())
305 widget->resize(size: newSize);
306 view.show();
307 widget->show();
308 QVERIFY(QTest::qWaitForWindowExposed(&view));
309 QApplication::processEvents();
310
311 int x = 0;
312 int y = 0;
313 for (i = 0; i < layout.count(); ++i) {
314 QGraphicsLayoutItem *item = layout.itemAt(index: i);
315 Qt::Alignment align = layout.alignment(item);
316
317 int w = 10;
318 int h = 10;
319 switch(align) {
320 case Qt::AlignLeft:
321 break;
322 case Qt::AlignRight:
323 if (orientation == Qt::Vertical)
324 x += 40;
325 break;
326 case Qt::AlignHCenter:
327 if (orientation == Qt::Vertical)
328 x += 20;
329 break;
330 case Qt::AlignTop:
331 break;
332 case Qt::AlignBottom:
333 if (orientation == Qt::Horizontal)
334 y += 40;
335 break;
336 case Qt::AlignVCenter:
337 if (orientation == Qt::Horizontal)
338 y += 20;
339 break;
340 case Qt::AlignCenter:
341 if (orientation == Qt::Horizontal)
342 y += 20;
343 else
344 x += 20;
345 break;
346 case 0:
347 w = 50;
348 h = 50;
349 break;
350 default:
351 break;
352 }
353 QRectF expectedGeometry(x, y, w, h);
354 QCOMPARE(item->geometry(), expectedGeometry);
355 if (orientation == Qt::Horizontal) {
356 x += w;
357 y = 0;
358 x += spacing;
359 } else {
360 x = 0;
361 y += h;
362 y += spacing;
363 }
364 }
365}
366
367void tst_QGraphicsLinearLayout::count_data()
368{
369 QTest::addColumn<int>(name: "itemCount");
370 QTest::addColumn<int>(name: "layoutCount");
371 QTest::newRow(dataTag: "0, 0") << 0 << 0;
372 QTest::newRow(dataTag: "0, 5") << 0 << 5;
373 QTest::newRow(dataTag: "5, 0") << 5 << 0;
374 QTest::newRow(dataTag: "5, 5") << 5 << 5;
375}
376
377// int count() const public
378void tst_QGraphicsLinearLayout::count()
379{
380 QFETCH(int, itemCount);
381 QFETCH(int, layoutCount);
382
383 SubQGraphicsLinearLayout layout;
384 QCOMPARE(layout.count(), 0);
385
386 for (int i = 0; i < itemCount; ++i)
387 layout.addItem(item: new QGraphicsWidget);
388 QCOMPARE(layout.count(), itemCount);
389
390 for (int i = 0; i < layoutCount; ++i)
391 layout.addItem(item: new SubQGraphicsLinearLayout);
392 QCOMPARE(layout.count(), itemCount + layoutCount);
393
394 // see also removeAt()
395}
396
397void tst_QGraphicsLinearLayout::dump_data()
398{
399 QTest::addColumn<int>(name: "itemCount");
400 QTest::addColumn<int>(name: "layoutCount");
401 for (int i = -1; i < 3; ++i) {
402 const QByteArray iB = QByteArray::number(i);
403 QTest::newRow(dataTag: (iB + ", 0, 0").constData()) << 0 << 0;
404 QTest::newRow(dataTag: (iB + ", 0, 5").constData()) << 5 << 5;
405 QTest::newRow(dataTag: (iB + ", 5, 0").constData()) << 5 << 5;
406 QTest::newRow(dataTag: (iB + ", 5, 5").constData()) << 5 << 5;
407 }
408}
409
410// void dump(int indent = 0) const public
411void tst_QGraphicsLinearLayout::dump()
412{
413 QFETCH(int, itemCount);
414 QFETCH(int, layoutCount);
415 SubQGraphicsLinearLayout layout;
416 for (int i = 0; i < itemCount; ++i)
417 layout.addItem(item: new QGraphicsWidget);
418 for (int i = 0; i < layoutCount; ++i)
419 layout.addItem(item: new SubQGraphicsLinearLayout);
420}
421
422void tst_QGraphicsLinearLayout::geometry_data()
423{
424 QTest::addColumn<int>(name: "itemCount");
425 QTest::addColumn<int>(name: "layoutCount");
426 QTest::addColumn<int>(name: "itemSpacing");
427 QTest::addColumn<int>(name: "spacing");
428 QTest::addColumn<Qt::Orientation>(name: "orientation");
429 QTest::addColumn<QRectF>(name: "rect");
430
431 QTest::newRow(dataTag: "null") << 0 << 0 << 0 << 0 << Qt::Horizontal << QRectF();
432
433 QTest::newRow(dataTag: "one item") << 1 << 0 << 0 << 0 << Qt::Horizontal << QRectF(0, 0, 10, 10);
434 QTest::newRow(dataTag: "one layout") << 0 << 1 << 0 << 0 << Qt::Horizontal << QRectF(0, 0, 10, 10);
435 QTest::newRow(dataTag: "two h") << 1 << 1 << 0 << 0 << Qt::Horizontal << QRectF(0, 0, 20, 10);
436 QTest::newRow(dataTag: "two v") << 1 << 1 << 0 << 0 << Qt::Vertical << QRectF(0, 0, 10, 20);
437
438 QTest::newRow(dataTag: "two w/itemspacing") << 1 << 1 << 5 << 0 << Qt::Horizontal << QRectF(0, 0, 25, 10);
439 QTest::newRow(dataTag: "two w/spacing") << 1 << 1 << 8 << 0 << Qt::Horizontal << QRectF(0, 0, 28, 10);
440
441 QTest::newRow(dataTag: "two w/itemspacing v") << 1 << 1 << 5 << 0 << Qt::Vertical << QRectF(0, 0, 10, 25);
442 QTest::newRow(dataTag: "two w/spacing v") << 1 << 1 << 8 << 0 << Qt::Vertical << QRectF(0, 0, 10, 28);
443}
444
445// QRectF geometry() const public
446void tst_QGraphicsLinearLayout::geometry()
447{
448 QFETCH(int, itemCount);
449 QFETCH(int, layoutCount);
450 QFETCH(int, itemSpacing);
451 QFETCH(int, spacing);
452 QFETCH(Qt::Orientation, orientation);
453 QFETCH(QRectF, rect);
454 QGraphicsScene scene;
455 QGraphicsView view(&scene);
456 QGraphicsWidget *widget = new QGraphicsWidget(0, Qt::Window);
457 SubQGraphicsLinearLayout &layout = *(new SubQGraphicsLinearLayout(orientation));
458 scene.addItem(item: widget);
459 widget->setLayout(&layout);
460 widget->setContentsMargins(left: 0, top: 0, right: 0, bottom: 0);
461 for (int i = 0; i < itemCount; ++i)
462 layout.addItem(item: new QGraphicsWidget);
463 for (int i = 0; i < layoutCount; ++i)
464 layout.addItem(item: new SubQGraphicsLinearLayout);
465
466 for (int i = 0; i < layout.count(); ++i) {
467 QGraphicsLayoutItem *item = layout.itemAt(index: i);
468 item->setMaximumSize(aw: 10, ah: 10);
469 item->setMinimumSize(aw: 10, ah: 10);
470 }
471 layout.setItemSpacing(index: 0, spacing: itemSpacing);
472 layout.setSpacing(spacing);
473 layout.setContentsMargins(left: 0, top: 0, right: 0, bottom: 0);
474
475 widget->show();
476 view.show();
477 QApplication::processEvents();
478 QCOMPARE(layout.geometry(), rect);
479 delete widget;
480}
481
482void tst_QGraphicsLinearLayout::insertItem_data()
483{
484 QTest::addColumn<int>(name: "itemCount");
485 QTest::addColumn<int>(name: "layoutCount");
486 QTest::addColumn<int>(name: "insertItemAt");
487 QTest::addColumn<bool>(name: "isWidget");
488 for (int i = -1; i < 4; ++i) {
489 const QByteArray iB = QByteArray::number(i);
490 for (int j = 0; j < 2; ++j) {
491 const QByteArray postFix = iB + ' ' + QByteArray::number(j);
492 QTest::newRow(dataTag: ("0, 0, " + postFix).constData()) << 0 << 0 << i << (bool)j;
493 QTest::newRow(dataTag: ("1, 0, " + postFix).constData()) << 1 << 0 << i << (bool)j;
494 QTest::newRow(dataTag: ("0, 1, " + postFix).constData()) << 0 << 1 << i << (bool)j;
495 QTest::newRow(dataTag: ("2, 2, " + postFix).constData()) << 2 << 2 << i << (bool)j;
496 }
497 }
498}
499
500// void insertItem(int index, QGraphicsLayoutItem* item) public
501void tst_QGraphicsLinearLayout::insertItem()
502{
503 QFETCH(int, itemCount);
504 QFETCH(int, layoutCount);
505 QFETCH(int, insertItemAt);
506 QFETCH(bool, isWidget);
507 if (insertItemAt > layoutCount + itemCount)
508 return;
509
510 SubQGraphicsLinearLayout layout;
511 for (int i = 0; i < itemCount; ++i)
512 layout.addItem(item: new QGraphicsWidget);
513 for (int i = 0; i < layoutCount; ++i)
514 layout.addItem(item: new SubQGraphicsLinearLayout);
515
516 QGraphicsLayoutItem *item = 0;
517 if (isWidget)
518 item = new QGraphicsWidget;
519 else
520 item = new SubQGraphicsLinearLayout;
521
522 QSizeF oldSizeHint = layout.sizeHint(which: Qt::PreferredSize, constraint: QSizeF());
523 layout.insertItem(index: insertItemAt, item);
524 QCOMPARE(layout.count(), itemCount + layoutCount + 1);
525
526 if (insertItemAt >= 0 && (itemCount + layoutCount >= 0)) {
527 QCOMPARE(layout.itemAt(insertItemAt), item);
528 }
529
530 layout.activate();
531 QSizeF newSizeHint = layout.sizeHint(which: Qt::PreferredSize, constraint: QSizeF());
532 if (!isWidget && layout.count() == 1)
533 QCOMPARE(oldSizeHint.width(), newSizeHint.width());
534 else if (itemCount + layoutCount > 0)
535 QVERIFY(oldSizeHint.width() < newSizeHint.width());
536}
537
538void tst_QGraphicsLinearLayout::insertStretch_data()
539{
540 QTest::addColumn<int>(name: "itemCount");
541 QTest::addColumn<int>(name: "layoutCount");
542 QTest::addColumn<int>(name: "insertItemAt");
543 QTest::addColumn<int>(name: "stretch");
544 for (int i = -1; i < 4; ++i) {
545 const QByteArray iB = QByteArray::number(i);
546 for (int j = 0; j < 2; ++j) {
547 const QByteArray postFix = iB + ' ' + QByteArray::number(j);
548 QTest::newRow(dataTag: ("0, 0, " + postFix).constData()) << 0 << 0 << i << j;
549 QTest::newRow(dataTag: ("1, 0, " + postFix).constData()) << 1 << 0 << i << j;
550 QTest::newRow(dataTag: ("0, 1, " + postFix).constData()) << 0 << 1 << i << j;
551 QTest::newRow(dataTag: ("2, 2, " + postFix).constData()) << 2 << 2 << i << j;
552 }
553 }
554}
555
556// void insertStretch(int index, int stretch = 1) public
557void tst_QGraphicsLinearLayout::insertStretch()
558{
559 QFETCH(int, itemCount);
560 QFETCH(int, layoutCount);
561 QFETCH(int, insertItemAt);
562 QFETCH(int, stretch);
563 if (insertItemAt > layoutCount + itemCount)
564 return;
565
566 QGraphicsScene scene;
567 QGraphicsView view(&scene);
568 QGraphicsWidget *widget = new QGraphicsWidget(0, Qt::Window);
569 SubQGraphicsLinearLayout *layout = new SubQGraphicsLinearLayout;
570 scene.addItem(item: widget);
571
572 QList<QGraphicsWidget *>items;
573 QGraphicsWidget *item = 0;
574 for (int i = 0; i < itemCount; ++i) {
575 item = new RectWidget;
576 item->setMinimumSize(aw: 10, ah: 10);
577 item->setPreferredSize(aw: 25, ah: 25);
578 item->setMaximumSize(aw: 50, ah: 50);
579 layout->addItem(item);
580 }
581 for (int i = 0; i < layoutCount; ++i) {
582 item = new RectWidget;
583 item->setMinimumSize(aw: 10, ah: 10);
584 item->setPreferredSize(aw: 25, ah: 25);
585 item->setMaximumSize(aw: 50, ah: 50);
586 SubQGraphicsLinearLayout *sublayout = new SubQGraphicsLinearLayout;
587 sublayout->addItem(item);
588 layout->addItem(item: sublayout);
589 }
590 widget->setLayout(layout);
591 layout->insertStretch(index: insertItemAt, stretch);
592 QCOMPARE(layout->count(), itemCount + layoutCount);
593
594 layout->activate();
595 view.show();
596 widget->show();
597
598 int prevStretch = -2;
599 int prevWidth = -2;
600 widget->resize(w: (layoutCount + itemCount) * 25 + 25, h: 25);
601 for (int i = 0; i < layout->count(); ++i) {
602 if (QGraphicsLayoutItem *item = layout->itemAt(index: i)) {
603 if (prevStretch != -2) {
604 if (layout->stretchFactor(item) >= prevStretch) {
605 QVERIFY(item->geometry().width() >= prevWidth);
606 } else {
607 QVERIFY(item->geometry().width() < prevWidth);
608 }
609 }
610 prevStretch = layout->stretchFactor(item);
611 prevWidth = (int)(item->geometry().width());
612 }
613 }
614
615 delete widget;
616}
617
618void tst_QGraphicsLinearLayout::invalidate_data()
619{
620 QTest::addColumn<int>(name: "count");
621 QTest::newRow(dataTag: "0") << 0;
622 QTest::newRow(dataTag: "1") << 1;
623 QTest::newRow(dataTag: "2") << 2;
624 QTest::newRow(dataTag: "3") << 3;
625}
626
627// void invalidate() public
628void tst_QGraphicsLinearLayout::invalidate()
629{
630 QFETCH(int, count);
631 QGraphicsScene scene;
632 QGraphicsView view(&scene);
633 QGraphicsWidget *widget = new QGraphicsWidget(0, Qt::Window);
634 SubQGraphicsLinearLayout &layout = *(new SubQGraphicsLinearLayout);
635 scene.addItem(item: widget);
636 widget->setLayout(&layout);
637 widget->setContentsMargins(left: 0, top: 0, right: 0, bottom: 0);
638 layout.setContentsMargins(left: 0, top: 0, right: 0, bottom: 0);
639 view.show();
640 widget->show();
641 QVERIFY(QTest::qWaitForWindowExposed(&view));
642 qApp->processEvents();
643 layout.layoutRequest = 0;
644
645 layout.setContentsMargins(left: 1, top: 2, right: 3, bottom: 4);
646 QApplication::sendPostedEvents(receiver: 0, event_type: 0);
647 QCOMPARE(layout.layoutRequest, 1);
648
649 layout.setOrientation(Qt::Vertical);
650 QApplication::sendPostedEvents(receiver: 0, event_type: 0);
651 QCOMPARE(layout.layoutRequest, 2);
652
653 for (int i = 0; i < count; ++i)
654 layout.invalidate(); // Event is compressed, should only get one layoutrequest
655 QApplication::sendPostedEvents(receiver: 0, event_type: 0);
656 QCOMPARE(layout.layoutRequest, count ? 3 : 2);
657 delete widget;
658}
659
660void tst_QGraphicsLinearLayout::itemAt_data()
661{
662 QTest::addColumn<int>(name: "index");
663 QTest::newRow(dataTag: "0") << 0;
664 QTest::newRow(dataTag: "1") << 1;
665 QTest::newRow(dataTag: "2") << 2;
666}
667
668// QGraphicsLayoutItem* itemAt(int index) const public
669void tst_QGraphicsLinearLayout::itemAt()
670{
671 // see also the insertItem() etc tests
672 QFETCH(int, index);
673 SubQGraphicsLinearLayout layout;
674 for (int i = 0; i < 3; ++i)
675 layout.addItem(item: new QGraphicsWidget);
676
677 QVERIFY(layout.itemAt(index) != 0);
678}
679
680void tst_QGraphicsLinearLayout::itemAt_visualOrder()
681{
682 QGraphicsLinearLayout *l = new QGraphicsLinearLayout;
683
684 QGraphicsWidget *w1 = new QGraphicsWidget;
685 l->addItem(item: w1);
686
687 QGraphicsWidget *w3 = new QGraphicsWidget;
688 l->addItem(item: w3);
689
690 QGraphicsWidget *w0 = new QGraphicsWidget;
691 l->insertItem(index: 0, item: w0);
692
693 QGraphicsWidget *w2 = new QGraphicsWidget;
694 l->insertItem(index: 2, item: w2);
695
696 QCOMPARE(l->itemAt(0), static_cast<QGraphicsLayoutItem*>(w0));
697 QCOMPARE(l->itemAt(1), static_cast<QGraphicsLayoutItem*>(w1));
698 QCOMPARE(l->itemAt(2), static_cast<QGraphicsLayoutItem*>(w2));
699 QCOMPARE(l->itemAt(3), static_cast<QGraphicsLayoutItem*>(w3));
700}
701
702void tst_QGraphicsLinearLayout::orientation_data()
703{
704 QTest::addColumn<Qt::Orientation>(name: "orientation");
705 QTest::newRow(dataTag: "vertical") << Qt::Vertical;
706 QTest::newRow(dataTag: "horizontal") << Qt::Horizontal;
707}
708
709// Qt::Orientation orientation() const public
710void tst_QGraphicsLinearLayout::orientation()
711{
712 QFETCH(Qt::Orientation, orientation);
713
714 QGraphicsScene scene;
715 QGraphicsView view(&scene);
716 QGraphicsWidget *widget = new QGraphicsWidget(0, Qt::Window);
717 Qt::Orientation initialOrientation = (orientation == Qt::Vertical ? Qt::Horizontal : Qt::Vertical);
718 SubQGraphicsLinearLayout &layout = *(new SubQGraphicsLinearLayout(initialOrientation));
719 scene.addItem(item: widget);
720 widget->setLayout(&layout);
721 widget->setContentsMargins(left: 0, top: 0, right: 0, bottom: 0);
722 layout.setContentsMargins(left: 0, top: 0, right: 0, bottom: 0);
723 int i;
724 int itemCount = 3;
725 for (i = 0; i < itemCount; ++i)
726 layout.addItem(item: new RectWidget);
727 QCOMPARE(layout.orientation(), initialOrientation);
728 QList<qreal> positions;
729
730 view.show();
731 widget->show();
732 qApp->processEvents();
733
734 for (i = 0; i < itemCount; ++i) {
735 QGraphicsWidget *item = static_cast<QGraphicsWidget*>(layout.itemAt(index: i));
736 qreal pos;
737 if (initialOrientation == Qt::Horizontal)
738 pos = item->pos().x();
739 else
740 pos = item->pos().y();
741 positions.append(t: pos);
742
743 }
744
745 layout.setOrientation(orientation);
746 QCOMPARE(layout.orientation(), orientation);
747 // important to resize to preferredsize when orientation is switched
748 widget->resize(size: widget->effectiveSizeHint(which: Qt::PreferredSize));
749 qApp->processEvents();
750 for (i = 0; i < positions.count(); ++i) {
751 QGraphicsWidget *item = static_cast<QGraphicsWidget*>(layout.itemAt(index: i));
752 if (initialOrientation == Qt::Horizontal)
753 QCOMPARE(item->pos().y(), positions.at(i));
754 else
755 QCOMPARE(item->pos().x(), positions.at(i));
756 }
757}
758
759void tst_QGraphicsLinearLayout::removeAt_data()
760{
761 QTest::addColumn<int>(name: "itemCount");
762 QTest::addColumn<int>(name: "layoutCount");
763 QTest::addColumn<int>(name: "removeItemAt");
764 QTest::addColumn<Qt::Orientation>(name: "orientation");
765 for (int i = -1; i < 4; ++i) {
766 const QByteArray iB = QByteArray::number(i);
767 for (int k = 0; k < 2; ++k) {
768 Qt::Orientation orientation = (k == 0) ? Qt::Vertical : Qt::Horizontal;
769 QTest::newRow(dataTag: ("0, 0, " + iB).constData()) << 0 << 0 << i << orientation;
770 QTest::newRow(dataTag: ("1, 0, " + iB).constData()) << 1 << 0 << i << orientation;
771 QTest::newRow(dataTag: ("0, 1, " + iB).constData()) << 0 << 1 << i << orientation;
772 QTest::newRow(dataTag: ("2, 2, " + iB).constData()) << 2 << 2 << i << orientation;
773 }
774 }
775}
776
777// void removeAt(int index) public
778void tst_QGraphicsLinearLayout::removeAt()
779{
780 QFETCH(int, itemCount);
781 QFETCH(int, layoutCount);
782 QFETCH(int, removeItemAt);
783 QFETCH(Qt::Orientation, orientation);
784 if (removeItemAt >= layoutCount + itemCount)
785 return;
786
787 SubQGraphicsLinearLayout layout(orientation);
788 for (int i = 0; i < itemCount; ++i)
789 layout.addItem(item: new QGraphicsWidget);
790 for (int i = 0; i < layoutCount; ++i)
791 layout.addItem(item: new SubQGraphicsLinearLayout);
792 QSizeF oldSizeHint = layout.sizeHint(which: Qt::PreferredSize, constraint: QSizeF());
793
794 QGraphicsLayoutItem *w = 0;
795 if (removeItemAt >= 0 && removeItemAt < layout.count())
796 w = layout.itemAt(index: removeItemAt);
797 if (w) {
798 QGraphicsLayoutItem *wParent = w->parentLayoutItem();
799 QCOMPARE(wParent, static_cast<QGraphicsLayoutItem *>(&layout));
800 layout.removeAt(index: removeItemAt);
801 wParent = w->parentLayoutItem();
802 QCOMPARE(wParent, nullptr);
803 delete w;
804 }
805 QCOMPARE(layout.count(), itemCount + layoutCount - (w ? 1 : 0));
806
807 layout.activate();
808 QSizeF newSizeHint = layout.sizeHint(which: Qt::PreferredSize, constraint: QSizeF());
809 if (orientation == Qt::Horizontal)
810 QVERIFY(oldSizeHint.width() >= newSizeHint.width());
811 else
812 QVERIFY(oldSizeHint.height() >= newSizeHint.height());
813}
814
815void tst_QGraphicsLinearLayout::removeItem_data()
816{
817 QTest::addColumn<int>(name: "itemCount");
818 QTest::addColumn<int>(name: "layoutCount");
819 QTest::addColumn<int>(name: "removeItemAt");
820 for (int i = -1; i < 4; ++i) {
821 const QByteArray iB = QByteArray::number(i);
822 QTest::newRow(dataTag: ("0, 0, " + iB).constData()) << 0 << 0 << i;
823 QTest::newRow(dataTag: ("1, 0, " + iB).constData()) << 1 << 0 << i;
824 QTest::newRow(dataTag: ("0, 1, " + iB).constData()) << 0 << 1 << i;
825 QTest::newRow(dataTag: ("2, 2, " + iB).constData()) << 2 << 2 << i;
826 }
827}
828
829// void removeItem(QGraphicsLayoutItem* item) public
830void tst_QGraphicsLinearLayout::removeItem()
831{
832 QFETCH(int, itemCount);
833 QFETCH(int, layoutCount);
834 QFETCH(int, removeItemAt);
835 if (removeItemAt >= layoutCount + itemCount)
836 return;
837
838 SubQGraphicsLinearLayout layout;
839 for (int i = 0; i < itemCount; ++i)
840 layout.addItem(item: new QGraphicsWidget);
841 for (int i = 0; i < layoutCount; ++i)
842 layout.addItem(item: new SubQGraphicsLinearLayout);
843
844 QGraphicsLayoutItem *w = 0;
845 if (removeItemAt >= 0 && removeItemAt < layout.count())
846 w = layout.itemAt(index: removeItemAt);
847 QSizeF oldSizeHint = layout.sizeHint(which: Qt::PreferredSize, constraint: QSizeF());
848 if (w) {
849 layout.removeItem(item: w);
850 delete w;
851 }
852 QCOMPARE(layout.count(), itemCount + layoutCount - (w ? 1 : 0));
853
854 layout.activate();
855 QSizeF newSizeHint = layout.sizeHint(which: Qt::PreferredSize, constraint: QSizeF());
856 QVERIFY(oldSizeHint.width() >= newSizeHint.width());
857}
858
859void tst_QGraphicsLinearLayout::setGeometry_data()
860{
861 QTest::addColumn<QRectF>(name: "rect");
862 QTest::newRow(dataTag: "null") << QRectF();
863 QTest::newRow(dataTag: "small") << QRectF(0, 0, 10, 10);
864}
865
866// void setGeometry(QRectF const& rect) public
867void tst_QGraphicsLinearLayout::setGeometry()
868{
869 QFETCH(QRectF, rect);
870 QGraphicsScene scene;
871 QGraphicsView view(&scene);
872 QGraphicsWidget *widget = new QGraphicsWidget(0, Qt::Window);
873 SubQGraphicsLinearLayout &layout = *(new SubQGraphicsLinearLayout);
874 scene.addItem(item: widget);
875 widget->setLayout(&layout);
876 widget->setContentsMargins(left: 0, top: 0, right: 0, bottom: 0);
877 layout.setContentsMargins(left: 0, top: 0, right: 0, bottom: 0);
878 layout.setMaximumSize(aw: 100, ah: 100);
879 view.show();
880 widget->show();
881 QApplication::processEvents();
882 widget->setGeometry(rect);
883 QCOMPARE(layout.geometry(), rect);
884 // see also geometry()
885 delete widget;
886}
887
888class LayoutStyle : public QProxyStyle
889{
890public:
891 LayoutStyle(const QString &key)
892 : QProxyStyle(key),
893 horizontalSpacing(-1), verticalSpacing(-1) {}
894
895 virtual int pixelMetric(QStyle::PixelMetric pm, const QStyleOption *option = 0, const QWidget *widget = 0) const override
896 {
897 if (pm == QStyle::PM_LayoutHorizontalSpacing && horizontalSpacing >= 0) {
898 return horizontalSpacing;
899 } else if (pm == QStyle::PM_LayoutVerticalSpacing && verticalSpacing >= 0) {
900 return verticalSpacing;
901 }
902 return QProxyStyle::pixelMetric(metric: pm, option, widget);
903 }
904
905 int horizontalSpacing;
906 int verticalSpacing;
907};
908
909void tst_QGraphicsLinearLayout::defaultSpacing()
910{
911 QGraphicsScene scene;
912 QGraphicsView view(&scene);
913 LayoutStyle *style = new LayoutStyle(QLatin1String("windows"));
914 style->horizontalSpacing = 5;
915 style->verticalSpacing = 3;
916 LayoutStyle *style2 = new LayoutStyle(QLatin1String("windows"));
917 style2->horizontalSpacing = 25;
918 style2->verticalSpacing = 23;
919
920 QGraphicsWidget *widget = new QGraphicsWidget(0, Qt::Window);
921 widget->setStyle(style);
922
923 // Horizontal layout
924 SubQGraphicsLinearLayout *layout = new SubQGraphicsLinearLayout(Qt::Horizontal);
925 widget->setLayout(layout);
926 Q_ASSERT(widget->style());
927 scene.addItem(item: widget);
928 layout->setContentsMargins(left: 0, top: 0, right: 0, bottom: 0);
929 view.show();
930
931 for (int i = 0; i < 2; ++i) {
932 QGraphicsWidget *w = new QGraphicsWidget;
933 layout->addItem(item: w);
934 }
935
936 // Horizontal layout
937 qreal styleSpacing = (qreal)style->pixelMetric(pm: QStyle::PM_LayoutHorizontalSpacing);
938 QCOMPARE(styleSpacing, qreal(5));
939 QCOMPARE(styleSpacing, layout->spacing());
940 QCOMPARE(layout->effectiveSizeHint(Qt::PreferredSize).width(), qreal(105));
941 style->horizontalSpacing = 15;
942 // If the style method changes return value, the layout must be invalidated by the application
943 layout->invalidate();
944 styleSpacing = (qreal)style->pixelMetric(pm: QStyle::PM_LayoutHorizontalSpacing);
945 QCOMPARE(styleSpacing, qreal(15));
946 QCOMPARE(styleSpacing, layout->spacing());
947 QCOMPARE(layout->effectiveSizeHint(Qt::PreferredSize).width(), qreal(115));
948 widget->setStyle(style2);
949 // If the style itself changes, the layout will pick that up
950 QCOMPARE(layout->effectiveSizeHint(Qt::PreferredSize).width(), qreal(125));
951 QCOMPARE(layout->spacing(), qreal(25));
952
953 // Vertical layout
954 widget->setStyle(style);
955 layout->setOrientation(Qt::Vertical);
956 styleSpacing = (qreal)style->pixelMetric(pm: QStyle::PM_LayoutVerticalSpacing);
957 QCOMPARE(styleSpacing, qreal(3));
958 QCOMPARE(styleSpacing, layout->spacing());
959 QCOMPARE(layout->effectiveSizeHint(Qt::PreferredSize).height(), qreal(103));
960 style->verticalSpacing = 13;
961 // If the style method changes return value, the layout must be invalidated by the application
962 layout->invalidate();
963 styleSpacing = (qreal)style->pixelMetric(pm: QStyle::PM_LayoutVerticalSpacing);
964 QCOMPARE(styleSpacing, qreal(13));
965 QCOMPARE(styleSpacing, layout->spacing());
966 QCOMPARE(layout->effectiveSizeHint(Qt::PreferredSize).height(), qreal(113));
967 widget->setStyle(style2);
968 // If the style itself changes, the layout will pick that up
969 QCOMPARE(layout->effectiveSizeHint(Qt::PreferredSize).height(), qreal(123));
970 QCOMPARE(layout->spacing(), qreal(23));
971
972
973 delete widget;
974}
975
976void tst_QGraphicsLinearLayout::setSpacing_data()
977{
978 QTest::addColumn<qreal>(name: "spacing");
979 QTest::newRow(dataTag: "0") << (qreal)0;
980 QTest::newRow(dataTag: "5") << (qreal)5;
981 QTest::newRow(dataTag: "3.3") << (qreal)3.3;
982 QTest::newRow(dataTag: "-4.3") << (qreal)4.3;
983}
984
985// void setSpacing(qreal spacing) public
986void tst_QGraphicsLinearLayout::setSpacing()
987{
988 QFETCH(qreal, spacing);
989
990 QGraphicsScene scene;
991 QGraphicsView view(&scene);
992 QGraphicsWidget *widget = new QGraphicsWidget(0, Qt::Window);
993 SubQGraphicsLinearLayout &layout = *(new SubQGraphicsLinearLayout);
994 scene.addItem(item: widget);
995 widget->setLayout(&layout);
996 layout.setContentsMargins(left: 0, top: 0, right: 0, bottom: 0);
997
998 // The remainder of this test is only applicable if the style uses uniform spacing
999 qreal oldSpacing = layout.spacing();
1000 if (oldSpacing != -1) {
1001 for (int i = 0; i < 3; ++i)
1002 layout.addItem(item: new QGraphicsWidget);
1003 QSizeF oldSizeHint = layout.sizeHint(which: Qt::PreferredSize);
1004
1005 layout.setSpacing(spacing);
1006 QCOMPARE(layout.spacing(), spacing);
1007
1008 view.show();
1009 widget->show();
1010 QApplication::processEvents();
1011 QSizeF newSizeHint = layout.sizeHint(which: Qt::PreferredSize);
1012
1013 QCOMPARE(oldSizeHint.width() - oldSpacing * 2, newSizeHint.width() - spacing * 2);
1014 }
1015 delete widget;
1016}
1017
1018void tst_QGraphicsLinearLayout::setItemSpacing_data()
1019{
1020 QTest::addColumn<int>(name: "index");
1021 QTest::addColumn<int>(name: "spacing");
1022
1023 QTest::newRow(dataTag: "0 at 0") << 0 << 0;
1024 QTest::newRow(dataTag: "10 at 0") << 0 << 10;
1025 QTest::newRow(dataTag: "10 at 1") << 1 << 10;
1026 QTest::newRow(dataTag: "10 at the end") << 4 << 10;
1027}
1028
1029void tst_QGraphicsLinearLayout::setItemSpacing()
1030{
1031 QFETCH(int, index);
1032 QFETCH(int, spacing);
1033
1034 QGraphicsScene scene;
1035 QGraphicsView view(&scene);
1036 QGraphicsWidget *widget = new QGraphicsWidget(0, Qt::Window);
1037 SubQGraphicsLinearLayout *layout = new SubQGraphicsLinearLayout;
1038 scene.addItem(item: widget);
1039 widget->setLayout(layout);
1040 layout->setContentsMargins(left: 0, top: 0, right: 0, bottom: 0);
1041 for (int i = 0; i < 5; ++i) {
1042 QGraphicsWidget *w = new QGraphicsWidget;
1043 layout->addItem(item: w);
1044 }
1045 QSizeF oldSizeHint = layout->sizeHint(which: Qt::PreferredSize);
1046 qreal oldSpacing = 0;
1047 if (index < layout->count() - 1)
1048 oldSpacing = layout->spacing();
1049 else
1050 spacing = 0;
1051
1052 layout->setItemSpacing(index, spacing);
1053 view.show();
1054 QApplication::processEvents();
1055 QSizeF newSizeHint = layout->sizeHint(which: Qt::PreferredSize);
1056
1057 // The remainder of this test is only applicable if the style uses uniform spacing
1058 if (oldSpacing >= 0) {
1059 QCOMPARE(newSizeHint.width() - spacing, oldSizeHint.width() - oldSpacing);
1060 }
1061 delete widget;
1062}
1063
1064void tst_QGraphicsLinearLayout::itemSpacing()
1065{
1066 QGraphicsScene scene;
1067 QGraphicsView view(&scene);
1068 QGraphicsWidget *widget = new QGraphicsWidget(0, Qt::Window);
1069 SubQGraphicsLinearLayout *layout = new SubQGraphicsLinearLayout;
1070 scene.addItem(item: widget);
1071 widget->setLayout(layout);
1072 layout->setContentsMargins(left: 0, top: 0, right: 0, bottom: 0);
1073 for (int i = 0; i < 5; ++i) {
1074 QGraphicsWidget *w = new QGraphicsWidget;
1075 layout->addItem(item: w);
1076 }
1077
1078 // Check defaults
1079 qreal defaultSpacing = layout->spacing();
1080 if (defaultSpacing >= 0) {
1081 QCOMPARE(layout->itemSpacing(0), defaultSpacing);
1082 } else {
1083 // all widgets are the same, so the spacing should be uniform
1084 QCOMPARE(layout->itemSpacing(0), layout->itemSpacing(1));
1085 }
1086
1087 layout->setItemSpacing(index: 1, spacing: 42);
1088 QCOMPARE(layout->itemSpacing(1), qreal(42));
1089
1090 // try to unset
1091 layout->setItemSpacing(index: 1, spacing: -1);
1092 QCOMPARE(layout->itemSpacing(1), defaultSpacing);
1093
1094 delete widget;
1095}
1096
1097/**
1098 * The stretch factors are not applied linearly, but they are used together with both the preferred size, maximum size to form the
1099 * internal effective stretch factor.
1100 * There is only need to apply stretch factors if the size of the layout is different than the layouts preferred size.
1101 * (If the size of the layout is the preferred size, then all items should get their preferred sizes.
1102 * However, imagine this use case:
1103 * Layout
1104 * +----------+----------+----------+
1105 * name | A | B | C |
1106 * stretch | 1 | 2 | 3 |
1107 * sizehints|[5,10,50] |[5,10,50] |[5,10,50] |
1108 * +----------+----------+----------+
1109 *
1110 * layout->resize(120, h)
1111 *
1112 * In QLayout, C would become 50, B would become 50 and A would get 20. When scaling a layout this would give a jerky feeling, since
1113 * the item with the highest stretch factor will first resize. When that has reached its maximum the next candidate for stretch will
1114 * resize, and finally, item with the lowest stretch factor will resize.
1115 * In QGraphicsLinearLayout we try to scale all items so that they all reach their maximum at the same time. This means that
1116 * their relative sizes are not proportional to their stretch factors.
1117 */
1118
1119typedef QList<int> IntList;
1120
1121void tst_QGraphicsLinearLayout::setStretchFactor_data()
1122{
1123 QTest::addColumn<qreal>(name: "totalSize");
1124 QTest::addColumn<IntList>(name: "stretches");
1125
1126 QTest::newRow(dataTag: QString("60 [1,2]").toLatin1()) << qreal(60.0) << (IntList() << 1 << 2);
1127 QTest::newRow(dataTag: QString("60 [1,2,3]").toLatin1()) << qreal(60.0) << (IntList() << 1 << 2 << 3);
1128 QTest::newRow(dataTag: QString("120 [1,2,3,6]").toLatin1()) << qreal(120.0) << (IntList() << 1 << 2 << 3 << 6);
1129}
1130
1131// void setStretchFactor(QGraphicsLayoutItem* item, int stretch) public
1132void tst_QGraphicsLinearLayout::setStretchFactor()
1133{
1134 QFETCH(qreal, totalSize);
1135 QFETCH(IntList, stretches);
1136 QGraphicsScene scene;
1137 QGraphicsView view(&scene);
1138 QGraphicsWidget *widget = new QGraphicsWidget(0, Qt::Window);
1139 SubQGraphicsLinearLayout &layout = *(new SubQGraphicsLinearLayout);
1140 scene.addItem(item: widget);
1141 widget->setLayout(&layout);
1142 layout.setContentsMargins(left: 0, top: 0, right: 0, bottom: 0);
1143 layout.setSpacing(0.0);
1144 widget->setContentsMargins(left: 0, top: 0, right: 0, bottom: 0);
1145
1146
1147 int i;
1148 for (i = 0; i < stretches.count(); ++i) {
1149 QGraphicsWidget *item = new RectWidget(widget);
1150 item->setMinimumSize(aw: 5,ah: 5);
1151 item->setPreferredSize(aw: 10,ah: 5);
1152 item->setMaximumSize(aw: 50,ah: 5);
1153 layout.addItem(item);
1154 layout.setStretchFactor(item, stretch: stretches.at(i));
1155 }
1156
1157 widget->resize(w: totalSize, h: 10);
1158 QApplication::processEvents();
1159
1160 view.show();
1161 widget->show();
1162
1163 qreal firstStretch = -1;
1164 qreal firstExtent = -1.;
1165 qreal sumExtent = 0;
1166 for (i = 0; i < stretches.count(); ++i) {
1167 QGraphicsWidget *item = static_cast<QGraphicsWidget*>(layout.itemAt(index: i));
1168 qreal extent = item->size().width();
1169 qreal stretch = (qreal)stretches.at(i);
1170 if (firstStretch != -1 && firstExtent != -1) {
1171 // The resulting widths does not correspond linearly to the stretch factors.
1172 if (stretch == firstStretch)
1173 QCOMPARE(extent, firstExtent);
1174 else if (stretch > firstStretch)
1175 QVERIFY(extent > firstExtent);
1176 else
1177 QVERIFY(extent < firstExtent);
1178 } else {
1179 firstStretch = (qreal)stretch;
1180 firstExtent = extent;
1181 }
1182 sumExtent+= extent;
1183 }
1184 QCOMPARE(sumExtent, totalSize);
1185
1186 delete widget;
1187}
1188
1189void tst_QGraphicsLinearLayout::testStretch()
1190{
1191 QGraphicsScene scene;
1192 QGraphicsView *view = new QGraphicsView(&scene);
1193 Q_UNUSED(view);
1194 QGraphicsWidget *form = new QGraphicsWidget(0, Qt::Window);
1195
1196 scene.addItem(item: form);
1197 form->setMinimumSize(aw: 600, ah: 600);
1198 form->setMaximumSize(aw: 600, ah: 600);
1199 QGraphicsLinearLayout *layout = new QGraphicsLinearLayout(Qt::Horizontal, form);
1200 QGraphicsWidget *w1 = new RectWidget;
1201 w1->setPreferredSize(aw: 100,ah: 100);
1202 w1->setSizePolicy(hPolicy: QSizePolicy::Fixed, vPolicy: QSizePolicy::Fixed);
1203 QGraphicsWidget *w2 = new RectWidget;
1204 w2->setPreferredSize(aw: 200,ah: 200);
1205 w2->setSizePolicy(hPolicy: QSizePolicy::Fixed, vPolicy: QSizePolicy::Fixed);
1206 layout->setSpacing(0);
1207 layout->setContentsMargins(left: 0, top: 0, right: 0, bottom: 0);
1208 layout->addItem(item: w1);
1209 layout->addStretch(stretch: 2);
1210 layout->addItem(item: w2);
1211 QCOMPARE(layout->count(), 2);
1212 QCOMPARE(layout->itemAt(0), w1);
1213 QCOMPARE(layout->itemAt(1), w2);
1214 layout->activate();
1215
1216 //view->setSceneRect(-50, -50, 800, 800);
1217 //view->show();
1218 //QVERIFY(QTest::qWaitForWindowExposed(view));
1219 QCOMPARE(form->geometry().size(), QSizeF(600,600));
1220 QCOMPARE(w1->geometry(), QRectF(0, 0, 100, 100));
1221 QCOMPARE(w2->geometry(), QRectF(400, 0, 200, 200));
1222}
1223
1224void tst_QGraphicsLinearLayout::defaultStretchFactors_data()
1225{
1226 QTest::addColumn<Qt::Orientation>(name: "orientation");
1227 QTest::addColumn<int>(name: "count");
1228 QTest::addColumn<IntList>(name: "preferredSizeHints");
1229 QTest::addColumn<IntList>(name: "stretches");
1230 QTest::addColumn<IntList>(name: "ignoreFlag");
1231 QTest::addColumn<QSizeF>(name: "newSize");
1232 QTest::addColumn<IntList>(name: "expectedSizes");
1233
1234 QTest::newRow(dataTag: "hor") << Qt::Horizontal << 3
1235 << (IntList() << 20 << 40 << 60)
1236 << (IntList())
1237 << (IntList())
1238 << QSizeF()
1239 << (IntList() << 20 << 40 << 60);
1240
1241 QTest::newRow(dataTag: "ver") << Qt::Vertical << 3
1242 << (IntList() << 20 << 40 << 60)
1243 << (IntList())
1244 << (IntList())
1245 << QSizeF()
1246 << (IntList() << 20 << 40 << 60);
1247
1248 QTest::newRow(dataTag: "hor,ignore123") << Qt::Horizontal << 3
1249 << (IntList() << 20 << 40 << 60)
1250 << (IntList())
1251 << (IntList() << 1 << 1 << 1)
1252 << QSizeF()
1253 << (IntList() << 0 << 0 << 0);
1254
1255 QTest::newRow(dataTag: "hor,ignore23") << Qt::Horizontal << 3
1256 << (IntList() << 10 << 10 << 10)
1257 << (IntList())
1258 << (IntList() << 0 << 1 << 1)
1259 << QSizeF(200, 50)
1260 << (IntList()); //### stretches are not linear.
1261
1262 QTest::newRow(dataTag: "hor,ignore2") << Qt::Horizontal << 3
1263 << (IntList() << 10 << 10 << 10)
1264 << (IntList())
1265 << (IntList() << 0 << 1 << 0)
1266 << QSizeF()
1267 << (IntList() << 10 << 0 << 10);
1268
1269}
1270
1271void tst_QGraphicsLinearLayout::defaultStretchFactors()
1272{
1273 QFETCH(Qt::Orientation, orientation);
1274 QFETCH(int, count);
1275 QFETCH(IntList, preferredSizeHints);
1276 QFETCH(IntList, stretches);
1277 QFETCH(IntList, ignoreFlag);
1278 QFETCH(QSizeF, newSize);
1279 QFETCH(IntList, expectedSizes);
1280
1281 QGraphicsScene scene;
1282 QGraphicsView view(&scene);
1283 QGraphicsWidget *widget = new QGraphicsWidget(0, Qt::Window);
1284 SubQGraphicsLinearLayout *layout = new SubQGraphicsLinearLayout(orientation);
1285 scene.addItem(item: widget);
1286 widget->setLayout(layout);
1287 layout->setContentsMargins(left: 0, top: 0, right: 0, bottom: 0);
1288 layout->setSpacing(0.0);
1289 widget->setContentsMargins(left: 0, top: 0, right: 0, bottom: 0);
1290
1291 int i;
1292 for (i = 0; i < count; ++i) {
1293 RectWidget *item = new RectWidget(widget);
1294 layout->addItem(item);
1295 if (preferredSizeHints.value(i, defaultValue: -1) >= 0) {
1296 item->setSizeHint(which: Qt::PreferredSize, size: QSizeF(preferredSizeHints.at(i), preferredSizeHints.at(i)));
1297 }
1298 if (stretches.value(i, defaultValue: -1) >= 0) {
1299 layout->setStretchFactor(item, stretch: stretches.at(i));
1300 }
1301 if (ignoreFlag.value(i, defaultValue: 0) != 0) {
1302 QSizePolicy sp = item->sizePolicy();
1303 if (orientation == Qt::Horizontal)
1304 sp.setHorizontalPolicy(QSizePolicy::Policy(sp.horizontalPolicy() | QSizePolicy::IgnoreFlag));
1305 else
1306 sp.setVerticalPolicy(QSizePolicy::Policy(sp.verticalPolicy() | QSizePolicy::IgnoreFlag));
1307 item->setSizePolicy(sp);
1308 }
1309 }
1310
1311 QApplication::processEvents();
1312
1313 widget->show();
1314 view.show();
1315 view.resize(w: 400,h: 300);
1316 if (newSize.isValid())
1317 widget->resize(size: newSize);
1318
1319 QApplication::processEvents();
1320 for (i = 0; i < count; ++i) {
1321 QSizeF itemSize = layout->itemAt(index: i)->geometry().size();
1322 if (orientation == Qt::Vertical)
1323 itemSize.transpose();
1324 if (i < expectedSizes.count())
1325 QCOMPARE(itemSize.width(), qreal(expectedSizes.at(i)));
1326 }
1327
1328 delete widget;
1329}
1330
1331Q_DECLARE_METATYPE(Qt::SizeHint)
1332void tst_QGraphicsLinearLayout::sizeHint_data()
1333{
1334 QTest::addColumn<Qt::SizeHint>(name: "which");
1335 QTest::addColumn<QSizeF>(name: "constraint");
1336 QTest::addColumn<qreal>(name: "spacing");
1337 QTest::addColumn<qreal>(name: "layoutMargin");
1338 QTest::addColumn<QSizeF>(name: "sizeHint");
1339
1340 QTest::newRow(dataTag: "minimumSize") << Qt::MinimumSize << QSizeF() << qreal(0.0) << qreal(0.0) << QSizeF(30, 10);
1341 QTest::newRow(dataTag: "preferredSize") << Qt::PreferredSize << QSizeF() << qreal(0.0) << qreal(0.0) << QSizeF(75, 25);
1342 QTest::newRow(dataTag: "maximumSize") << Qt::MaximumSize << QSizeF() << qreal(0.0) << qreal(0.0) << QSizeF(150, 50);
1343 QTest::newRow(dataTag: "minimumSize, spacing=3") << Qt::MinimumSize << QSizeF() << qreal(3.0) << qreal(0.0) << QSizeF(30 + 2*3, 10);
1344 QTest::newRow(dataTag: "minimumSize, spacing=3, layoutMargin=10") << Qt::MinimumSize << QSizeF() << qreal(3.0) << qreal(10.0) << QSizeF(30 + 2*3 + 2*10, 10 + 2*10);
1345 QTest::newRow(dataTag: "minimumSize, spacing=0, layoutMargin=7") << Qt::MinimumSize << QSizeF() << qreal(0.0) << qreal(7.0) << QSizeF(30 + 0 + 2*7, 10 + 2*7);
1346}
1347
1348// QSizeF sizeHint(Qt::SizeHint which, QSizeF const& constraint) const public
1349void tst_QGraphicsLinearLayout::sizeHint()
1350{
1351 QFETCH(Qt::SizeHint, which);
1352 QFETCH(QSizeF, constraint);
1353 QFETCH(qreal, spacing);
1354 QFETCH(qreal, layoutMargin);
1355 QFETCH(QSizeF, sizeHint);
1356
1357 QGraphicsScene scene;
1358 QGraphicsView view(&scene);
1359 QGraphicsWidget *widget = new QGraphicsWidget(0, Qt::Window);
1360 SubQGraphicsLinearLayout &layout = *(new SubQGraphicsLinearLayout);
1361 scene.addItem(item: widget);
1362 widget->setLayout(&layout);
1363 layout.setContentsMargins(left: layoutMargin, top: layoutMargin, right: layoutMargin, bottom: layoutMargin);
1364 layout.setSpacing(spacing);
1365 for (int i = 0; i < 3; ++i) {
1366 QGraphicsWidget *item = new QGraphicsWidget(widget);
1367 item->setMinimumSize(aw: 10, ah: 10);
1368 item->setPreferredSize(aw: 25, ah: 25);
1369 item->setMaximumSize(aw: 50, ah: 50);
1370 layout.addItem(item);
1371 }
1372 QApplication::processEvents();
1373 QCOMPARE(layout.sizeHint(which, constraint), sizeHint);
1374 delete widget;
1375}
1376
1377void tst_QGraphicsLinearLayout::updateGeometry()
1378{
1379 QGraphicsScene scene;
1380 QGraphicsView view(&scene);
1381
1382 QGraphicsWidget *window = new QGraphicsWidget(0, Qt::Window);
1383 QGraphicsWidget *w1 = new QGraphicsWidget(window);
1384 w1->setMinimumSize(aw: 100, ah: 40);
1385 SubQGraphicsLinearLayout *layout = new SubQGraphicsLinearLayout;
1386 layout->addItem(item: w1);
1387 scene.addItem(item: window);
1388 window->setLayout(layout);
1389 layout->setContentsMargins(left: 0, top: 0, right: 0, bottom: 0);
1390 QCOMPARE(w1->parentLayoutItem(), static_cast<QGraphicsLayoutItem*>(layout));
1391 QCOMPARE(layout->parentLayoutItem(), static_cast<QGraphicsLayoutItem*>(window));
1392
1393 view.show();
1394 QApplication::processEvents();
1395 QCOMPARE(window->size().toSize(), QSize(100, 50));
1396 w1->setMinimumSize(aw: 110, ah: 60);
1397 QApplication::processEvents();
1398 QCOMPARE(window->size().toSize(), QSize(110, 60));
1399 QApplication::processEvents();
1400
1401 {
1402 delete window;
1403 window = new QGraphicsWidget(0, Qt::Window);
1404 SubQGraphicsLinearLayout *layout2a = new SubQGraphicsLinearLayout;
1405 QGraphicsWidget *w1 = new QGraphicsWidget(window);
1406 w1->setMinimumSize(aw: 110, ah: 50);
1407 layout2a->addItem(item: w1);
1408 SubQGraphicsLinearLayout *layout2 = new SubQGraphicsLinearLayout;
1409 layout2->addItem(item: layout2a);
1410 layout2->setContentsMargins(left: 1, top: 1, right: 1, bottom: 1);
1411 layout2a->setContentsMargins(left: 1, top: 1, right: 1, bottom: 1);
1412 window->setLayout(layout2);
1413 QApplication::processEvents();
1414 QCOMPARE(w1->parentLayoutItem(), static_cast<QGraphicsLayoutItem*>(layout2a));
1415 QCOMPARE(layout2a->parentLayoutItem(), static_cast<QGraphicsLayoutItem*>(layout2));
1416 QCOMPARE(layout2->parentLayoutItem(), static_cast<QGraphicsLayoutItem*>(window));
1417 QCOMPARE(window->size().toSize(), QSize(114, 54));
1418 QApplication::processEvents();
1419 w1->setMinimumSize(aw: 120, ah: 60);
1420 QApplication::processEvents();
1421 QCOMPARE(window->size().toSize(), QSize(124, 64));
1422 }
1423
1424 {
1425 delete window;
1426 window = new QGraphicsWidget(0, Qt::Window);
1427 scene.addItem(item: window);
1428 window->show();
1429 QGraphicsWidget *w1 = new QGraphicsWidget(window);
1430 w1->setMinimumSize(aw: 100, ah: 50);
1431 SubQGraphicsLinearLayout *layout2a = new SubQGraphicsLinearLayout;
1432 layout2a->addItem(item: w1);
1433 SubQGraphicsLinearLayout *layout2 = new SubQGraphicsLinearLayout;
1434 layout2->addItem(item: layout2a);
1435 layout2a->setContentsMargins(left: 1, top: 1, right: 1, bottom: 1);
1436 window->setLayout(layout2);
1437 QApplication::processEvents();
1438 qreal left, top, right, bottom;
1439 layout2->getContentsMargins(left: &left, top: &top, right: &right, bottom: &bottom);
1440 QCOMPARE(window->size().toSize(), QSize(102 +left + right, 52 + top + bottom));
1441 }
1442
1443 {
1444 delete window;
1445 window = new QGraphicsWidget(0, Qt::Window);
1446 scene.addItem(item: window);
1447 QGraphicsWidget *w1 = new QGraphicsWidget(window);
1448 w1->setMinimumSize(aw: 100, ah: 50);
1449 window->setLayout(0);
1450 SubQGraphicsLinearLayout *layout2a = new SubQGraphicsLinearLayout;
1451 layout2a->addItem(item: w1);
1452 SubQGraphicsLinearLayout *layout2 = new SubQGraphicsLinearLayout;
1453 layout2->addItem(item: layout2a);
1454 window->resize(w: 200, h: 80);
1455 window->setLayout(layout2);
1456 window->show();
1457 QApplication::processEvents();
1458 QCOMPARE(window->size().toSize(), QSize(200, 80));
1459 }
1460
1461}
1462
1463void tst_QGraphicsLinearLayout::layoutDirection()
1464{
1465 QGraphicsScene scene;
1466 QGraphicsView view(&scene);
1467
1468 QGraphicsWidget *window = new QGraphicsWidget(0, Qt::Window);
1469 QGraphicsLinearLayout *layout = new QGraphicsLinearLayout;
1470 layout->setContentsMargins(left: 1, top: 2, right: 3, bottom: 4);
1471 layout->setSpacing(6);
1472
1473 RectWidget *w1 = new RectWidget;
1474 w1->setPreferredSize(aw: 20, ah: 20);
1475 w1->setSizePolicy(hPolicy: QSizePolicy::Fixed, vPolicy: QSizePolicy::Fixed);
1476 layout->addItem(item: w1);
1477 RectWidget *w2 = new RectWidget;
1478 w2->setPreferredSize(aw: 20, ah: 20);
1479 w2->setSizePolicy(hPolicy: QSizePolicy::Fixed, vPolicy: QSizePolicy::Fixed);
1480 layout->addItem(item: w2);
1481
1482 scene.addItem(item: window);
1483 window->setLayout(layout);
1484 view.show();
1485 window->resize(w: 50, h: 20);
1486 window->setLayoutDirection(Qt::LeftToRight);
1487 QApplication::processEvents();
1488 QCOMPARE(w1->geometry().left(), 1.0);
1489 QCOMPARE(w1->geometry().right(), 21.0);
1490 QCOMPARE(w2->geometry().left(), 27.0);
1491 QCOMPARE(w2->geometry().right(), 47.0);
1492
1493 window->setLayoutDirection(Qt::RightToLeft);
1494 QApplication::processEvents();
1495 QCOMPARE(w1->geometry().right(), 49.0);
1496 QCOMPARE(w1->geometry().left(), 29.0);
1497 QCOMPARE(w2->geometry().right(), 23.0);
1498 QCOMPARE(w2->geometry().left(), 3.0);
1499
1500 delete window;
1501}
1502
1503void tst_QGraphicsLinearLayout::removeLayout()
1504{
1505 QGraphicsScene scene;
1506 RectWidget *textEdit = new RectWidget;
1507 RectWidget *pushButton = new RectWidget;
1508 scene.addItem(item: textEdit);
1509 scene.addItem(item: pushButton);
1510
1511 QGraphicsLinearLayout *layout = new QGraphicsLinearLayout;
1512 layout->addItem(item: textEdit);
1513 layout->addItem(item: pushButton);
1514
1515 QGraphicsWidget *form = new QGraphicsWidget;
1516 form->setLayout(layout);
1517 scene.addItem(item: form);
1518
1519 QGraphicsView view(&scene);
1520 view.show();
1521 QVERIFY(QTest::qWaitForWindowExposed(&view));
1522
1523 QRectF r1 = textEdit->geometry();
1524 QRectF r2 = pushButton->geometry();
1525 form->setLayout(0);
1526 //documentation of QGraphicsWidget::setLayout:
1527 //If layout is 0, the widget is left without a layout. Existing subwidgets' geometries will remain unaffected.
1528 QCOMPARE(textEdit->geometry(), r1);
1529 QCOMPARE(pushButton->geometry(), r2);
1530}
1531
1532void tst_QGraphicsLinearLayout::avoidRecursionInInsertItem()
1533{
1534 QGraphicsWidget window(0, Qt::Window);
1535 QGraphicsLinearLayout *layout = new QGraphicsLinearLayout(&window);
1536 QCOMPARE(layout->count(), 0);
1537 QTest::ignoreMessage(type: QtWarningMsg, message: "QGraphicsLinearLayout::insertItem: cannot insert itself");
1538 layout->insertItem(index: 0, item: layout);
1539 QCOMPARE(layout->count(), 0);
1540}
1541
1542void tst_QGraphicsLinearLayout::styleInfoLeak()
1543{
1544 QGraphicsLinearLayout layout;
1545 layout.spacing();
1546}
1547
1548void tst_QGraphicsLinearLayout::task218400_insertStretchCrash()
1549{
1550 QGraphicsScene *scene = new QGraphicsScene;
1551 QGraphicsWidget *a = scene->addWidget(widget: new QWidget);
1552 QGraphicsWidget *b = scene->addWidget(widget: new QWidget);
1553
1554 QGraphicsLinearLayout *layout = new QGraphicsLinearLayout;
1555 layout->addItem(item: a);
1556 layout->addItem(item: b);
1557 layout->insertStretch(index: 0); // inserts gap in item grid in the layout engine
1558
1559 QGraphicsWidget *form = new QGraphicsWidget;
1560 form->setLayout(layout); // crash
1561}
1562
1563void tst_QGraphicsLinearLayout::testAlignmentInLargerLayout()
1564{
1565 QGraphicsScene *scene = new QGraphicsScene;
1566 QGraphicsWidget *form = new QGraphicsWidget;
1567 scene->addItem(item: form);
1568 QGraphicsLinearLayout *layout = new QGraphicsLinearLayout(Qt::Vertical, form);
1569 layout->setSpacing(0);
1570 layout->setContentsMargins(left: 0,top: 0,right: 0,bottom: 0);
1571
1572 QGraphicsWidget *a = new QGraphicsWidget;
1573 a->setMaximumSize(aw: 100,ah: 100);
1574 layout->addItem(item: a);
1575
1576 QCOMPARE(form->maximumSize(), QSizeF(100,100));
1577 QCOMPARE(layout->maximumSize(), QSizeF(100,100));
1578 layout->setMinimumSize(QSizeF(200,200));
1579 layout->setMaximumSize(QSizeF(200,200));
1580
1581 layout->setAlignment(item: a, alignment: Qt::AlignCenter);
1582 layout->activate();
1583 QCOMPARE(a->geometry(), QRectF(50,50,100,100));
1584
1585 layout->setAlignment(item: a, alignment: Qt::AlignRight | Qt::AlignBottom);
1586 layout->activate();
1587 QCOMPARE(a->geometry(), QRectF(100,100,100,100));
1588
1589 layout->setAlignment(item: a, alignment: Qt::AlignHCenter | Qt::AlignTop);
1590 layout->activate();
1591 QCOMPARE(a->geometry(), QRectF(50,0,100,100));
1592
1593 QGraphicsWidget *b = new QGraphicsWidget;
1594 b->setMaximumSize(aw: 100,ah: 100);
1595 layout->addItem(item: b);
1596
1597 layout->setAlignment(item: a, alignment: Qt::AlignCenter);
1598 layout->setAlignment(item: b, alignment: Qt::AlignCenter);
1599 layout->activate();
1600 QCOMPARE(a->geometry(), QRectF(50,0,100,100));
1601 QCOMPARE(b->geometry(), QRectF(50,100,100,100));
1602
1603 layout->setAlignment(item: a, alignment: Qt::AlignRight | Qt::AlignBottom);
1604 layout->setAlignment(item: b, alignment: Qt::AlignLeft | Qt::AlignTop);
1605 layout->activate();
1606 QCOMPARE(a->geometry(), QRectF(100,0,100,100));
1607 QCOMPARE(b->geometry(), QRectF(0,100,100,100));
1608}
1609
1610void tst_QGraphicsLinearLayout::testOffByOneInLargerLayout() {
1611 QGraphicsScene *scene = new QGraphicsScene;
1612 QGraphicsWidget *form = new QGraphicsWidget;
1613 scene->addItem(item: form);
1614 QGraphicsLinearLayout *layout = new QGraphicsLinearLayout(Qt::Vertical, form);
1615 layout->setSpacing(0);
1616 layout->setContentsMargins(left: 0,top: 0,right: 0,bottom: 0);
1617
1618 QGraphicsWidget *a = new QGraphicsWidget;
1619 QGraphicsWidget *b = new QGraphicsWidget;
1620 a->setMaximumSize(aw: 100,ah: 100);
1621 b->setMaximumSize(aw: 100,ah: 100);
1622 layout->addItem(item: a);
1623 layout->addItem(item: b);
1624
1625 layout->setAlignment(item: a, alignment: Qt::AlignRight | Qt::AlignBottom);
1626 layout->setAlignment(item: b, alignment: Qt::AlignLeft | Qt::AlignTop);
1627 layout->setMinimumSize(QSizeF(101,201));
1628 layout->setMaximumSize(QSizeF(101,201));
1629 layout->activate();
1630 QCOMPARE(a->geometry(), QRectF(1,0.5,100,100));
1631 QCOMPARE(b->geometry(), QRectF(0,100.5,100,100));
1632
1633 layout->setMinimumSize(QSizeF(100,200));
1634 layout->setMaximumSize(QSizeF(100,200));
1635 layout->activate();
1636 QCOMPARE(a->geometry(), QRectF(0,0,100,100));
1637 QCOMPARE(b->geometry(), QRectF(0,100,100,100));
1638
1639 layout->setMinimumSize(QSizeF(99,199));
1640 layout->setMaximumSize(QSizeF(99,199));
1641 layout->activate();
1642 QCOMPARE(a->geometry(), QRectF(0,0,99,99.5));
1643 QCOMPARE(b->geometry(), QRectF(0,99.5,99,99.5));
1644}
1645void tst_QGraphicsLinearLayout::testDefaultAlignment()
1646{
1647 QGraphicsWidget *widget = new QGraphicsWidget;
1648 QGraphicsLinearLayout *layout = new QGraphicsLinearLayout(Qt::Vertical, widget);
1649 layout->setContentsMargins(left: 0, top: 0, right: 0, bottom: 0);
1650 layout->setSpacing(0);
1651
1652 QGraphicsWidget *w = new QGraphicsWidget;
1653 w->setMinimumSize(aw: 50,ah: 50);
1654 w->setMaximumSize(aw: 50,ah: 50);
1655 layout->addItem(item: w);
1656
1657 //Default alignment should be to the top-left
1658 QCOMPARE(layout->alignment(w), 0);
1659
1660 //First, check by forcing the layout to be bigger
1661 layout->setMinimumSize(aw: 100,ah: 100);
1662 layout->activate();
1663 QCOMPARE(layout->geometry(), QRectF(0,0,100,100));
1664 QCOMPARE(w->geometry(), QRectF(0,0,50,50));
1665 layout->setMinimumSize(aw: -1,ah: -1);
1666
1667 //Second, check by adding a larger item in the column
1668 QGraphicsWidget *w2 = new QGraphicsWidget;
1669 w2->setMinimumSize(aw: 100,ah: 100);
1670 w2->setMaximumSize(aw: 100,ah: 100);
1671 layout->addItem(item: w2);
1672 layout->activate();
1673 QCOMPARE(layout->geometry(), QRectF(0,0,100,150));
1674 QCOMPARE(w->geometry(), QRectF(0,0,50,50));
1675 QCOMPARE(w2->geometry(), QRectF(0,50,100,100));
1676}
1677
1678void tst_QGraphicsLinearLayout::combineSizePolicies()
1679{
1680 QGraphicsWidget *widget = new QGraphicsWidget;
1681 QGraphicsLinearLayout *layout = new QGraphicsLinearLayout(Qt::Horizontal, widget);
1682 layout->setContentsMargins(left: 0, top: 0, right: 0, bottom: 0);
1683 layout->setSpacing(0);
1684
1685 QGraphicsWidget *w1 = new QGraphicsWidget;
1686 w1->setMaximumSize(aw: 200,ah: 200);
1687 w1->setSizePolicy(hPolicy: QSizePolicy::Preferred, vPolicy: QSizePolicy::Preferred);
1688 layout->addItem(item: w1);
1689
1690 QGraphicsWidget *w2 = new QGraphicsWidget;
1691 w2->setPreferredSize(aw: 50,ah: 50);
1692 w2->setSizePolicy(hPolicy: QSizePolicy::Fixed, vPolicy: QSizePolicy::Fixed);
1693 layout->addItem(item: w2);
1694 QCOMPARE(layout->maximumHeight(), qreal(200));
1695
1696 // now remove the fixed vertical size policy, and set instead the maximum height to 50
1697 // this should in effect give the same maximumHeight
1698 w2->setMaximumHeight(50);
1699 w2->setSizePolicy(hPolicy: QSizePolicy::Fixed, vPolicy: QSizePolicy::Preferred);
1700 QCOMPARE(layout->maximumHeight(), qreal(200));
1701}
1702
1703void tst_QGraphicsLinearLayout::hiddenItems()
1704{
1705 QGraphicsWidget *widget = new QGraphicsWidget;
1706 QGraphicsLinearLayout *layout = new QGraphicsLinearLayout(Qt::Horizontal, widget);
1707 layout->setContentsMargins(left: 0, top: 0, right: 0, bottom: 0);
1708 layout->setSpacing(2);
1709
1710 RectWidget *w1 = new RectWidget;
1711 w1->setPreferredSize(QSizeF(20, 20));
1712 layout->addItem(item: w1);
1713
1714 RectWidget *w2 = new RectWidget;
1715 w2->setPreferredSize(QSizeF(20, 20));
1716 layout->addItem(item: w2);
1717
1718 RectWidget *w3 = new RectWidget;
1719 w3->setPreferredSize(QSizeF(20, 20));
1720 layout->addItem(item: w3);
1721
1722 QCOMPARE(layout->preferredWidth(), qreal(64));
1723 w2->hide();
1724 QCOMPARE(layout->preferredWidth(), qreal(42));
1725 w2->show();
1726 QCOMPARE(layout->preferredWidth(), qreal(64));
1727 QSizePolicy sp = w2->sizePolicy();
1728 sp.setRetainSizeWhenHidden(true);
1729 w2->setSizePolicy(sp);
1730 QCOMPARE(layout->preferredWidth(), qreal(64));
1731 w2->hide();
1732 QCOMPARE(layout->preferredWidth(), qreal(64));
1733 sp.setRetainSizeWhenHidden(false);
1734 w2->setSizePolicy(sp);
1735 QCOMPARE(layout->preferredWidth(), qreal(42));
1736}
1737
1738QTEST_MAIN(tst_QGraphicsLinearLayout)
1739#include "tst_qgraphicslinearlayout.moc"
1740
1741

source code of qtbase/tests/auto/widgets/graphicsview/qgraphicslinearlayout/tst_qgraphicslinearlayout.cpp