1 /****************************************************************************
3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
4 ** All rights reserved.
5 ** Contact: Nokia Corporation (qt-info@nokia.com)
7 ** This file is part of the test suite of the Qt Toolkit.
9 ** $QT_BEGIN_LICENSE:LGPL$
10 ** GNU Lesser General Public License Usage
11 ** This file may be used under the terms of the GNU Lesser General Public
12 ** License version 2.1 as published by the Free Software Foundation and
13 ** appearing in the file LICENSE.LGPL included in the packaging of this
14 ** file. Please review the following information to ensure the GNU Lesser
15 ** General Public License version 2.1 requirements will be met:
16 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
18 ** In addition, as a special exception, Nokia gives you certain additional
19 ** rights. These rights are described in the Nokia Qt LGPL Exception
20 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
22 ** GNU General Public License Usage
23 ** Alternatively, this file may be used under the terms of the GNU General
24 ** Public License version 3.0 as published by the Free Software Foundation
25 ** and appearing in the file LICENSE.GPL included in the packaging of this
26 ** file. Please review the following information to ensure the GNU General
27 ** Public License version 3.0 requirements will be met:
28 ** http://www.gnu.org/copyleft/gpl.html.
31 ** Alternatively, this file may be used in accordance with the terms and
32 ** conditions contained in a signed written agreement between you and Nokia.
40 ****************************************************************************/
41 #include <QtTest/QtTest>
42 #include <private/qlistmodelinterface_p.h>
44 #include <qdeclarativeengine.h>
45 #include <private/qsgrectangle_p.h>
46 #include <private/qsgpositioners_p.h>
47 #include <private/qdeclarativetransition_p.h>
48 #include <private/qsgitem_p.h>
49 #include <qdeclarativeexpression.h>
50 #include <QtWidgets/qgraphicswidget.h>
51 #include "../../../shared/util.h"
53 class tst_qsgpositioners : public QObject
60 void test_horizontal();
61 void test_horizontal_rtl();
62 void test_horizontal_spacing();
63 void test_horizontal_spacing_rightToLeft();
64 void test_horizontal_animated();
65 void test_horizontal_animated_rightToLeft();
66 void test_horizontal_animated_disabled();
68 void test_vertical_spacing();
69 void test_vertical_animated();
71 void test_grid_topToBottom();
72 void test_grid_rightToLeft();
73 void test_grid_spacing();
74 void test_grid_row_column_spacing();
75 void test_grid_animated();
76 void test_grid_animated_rightToLeft();
77 void test_grid_zero_columns();
78 void test_propertychanges();
81 void test_flow_rightToLeft();
82 void test_flow_topToBottom();
83 void test_flow_resize();
84 void test_flow_resize_rightToLeft();
85 void test_flow_implicit_resize();
86 void test_conflictinganchors();
87 void test_mirroring();
88 void test_allInvisible();
89 void test_attachedproperties();
90 void test_attachedproperties_data();
91 void test_attachedproperties_dynamic();
94 QSGView *createView(const QString &filename, bool wait=true);
97 tst_qsgpositioners::tst_qsgpositioners()
101 void tst_qsgpositioners::test_horizontal()
103 QSGView *canvas = createView(SRCDIR "/data/horizontal.qml");
105 canvas->rootObject()->setProperty("testRightToLeft", false);
107 QSGRectangle *one = canvas->rootObject()->findChild<QSGRectangle*>("one");
110 QSGRectangle *two = canvas->rootObject()->findChild<QSGRectangle*>("two");
113 QSGRectangle *three = canvas->rootObject()->findChild<QSGRectangle*>("three");
116 QCOMPARE(one->x(), 0.0);
117 QCOMPARE(one->y(), 0.0);
118 QCOMPARE(two->x(), 50.0);
119 QCOMPARE(two->y(), 0.0);
120 QCOMPARE(three->x(), 70.0);
121 QCOMPARE(three->y(), 0.0);
123 QSGItem *row = canvas->rootObject()->findChild<QSGItem*>("row");
124 QCOMPARE(row->width(), 110.0);
125 QCOMPARE(row->height(), 50.0);
130 void tst_qsgpositioners::test_horizontal_rtl()
132 QSGView *canvas = createView(SRCDIR "/data/horizontal.qml");
134 canvas->rootObject()->setProperty("testRightToLeft", true);
136 QSGRectangle *one = canvas->rootObject()->findChild<QSGRectangle*>("one");
139 QSGRectangle *two = canvas->rootObject()->findChild<QSGRectangle*>("two");
142 QSGRectangle *three = canvas->rootObject()->findChild<QSGRectangle*>("three");
145 QCOMPARE(one->x(), 60.0);
146 QCOMPARE(one->y(), 0.0);
147 QCOMPARE(two->x(), 40.0);
148 QCOMPARE(two->y(), 0.0);
149 QCOMPARE(three->x(), 0.0);
150 QCOMPARE(three->y(), 0.0);
152 QSGItem *row = canvas->rootObject()->findChild<QSGItem*>("row");
153 QCOMPARE(row->width(), 110.0);
154 QCOMPARE(row->height(), 50.0);
156 // Change the width of the row and check that items stay to the right
158 QTRY_COMPARE(one->x(), 150.0);
159 QCOMPARE(one->y(), 0.0);
160 QCOMPARE(two->x(), 130.0);
161 QCOMPARE(two->y(), 0.0);
162 QCOMPARE(three->x(), 90.0);
163 QCOMPARE(three->y(), 0.0);
168 void tst_qsgpositioners::test_horizontal_spacing()
170 QSGView *canvas = createView(SRCDIR "/data/horizontal-spacing.qml");
172 canvas->rootObject()->setProperty("testRightToLeft", false);
174 QSGRectangle *one = canvas->rootObject()->findChild<QSGRectangle*>("one");
177 QSGRectangle *two = canvas->rootObject()->findChild<QSGRectangle*>("two");
180 QSGRectangle *three = canvas->rootObject()->findChild<QSGRectangle*>("three");
183 QCOMPARE(one->x(), 0.0);
184 QCOMPARE(one->y(), 0.0);
185 QCOMPARE(two->x(), 60.0);
186 QCOMPARE(two->y(), 0.0);
187 QCOMPARE(three->x(), 90.0);
188 QCOMPARE(three->y(), 0.0);
190 QSGItem *row = canvas->rootObject()->findChild<QSGItem*>("row");
191 QCOMPARE(row->width(), 130.0);
192 QCOMPARE(row->height(), 50.0);
197 void tst_qsgpositioners::test_horizontal_spacing_rightToLeft()
199 QSGView *canvas = createView(SRCDIR "/data/horizontal-spacing.qml");
201 canvas->rootObject()->setProperty("testRightToLeft", true);
203 QSGRectangle *one = canvas->rootObject()->findChild<QSGRectangle*>("one");
206 QSGRectangle *two = canvas->rootObject()->findChild<QSGRectangle*>("two");
209 QSGRectangle *three = canvas->rootObject()->findChild<QSGRectangle*>("three");
212 QCOMPARE(one->x(), 80.0);
213 QCOMPARE(one->y(), 0.0);
214 QCOMPARE(two->x(), 50.0);
215 QCOMPARE(two->y(), 0.0);
216 QCOMPARE(three->x(), 00.0);
217 QCOMPARE(three->y(), 0.0);
219 QSGItem *row = canvas->rootObject()->findChild<QSGItem*>("row");
220 QCOMPARE(row->width(), 130.0);
221 QCOMPARE(row->height(), 50.0);
226 void tst_qsgpositioners::test_horizontal_animated()
228 QSGView *canvas = createView(SRCDIR "/data/horizontal-animated.qml", false);
230 canvas->rootObject()->setProperty("testRightToLeft", false);
232 QSGRectangle *one = canvas->rootObject()->findChild<QSGRectangle*>("one");
235 QSGRectangle *two = canvas->rootObject()->findChild<QSGRectangle*>("two");
238 QSGRectangle *three = canvas->rootObject()->findChild<QSGRectangle*>("three");
241 //Note that they animate in
242 QCOMPARE(one->x(), -100.0);
243 QCOMPARE(two->x(), -100.0);
244 QCOMPARE(three->x(), -100.0);
246 QTest::qWaitForWindowShown(canvas); //It may not relayout until the next frame, so it needs to be drawn
248 QSGItem *row = canvas->rootObject()->findChild<QSGItem*>("row");
250 QCOMPARE(row->width(), 100.0);
251 QCOMPARE(row->height(), 50.0);
253 //QTRY_COMPARE used instead of waiting for the expected time of animation completion
254 //Note that this means the duration of the animation is NOT tested
256 QTRY_COMPARE(one->x(), 0.0);
257 QTRY_COMPARE(one->y(), 0.0);
258 QTRY_COMPARE(two->isVisible(), false);
259 QTRY_COMPARE(two->x(), -100.0);//Not 'in' yet
260 QTRY_COMPARE(two->y(), 0.0);
261 QTRY_COMPARE(three->x(), 50.0);
262 QTRY_COMPARE(three->y(), 0.0);
265 two->setVisible(true);
266 QTRY_COMPARE(two->isVisible(), true);
267 QTRY_COMPARE(row->width(), 150.0);
268 QTRY_COMPARE(row->height(), 50.0);
270 QTest::qWait(0);//Let the animation start
271 QCOMPARE(two->x(), -100.0);
272 QCOMPARE(three->x(), 50.0);
274 QTRY_COMPARE(two->x(), 50.0);
275 QTRY_COMPARE(three->x(), 100.0);
280 void tst_qsgpositioners::test_horizontal_animated_rightToLeft()
282 QSGView *canvas = createView(SRCDIR "/data/horizontal-animated.qml", false);
284 canvas->rootObject()->setProperty("testRightToLeft", true);
286 QSGRectangle *one = canvas->rootObject()->findChild<QSGRectangle*>("one");
289 QSGRectangle *two = canvas->rootObject()->findChild<QSGRectangle*>("two");
292 QSGRectangle *three = canvas->rootObject()->findChild<QSGRectangle*>("three");
295 //Note that they animate in
296 QCOMPARE(one->x(), -100.0);
297 QCOMPARE(two->x(), -100.0);
298 QCOMPARE(three->x(), -100.0);
300 QTest::qWaitForWindowShown(canvas); //It may not relayout until the next frame, so it needs to be drawn
302 QSGItem *row = canvas->rootObject()->findChild<QSGItem*>("row");
304 QCOMPARE(row->width(), 100.0);
305 QCOMPARE(row->height(), 50.0);
307 //QTRY_COMPARE used instead of waiting for the expected time of animation completion
308 //Note that this means the duration of the animation is NOT tested
310 QTRY_COMPARE(one->x(), 50.0);
311 QTRY_COMPARE(one->y(), 0.0);
312 QTRY_COMPARE(two->isVisible(), false);
313 QTRY_COMPARE(two->x(), -100.0);//Not 'in' yet
314 QTRY_COMPARE(two->y(), 0.0);
315 QTRY_COMPARE(three->x(), 0.0);
316 QTRY_COMPARE(three->y(), 0.0);
319 two->setVisible(true);
320 QTRY_COMPARE(two->isVisible(), true);
322 // New size should propagate after visible change
323 QTRY_COMPARE(row->width(), 150.0);
324 QTRY_COMPARE(row->height(), 50.0);
326 QTest::qWait(0);//Let the animation start
327 QCOMPARE(one->x(), 50.0);
328 QCOMPARE(two->x(), -100.0);
330 QTRY_COMPARE(one->x(), 100.0);
331 QTRY_COMPARE(two->x(), 50.0);
336 void tst_qsgpositioners::test_horizontal_animated_disabled()
338 QSGView *canvas = createView(SRCDIR "/data/horizontal-animated-disabled.qml");
340 QSGRectangle *one = canvas->rootObject()->findChild<QSGRectangle*>("one");
343 QSGRectangle *two = canvas->rootObject()->findChild<QSGRectangle*>("two");
346 QSGRectangle *three = canvas->rootObject()->findChild<QSGRectangle*>("three");
349 QSGItem *row = canvas->rootObject()->findChild<QSGItem*>("row");
352 qApp->processEvents();
354 QCOMPARE(one->x(), 0.0);
355 QCOMPARE(one->y(), 0.0);
356 QCOMPARE(two->isVisible(), false);
357 QCOMPARE(two->x(), -100.0);//Not 'in' yet
358 QCOMPARE(two->y(), 0.0);
359 QCOMPARE(three->x(), 50.0);
360 QCOMPARE(three->y(), 0.0);
363 two->setVisible(true);
364 QCOMPARE(two->isVisible(), true);
365 qApp->processEvents();
366 QCOMPARE(row->width(), 150.0);
367 QCOMPARE(row->height(), 50.0);
369 qApp->processEvents();
370 QCOMPARE(two->x(), 50.0);
371 QCOMPARE(three->x(), 100.0);
376 void tst_qsgpositioners::test_vertical()
378 QSGView *canvas = createView(SRCDIR "/data/vertical.qml");
380 QSGRectangle *one = canvas->rootObject()->findChild<QSGRectangle*>("one");
383 QSGRectangle *two = canvas->rootObject()->findChild<QSGRectangle*>("two");
386 QSGRectangle *three = canvas->rootObject()->findChild<QSGRectangle*>("three");
389 QCOMPARE(one->x(), 0.0);
390 QCOMPARE(one->y(), 0.0);
391 QCOMPARE(two->x(), 0.0);
392 QCOMPARE(two->y(), 50.0);
393 QCOMPARE(three->x(), 0.0);
394 QCOMPARE(three->y(), 60.0);
396 QSGItem *column = canvas->rootObject()->findChild<QSGItem*>("column");
398 QCOMPARE(column->height(), 80.0);
399 QCOMPARE(column->width(), 50.0);
404 void tst_qsgpositioners::test_vertical_spacing()
406 QSGView *canvas = createView(SRCDIR "/data/vertical-spacing.qml");
408 QSGRectangle *one = canvas->rootObject()->findChild<QSGRectangle*>("one");
411 QSGRectangle *two = canvas->rootObject()->findChild<QSGRectangle*>("two");
414 QSGRectangle *three = canvas->rootObject()->findChild<QSGRectangle*>("three");
417 QCOMPARE(one->x(), 0.0);
418 QCOMPARE(one->y(), 0.0);
419 QCOMPARE(two->x(), 0.0);
420 QCOMPARE(two->y(), 60.0);
421 QCOMPARE(three->x(), 0.0);
422 QCOMPARE(three->y(), 80.0);
424 QSGItem *column = canvas->rootObject()->findChild<QSGItem*>("column");
425 QCOMPARE(column->height(), 100.0);
426 QCOMPARE(column->width(), 50.0);
431 void tst_qsgpositioners::test_vertical_animated()
433 QSGView *canvas = createView(SRCDIR "/data/vertical-animated.qml", false);
435 //Note that they animate in
436 QSGRectangle *one = canvas->rootObject()->findChild<QSGRectangle*>("one");
438 QCOMPARE(one->y(), -100.0);
440 QSGRectangle *two = canvas->rootObject()->findChild<QSGRectangle*>("two");
442 QCOMPARE(two->y(), -100.0);
444 QSGRectangle *three = canvas->rootObject()->findChild<QSGRectangle*>("three");
446 QCOMPARE(three->y(), -100.0);
448 QTest::qWaitForWindowShown(canvas); //It may not relayout until the next frame, so it needs to be drawn
450 QSGItem *column = canvas->rootObject()->findChild<QSGItem*>("column");
452 QCOMPARE(column->height(), 100.0);
453 QCOMPARE(column->width(), 50.0);
455 //QTRY_COMPARE used instead of waiting for the expected time of animation completion
456 //Note that this means the duration of the animation is NOT tested
458 QTRY_COMPARE(one->y(), 0.0);
459 QTRY_COMPARE(one->x(), 0.0);
460 QTRY_COMPARE(two->isVisible(), false);
461 QTRY_COMPARE(two->y(), -100.0);//Not 'in' yet
462 QTRY_COMPARE(two->x(), 0.0);
463 QTRY_COMPARE(three->y(), 50.0);
464 QTRY_COMPARE(three->x(), 0.0);
467 two->setVisible(true);
468 QTRY_COMPARE(two->isVisible(), true);
469 QTRY_COMPARE(column->height(), 150.0);
470 QTRY_COMPARE(column->width(), 50.0);
471 QTest::qWait(0);//Let the animation start
472 QCOMPARE(two->y(), -100.0);
473 QCOMPARE(three->y(), 50.0);
475 QTRY_COMPARE(two->y(), 50.0);
476 QTRY_COMPARE(three->y(), 100.0);
481 void tst_qsgpositioners::test_grid()
483 QSGView *canvas = createView(SRCDIR "/data/gridtest.qml");
485 QSGRectangle *one = canvas->rootObject()->findChild<QSGRectangle*>("one");
487 QSGRectangle *two = canvas->rootObject()->findChild<QSGRectangle*>("two");
489 QSGRectangle *three = canvas->rootObject()->findChild<QSGRectangle*>("three");
491 QSGRectangle *four = canvas->rootObject()->findChild<QSGRectangle*>("four");
493 QSGRectangle *five = canvas->rootObject()->findChild<QSGRectangle*>("five");
496 QCOMPARE(one->x(), 0.0);
497 QCOMPARE(one->y(), 0.0);
498 QCOMPARE(two->x(), 50.0);
499 QCOMPARE(two->y(), 0.0);
500 QCOMPARE(three->x(), 70.0);
501 QCOMPARE(three->y(), 0.0);
502 QCOMPARE(four->x(), 0.0);
503 QCOMPARE(four->y(), 50.0);
504 QCOMPARE(five->x(), 50.0);
505 QCOMPARE(five->y(), 50.0);
507 QSGGrid *grid = canvas->rootObject()->findChild<QSGGrid*>("grid");
508 QCOMPARE(grid->flow(), QSGGrid::LeftToRight);
509 QCOMPARE(grid->width(), 100.0);
510 QCOMPARE(grid->height(), 100.0);
515 void tst_qsgpositioners::test_grid_topToBottom()
517 QSGView *canvas = createView(SRCDIR "/data/grid-toptobottom.qml");
519 QSGRectangle *one = canvas->rootObject()->findChild<QSGRectangle*>("one");
521 QSGRectangle *two = canvas->rootObject()->findChild<QSGRectangle*>("two");
523 QSGRectangle *three = canvas->rootObject()->findChild<QSGRectangle*>("three");
525 QSGRectangle *four = canvas->rootObject()->findChild<QSGRectangle*>("four");
527 QSGRectangle *five = canvas->rootObject()->findChild<QSGRectangle*>("five");
530 QCOMPARE(one->x(), 0.0);
531 QCOMPARE(one->y(), 0.0);
532 QCOMPARE(two->x(), 0.0);
533 QCOMPARE(two->y(), 50.0);
534 QCOMPARE(three->x(), 0.0);
535 QCOMPARE(three->y(), 100.0);
536 QCOMPARE(four->x(), 50.0);
537 QCOMPARE(four->y(), 0.0);
538 QCOMPARE(five->x(), 50.0);
539 QCOMPARE(five->y(), 50.0);
541 QSGGrid *grid = canvas->rootObject()->findChild<QSGGrid*>("grid");
542 QCOMPARE(grid->flow(), QSGGrid::TopToBottom);
543 QCOMPARE(grid->width(), 100.0);
544 QCOMPARE(grid->height(), 120.0);
549 void tst_qsgpositioners::test_grid_rightToLeft()
551 QSGView *canvas = createView(SRCDIR "/data/gridtest.qml");
553 canvas->rootObject()->setProperty("testRightToLeft", true);
555 QSGRectangle *one = canvas->rootObject()->findChild<QSGRectangle*>("one");
557 QSGRectangle *two = canvas->rootObject()->findChild<QSGRectangle*>("two");
559 QSGRectangle *three = canvas->rootObject()->findChild<QSGRectangle*>("three");
561 QSGRectangle *four = canvas->rootObject()->findChild<QSGRectangle*>("four");
563 QSGRectangle *five = canvas->rootObject()->findChild<QSGRectangle*>("five");
566 QCOMPARE(one->x(), 50.0);
567 QCOMPARE(one->y(), 0.0);
568 QCOMPARE(two->x(), 30.0);
569 QCOMPARE(two->y(), 0.0);
570 QCOMPARE(three->x(), 0.0);
571 QCOMPARE(three->y(), 0.0);
572 QCOMPARE(four->x(), 50.0);
573 QCOMPARE(four->y(), 50.0);
574 QCOMPARE(five->x(), 40.0);
575 QCOMPARE(five->y(), 50.0);
577 QSGGrid *grid = canvas->rootObject()->findChild<QSGGrid*>("grid");
578 QCOMPARE(grid->layoutDirection(), Qt::RightToLeft);
579 QCOMPARE(grid->width(), 100.0);
580 QCOMPARE(grid->height(), 100.0);
582 // Change the width of the grid and check that items stay to the right
584 QTRY_COMPARE(one->x(), 150.0);
585 QCOMPARE(one->y(), 0.0);
586 QCOMPARE(two->x(), 130.0);
587 QCOMPARE(two->y(), 0.0);
588 QCOMPARE(three->x(), 100.0);
589 QCOMPARE(three->y(), 0.0);
590 QCOMPARE(four->x(), 150.0);
591 QCOMPARE(four->y(), 50.0);
592 QCOMPARE(five->x(), 140.0);
593 QCOMPARE(five->y(), 50.0);
598 void tst_qsgpositioners::test_grid_spacing()
600 QSGView *canvas = createView(SRCDIR "/data/grid-spacing.qml");
602 QSGRectangle *one = canvas->rootObject()->findChild<QSGRectangle*>("one");
604 QSGRectangle *two = canvas->rootObject()->findChild<QSGRectangle*>("two");
606 QSGRectangle *three = canvas->rootObject()->findChild<QSGRectangle*>("three");
608 QSGRectangle *four = canvas->rootObject()->findChild<QSGRectangle*>("four");
610 QSGRectangle *five = canvas->rootObject()->findChild<QSGRectangle*>("five");
613 QCOMPARE(one->x(), 0.0);
614 QCOMPARE(one->y(), 0.0);
615 QCOMPARE(two->x(), 54.0);
616 QCOMPARE(two->y(), 0.0);
617 QCOMPARE(three->x(), 78.0);
618 QCOMPARE(three->y(), 0.0);
619 QCOMPARE(four->x(), 0.0);
620 QCOMPARE(four->y(), 54.0);
621 QCOMPARE(five->x(), 54.0);
622 QCOMPARE(five->y(), 54.0);
624 QSGItem *grid = canvas->rootObject()->findChild<QSGItem*>("grid");
625 QCOMPARE(grid->width(), 128.0);
626 QCOMPARE(grid->height(), 104.0);
631 void tst_qsgpositioners::test_grid_row_column_spacing()
633 QSGView *canvas = createView(SRCDIR "/data/grid-row-column-spacing.qml");
635 QSGRectangle *one = canvas->rootObject()->findChild<QSGRectangle*>("one");
637 QSGRectangle *two = canvas->rootObject()->findChild<QSGRectangle*>("two");
639 QSGRectangle *three = canvas->rootObject()->findChild<QSGRectangle*>("three");
641 QSGRectangle *four = canvas->rootObject()->findChild<QSGRectangle*>("four");
643 QSGRectangle *five = canvas->rootObject()->findChild<QSGRectangle*>("five");
646 QCOMPARE(one->x(), 0.0);
647 QCOMPARE(one->y(), 0.0);
648 QCOMPARE(two->x(), 61.0);
649 QCOMPARE(two->y(), 0.0);
650 QCOMPARE(three->x(), 92.0);
651 QCOMPARE(three->y(), 0.0);
652 QCOMPARE(four->x(), 0.0);
653 QCOMPARE(four->y(), 57.0);
654 QCOMPARE(five->x(), 61.0);
655 QCOMPARE(five->y(), 57.0);
657 QSGItem *grid = canvas->rootObject()->findChild<QSGItem*>("grid");
658 QCOMPARE(grid->width(), 142.0);
659 QCOMPARE(grid->height(), 107.0);
664 void tst_qsgpositioners::test_grid_animated()
666 QSGView *canvas = createView(SRCDIR "/data/grid-animated.qml", false);
668 canvas->rootObject()->setProperty("testRightToLeft", false);
670 //Note that all animate in
671 QSGRectangle *one = canvas->rootObject()->findChild<QSGRectangle*>("one");
673 QCOMPARE(one->x(), -100.0);
674 QCOMPARE(one->y(), -100.0);
676 QSGRectangle *two = canvas->rootObject()->findChild<QSGRectangle*>("two");
678 QCOMPARE(two->x(), -100.0);
679 QCOMPARE(two->y(), -100.0);
681 QSGRectangle *three = canvas->rootObject()->findChild<QSGRectangle*>("three");
683 QCOMPARE(three->x(), -100.0);
684 QCOMPARE(three->y(), -100.0);
686 QSGRectangle *four = canvas->rootObject()->findChild<QSGRectangle*>("four");
688 QCOMPARE(four->x(), -100.0);
689 QCOMPARE(four->y(), -100.0);
691 QSGRectangle *five = canvas->rootObject()->findChild<QSGRectangle*>("five");
693 QCOMPARE(five->x(), -100.0);
694 QCOMPARE(five->y(), -100.0);
696 QTest::qWaitForWindowShown(canvas); //It may not relayout until the next frame, so it needs to be drawn
698 QSGItem *grid = canvas->rootObject()->findChild<QSGItem*>("grid");
700 QCOMPARE(grid->width(), 150.0);
701 QCOMPARE(grid->height(), 100.0);
703 //QTRY_COMPARE used instead of waiting for the expected time of animation completion
704 //Note that this means the duration of the animation is NOT tested
706 QTRY_COMPARE(one->y(), 0.0);
707 QTRY_COMPARE(one->x(), 0.0);
708 QTRY_COMPARE(two->isVisible(), false);
709 QTRY_COMPARE(two->y(), -100.0);
710 QTRY_COMPARE(two->x(), -100.0);
711 QTRY_COMPARE(three->y(), 0.0);
712 QTRY_COMPARE(three->x(), 50.0);
713 QTRY_COMPARE(four->y(), 0.0);
714 QTRY_COMPARE(four->x(), 100.0);
715 QTRY_COMPARE(five->y(), 50.0);
716 QTRY_COMPARE(five->x(), 0.0);
719 two->setVisible(true);
720 QCOMPARE(two->isVisible(), true);
721 QCOMPARE(grid->width(), 150.0);
722 QCOMPARE(grid->height(), 100.0);
723 QTest::qWait(0);//Let the animation start
724 QCOMPARE(two->x(), -100.0);
725 QCOMPARE(two->y(), -100.0);
726 QCOMPARE(one->x(), 0.0);
727 QCOMPARE(one->y(), 0.0);
728 QCOMPARE(three->x(), 50.0);
729 QCOMPARE(three->y(), 0.0);
730 QCOMPARE(four->x(), 100.0);
731 QCOMPARE(four->y(), 0.0);
732 QCOMPARE(five->x(), 0.0);
733 QCOMPARE(five->y(), 50.0);
734 //Let the animation complete
735 QTRY_COMPARE(two->x(), 50.0);
736 QTRY_COMPARE(two->y(), 0.0);
737 QTRY_COMPARE(one->x(), 0.0);
738 QTRY_COMPARE(one->y(), 0.0);
739 QTRY_COMPARE(three->x(), 100.0);
740 QTRY_COMPARE(three->y(), 0.0);
741 QTRY_COMPARE(four->x(), 0.0);
742 QTRY_COMPARE(four->y(), 50.0);
743 QTRY_COMPARE(five->x(), 50.0);
744 QTRY_COMPARE(five->y(), 50.0);
749 void tst_qsgpositioners::test_grid_animated_rightToLeft()
751 QSGView *canvas = createView(SRCDIR "/data/grid-animated.qml", false);
753 canvas->rootObject()->setProperty("testRightToLeft", true);
755 //Note that all animate in
756 QSGRectangle *one = canvas->rootObject()->findChild<QSGRectangle*>("one");
758 QCOMPARE(one->x(), -100.0);
759 QCOMPARE(one->y(), -100.0);
761 QSGRectangle *two = canvas->rootObject()->findChild<QSGRectangle*>("two");
763 QCOMPARE(two->x(), -100.0);
764 QCOMPARE(two->y(), -100.0);
766 QSGRectangle *three = canvas->rootObject()->findChild<QSGRectangle*>("three");
768 QCOMPARE(three->x(), -100.0);
769 QCOMPARE(three->y(), -100.0);
771 QSGRectangle *four = canvas->rootObject()->findChild<QSGRectangle*>("four");
773 QCOMPARE(four->x(), -100.0);
774 QCOMPARE(four->y(), -100.0);
776 QSGRectangle *five = canvas->rootObject()->findChild<QSGRectangle*>("five");
778 QCOMPARE(five->x(), -100.0);
779 QCOMPARE(five->y(), -100.0);
781 QTest::qWaitForWindowShown(canvas); //It may not relayout until the next frame, so it needs to be drawn
783 QSGItem *grid = canvas->rootObject()->findChild<QSGItem*>("grid");
785 QCOMPARE(grid->width(), 150.0);
786 QCOMPARE(grid->height(), 100.0);
788 //QTRY_COMPARE used instead of waiting for the expected time of animation completion
789 //Note that this means the duration of the animation is NOT tested
791 QTRY_COMPARE(one->y(), 0.0);
792 QTRY_COMPARE(one->x(), 100.0);
793 QTRY_COMPARE(two->isVisible(), false);
794 QTRY_COMPARE(two->y(), -100.0);
795 QTRY_COMPARE(two->x(), -100.0);
796 QTRY_COMPARE(three->y(), 0.0);
797 QTRY_COMPARE(three->x(), 50.0);
798 QTRY_COMPARE(four->y(), 0.0);
799 QTRY_COMPARE(four->x(), 0.0);
800 QTRY_COMPARE(five->y(), 50.0);
801 QTRY_COMPARE(five->x(), 100.0);
804 two->setVisible(true);
805 QCOMPARE(two->isVisible(), true);
806 QCOMPARE(grid->width(), 150.0);
807 QCOMPARE(grid->height(), 100.0);
808 QTest::qWait(0);//Let the animation start
809 QCOMPARE(two->x(), -100.0);
810 QCOMPARE(two->y(), -100.0);
811 QCOMPARE(one->x(), 100.0);
812 QCOMPARE(one->y(), 0.0);
813 QCOMPARE(three->x(), 50.0);
814 QCOMPARE(three->y(), 0.0);
815 QCOMPARE(four->x(), 0.0);
816 QCOMPARE(four->y(), 0.0);
817 QCOMPARE(five->x(), 100.0);
818 QCOMPARE(five->y(), 50.0);
819 //Let the animation complete
820 QTRY_COMPARE(two->x(), 50.0);
821 QTRY_COMPARE(two->y(), 0.0);
822 QTRY_COMPARE(one->x(), 100.0);
823 QTRY_COMPARE(one->y(), 0.0);
824 QTRY_COMPARE(three->x(), 0.0);
825 QTRY_COMPARE(three->y(), 0.0);
826 QTRY_COMPARE(four->x(), 100.0);
827 QTRY_COMPARE(four->y(), 50.0);
828 QTRY_COMPARE(five->x(), 50.0);
829 QTRY_COMPARE(five->y(), 50.0);
834 void tst_qsgpositioners::test_grid_zero_columns()
836 QSGView *canvas = createView(SRCDIR "/data/gridzerocolumns.qml");
838 QSGRectangle *one = canvas->rootObject()->findChild<QSGRectangle*>("one");
840 QSGRectangle *two = canvas->rootObject()->findChild<QSGRectangle*>("two");
842 QSGRectangle *three = canvas->rootObject()->findChild<QSGRectangle*>("three");
844 QSGRectangle *four = canvas->rootObject()->findChild<QSGRectangle*>("four");
846 QSGRectangle *five = canvas->rootObject()->findChild<QSGRectangle*>("five");
849 QCOMPARE(one->x(), 0.0);
850 QCOMPARE(one->y(), 0.0);
851 QCOMPARE(two->x(), 50.0);
852 QCOMPARE(two->y(), 0.0);
853 QCOMPARE(three->x(), 70.0);
854 QCOMPARE(three->y(), 0.0);
855 QCOMPARE(four->x(), 120.0);
856 QCOMPARE(four->y(), 0.0);
857 QCOMPARE(five->x(), 0.0);
858 QCOMPARE(five->y(), 50.0);
860 QSGItem *grid = canvas->rootObject()->findChild<QSGItem*>("grid");
861 QCOMPARE(grid->width(), 170.0);
862 QCOMPARE(grid->height(), 60.0);
867 void tst_qsgpositioners::test_propertychanges()
869 QSGView *canvas = createView(SRCDIR "/data/propertychangestest.qml");
871 QSGGrid *grid = qobject_cast<QSGGrid*>(canvas->rootObject());
873 QDeclarativeTransition *rowTransition = canvas->rootObject()->findChild<QDeclarativeTransition*>("rowTransition");
874 QDeclarativeTransition *columnTransition = canvas->rootObject()->findChild<QDeclarativeTransition*>("columnTransition");
876 QSignalSpy addSpy(grid, SIGNAL(addChanged()));
877 QSignalSpy moveSpy(grid, SIGNAL(moveChanged()));
878 QSignalSpy columnsSpy(grid, SIGNAL(columnsChanged()));
879 QSignalSpy rowsSpy(grid, SIGNAL(rowsChanged()));
882 QVERIFY(rowTransition);
883 QVERIFY(columnTransition);
884 QCOMPARE(grid->add(), columnTransition);
885 QCOMPARE(grid->move(), columnTransition);
886 QCOMPARE(grid->columns(), 4);
887 QCOMPARE(grid->rows(), -1);
889 grid->setAdd(rowTransition);
890 grid->setMove(rowTransition);
891 QCOMPARE(grid->add(), rowTransition);
892 QCOMPARE(grid->move(), rowTransition);
893 QCOMPARE(addSpy.count(),1);
894 QCOMPARE(moveSpy.count(),1);
896 grid->setAdd(rowTransition);
897 grid->setMove(rowTransition);
898 QCOMPARE(addSpy.count(),1);
899 QCOMPARE(moveSpy.count(),1);
903 QCOMPARE(addSpy.count(),2);
904 QCOMPARE(moveSpy.count(),2);
906 grid->setColumns(-1);
908 QCOMPARE(grid->columns(), -1);
909 QCOMPARE(grid->rows(), 3);
910 QCOMPARE(columnsSpy.count(),1);
911 QCOMPARE(rowsSpy.count(),1);
913 grid->setColumns(-1);
915 QCOMPARE(columnsSpy.count(),1);
916 QCOMPARE(rowsSpy.count(),1);
920 QCOMPARE(columnsSpy.count(),2);
921 QCOMPARE(rowsSpy.count(),2);
926 void tst_qsgpositioners::test_repeater()
928 QSGView *canvas = createView(SRCDIR "/data/repeatertest.qml");
930 QSGRectangle *one = canvas->rootObject()->findChild<QSGRectangle*>("one");
933 QSGRectangle *two = canvas->rootObject()->findChild<QSGRectangle*>("two");
936 QSGRectangle *three = canvas->rootObject()->findChild<QSGRectangle*>("three");
939 QCOMPARE(one->x(), 0.0);
940 QCOMPARE(one->y(), 0.0);
941 QCOMPARE(two->x(), 50.0);
942 QCOMPARE(two->y(), 0.0);
943 QCOMPARE(three->x(), 100.0);
944 QCOMPARE(three->y(), 0.0);
949 void tst_qsgpositioners::test_flow()
951 QSGView *canvas = createView(SRCDIR "/data/flowtest.qml");
953 canvas->rootObject()->setProperty("testRightToLeft", false);
955 QSGRectangle *one = canvas->rootObject()->findChild<QSGRectangle*>("one");
957 QSGRectangle *two = canvas->rootObject()->findChild<QSGRectangle*>("two");
959 QSGRectangle *three = canvas->rootObject()->findChild<QSGRectangle*>("three");
961 QSGRectangle *four = canvas->rootObject()->findChild<QSGRectangle*>("four");
963 QSGRectangle *five = canvas->rootObject()->findChild<QSGRectangle*>("five");
966 QCOMPARE(one->x(), 0.0);
967 QCOMPARE(one->y(), 0.0);
968 QCOMPARE(two->x(), 50.0);
969 QCOMPARE(two->y(), 0.0);
970 QCOMPARE(three->x(), 0.0);
971 QCOMPARE(three->y(), 50.0);
972 QCOMPARE(four->x(), 0.0);
973 QCOMPARE(four->y(), 70.0);
974 QCOMPARE(five->x(), 50.0);
975 QCOMPARE(five->y(), 70.0);
977 QSGItem *flow = canvas->rootObject()->findChild<QSGItem*>("flow");
979 QCOMPARE(flow->width(), 90.0);
980 QCOMPARE(flow->height(), 120.0);
985 void tst_qsgpositioners::test_flow_rightToLeft()
987 QSGView *canvas = createView(SRCDIR "/data/flowtest.qml");
989 canvas->rootObject()->setProperty("testRightToLeft", true);
991 QSGRectangle *one = canvas->rootObject()->findChild<QSGRectangle*>("one");
993 QSGRectangle *two = canvas->rootObject()->findChild<QSGRectangle*>("two");
995 QSGRectangle *three = canvas->rootObject()->findChild<QSGRectangle*>("three");
997 QSGRectangle *four = canvas->rootObject()->findChild<QSGRectangle*>("four");
999 QSGRectangle *five = canvas->rootObject()->findChild<QSGRectangle*>("five");
1002 QCOMPARE(one->x(), 40.0);
1003 QCOMPARE(one->y(), 0.0);
1004 QCOMPARE(two->x(), 20.0);
1005 QCOMPARE(two->y(), 0.0);
1006 QCOMPARE(three->x(), 40.0);
1007 QCOMPARE(three->y(), 50.0);
1008 QCOMPARE(four->x(), 40.0);
1009 QCOMPARE(four->y(), 70.0);
1010 QCOMPARE(five->x(), 30.0);
1011 QCOMPARE(five->y(), 70.0);
1013 QSGItem *flow = canvas->rootObject()->findChild<QSGItem*>("flow");
1015 QCOMPARE(flow->width(), 90.0);
1016 QCOMPARE(flow->height(), 120.0);
1021 void tst_qsgpositioners::test_flow_topToBottom()
1023 QSGView *canvas = createView(SRCDIR "/data/flowtest-toptobottom.qml");
1025 canvas->rootObject()->setProperty("testRightToLeft", false);
1027 QSGRectangle *one = canvas->rootObject()->findChild<QSGRectangle*>("one");
1029 QSGRectangle *two = canvas->rootObject()->findChild<QSGRectangle*>("two");
1031 QSGRectangle *three = canvas->rootObject()->findChild<QSGRectangle*>("three");
1032 QVERIFY(three != 0);
1033 QSGRectangle *four = canvas->rootObject()->findChild<QSGRectangle*>("four");
1035 QSGRectangle *five = canvas->rootObject()->findChild<QSGRectangle*>("five");
1038 QCOMPARE(one->x(), 0.0);
1039 QCOMPARE(one->y(), 0.0);
1040 QCOMPARE(two->x(), 50.0);
1041 QCOMPARE(two->y(), 0.0);
1042 QCOMPARE(three->x(), 50.0);
1043 QCOMPARE(three->y(), 50.0);
1044 QCOMPARE(four->x(), 100.0);
1045 QCOMPARE(four->y(), 00.0);
1046 QCOMPARE(five->x(), 100.0);
1047 QCOMPARE(five->y(), 50.0);
1049 QSGItem *flow = canvas->rootObject()->findChild<QSGItem*>("flow");
1051 QCOMPARE(flow->height(), 90.0);
1052 QCOMPARE(flow->width(), 150.0);
1054 canvas->rootObject()->setProperty("testRightToLeft", true);
1057 QCOMPARE(flow->height(), 90.0);
1058 QCOMPARE(flow->width(), 150.0);
1060 QCOMPARE(one->x(), 100.0);
1061 QCOMPARE(one->y(), 0.0);
1062 QCOMPARE(two->x(), 80.0);
1063 QCOMPARE(two->y(), 0.0);
1064 QCOMPARE(three->x(), 50.0);
1065 QCOMPARE(three->y(), 50.0);
1066 QCOMPARE(four->x(), 0.0);
1067 QCOMPARE(four->y(), 0.0);
1068 QCOMPARE(five->x(), 40.0);
1069 QCOMPARE(five->y(), 50.0);
1074 void tst_qsgpositioners::test_flow_resize()
1076 QSGView *canvas = createView(SRCDIR "/data/flowtest.qml");
1078 QSGItem *root = qobject_cast<QSGItem*>(canvas->rootObject());
1080 root->setWidth(125);
1081 root->setProperty("testRightToLeft", false);
1083 QSGRectangle *one = canvas->rootObject()->findChild<QSGRectangle*>("one");
1085 QSGRectangle *two = canvas->rootObject()->findChild<QSGRectangle*>("two");
1087 QSGRectangle *three = canvas->rootObject()->findChild<QSGRectangle*>("three");
1088 QVERIFY(three != 0);
1089 QSGRectangle *four = canvas->rootObject()->findChild<QSGRectangle*>("four");
1091 QSGRectangle *five = canvas->rootObject()->findChild<QSGRectangle*>("five");
1094 QTRY_COMPARE(one->x(), 0.0);
1095 QTRY_COMPARE(one->y(), 0.0);
1096 QTRY_COMPARE(two->x(), 50.0);
1097 QTRY_COMPARE(two->y(), 0.0);
1098 QTRY_COMPARE(three->x(), 70.0);
1099 QTRY_COMPARE(three->y(), 0.0);
1100 QTRY_COMPARE(four->x(), 0.0);
1101 QTRY_COMPARE(four->y(), 50.0);
1102 QTRY_COMPARE(five->x(), 50.0);
1103 QTRY_COMPARE(five->y(), 50.0);
1108 void tst_qsgpositioners::test_flow_resize_rightToLeft()
1110 QSGView *canvas = createView(SRCDIR "/data/flowtest.qml");
1112 QSGItem *root = qobject_cast<QSGItem*>(canvas->rootObject());
1114 root->setWidth(125);
1115 root->setProperty("testRightToLeft", true);
1117 QSGRectangle *one = canvas->rootObject()->findChild<QSGRectangle*>("one");
1118 QTRY_VERIFY(one != 0);
1119 QSGRectangle *two = canvas->rootObject()->findChild<QSGRectangle*>("two");
1121 QSGRectangle *three = canvas->rootObject()->findChild<QSGRectangle*>("three");
1122 QVERIFY(three != 0);
1123 QSGRectangle *four = canvas->rootObject()->findChild<QSGRectangle*>("four");
1125 QSGRectangle *five = canvas->rootObject()->findChild<QSGRectangle*>("five");
1128 QCOMPARE(one->x(), 75.0);
1129 QCOMPARE(one->y(), 0.0);
1130 QCOMPARE(two->x(), 55.0);
1131 QCOMPARE(two->y(), 0.0);
1132 QCOMPARE(three->x(), 5.0);
1133 QCOMPARE(three->y(), 0.0);
1134 QCOMPARE(four->x(), 75.0);
1135 QCOMPARE(four->y(), 50.0);
1136 QCOMPARE(five->x(), 65.0);
1137 QCOMPARE(five->y(), 50.0);
1142 void tst_qsgpositioners::test_flow_implicit_resize()
1144 QSGView *canvas = createView(SRCDIR "/data/flow-testimplicitsize.qml");
1145 QVERIFY(canvas->rootObject() != 0);
1147 QSGFlow *flow = canvas->rootObject()->findChild<QSGFlow*>("flow");
1150 QCOMPARE(flow->width(), 100.0);
1151 QCOMPARE(flow->height(), 120.0);
1153 canvas->rootObject()->setProperty("flowLayout", 0);
1154 QCOMPARE(flow->flow(), QSGFlow::LeftToRight);
1155 QCOMPARE(flow->width(), 220.0);
1156 QCOMPARE(flow->height(), 50.0);
1158 canvas->rootObject()->setProperty("flowLayout", 1);
1159 QCOMPARE(flow->flow(), QSGFlow::TopToBottom);
1160 QCOMPARE(flow->width(), 100.0);
1161 QCOMPARE(flow->height(), 120.0);
1163 canvas->rootObject()->setProperty("flowLayout", 2);
1164 QCOMPARE(flow->layoutDirection(), Qt::RightToLeft);
1165 QCOMPARE(flow->width(), 220.0);
1166 QCOMPARE(flow->height(), 50.0);
1171 QString warningMessage;
1173 void interceptWarnings(QtMsgType type, const char *msg)
1176 warningMessage = msg;
1179 void tst_qsgpositioners::test_conflictinganchors()
1181 QtMsgHandler oldMsgHandler = qInstallMsgHandler(interceptWarnings);
1182 QDeclarativeEngine engine;
1183 QDeclarativeComponent component(&engine);
1185 component.setData("import QtQuick 2.0\nColumn { Item {} }", QUrl::fromLocalFile(""));
1186 QSGItem *item = qobject_cast<QSGItem*>(component.create());
1188 QVERIFY(warningMessage.isEmpty());
1191 component.setData("import QtQuick 2.0\nRow { Item {} }", QUrl::fromLocalFile(""));
1192 item = qobject_cast<QSGItem*>(component.create());
1194 QVERIFY(warningMessage.isEmpty());
1197 component.setData("import QtQuick 2.0\nGrid { Item {} }", QUrl::fromLocalFile(""));
1198 item = qobject_cast<QSGItem*>(component.create());
1200 QVERIFY(warningMessage.isEmpty());
1203 component.setData("import QtQuick 2.0\nFlow { Item {} }", QUrl::fromLocalFile(""));
1204 item = qobject_cast<QSGItem*>(component.create());
1206 QVERIFY(warningMessage.isEmpty());
1209 component.setData("import QtQuick 2.0\nColumn { Item { anchors.top: parent.top } }", QUrl::fromLocalFile(""));
1210 item = qobject_cast<QSGItem*>(component.create());
1212 QCOMPARE(warningMessage, QString("file::2:1: QML Column: Cannot specify top, bottom, verticalCenter, fill or centerIn anchors for items inside Column"));
1213 warningMessage.clear();
1216 component.setData("import QtQuick 2.0\nColumn { Item { anchors.centerIn: parent } }", QUrl::fromLocalFile(""));
1217 item = qobject_cast<QSGItem*>(component.create());
1219 QCOMPARE(warningMessage, QString("file::2:1: QML Column: Cannot specify top, bottom, verticalCenter, fill or centerIn anchors for items inside Column"));
1220 warningMessage.clear();
1223 component.setData("import QtQuick 2.0\nColumn { Item { anchors.left: parent.left } }", QUrl::fromLocalFile(""));
1224 item = qobject_cast<QSGItem*>(component.create());
1226 QVERIFY(warningMessage.isEmpty());
1227 warningMessage.clear();
1230 component.setData("import QtQuick 2.0\nRow { Item { anchors.left: parent.left } }", QUrl::fromLocalFile(""));
1231 item = qobject_cast<QSGItem*>(component.create());
1233 QCOMPARE(warningMessage, QString("file::2:1: QML Row: Cannot specify left, right, horizontalCenter, fill or centerIn anchors for items inside Row"));
1234 warningMessage.clear();
1237 component.setData("import QtQuick 2.0\nRow { Item { anchors.fill: parent } }", QUrl::fromLocalFile(""));
1238 item = qobject_cast<QSGItem*>(component.create());
1240 QCOMPARE(warningMessage, QString("file::2:1: QML Row: Cannot specify left, right, horizontalCenter, fill or centerIn anchors for items inside Row"));
1241 warningMessage.clear();
1244 component.setData("import QtQuick 2.0\nRow { Item { anchors.top: parent.top } }", QUrl::fromLocalFile(""));
1245 item = qobject_cast<QSGItem*>(component.create());
1247 QVERIFY(warningMessage.isEmpty());
1248 warningMessage.clear();
1251 component.setData("import QtQuick 2.0\nGrid { Item { anchors.horizontalCenter: parent.horizontalCenter } }", QUrl::fromLocalFile(""));
1252 item = qobject_cast<QSGItem*>(component.create());
1254 QCOMPARE(warningMessage, QString("file::2:1: QML Grid: Cannot specify anchors for items inside Grid"));
1255 warningMessage.clear();
1258 component.setData("import QtQuick 2.0\nGrid { Item { anchors.centerIn: parent } }", QUrl::fromLocalFile(""));
1259 item = qobject_cast<QSGItem*>(component.create());
1261 QCOMPARE(warningMessage, QString("file::2:1: QML Grid: Cannot specify anchors for items inside Grid"));
1262 warningMessage.clear();
1265 component.setData("import QtQuick 2.0\nFlow { Item { anchors.verticalCenter: parent.verticalCenter } }", QUrl::fromLocalFile(""));
1266 item = qobject_cast<QSGItem*>(component.create());
1268 QCOMPARE(warningMessage, QString("file::2:1: QML Flow: Cannot specify anchors for items inside Flow"));
1271 component.setData("import QtQuick 2.0\nFlow { Item { anchors.fill: parent } }", QUrl::fromLocalFile(""));
1272 item = qobject_cast<QSGItem*>(component.create());
1274 QCOMPARE(warningMessage, QString("file::2:1: QML Flow: Cannot specify anchors for items inside Flow"));
1275 qInstallMsgHandler(oldMsgHandler);
1279 void tst_qsgpositioners::test_mirroring()
1281 QList<QString> qmlFiles;
1282 qmlFiles << "horizontal.qml" << "gridtest.qml" << "flowtest.qml";
1283 QList<QString> objectNames;
1284 objectNames << "one" << "two" << "three" << "four" << "five";
1286 foreach(const QString qmlFile, qmlFiles) {
1287 QSGView *canvasA = createView(QString(SRCDIR) + "/data/" + qmlFile);
1288 QSGItem *rootA = qobject_cast<QSGItem*>(canvasA->rootObject());
1290 QSGView *canvasB = createView(QString(SRCDIR) + "/data/" + qmlFile);
1291 QSGItem *rootB = qobject_cast<QSGItem*>(canvasB->rootObject());
1293 rootA->setProperty("testRightToLeft", true); // layoutDirection: Qt.RightToLeft
1296 foreach(const QString objectName, objectNames) {
1297 // horizontal.qml only has three items
1298 if (qmlFile == QString("horizontal.qml") && objectName == QString("four"))
1300 QSGItem *itemA = rootA->findChild<QSGItem*>(objectName);
1301 QSGItem *itemB = rootB->findChild<QSGItem*>(objectName);
1302 QTRY_VERIFY(itemA->x() != itemB->x());
1305 QSGItemPrivate* rootPrivateB = QSGItemPrivate::get(rootB);
1307 rootPrivateB->effectiveLayoutMirror = true; // LayoutMirroring.enabled: true
1308 rootPrivateB->isMirrorImplicit = false;
1309 rootPrivateB->inheritMirrorFromItem = true; // LayoutMirroring.childrenInherit: true
1310 rootPrivateB->resolveLayoutMirror();
1313 foreach(const QString objectName, objectNames) {
1314 // horizontal.qml only has three items
1315 if (qmlFile == QString("horizontal.qml") && objectName == QString("four"))
1317 QSGItem *itemA = rootA->findChild<QSGItem*>(objectName);
1318 QSGItem *itemB = rootB->findChild<QSGItem*>(objectName);
1319 QTRY_COMPARE(itemA->x(), itemB->x());
1322 rootA->setProperty("testRightToLeft", false); // layoutDirection: Qt.LeftToRight
1323 rootB->setProperty("testRightToLeft", true); // layoutDirection: Qt.RightToLeft
1325 // LTR == RTL + mirror
1326 foreach(const QString objectName, objectNames) {
1327 // horizontal.qml only has three items
1328 if (qmlFile == QString("horizontal.qml") && objectName == QString("four"))
1330 QSGItem *itemA = rootA->findChild<QSGItem*>(objectName);
1331 QSGItem *itemB = rootB->findChild<QSGItem*>(objectName);
1332 QTRY_COMPARE(itemA->x(), itemB->x());
1339 void tst_qsgpositioners::test_allInvisible()
1342 QSGView *canvas = createView(SRCDIR "/data/allInvisible.qml");
1344 QSGItem *root = qobject_cast<QSGItem*>(canvas->rootObject());
1347 QSGRow *row = canvas->rootObject()->findChild<QSGRow*>("row");
1349 QVERIFY(row->width() == 0);
1350 QVERIFY(row->height() == 0);
1351 QSGColumn *column = canvas->rootObject()->findChild<QSGColumn*>("column");
1352 QVERIFY(column != 0);
1353 QVERIFY(column->width() == 0);
1354 QVERIFY(column->height() == 0);
1357 void tst_qsgpositioners::test_attachedproperties()
1359 QFETCH(QString, filename);
1361 QSGView *canvas = createView(filename);
1362 QVERIFY(canvas->rootObject() != 0);
1364 QSGRectangle *greenRect = canvas->rootObject()->findChild<QSGRectangle *>("greenRect");
1365 QVERIFY(greenRect != 0);
1367 int posIndex = greenRect->property("posIndex").toInt();
1368 QVERIFY(posIndex == 0);
1369 bool isFirst = greenRect->property("isFirstItem").toBool();
1370 QVERIFY(isFirst == true);
1371 bool isLast = greenRect->property("isLastItem").toBool();
1372 QVERIFY(isLast == false);
1374 QSGRectangle *yellowRect = canvas->rootObject()->findChild<QSGRectangle *>("yellowRect");
1375 QVERIFY(yellowRect != 0);
1377 posIndex = yellowRect->property("posIndex").toInt();
1378 QVERIFY(posIndex == -1);
1379 isFirst = yellowRect->property("isFirstItem").toBool();
1380 QVERIFY(isFirst == false);
1381 isLast = yellowRect->property("isLastItem").toBool();
1382 QVERIFY(isLast == false);
1384 yellowRect->metaObject()->invokeMethod(yellowRect, "onDemandPositioner");
1386 posIndex = yellowRect->property("posIndex").toInt();
1387 QVERIFY(posIndex == 1);
1388 isFirst = yellowRect->property("isFirstItem").toBool();
1389 QVERIFY(isFirst == false);
1390 isLast = yellowRect->property("isLastItem").toBool();
1391 QVERIFY(isLast == true);
1396 void tst_qsgpositioners::test_attachedproperties_data()
1398 QTest::addColumn<QString>("filename");
1400 QTest::newRow("column") << SRCDIR "/data/attachedproperties-column.qml";
1401 QTest::newRow("row") << SRCDIR "/data/attachedproperties-row.qml";
1402 QTest::newRow("grid") << SRCDIR "/data/attachedproperties-grid.qml";
1403 QTest::newRow("flow") << SRCDIR "/data/attachedproperties-flow.qml";
1406 void tst_qsgpositioners::test_attachedproperties_dynamic()
1408 QSGView *canvas = createView(SRCDIR "/data/attachedproperties-dynamic.qml");
1409 QVERIFY(canvas->rootObject() != 0);
1411 QSGRow *row = canvas->rootObject()->findChild<QSGRow *>("pos");
1414 QSGRectangle *rect0 = canvas->rootObject()->findChild<QSGRectangle *>("rect0");
1415 QVERIFY(rect0 != 0);
1417 int posIndex = rect0->property("index").toInt();
1418 QVERIFY(posIndex == 0);
1419 bool isFirst = rect0->property("firstItem").toBool();
1420 QVERIFY(isFirst == true);
1421 bool isLast = rect0->property("lastItem").toBool();
1422 QVERIFY(isLast == false);
1424 QSGRectangle *rect1 = canvas->rootObject()->findChild<QSGRectangle *>("rect1");
1425 QVERIFY(rect1 != 0);
1427 posIndex = rect1->property("index").toInt();
1428 QVERIFY(posIndex == 1);
1429 isFirst = rect1->property("firstItem").toBool();
1430 QVERIFY(isFirst == false);
1431 isLast = rect1->property("lastItem").toBool();
1432 QVERIFY(isLast == true);
1434 row->metaObject()->invokeMethod(row, "createSubRect");
1436 QTRY_VERIFY(rect1->property("index").toInt() == 1);
1437 QTRY_VERIFY(rect1->property("firstItem").toBool() == false);
1438 QTRY_VERIFY(rect1->property("lastItem").toBool() == false);
1440 QSGRectangle *rect2 = canvas->rootObject()->findChild<QSGRectangle *>("rect2");
1441 QVERIFY(rect2 != 0);
1443 posIndex = rect2->property("index").toInt();
1444 QVERIFY(posIndex == 2);
1445 isFirst = rect2->property("firstItem").toBool();
1446 QVERIFY(isFirst == false);
1447 isLast = rect2->property("lastItem").toBool();
1448 QVERIFY(isLast == true);
1450 row->metaObject()->invokeMethod(row, "destroySubRect");
1452 qApp->processEvents(QEventLoop::DeferredDeletion);
1454 QTRY_VERIFY(rect1->property("index").toInt() == 1);
1455 QTRY_VERIFY(rect1->property("firstItem").toBool() == false);
1456 QTRY_VERIFY(rect1->property("lastItem").toBool() == true);
1461 QSGView *tst_qsgpositioners::createView(const QString &filename, bool wait)
1463 QSGView *canvas = new QSGView(0);
1465 canvas->setSource(QUrl::fromLocalFile(filename));
1468 QTest::qWaitForWindowShown(canvas); //It may not relayout until the next frame, so it needs to be drawn
1474 QTEST_MAIN(tst_qsgpositioners)
1476 #include "tst_qsgpositioners.moc"