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 | |
40 | class tst_QGraphicsLinearLayout : public QObject { |
41 | Q_OBJECT |
42 | |
43 | private 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. |
102 | class SubQGraphicsLinearLayout : public QGraphicsLinearLayout { |
103 | public: |
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. |
136 | void 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 | |
143 | class RectWidget : public QGraphicsWidget |
144 | { |
145 | public: |
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 | |
174 | Q_DECLARE_METATYPE(Qt::Orientation) |
175 | void 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 | |
182 | void 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 | |
221 | Q_DECLARE_METATYPE(Qt::AlignmentFlag) |
222 | void 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 | |
232 | void 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 | |
367 | void 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 |
378 | void 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 | |
397 | void 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 |
411 | void 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 | |
422 | void 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 |
446 | void 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 | |
482 | void 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 |
501 | void 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 | |
538 | void 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 |
557 | void 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 | |
618 | void 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 |
628 | void 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 | |
660 | void 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 |
669 | void 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 | |
680 | void 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 | |
702 | void 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 |
710 | void 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 | |
759 | void 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 |
778 | void 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 | |
815 | void 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 |
830 | void 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 | |
859 | void 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 |
867 | void 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 | |
888 | class LayoutStyle : public QProxyStyle |
889 | { |
890 | public: |
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 | |
909 | void 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 | |
976 | void 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 |
986 | void 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 | |
1018 | void 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 | |
1029 | void 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 | |
1064 | void 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 | |
1119 | typedef QList<int> IntList; |
1120 | |
1121 | void 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 |
1132 | void 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 | |
1189 | void 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 | |
1224 | void 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 | |
1271 | void 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 | |
1331 | Q_DECLARE_METATYPE(Qt::SizeHint) |
1332 | void 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 |
1349 | void 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 | |
1377 | void 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 | |
1463 | void 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 | |
1503 | void 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 | |
1532 | void 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 | |
1542 | void tst_QGraphicsLinearLayout::styleInfoLeak() |
1543 | { |
1544 | QGraphicsLinearLayout layout; |
1545 | layout.spacing(); |
1546 | } |
1547 | |
1548 | void 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 | |
1563 | void 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 | |
1610 | void 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 | } |
1645 | void 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 | |
1678 | void 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 | |
1703 | void 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 | |
1738 | QTEST_MAIN(tst_QGraphicsLinearLayout) |
1739 | #include "tst_qgraphicslinearlayout.moc" |
1740 | |
1741 | |