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"
54 // In Symbian OS test data is located in applications private dir
58 class tst_qsgpositioners : public QObject
65 void test_horizontal();
66 void test_horizontal_rtl();
67 void test_horizontal_spacing();
68 void test_horizontal_spacing_rightToLeft();
69 void test_horizontal_animated();
70 void test_horizontal_animated_rightToLeft();
71 void test_horizontal_animated_disabled();
73 void test_vertical_spacing();
74 void test_vertical_animated();
76 void test_grid_topToBottom();
77 void test_grid_rightToLeft();
78 void test_grid_spacing();
79 void test_grid_row_column_spacing();
80 void test_grid_animated();
81 void test_grid_animated_rightToLeft();
82 void test_grid_zero_columns();
83 void test_propertychanges();
86 void test_flow_rightToLeft();
87 void test_flow_topToBottom();
88 void test_flow_resize();
89 void test_flow_resize_rightToLeft();
90 void test_flow_implicit_resize();
91 void test_conflictinganchors();
92 void test_mirroring();
93 void test_allInvisible();
94 void test_attachedproperties();
95 void test_attachedproperties_data();
96 void test_attachedproperties_dynamic();
99 QSGView *createView(const QString &filename, bool wait=true);
102 tst_qsgpositioners::tst_qsgpositioners()
106 void tst_qsgpositioners::test_horizontal()
108 QSGView *canvas = createView(SRCDIR "/data/horizontal.qml");
110 canvas->rootObject()->setProperty("testRightToLeft", false);
112 QSGRectangle *one = canvas->rootObject()->findChild<QSGRectangle*>("one");
115 QSGRectangle *two = canvas->rootObject()->findChild<QSGRectangle*>("two");
118 QSGRectangle *three = canvas->rootObject()->findChild<QSGRectangle*>("three");
121 QCOMPARE(one->x(), 0.0);
122 QCOMPARE(one->y(), 0.0);
123 QCOMPARE(two->x(), 50.0);
124 QCOMPARE(two->y(), 0.0);
125 QCOMPARE(three->x(), 70.0);
126 QCOMPARE(three->y(), 0.0);
128 QSGItem *row = canvas->rootObject()->findChild<QSGItem*>("row");
129 QCOMPARE(row->width(), 110.0);
130 QCOMPARE(row->height(), 50.0);
135 void tst_qsgpositioners::test_horizontal_rtl()
137 QSGView *canvas = createView(SRCDIR "/data/horizontal.qml");
139 canvas->rootObject()->setProperty("testRightToLeft", true);
141 QSGRectangle *one = canvas->rootObject()->findChild<QSGRectangle*>("one");
144 QSGRectangle *two = canvas->rootObject()->findChild<QSGRectangle*>("two");
147 QSGRectangle *three = canvas->rootObject()->findChild<QSGRectangle*>("three");
150 QCOMPARE(one->x(), 60.0);
151 QCOMPARE(one->y(), 0.0);
152 QCOMPARE(two->x(), 40.0);
153 QCOMPARE(two->y(), 0.0);
154 QCOMPARE(three->x(), 0.0);
155 QCOMPARE(three->y(), 0.0);
157 QSGItem *row = canvas->rootObject()->findChild<QSGItem*>("row");
158 QCOMPARE(row->width(), 110.0);
159 QCOMPARE(row->height(), 50.0);
161 // Change the width of the row and check that items stay to the right
163 QTRY_COMPARE(one->x(), 150.0);
164 QCOMPARE(one->y(), 0.0);
165 QCOMPARE(two->x(), 130.0);
166 QCOMPARE(two->y(), 0.0);
167 QCOMPARE(three->x(), 90.0);
168 QCOMPARE(three->y(), 0.0);
173 void tst_qsgpositioners::test_horizontal_spacing()
175 QSGView *canvas = createView(SRCDIR "/data/horizontal-spacing.qml");
177 canvas->rootObject()->setProperty("testRightToLeft", false);
179 QSGRectangle *one = canvas->rootObject()->findChild<QSGRectangle*>("one");
182 QSGRectangle *two = canvas->rootObject()->findChild<QSGRectangle*>("two");
185 QSGRectangle *three = canvas->rootObject()->findChild<QSGRectangle*>("three");
188 QCOMPARE(one->x(), 0.0);
189 QCOMPARE(one->y(), 0.0);
190 QCOMPARE(two->x(), 60.0);
191 QCOMPARE(two->y(), 0.0);
192 QCOMPARE(three->x(), 90.0);
193 QCOMPARE(three->y(), 0.0);
195 QSGItem *row = canvas->rootObject()->findChild<QSGItem*>("row");
196 QCOMPARE(row->width(), 130.0);
197 QCOMPARE(row->height(), 50.0);
202 void tst_qsgpositioners::test_horizontal_spacing_rightToLeft()
204 QSGView *canvas = createView(SRCDIR "/data/horizontal-spacing.qml");
206 canvas->rootObject()->setProperty("testRightToLeft", true);
208 QSGRectangle *one = canvas->rootObject()->findChild<QSGRectangle*>("one");
211 QSGRectangle *two = canvas->rootObject()->findChild<QSGRectangle*>("two");
214 QSGRectangle *three = canvas->rootObject()->findChild<QSGRectangle*>("three");
217 QCOMPARE(one->x(), 80.0);
218 QCOMPARE(one->y(), 0.0);
219 QCOMPARE(two->x(), 50.0);
220 QCOMPARE(two->y(), 0.0);
221 QCOMPARE(three->x(), 00.0);
222 QCOMPARE(three->y(), 0.0);
224 QSGItem *row = canvas->rootObject()->findChild<QSGItem*>("row");
225 QCOMPARE(row->width(), 130.0);
226 QCOMPARE(row->height(), 50.0);
231 void tst_qsgpositioners::test_horizontal_animated()
233 QSGView *canvas = createView(SRCDIR "/data/horizontal-animated.qml", false);
235 canvas->rootObject()->setProperty("testRightToLeft", false);
237 QSGRectangle *one = canvas->rootObject()->findChild<QSGRectangle*>("one");
240 QSGRectangle *two = canvas->rootObject()->findChild<QSGRectangle*>("two");
243 QSGRectangle *three = canvas->rootObject()->findChild<QSGRectangle*>("three");
246 //Note that they animate in
247 QCOMPARE(one->x(), -100.0);
248 QCOMPARE(two->x(), -100.0);
249 QCOMPARE(three->x(), -100.0);
251 QTest::qWaitForWindowShown(canvas); //It may not relayout until the next frame, so it needs to be drawn
253 QSGItem *row = canvas->rootObject()->findChild<QSGItem*>("row");
255 QCOMPARE(row->width(), 100.0);
256 QCOMPARE(row->height(), 50.0);
258 //QTRY_COMPARE used instead of waiting for the expected time of animation completion
259 //Note that this means the duration of the animation is NOT tested
261 QTRY_COMPARE(one->x(), 0.0);
262 QTRY_COMPARE(one->y(), 0.0);
263 QTRY_COMPARE(two->isVisible(), false);
264 QTRY_COMPARE(two->x(), -100.0);//Not 'in' yet
265 QTRY_COMPARE(two->y(), 0.0);
266 QTRY_COMPARE(three->x(), 50.0);
267 QTRY_COMPARE(three->y(), 0.0);
270 two->setVisible(true);
271 QTRY_COMPARE(two->isVisible(), true);
272 QTRY_COMPARE(row->width(), 150.0);
273 QTRY_COMPARE(row->height(), 50.0);
275 QTest::qWait(0);//Let the animation start
276 QCOMPARE(two->x(), -100.0);
277 QCOMPARE(three->x(), 50.0);
279 QTRY_COMPARE(two->x(), 50.0);
280 QTRY_COMPARE(three->x(), 100.0);
285 void tst_qsgpositioners::test_horizontal_animated_rightToLeft()
287 QSGView *canvas = createView(SRCDIR "/data/horizontal-animated.qml", false);
289 canvas->rootObject()->setProperty("testRightToLeft", true);
291 QSGRectangle *one = canvas->rootObject()->findChild<QSGRectangle*>("one");
294 QSGRectangle *two = canvas->rootObject()->findChild<QSGRectangle*>("two");
297 QSGRectangle *three = canvas->rootObject()->findChild<QSGRectangle*>("three");
300 //Note that they animate in
301 QCOMPARE(one->x(), -100.0);
302 QCOMPARE(two->x(), -100.0);
303 QCOMPARE(three->x(), -100.0);
305 QTest::qWaitForWindowShown(canvas); //It may not relayout until the next frame, so it needs to be drawn
307 QSGItem *row = canvas->rootObject()->findChild<QSGItem*>("row");
309 QCOMPARE(row->width(), 100.0);
310 QCOMPARE(row->height(), 50.0);
312 //QTRY_COMPARE used instead of waiting for the expected time of animation completion
313 //Note that this means the duration of the animation is NOT tested
315 QTRY_COMPARE(one->x(), 50.0);
316 QTRY_COMPARE(one->y(), 0.0);
317 QTRY_COMPARE(two->isVisible(), false);
318 QTRY_COMPARE(two->x(), -100.0);//Not 'in' yet
319 QTRY_COMPARE(two->y(), 0.0);
320 QTRY_COMPARE(three->x(), 0.0);
321 QTRY_COMPARE(three->y(), 0.0);
324 two->setVisible(true);
325 QTRY_COMPARE(two->isVisible(), true);
327 // New size should propagate after visible change
328 QTRY_COMPARE(row->width(), 150.0);
329 QTRY_COMPARE(row->height(), 50.0);
331 QTest::qWait(0);//Let the animation start
332 QCOMPARE(one->x(), 50.0);
333 QCOMPARE(two->x(), -100.0);
335 QTRY_COMPARE(one->x(), 100.0);
336 QTRY_COMPARE(two->x(), 50.0);
341 void tst_qsgpositioners::test_horizontal_animated_disabled()
343 QSGView *canvas = createView(SRCDIR "/data/horizontal-animated-disabled.qml");
345 QSGRectangle *one = canvas->rootObject()->findChild<QSGRectangle*>("one");
348 QSGRectangle *two = canvas->rootObject()->findChild<QSGRectangle*>("two");
351 QSGRectangle *three = canvas->rootObject()->findChild<QSGRectangle*>("three");
354 QSGItem *row = canvas->rootObject()->findChild<QSGItem*>("row");
357 qApp->processEvents();
359 QCOMPARE(one->x(), 0.0);
360 QCOMPARE(one->y(), 0.0);
361 QCOMPARE(two->isVisible(), false);
362 QCOMPARE(two->x(), -100.0);//Not 'in' yet
363 QCOMPARE(two->y(), 0.0);
364 QCOMPARE(three->x(), 50.0);
365 QCOMPARE(three->y(), 0.0);
368 two->setVisible(true);
369 QCOMPARE(two->isVisible(), true);
370 qApp->processEvents();
371 QCOMPARE(row->width(), 150.0);
372 QCOMPARE(row->height(), 50.0);
374 qApp->processEvents();
375 QCOMPARE(two->x(), 50.0);
376 QCOMPARE(three->x(), 100.0);
381 void tst_qsgpositioners::test_vertical()
383 QSGView *canvas = createView(SRCDIR "/data/vertical.qml");
385 QSGRectangle *one = canvas->rootObject()->findChild<QSGRectangle*>("one");
388 QSGRectangle *two = canvas->rootObject()->findChild<QSGRectangle*>("two");
391 QSGRectangle *three = canvas->rootObject()->findChild<QSGRectangle*>("three");
394 QCOMPARE(one->x(), 0.0);
395 QCOMPARE(one->y(), 0.0);
396 QCOMPARE(two->x(), 0.0);
397 QCOMPARE(two->y(), 50.0);
398 QCOMPARE(three->x(), 0.0);
399 QCOMPARE(three->y(), 60.0);
401 QSGItem *column = canvas->rootObject()->findChild<QSGItem*>("column");
403 QCOMPARE(column->height(), 80.0);
404 QCOMPARE(column->width(), 50.0);
409 void tst_qsgpositioners::test_vertical_spacing()
411 QSGView *canvas = createView(SRCDIR "/data/vertical-spacing.qml");
413 QSGRectangle *one = canvas->rootObject()->findChild<QSGRectangle*>("one");
416 QSGRectangle *two = canvas->rootObject()->findChild<QSGRectangle*>("two");
419 QSGRectangle *three = canvas->rootObject()->findChild<QSGRectangle*>("three");
422 QCOMPARE(one->x(), 0.0);
423 QCOMPARE(one->y(), 0.0);
424 QCOMPARE(two->x(), 0.0);
425 QCOMPARE(two->y(), 60.0);
426 QCOMPARE(three->x(), 0.0);
427 QCOMPARE(three->y(), 80.0);
429 QSGItem *column = canvas->rootObject()->findChild<QSGItem*>("column");
430 QCOMPARE(column->height(), 100.0);
431 QCOMPARE(column->width(), 50.0);
436 void tst_qsgpositioners::test_vertical_animated()
438 QSGView *canvas = createView(SRCDIR "/data/vertical-animated.qml", false);
440 //Note that they animate in
441 QSGRectangle *one = canvas->rootObject()->findChild<QSGRectangle*>("one");
443 QCOMPARE(one->y(), -100.0);
445 QSGRectangle *two = canvas->rootObject()->findChild<QSGRectangle*>("two");
447 QCOMPARE(two->y(), -100.0);
449 QSGRectangle *three = canvas->rootObject()->findChild<QSGRectangle*>("three");
451 QCOMPARE(three->y(), -100.0);
453 QTest::qWaitForWindowShown(canvas); //It may not relayout until the next frame, so it needs to be drawn
455 QSGItem *column = canvas->rootObject()->findChild<QSGItem*>("column");
457 QCOMPARE(column->height(), 100.0);
458 QCOMPARE(column->width(), 50.0);
460 //QTRY_COMPARE used instead of waiting for the expected time of animation completion
461 //Note that this means the duration of the animation is NOT tested
463 QTRY_COMPARE(one->y(), 0.0);
464 QTRY_COMPARE(one->x(), 0.0);
465 QTRY_COMPARE(two->isVisible(), false);
466 QTRY_COMPARE(two->y(), -100.0);//Not 'in' yet
467 QTRY_COMPARE(two->x(), 0.0);
468 QTRY_COMPARE(three->y(), 50.0);
469 QTRY_COMPARE(three->x(), 0.0);
472 two->setVisible(true);
473 QTRY_COMPARE(two->isVisible(), true);
474 QTRY_COMPARE(column->height(), 150.0);
475 QTRY_COMPARE(column->width(), 50.0);
476 QTest::qWait(0);//Let the animation start
477 QCOMPARE(two->y(), -100.0);
478 QCOMPARE(three->y(), 50.0);
480 QTRY_COMPARE(two->y(), 50.0);
481 QTRY_COMPARE(three->y(), 100.0);
486 void tst_qsgpositioners::test_grid()
488 QSGView *canvas = createView(SRCDIR "/data/gridtest.qml");
490 QSGRectangle *one = canvas->rootObject()->findChild<QSGRectangle*>("one");
492 QSGRectangle *two = canvas->rootObject()->findChild<QSGRectangle*>("two");
494 QSGRectangle *three = canvas->rootObject()->findChild<QSGRectangle*>("three");
496 QSGRectangle *four = canvas->rootObject()->findChild<QSGRectangle*>("four");
498 QSGRectangle *five = canvas->rootObject()->findChild<QSGRectangle*>("five");
501 QCOMPARE(one->x(), 0.0);
502 QCOMPARE(one->y(), 0.0);
503 QCOMPARE(two->x(), 50.0);
504 QCOMPARE(two->y(), 0.0);
505 QCOMPARE(three->x(), 70.0);
506 QCOMPARE(three->y(), 0.0);
507 QCOMPARE(four->x(), 0.0);
508 QCOMPARE(four->y(), 50.0);
509 QCOMPARE(five->x(), 50.0);
510 QCOMPARE(five->y(), 50.0);
512 QSGGrid *grid = canvas->rootObject()->findChild<QSGGrid*>("grid");
513 QCOMPARE(grid->flow(), QSGGrid::LeftToRight);
514 QCOMPARE(grid->width(), 100.0);
515 QCOMPARE(grid->height(), 100.0);
520 void tst_qsgpositioners::test_grid_topToBottom()
522 QSGView *canvas = createView(SRCDIR "/data/grid-toptobottom.qml");
524 QSGRectangle *one = canvas->rootObject()->findChild<QSGRectangle*>("one");
526 QSGRectangle *two = canvas->rootObject()->findChild<QSGRectangle*>("two");
528 QSGRectangle *three = canvas->rootObject()->findChild<QSGRectangle*>("three");
530 QSGRectangle *four = canvas->rootObject()->findChild<QSGRectangle*>("four");
532 QSGRectangle *five = canvas->rootObject()->findChild<QSGRectangle*>("five");
535 QCOMPARE(one->x(), 0.0);
536 QCOMPARE(one->y(), 0.0);
537 QCOMPARE(two->x(), 0.0);
538 QCOMPARE(two->y(), 50.0);
539 QCOMPARE(three->x(), 0.0);
540 QCOMPARE(three->y(), 100.0);
541 QCOMPARE(four->x(), 50.0);
542 QCOMPARE(four->y(), 0.0);
543 QCOMPARE(five->x(), 50.0);
544 QCOMPARE(five->y(), 50.0);
546 QSGGrid *grid = canvas->rootObject()->findChild<QSGGrid*>("grid");
547 QCOMPARE(grid->flow(), QSGGrid::TopToBottom);
548 QCOMPARE(grid->width(), 100.0);
549 QCOMPARE(grid->height(), 120.0);
554 void tst_qsgpositioners::test_grid_rightToLeft()
556 QSGView *canvas = createView(SRCDIR "/data/gridtest.qml");
558 canvas->rootObject()->setProperty("testRightToLeft", true);
560 QSGRectangle *one = canvas->rootObject()->findChild<QSGRectangle*>("one");
562 QSGRectangle *two = canvas->rootObject()->findChild<QSGRectangle*>("two");
564 QSGRectangle *three = canvas->rootObject()->findChild<QSGRectangle*>("three");
566 QSGRectangle *four = canvas->rootObject()->findChild<QSGRectangle*>("four");
568 QSGRectangle *five = canvas->rootObject()->findChild<QSGRectangle*>("five");
571 QCOMPARE(one->x(), 50.0);
572 QCOMPARE(one->y(), 0.0);
573 QCOMPARE(two->x(), 30.0);
574 QCOMPARE(two->y(), 0.0);
575 QCOMPARE(three->x(), 0.0);
576 QCOMPARE(three->y(), 0.0);
577 QCOMPARE(four->x(), 50.0);
578 QCOMPARE(four->y(), 50.0);
579 QCOMPARE(five->x(), 40.0);
580 QCOMPARE(five->y(), 50.0);
582 QSGGrid *grid = canvas->rootObject()->findChild<QSGGrid*>("grid");
583 QCOMPARE(grid->layoutDirection(), Qt::RightToLeft);
584 QCOMPARE(grid->width(), 100.0);
585 QCOMPARE(grid->height(), 100.0);
587 // Change the width of the grid and check that items stay to the right
589 QTRY_COMPARE(one->x(), 150.0);
590 QCOMPARE(one->y(), 0.0);
591 QCOMPARE(two->x(), 130.0);
592 QCOMPARE(two->y(), 0.0);
593 QCOMPARE(three->x(), 100.0);
594 QCOMPARE(three->y(), 0.0);
595 QCOMPARE(four->x(), 150.0);
596 QCOMPARE(four->y(), 50.0);
597 QCOMPARE(five->x(), 140.0);
598 QCOMPARE(five->y(), 50.0);
603 void tst_qsgpositioners::test_grid_spacing()
605 QSGView *canvas = createView(SRCDIR "/data/grid-spacing.qml");
607 QSGRectangle *one = canvas->rootObject()->findChild<QSGRectangle*>("one");
609 QSGRectangle *two = canvas->rootObject()->findChild<QSGRectangle*>("two");
611 QSGRectangle *three = canvas->rootObject()->findChild<QSGRectangle*>("three");
613 QSGRectangle *four = canvas->rootObject()->findChild<QSGRectangle*>("four");
615 QSGRectangle *five = canvas->rootObject()->findChild<QSGRectangle*>("five");
618 QCOMPARE(one->x(), 0.0);
619 QCOMPARE(one->y(), 0.0);
620 QCOMPARE(two->x(), 54.0);
621 QCOMPARE(two->y(), 0.0);
622 QCOMPARE(three->x(), 78.0);
623 QCOMPARE(three->y(), 0.0);
624 QCOMPARE(four->x(), 0.0);
625 QCOMPARE(four->y(), 54.0);
626 QCOMPARE(five->x(), 54.0);
627 QCOMPARE(five->y(), 54.0);
629 QSGItem *grid = canvas->rootObject()->findChild<QSGItem*>("grid");
630 QCOMPARE(grid->width(), 128.0);
631 QCOMPARE(grid->height(), 104.0);
636 void tst_qsgpositioners::test_grid_row_column_spacing()
638 QSGView *canvas = createView(SRCDIR "/data/grid-row-column-spacing.qml");
640 QSGRectangle *one = canvas->rootObject()->findChild<QSGRectangle*>("one");
642 QSGRectangle *two = canvas->rootObject()->findChild<QSGRectangle*>("two");
644 QSGRectangle *three = canvas->rootObject()->findChild<QSGRectangle*>("three");
646 QSGRectangle *four = canvas->rootObject()->findChild<QSGRectangle*>("four");
648 QSGRectangle *five = canvas->rootObject()->findChild<QSGRectangle*>("five");
651 QCOMPARE(one->x(), 0.0);
652 QCOMPARE(one->y(), 0.0);
653 QCOMPARE(two->x(), 61.0);
654 QCOMPARE(two->y(), 0.0);
655 QCOMPARE(three->x(), 92.0);
656 QCOMPARE(three->y(), 0.0);
657 QCOMPARE(four->x(), 0.0);
658 QCOMPARE(four->y(), 57.0);
659 QCOMPARE(five->x(), 61.0);
660 QCOMPARE(five->y(), 57.0);
662 QSGItem *grid = canvas->rootObject()->findChild<QSGItem*>("grid");
663 QCOMPARE(grid->width(), 142.0);
664 QCOMPARE(grid->height(), 107.0);
669 void tst_qsgpositioners::test_grid_animated()
671 QSGView *canvas = createView(SRCDIR "/data/grid-animated.qml", false);
673 canvas->rootObject()->setProperty("testRightToLeft", false);
675 //Note that all animate in
676 QSGRectangle *one = canvas->rootObject()->findChild<QSGRectangle*>("one");
678 QCOMPARE(one->x(), -100.0);
679 QCOMPARE(one->y(), -100.0);
681 QSGRectangle *two = canvas->rootObject()->findChild<QSGRectangle*>("two");
683 QCOMPARE(two->x(), -100.0);
684 QCOMPARE(two->y(), -100.0);
686 QSGRectangle *three = canvas->rootObject()->findChild<QSGRectangle*>("three");
688 QCOMPARE(three->x(), -100.0);
689 QCOMPARE(three->y(), -100.0);
691 QSGRectangle *four = canvas->rootObject()->findChild<QSGRectangle*>("four");
693 QCOMPARE(four->x(), -100.0);
694 QCOMPARE(four->y(), -100.0);
696 QSGRectangle *five = canvas->rootObject()->findChild<QSGRectangle*>("five");
698 QCOMPARE(five->x(), -100.0);
699 QCOMPARE(five->y(), -100.0);
701 QTest::qWaitForWindowShown(canvas); //It may not relayout until the next frame, so it needs to be drawn
703 QSGItem *grid = canvas->rootObject()->findChild<QSGItem*>("grid");
705 QCOMPARE(grid->width(), 150.0);
706 QCOMPARE(grid->height(), 100.0);
708 //QTRY_COMPARE used instead of waiting for the expected time of animation completion
709 //Note that this means the duration of the animation is NOT tested
711 QTRY_COMPARE(one->y(), 0.0);
712 QTRY_COMPARE(one->x(), 0.0);
713 QTRY_COMPARE(two->isVisible(), false);
714 QTRY_COMPARE(two->y(), -100.0);
715 QTRY_COMPARE(two->x(), -100.0);
716 QTRY_COMPARE(three->y(), 0.0);
717 QTRY_COMPARE(three->x(), 50.0);
718 QTRY_COMPARE(four->y(), 0.0);
719 QTRY_COMPARE(four->x(), 100.0);
720 QTRY_COMPARE(five->y(), 50.0);
721 QTRY_COMPARE(five->x(), 0.0);
724 two->setVisible(true);
725 QCOMPARE(two->isVisible(), true);
726 QCOMPARE(grid->width(), 150.0);
727 QCOMPARE(grid->height(), 100.0);
728 QTest::qWait(0);//Let the animation start
729 QCOMPARE(two->x(), -100.0);
730 QCOMPARE(two->y(), -100.0);
731 QCOMPARE(one->x(), 0.0);
732 QCOMPARE(one->y(), 0.0);
733 QCOMPARE(three->x(), 50.0);
734 QCOMPARE(three->y(), 0.0);
735 QCOMPARE(four->x(), 100.0);
736 QCOMPARE(four->y(), 0.0);
737 QCOMPARE(five->x(), 0.0);
738 QCOMPARE(five->y(), 50.0);
739 //Let the animation complete
740 QTRY_COMPARE(two->x(), 50.0);
741 QTRY_COMPARE(two->y(), 0.0);
742 QTRY_COMPARE(one->x(), 0.0);
743 QTRY_COMPARE(one->y(), 0.0);
744 QTRY_COMPARE(three->x(), 100.0);
745 QTRY_COMPARE(three->y(), 0.0);
746 QTRY_COMPARE(four->x(), 0.0);
747 QTRY_COMPARE(four->y(), 50.0);
748 QTRY_COMPARE(five->x(), 50.0);
749 QTRY_COMPARE(five->y(), 50.0);
754 void tst_qsgpositioners::test_grid_animated_rightToLeft()
756 QSGView *canvas = createView(SRCDIR "/data/grid-animated.qml", false);
758 canvas->rootObject()->setProperty("testRightToLeft", true);
760 //Note that all animate in
761 QSGRectangle *one = canvas->rootObject()->findChild<QSGRectangle*>("one");
763 QCOMPARE(one->x(), -100.0);
764 QCOMPARE(one->y(), -100.0);
766 QSGRectangle *two = canvas->rootObject()->findChild<QSGRectangle*>("two");
768 QCOMPARE(two->x(), -100.0);
769 QCOMPARE(two->y(), -100.0);
771 QSGRectangle *three = canvas->rootObject()->findChild<QSGRectangle*>("three");
773 QCOMPARE(three->x(), -100.0);
774 QCOMPARE(three->y(), -100.0);
776 QSGRectangle *four = canvas->rootObject()->findChild<QSGRectangle*>("four");
778 QCOMPARE(four->x(), -100.0);
779 QCOMPARE(four->y(), -100.0);
781 QSGRectangle *five = canvas->rootObject()->findChild<QSGRectangle*>("five");
783 QCOMPARE(five->x(), -100.0);
784 QCOMPARE(five->y(), -100.0);
786 QTest::qWaitForWindowShown(canvas); //It may not relayout until the next frame, so it needs to be drawn
788 QSGItem *grid = canvas->rootObject()->findChild<QSGItem*>("grid");
790 QCOMPARE(grid->width(), 150.0);
791 QCOMPARE(grid->height(), 100.0);
793 //QTRY_COMPARE used instead of waiting for the expected time of animation completion
794 //Note that this means the duration of the animation is NOT tested
796 QTRY_COMPARE(one->y(), 0.0);
797 QTRY_COMPARE(one->x(), 100.0);
798 QTRY_COMPARE(two->isVisible(), false);
799 QTRY_COMPARE(two->y(), -100.0);
800 QTRY_COMPARE(two->x(), -100.0);
801 QTRY_COMPARE(three->y(), 0.0);
802 QTRY_COMPARE(three->x(), 50.0);
803 QTRY_COMPARE(four->y(), 0.0);
804 QTRY_COMPARE(four->x(), 0.0);
805 QTRY_COMPARE(five->y(), 50.0);
806 QTRY_COMPARE(five->x(), 100.0);
809 two->setVisible(true);
810 QCOMPARE(two->isVisible(), true);
811 QCOMPARE(grid->width(), 150.0);
812 QCOMPARE(grid->height(), 100.0);
813 QTest::qWait(0);//Let the animation start
814 QCOMPARE(two->x(), -100.0);
815 QCOMPARE(two->y(), -100.0);
816 QCOMPARE(one->x(), 100.0);
817 QCOMPARE(one->y(), 0.0);
818 QCOMPARE(three->x(), 50.0);
819 QCOMPARE(three->y(), 0.0);
820 QCOMPARE(four->x(), 0.0);
821 QCOMPARE(four->y(), 0.0);
822 QCOMPARE(five->x(), 100.0);
823 QCOMPARE(five->y(), 50.0);
824 //Let the animation complete
825 QTRY_COMPARE(two->x(), 50.0);
826 QTRY_COMPARE(two->y(), 0.0);
827 QTRY_COMPARE(one->x(), 100.0);
828 QTRY_COMPARE(one->y(), 0.0);
829 QTRY_COMPARE(three->x(), 0.0);
830 QTRY_COMPARE(three->y(), 0.0);
831 QTRY_COMPARE(four->x(), 100.0);
832 QTRY_COMPARE(four->y(), 50.0);
833 QTRY_COMPARE(five->x(), 50.0);
834 QTRY_COMPARE(five->y(), 50.0);
839 void tst_qsgpositioners::test_grid_zero_columns()
841 QSGView *canvas = createView(SRCDIR "/data/gridzerocolumns.qml");
843 QSGRectangle *one = canvas->rootObject()->findChild<QSGRectangle*>("one");
845 QSGRectangle *two = canvas->rootObject()->findChild<QSGRectangle*>("two");
847 QSGRectangle *three = canvas->rootObject()->findChild<QSGRectangle*>("three");
849 QSGRectangle *four = canvas->rootObject()->findChild<QSGRectangle*>("four");
851 QSGRectangle *five = canvas->rootObject()->findChild<QSGRectangle*>("five");
854 QCOMPARE(one->x(), 0.0);
855 QCOMPARE(one->y(), 0.0);
856 QCOMPARE(two->x(), 50.0);
857 QCOMPARE(two->y(), 0.0);
858 QCOMPARE(three->x(), 70.0);
859 QCOMPARE(three->y(), 0.0);
860 QCOMPARE(four->x(), 120.0);
861 QCOMPARE(four->y(), 0.0);
862 QCOMPARE(five->x(), 0.0);
863 QCOMPARE(five->y(), 50.0);
865 QSGItem *grid = canvas->rootObject()->findChild<QSGItem*>("grid");
866 QCOMPARE(grid->width(), 170.0);
867 QCOMPARE(grid->height(), 60.0);
872 void tst_qsgpositioners::test_propertychanges()
874 QSGView *canvas = createView(SRCDIR "/data/propertychangestest.qml");
876 QSGGrid *grid = qobject_cast<QSGGrid*>(canvas->rootObject());
878 QDeclarativeTransition *rowTransition = canvas->rootObject()->findChild<QDeclarativeTransition*>("rowTransition");
879 QDeclarativeTransition *columnTransition = canvas->rootObject()->findChild<QDeclarativeTransition*>("columnTransition");
881 QSignalSpy addSpy(grid, SIGNAL(addChanged()));
882 QSignalSpy moveSpy(grid, SIGNAL(moveChanged()));
883 QSignalSpy columnsSpy(grid, SIGNAL(columnsChanged()));
884 QSignalSpy rowsSpy(grid, SIGNAL(rowsChanged()));
887 QVERIFY(rowTransition);
888 QVERIFY(columnTransition);
889 QCOMPARE(grid->add(), columnTransition);
890 QCOMPARE(grid->move(), columnTransition);
891 QCOMPARE(grid->columns(), 4);
892 QCOMPARE(grid->rows(), -1);
894 grid->setAdd(rowTransition);
895 grid->setMove(rowTransition);
896 QCOMPARE(grid->add(), rowTransition);
897 QCOMPARE(grid->move(), rowTransition);
898 QCOMPARE(addSpy.count(),1);
899 QCOMPARE(moveSpy.count(),1);
901 grid->setAdd(rowTransition);
902 grid->setMove(rowTransition);
903 QCOMPARE(addSpy.count(),1);
904 QCOMPARE(moveSpy.count(),1);
908 QCOMPARE(addSpy.count(),2);
909 QCOMPARE(moveSpy.count(),2);
911 grid->setColumns(-1);
913 QCOMPARE(grid->columns(), -1);
914 QCOMPARE(grid->rows(), 3);
915 QCOMPARE(columnsSpy.count(),1);
916 QCOMPARE(rowsSpy.count(),1);
918 grid->setColumns(-1);
920 QCOMPARE(columnsSpy.count(),1);
921 QCOMPARE(rowsSpy.count(),1);
925 QCOMPARE(columnsSpy.count(),2);
926 QCOMPARE(rowsSpy.count(),2);
931 void tst_qsgpositioners::test_repeater()
933 QSGView *canvas = createView(SRCDIR "/data/repeatertest.qml");
935 QSGRectangle *one = canvas->rootObject()->findChild<QSGRectangle*>("one");
938 QSGRectangle *two = canvas->rootObject()->findChild<QSGRectangle*>("two");
941 QSGRectangle *three = canvas->rootObject()->findChild<QSGRectangle*>("three");
944 QCOMPARE(one->x(), 0.0);
945 QCOMPARE(one->y(), 0.0);
946 QCOMPARE(two->x(), 50.0);
947 QCOMPARE(two->y(), 0.0);
948 QCOMPARE(three->x(), 100.0);
949 QCOMPARE(three->y(), 0.0);
954 void tst_qsgpositioners::test_flow()
956 QSGView *canvas = createView(SRCDIR "/data/flowtest.qml");
958 canvas->rootObject()->setProperty("testRightToLeft", false);
960 QSGRectangle *one = canvas->rootObject()->findChild<QSGRectangle*>("one");
962 QSGRectangle *two = canvas->rootObject()->findChild<QSGRectangle*>("two");
964 QSGRectangle *three = canvas->rootObject()->findChild<QSGRectangle*>("three");
966 QSGRectangle *four = canvas->rootObject()->findChild<QSGRectangle*>("four");
968 QSGRectangle *five = canvas->rootObject()->findChild<QSGRectangle*>("five");
971 QCOMPARE(one->x(), 0.0);
972 QCOMPARE(one->y(), 0.0);
973 QCOMPARE(two->x(), 50.0);
974 QCOMPARE(two->y(), 0.0);
975 QCOMPARE(three->x(), 0.0);
976 QCOMPARE(three->y(), 50.0);
977 QCOMPARE(four->x(), 0.0);
978 QCOMPARE(four->y(), 70.0);
979 QCOMPARE(five->x(), 50.0);
980 QCOMPARE(five->y(), 70.0);
982 QSGItem *flow = canvas->rootObject()->findChild<QSGItem*>("flow");
984 QCOMPARE(flow->width(), 90.0);
985 QCOMPARE(flow->height(), 120.0);
990 void tst_qsgpositioners::test_flow_rightToLeft()
992 QSGView *canvas = createView(SRCDIR "/data/flowtest.qml");
994 canvas->rootObject()->setProperty("testRightToLeft", true);
996 QSGRectangle *one = canvas->rootObject()->findChild<QSGRectangle*>("one");
998 QSGRectangle *two = canvas->rootObject()->findChild<QSGRectangle*>("two");
1000 QSGRectangle *three = canvas->rootObject()->findChild<QSGRectangle*>("three");
1001 QVERIFY(three != 0);
1002 QSGRectangle *four = canvas->rootObject()->findChild<QSGRectangle*>("four");
1004 QSGRectangle *five = canvas->rootObject()->findChild<QSGRectangle*>("five");
1007 QCOMPARE(one->x(), 40.0);
1008 QCOMPARE(one->y(), 0.0);
1009 QCOMPARE(two->x(), 20.0);
1010 QCOMPARE(two->y(), 0.0);
1011 QCOMPARE(three->x(), 40.0);
1012 QCOMPARE(three->y(), 50.0);
1013 QCOMPARE(four->x(), 40.0);
1014 QCOMPARE(four->y(), 70.0);
1015 QCOMPARE(five->x(), 30.0);
1016 QCOMPARE(five->y(), 70.0);
1018 QSGItem *flow = canvas->rootObject()->findChild<QSGItem*>("flow");
1020 QCOMPARE(flow->width(), 90.0);
1021 QCOMPARE(flow->height(), 120.0);
1026 void tst_qsgpositioners::test_flow_topToBottom()
1028 QSGView *canvas = createView(SRCDIR "/data/flowtest-toptobottom.qml");
1030 canvas->rootObject()->setProperty("testRightToLeft", false);
1032 QSGRectangle *one = canvas->rootObject()->findChild<QSGRectangle*>("one");
1034 QSGRectangle *two = canvas->rootObject()->findChild<QSGRectangle*>("two");
1036 QSGRectangle *three = canvas->rootObject()->findChild<QSGRectangle*>("three");
1037 QVERIFY(three != 0);
1038 QSGRectangle *four = canvas->rootObject()->findChild<QSGRectangle*>("four");
1040 QSGRectangle *five = canvas->rootObject()->findChild<QSGRectangle*>("five");
1043 QCOMPARE(one->x(), 0.0);
1044 QCOMPARE(one->y(), 0.0);
1045 QCOMPARE(two->x(), 50.0);
1046 QCOMPARE(two->y(), 0.0);
1047 QCOMPARE(three->x(), 50.0);
1048 QCOMPARE(three->y(), 50.0);
1049 QCOMPARE(four->x(), 100.0);
1050 QCOMPARE(four->y(), 00.0);
1051 QCOMPARE(five->x(), 100.0);
1052 QCOMPARE(five->y(), 50.0);
1054 QSGItem *flow = canvas->rootObject()->findChild<QSGItem*>("flow");
1056 QCOMPARE(flow->height(), 90.0);
1057 QCOMPARE(flow->width(), 150.0);
1059 canvas->rootObject()->setProperty("testRightToLeft", true);
1062 QCOMPARE(flow->height(), 90.0);
1063 QCOMPARE(flow->width(), 150.0);
1065 QCOMPARE(one->x(), 100.0);
1066 QCOMPARE(one->y(), 0.0);
1067 QCOMPARE(two->x(), 80.0);
1068 QCOMPARE(two->y(), 0.0);
1069 QCOMPARE(three->x(), 50.0);
1070 QCOMPARE(three->y(), 50.0);
1071 QCOMPARE(four->x(), 0.0);
1072 QCOMPARE(four->y(), 0.0);
1073 QCOMPARE(five->x(), 40.0);
1074 QCOMPARE(five->y(), 50.0);
1079 void tst_qsgpositioners::test_flow_resize()
1081 QSGView *canvas = createView(SRCDIR "/data/flowtest.qml");
1083 QSGItem *root = qobject_cast<QSGItem*>(canvas->rootObject());
1085 root->setWidth(125);
1086 root->setProperty("testRightToLeft", false);
1088 QSGRectangle *one = canvas->rootObject()->findChild<QSGRectangle*>("one");
1090 QSGRectangle *two = canvas->rootObject()->findChild<QSGRectangle*>("two");
1092 QSGRectangle *three = canvas->rootObject()->findChild<QSGRectangle*>("three");
1093 QVERIFY(three != 0);
1094 QSGRectangle *four = canvas->rootObject()->findChild<QSGRectangle*>("four");
1096 QSGRectangle *five = canvas->rootObject()->findChild<QSGRectangle*>("five");
1099 QTRY_COMPARE(one->x(), 0.0);
1100 QTRY_COMPARE(one->y(), 0.0);
1101 QTRY_COMPARE(two->x(), 50.0);
1102 QTRY_COMPARE(two->y(), 0.0);
1103 QTRY_COMPARE(three->x(), 70.0);
1104 QTRY_COMPARE(three->y(), 0.0);
1105 QTRY_COMPARE(four->x(), 0.0);
1106 QTRY_COMPARE(four->y(), 50.0);
1107 QTRY_COMPARE(five->x(), 50.0);
1108 QTRY_COMPARE(five->y(), 50.0);
1113 void tst_qsgpositioners::test_flow_resize_rightToLeft()
1115 QSGView *canvas = createView(SRCDIR "/data/flowtest.qml");
1117 QSGItem *root = qobject_cast<QSGItem*>(canvas->rootObject());
1119 root->setWidth(125);
1120 root->setProperty("testRightToLeft", true);
1122 QSGRectangle *one = canvas->rootObject()->findChild<QSGRectangle*>("one");
1123 QTRY_VERIFY(one != 0);
1124 QSGRectangle *two = canvas->rootObject()->findChild<QSGRectangle*>("two");
1126 QSGRectangle *three = canvas->rootObject()->findChild<QSGRectangle*>("three");
1127 QVERIFY(three != 0);
1128 QSGRectangle *four = canvas->rootObject()->findChild<QSGRectangle*>("four");
1130 QSGRectangle *five = canvas->rootObject()->findChild<QSGRectangle*>("five");
1133 QCOMPARE(one->x(), 75.0);
1134 QCOMPARE(one->y(), 0.0);
1135 QCOMPARE(two->x(), 55.0);
1136 QCOMPARE(two->y(), 0.0);
1137 QCOMPARE(three->x(), 5.0);
1138 QCOMPARE(three->y(), 0.0);
1139 QCOMPARE(four->x(), 75.0);
1140 QCOMPARE(four->y(), 50.0);
1141 QCOMPARE(five->x(), 65.0);
1142 QCOMPARE(five->y(), 50.0);
1147 void tst_qsgpositioners::test_flow_implicit_resize()
1149 QSGView *canvas = createView(SRCDIR "/data/flow-testimplicitsize.qml");
1150 QVERIFY(canvas->rootObject() != 0);
1152 QSGFlow *flow = canvas->rootObject()->findChild<QSGFlow*>("flow");
1155 QCOMPARE(flow->width(), 100.0);
1156 QCOMPARE(flow->height(), 120.0);
1158 canvas->rootObject()->setProperty("flowLayout", 0);
1159 QCOMPARE(flow->flow(), QSGFlow::LeftToRight);
1160 QCOMPARE(flow->width(), 220.0);
1161 QCOMPARE(flow->height(), 50.0);
1163 canvas->rootObject()->setProperty("flowLayout", 1);
1164 QCOMPARE(flow->flow(), QSGFlow::TopToBottom);
1165 QCOMPARE(flow->width(), 100.0);
1166 QCOMPARE(flow->height(), 120.0);
1168 canvas->rootObject()->setProperty("flowLayout", 2);
1169 QCOMPARE(flow->layoutDirection(), Qt::RightToLeft);
1170 QCOMPARE(flow->width(), 220.0);
1171 QCOMPARE(flow->height(), 50.0);
1176 QString warningMessage;
1178 void interceptWarnings(QtMsgType type, const char *msg)
1181 warningMessage = msg;
1184 void tst_qsgpositioners::test_conflictinganchors()
1186 QtMsgHandler oldMsgHandler = qInstallMsgHandler(interceptWarnings);
1187 QDeclarativeEngine engine;
1188 QDeclarativeComponent component(&engine);
1190 component.setData("import QtQuick 2.0\nColumn { Item {} }", QUrl::fromLocalFile(""));
1191 QSGItem *item = qobject_cast<QSGItem*>(component.create());
1193 QVERIFY(warningMessage.isEmpty());
1196 component.setData("import QtQuick 2.0\nRow { Item {} }", QUrl::fromLocalFile(""));
1197 item = qobject_cast<QSGItem*>(component.create());
1199 QVERIFY(warningMessage.isEmpty());
1202 component.setData("import QtQuick 2.0\nGrid { Item {} }", QUrl::fromLocalFile(""));
1203 item = qobject_cast<QSGItem*>(component.create());
1205 QVERIFY(warningMessage.isEmpty());
1208 component.setData("import QtQuick 2.0\nFlow { Item {} }", QUrl::fromLocalFile(""));
1209 item = qobject_cast<QSGItem*>(component.create());
1211 QVERIFY(warningMessage.isEmpty());
1214 component.setData("import QtQuick 2.0\nColumn { Item { anchors.top: parent.top } }", QUrl::fromLocalFile(""));
1215 item = qobject_cast<QSGItem*>(component.create());
1217 QCOMPARE(warningMessage, QString("file::2:1: QML Column: Cannot specify top, bottom, verticalCenter, fill or centerIn anchors for items inside Column"));
1218 warningMessage.clear();
1221 component.setData("import QtQuick 2.0\nColumn { Item { anchors.centerIn: parent } }", QUrl::fromLocalFile(""));
1222 item = qobject_cast<QSGItem*>(component.create());
1224 QCOMPARE(warningMessage, QString("file::2:1: QML Column: Cannot specify top, bottom, verticalCenter, fill or centerIn anchors for items inside Column"));
1225 warningMessage.clear();
1228 component.setData("import QtQuick 2.0\nColumn { Item { anchors.left: parent.left } }", QUrl::fromLocalFile(""));
1229 item = qobject_cast<QSGItem*>(component.create());
1231 QVERIFY(warningMessage.isEmpty());
1232 warningMessage.clear();
1235 component.setData("import QtQuick 2.0\nRow { Item { anchors.left: parent.left } }", QUrl::fromLocalFile(""));
1236 item = qobject_cast<QSGItem*>(component.create());
1238 QCOMPARE(warningMessage, QString("file::2:1: QML Row: Cannot specify left, right, horizontalCenter, fill or centerIn anchors for items inside Row"));
1239 warningMessage.clear();
1242 component.setData("import QtQuick 2.0\nRow { Item { anchors.fill: parent } }", QUrl::fromLocalFile(""));
1243 item = qobject_cast<QSGItem*>(component.create());
1245 QCOMPARE(warningMessage, QString("file::2:1: QML Row: Cannot specify left, right, horizontalCenter, fill or centerIn anchors for items inside Row"));
1246 warningMessage.clear();
1249 component.setData("import QtQuick 2.0\nRow { Item { anchors.top: parent.top } }", QUrl::fromLocalFile(""));
1250 item = qobject_cast<QSGItem*>(component.create());
1252 QVERIFY(warningMessage.isEmpty());
1253 warningMessage.clear();
1256 component.setData("import QtQuick 2.0\nGrid { Item { anchors.horizontalCenter: parent.horizontalCenter } }", QUrl::fromLocalFile(""));
1257 item = qobject_cast<QSGItem*>(component.create());
1259 QCOMPARE(warningMessage, QString("file::2:1: QML Grid: Cannot specify anchors for items inside Grid"));
1260 warningMessage.clear();
1263 component.setData("import QtQuick 2.0\nGrid { Item { anchors.centerIn: parent } }", QUrl::fromLocalFile(""));
1264 item = qobject_cast<QSGItem*>(component.create());
1266 QCOMPARE(warningMessage, QString("file::2:1: QML Grid: Cannot specify anchors for items inside Grid"));
1267 warningMessage.clear();
1270 component.setData("import QtQuick 2.0\nFlow { Item { anchors.verticalCenter: parent.verticalCenter } }", QUrl::fromLocalFile(""));
1271 item = qobject_cast<QSGItem*>(component.create());
1273 QCOMPARE(warningMessage, QString("file::2:1: QML Flow: Cannot specify anchors for items inside Flow"));
1276 component.setData("import QtQuick 2.0\nFlow { Item { anchors.fill: parent } }", QUrl::fromLocalFile(""));
1277 item = qobject_cast<QSGItem*>(component.create());
1279 QCOMPARE(warningMessage, QString("file::2:1: QML Flow: Cannot specify anchors for items inside Flow"));
1280 qInstallMsgHandler(oldMsgHandler);
1284 void tst_qsgpositioners::test_mirroring()
1286 QList<QString> qmlFiles;
1287 qmlFiles << "horizontal.qml" << "gridtest.qml" << "flowtest.qml";
1288 QList<QString> objectNames;
1289 objectNames << "one" << "two" << "three" << "four" << "five";
1291 foreach(const QString qmlFile, qmlFiles) {
1292 QSGView *canvasA = createView(QString(SRCDIR) + "/data/" + qmlFile);
1293 QSGItem *rootA = qobject_cast<QSGItem*>(canvasA->rootObject());
1295 QSGView *canvasB = createView(QString(SRCDIR) + "/data/" + qmlFile);
1296 QSGItem *rootB = qobject_cast<QSGItem*>(canvasB->rootObject());
1298 rootA->setProperty("testRightToLeft", true); // layoutDirection: Qt.RightToLeft
1301 foreach(const QString objectName, objectNames) {
1302 // horizontal.qml only has three items
1303 if (qmlFile == QString("horizontal.qml") && objectName == QString("four"))
1305 QSGItem *itemA = rootA->findChild<QSGItem*>(objectName);
1306 QSGItem *itemB = rootB->findChild<QSGItem*>(objectName);
1307 QTRY_VERIFY(itemA->x() != itemB->x());
1310 QSGItemPrivate* rootPrivateB = QSGItemPrivate::get(rootB);
1312 rootPrivateB->effectiveLayoutMirror = true; // LayoutMirroring.enabled: true
1313 rootPrivateB->isMirrorImplicit = false;
1314 rootPrivateB->inheritMirrorFromItem = true; // LayoutMirroring.childrenInherit: true
1315 rootPrivateB->resolveLayoutMirror();
1318 foreach(const QString objectName, objectNames) {
1319 // horizontal.qml only has three items
1320 if (qmlFile == QString("horizontal.qml") && objectName == QString("four"))
1322 QSGItem *itemA = rootA->findChild<QSGItem*>(objectName);
1323 QSGItem *itemB = rootB->findChild<QSGItem*>(objectName);
1324 QTRY_COMPARE(itemA->x(), itemB->x());
1327 rootA->setProperty("testRightToLeft", false); // layoutDirection: Qt.LeftToRight
1328 rootB->setProperty("testRightToLeft", true); // layoutDirection: Qt.RightToLeft
1330 // LTR == RTL + mirror
1331 foreach(const QString objectName, objectNames) {
1332 // horizontal.qml only has three items
1333 if (qmlFile == QString("horizontal.qml") && objectName == QString("four"))
1335 QSGItem *itemA = rootA->findChild<QSGItem*>(objectName);
1336 QSGItem *itemB = rootB->findChild<QSGItem*>(objectName);
1337 QTRY_COMPARE(itemA->x(), itemB->x());
1344 void tst_qsgpositioners::test_allInvisible()
1347 QSGView *canvas = createView(SRCDIR "/data/allInvisible.qml");
1349 QSGItem *root = qobject_cast<QSGItem*>(canvas->rootObject());
1352 QSGRow *row = canvas->rootObject()->findChild<QSGRow*>("row");
1354 QVERIFY(row->width() == 0);
1355 QVERIFY(row->height() == 0);
1356 QSGColumn *column = canvas->rootObject()->findChild<QSGColumn*>("column");
1357 QVERIFY(column != 0);
1358 QVERIFY(column->width() == 0);
1359 QVERIFY(column->height() == 0);
1362 void tst_qsgpositioners::test_attachedproperties()
1364 QFETCH(QString, filename);
1366 QSGView *canvas = createView(filename);
1367 QVERIFY(canvas->rootObject() != 0);
1369 QSGRectangle *greenRect = canvas->rootObject()->findChild<QSGRectangle *>("greenRect");
1370 QVERIFY(greenRect != 0);
1372 int posIndex = greenRect->property("posIndex").toInt();
1373 QVERIFY(posIndex == 0);
1374 bool isFirst = greenRect->property("isFirstItem").toBool();
1375 QVERIFY(isFirst == true);
1376 bool isLast = greenRect->property("isLastItem").toBool();
1377 QVERIFY(isLast == false);
1379 QSGRectangle *yellowRect = canvas->rootObject()->findChild<QSGRectangle *>("yellowRect");
1380 QVERIFY(yellowRect != 0);
1382 posIndex = yellowRect->property("posIndex").toInt();
1383 QVERIFY(posIndex == -1);
1384 isFirst = yellowRect->property("isFirstItem").toBool();
1385 QVERIFY(isFirst == false);
1386 isLast = yellowRect->property("isLastItem").toBool();
1387 QVERIFY(isLast == false);
1389 yellowRect->metaObject()->invokeMethod(yellowRect, "onDemandPositioner");
1391 posIndex = yellowRect->property("posIndex").toInt();
1392 QVERIFY(posIndex == 1);
1393 isFirst = yellowRect->property("isFirstItem").toBool();
1394 QVERIFY(isFirst == false);
1395 isLast = yellowRect->property("isLastItem").toBool();
1396 QVERIFY(isLast == true);
1401 void tst_qsgpositioners::test_attachedproperties_data()
1403 QTest::addColumn<QString>("filename");
1405 QTest::newRow("column") << SRCDIR "/data/attachedproperties-column.qml";
1406 QTest::newRow("row") << SRCDIR "/data/attachedproperties-row.qml";
1407 QTest::newRow("grid") << SRCDIR "/data/attachedproperties-grid.qml";
1408 QTest::newRow("flow") << SRCDIR "/data/attachedproperties-flow.qml";
1411 void tst_qsgpositioners::test_attachedproperties_dynamic()
1413 QSGView *canvas = createView(SRCDIR "/data/attachedproperties-dynamic.qml");
1414 QVERIFY(canvas->rootObject() != 0);
1416 QSGRow *row = canvas->rootObject()->findChild<QSGRow *>("pos");
1419 QSGRectangle *rect0 = canvas->rootObject()->findChild<QSGRectangle *>("rect0");
1420 QVERIFY(rect0 != 0);
1422 int posIndex = rect0->property("index").toInt();
1423 QVERIFY(posIndex == 0);
1424 bool isFirst = rect0->property("firstItem").toBool();
1425 QVERIFY(isFirst == true);
1426 bool isLast = rect0->property("lastItem").toBool();
1427 QVERIFY(isLast == false);
1429 QSGRectangle *rect1 = canvas->rootObject()->findChild<QSGRectangle *>("rect1");
1430 QVERIFY(rect1 != 0);
1432 posIndex = rect1->property("index").toInt();
1433 QVERIFY(posIndex == 1);
1434 isFirst = rect1->property("firstItem").toBool();
1435 QVERIFY(isFirst == false);
1436 isLast = rect1->property("lastItem").toBool();
1437 QVERIFY(isLast == true);
1439 row->metaObject()->invokeMethod(row, "createSubRect");
1441 QTRY_VERIFY(rect1->property("index").toInt() == 1);
1442 QTRY_VERIFY(rect1->property("firstItem").toBool() == false);
1443 QTRY_VERIFY(rect1->property("lastItem").toBool() == false);
1445 QSGRectangle *rect2 = canvas->rootObject()->findChild<QSGRectangle *>("rect2");
1446 QVERIFY(rect2 != 0);
1448 posIndex = rect2->property("index").toInt();
1449 QVERIFY(posIndex == 2);
1450 isFirst = rect2->property("firstItem").toBool();
1451 QVERIFY(isFirst == false);
1452 isLast = rect2->property("lastItem").toBool();
1453 QVERIFY(isLast == true);
1455 row->metaObject()->invokeMethod(row, "destroySubRect");
1457 qApp->processEvents(QEventLoop::DeferredDeletion);
1459 QTRY_VERIFY(rect1->property("index").toInt() == 1);
1460 QTRY_VERIFY(rect1->property("firstItem").toBool() == false);
1461 QTRY_VERIFY(rect1->property("lastItem").toBool() == true);
1466 QSGView *tst_qsgpositioners::createView(const QString &filename, bool wait)
1468 QSGView *canvas = new QSGView(0);
1470 canvas->setSource(QUrl::fromLocalFile(filename));
1473 QTest::qWaitForWindowShown(canvas); //It may not relayout until the next frame, so it needs to be drawn
1479 QTEST_MAIN(tst_qsgpositioners)
1481 #include "tst_qsgpositioners.moc"