aboutsummaryrefslogtreecommitdiffstats
path: root/tests/auto/quick/qquickpositioners
diff options
context:
space:
mode:
Diffstat (limited to 'tests/auto/quick/qquickpositioners')
-rw-r--r--tests/auto/quick/qquickpositioners/data/allInvisible.qml44
-rw-r--r--tests/auto/quick/qquickpositioners/data/attachedproperties-column.qml50
-rw-r--r--tests/auto/quick/qquickpositioners/data/attachedproperties-dynamic.qml44
-rw-r--r--tests/auto/quick/qquickpositioners/data/attachedproperties-flow.qml50
-rw-r--r--tests/auto/quick/qquickpositioners/data/attachedproperties-grid.qml50
-rw-r--r--tests/auto/quick/qquickpositioners/data/attachedproperties-row.qml50
-rw-r--r--tests/auto/quick/qquickpositioners/data/flow-testimplicitsize.qml19
-rw-r--r--tests/auto/quick/qquickpositioners/data/flowtest-toptobottom.qml44
-rw-r--r--tests/auto/quick/qquickpositioners/data/flowtest.qml43
-rw-r--r--tests/auto/quick/qquickpositioners/data/grid-animated.qml64
-rw-r--r--tests/auto/quick/qquickpositioners/data/grid-row-column-spacing.qml43
-rw-r--r--tests/auto/quick/qquickpositioners/data/grid-spacing.qml41
-rw-r--r--tests/auto/quick/qquickpositioners/data/grid-toptobottom.qml41
-rw-r--r--tests/auto/quick/qquickpositioners/data/gridtest.qml42
-rw-r--r--tests/auto/quick/qquickpositioners/data/gridzerocolumns.qml40
-rw-r--r--tests/auto/quick/qquickpositioners/data/horizontal-animated-disabled.qml40
-rw-r--r--tests/auto/quick/qquickpositioners/data/horizontal-animated.qml47
-rw-r--r--tests/auto/quick/qquickpositioners/data/horizontal-spacing.qml31
-rw-r--r--tests/auto/quick/qquickpositioners/data/horizontal.qml29
-rw-r--r--tests/auto/quick/qquickpositioners/data/propertychangestest.qml39
-rw-r--r--tests/auto/quick/qquickpositioners/data/rectangleComponent.qml11
-rw-r--r--tests/auto/quick/qquickpositioners/data/repeatertest.qml38
-rw-r--r--tests/auto/quick/qquickpositioners/data/transitions.qml196
-rw-r--r--tests/auto/quick/qquickpositioners/data/vertical-animated.qml41
-rw-r--r--tests/auto/quick/qquickpositioners/data/vertical-spacing.qml28
-rw-r--r--tests/auto/quick/qquickpositioners/data/vertical.qml27
-rw-r--r--tests/auto/quick/qquickpositioners/qquickpositioners.pro15
-rw-r--r--tests/auto/quick/qquickpositioners/tst_qquickpositioners.cpp1927
28 files changed, 3134 insertions, 0 deletions
diff --git a/tests/auto/quick/qquickpositioners/data/allInvisible.qml b/tests/auto/quick/qquickpositioners/data/allInvisible.qml
new file mode 100644
index 0000000000..5894171434
--- /dev/null
+++ b/tests/auto/quick/qquickpositioners/data/allInvisible.qml
@@ -0,0 +1,44 @@
+import QtQuick 2.0
+
+Item{
+ width: 400
+ height: 400
+ Column{
+ spacing: 20
+ objectName: "column"
+ Item{
+ width: 0
+ height: 20
+ visible: false
+ }
+ Item{
+ width: 20
+ height: 0
+ visible: false
+ }
+ Item{
+ width: 20
+ height: 20
+ visible: false
+ }
+ }
+ Row{
+ spacing: 20
+ objectName: "row"
+ Item{
+ width: 0
+ height: 20
+ visible: false
+ }
+ Item{
+ width: 20
+ height: 0
+ visible: false
+ }
+ Item{
+ width: 20
+ height: 20
+ visible: false
+ }
+ }
+}
diff --git a/tests/auto/quick/qquickpositioners/data/attachedproperties-column.qml b/tests/auto/quick/qquickpositioners/data/attachedproperties-column.qml
new file mode 100644
index 0000000000..4c667aa205
--- /dev/null
+++ b/tests/auto/quick/qquickpositioners/data/attachedproperties-column.qml
@@ -0,0 +1,50 @@
+import QtQuick 2.0
+
+Rectangle {
+ width: 100
+ height: 200
+
+ Column {
+
+ Rectangle {
+ width: 100
+ height: 100
+ color: 'red'
+ visible: false
+ }
+
+ Rectangle {
+ objectName: "greenRect"
+ width: 100
+ height: 100
+ color: 'green'
+ property int posIndex: Positioner.index
+ property bool isFirstItem: Positioner.isFirstItem
+ property bool isLastItem: Positioner.isLastItem
+ }
+
+ Rectangle {
+ width: 100
+ height: 100
+ color: 'blue'
+ visible: false
+ }
+
+ Rectangle {
+ objectName: "yellowRect"
+ width: 100
+ height: 100
+ color: 'yellow'
+
+ property int posIndex: -1
+ property bool isFirstItem: false
+ property bool isLastItem: false
+
+ function onDemandPositioner() {
+ posIndex = Positioner.index;
+ isFirstItem = Positioner.isFirstItem
+ isLastItem = Positioner.isLastItem
+ }
+ }
+ }
+}
diff --git a/tests/auto/quick/qquickpositioners/data/attachedproperties-dynamic.qml b/tests/auto/quick/qquickpositioners/data/attachedproperties-dynamic.qml
new file mode 100644
index 0000000000..894749dc16
--- /dev/null
+++ b/tests/auto/quick/qquickpositioners/data/attachedproperties-dynamic.qml
@@ -0,0 +1,44 @@
+import QtQuick 2.0
+
+Rectangle
+{
+ width: 300
+ height: 100
+
+ Row {
+ id: pos
+ objectName: "pos"
+ anchors.fill: parent
+
+ Rectangle {
+ objectName: "rect0"
+ width: 100
+ height: 100
+ color: 'red'
+ property int index: Positioner.index
+ property bool firstItem: Positioner.isFirstItem
+ property bool lastItem: Positioner.isLastItem
+ }
+
+ Rectangle {
+ objectName: "rect1"
+ width: 100
+ height: 100
+ color: 'green'
+ property int index: Positioner.index
+ property bool firstItem: Positioner.isFirstItem
+ property bool lastItem: Positioner.isLastItem
+ }
+
+ property QtObject subRect;
+
+ function createSubRect() {
+ var component = Qt.createComponent("rectangleComponent.qml");
+ subRect = component.createObject(pos, {});
+ }
+
+ function destroySubRect() {
+ subRect.destroy();
+ }
+ }
+}
diff --git a/tests/auto/quick/qquickpositioners/data/attachedproperties-flow.qml b/tests/auto/quick/qquickpositioners/data/attachedproperties-flow.qml
new file mode 100644
index 0000000000..e7f9a63e2a
--- /dev/null
+++ b/tests/auto/quick/qquickpositioners/data/attachedproperties-flow.qml
@@ -0,0 +1,50 @@
+import QtQuick 2.0
+
+Rectangle {
+ width: 200
+ height: 100
+
+ Flow {
+
+ Rectangle {
+ width: 100
+ height: 100
+ color: 'red'
+ visible: false
+ }
+
+ Rectangle {
+ objectName: "greenRect"
+ width: 100
+ height: 100
+ color: 'green'
+ property int posIndex: Positioner.index
+ property bool isFirstItem: Positioner.isFirstItem
+ property bool isLastItem: Positioner.isLastItem
+ }
+
+ Rectangle {
+ width: 100
+ height: 100
+ color: 'blue'
+ visible: false
+ }
+
+ Rectangle {
+ objectName: "yellowRect"
+ width: 100
+ height: 100
+ color: 'yellow'
+
+ property int posIndex: -1
+ property bool isFirstItem: false
+ property bool isLastItem: false
+
+ function onDemandPositioner() {
+ posIndex = Positioner.index;
+ isFirstItem = Positioner.isFirstItem
+ isLastItem = Positioner.isLastItem
+ }
+ }
+ }
+}
diff --git a/tests/auto/quick/qquickpositioners/data/attachedproperties-grid.qml b/tests/auto/quick/qquickpositioners/data/attachedproperties-grid.qml
new file mode 100644
index 0000000000..2094309b9f
--- /dev/null
+++ b/tests/auto/quick/qquickpositioners/data/attachedproperties-grid.qml
@@ -0,0 +1,50 @@
+import QtQuick 2.0
+
+Rectangle {
+ width: 200
+ height: 100
+
+ Grid {
+
+ Rectangle {
+ width: 100
+ height: 100
+ color: 'red'
+ visible: false
+ }
+
+ Rectangle {
+ objectName: "greenRect"
+ width: 100
+ height: 100
+ color: 'green'
+ property int posIndex: Positioner.index
+ property bool isFirstItem: Positioner.isFirstItem
+ property bool isLastItem: Positioner.isLastItem
+ }
+
+ Rectangle {
+ width: 100
+ height: 100
+ color: 'blue'
+ visible: false
+ }
+
+ Rectangle {
+ objectName: "yellowRect"
+ width: 100
+ height: 100
+ color: 'yellow'
+
+ property int posIndex: -1
+ property bool isFirstItem: false
+ property bool isLastItem: false
+
+ function onDemandPositioner() {
+ posIndex = Positioner.index;
+ isFirstItem = Positioner.isFirstItem
+ isLastItem = Positioner.isLastItem
+ }
+ }
+ }
+}
diff --git a/tests/auto/quick/qquickpositioners/data/attachedproperties-row.qml b/tests/auto/quick/qquickpositioners/data/attachedproperties-row.qml
new file mode 100644
index 0000000000..212a26b431
--- /dev/null
+++ b/tests/auto/quick/qquickpositioners/data/attachedproperties-row.qml
@@ -0,0 +1,50 @@
+import QtQuick 2.0
+
+Rectangle {
+ width: 200
+ height: 100
+
+ Row {
+
+ Rectangle {
+ width: 100
+ height: 100
+ color: 'red'
+ visible: false
+ }
+
+ Rectangle {
+ objectName: "greenRect"
+ width: 100
+ height: 100
+ color: 'green'
+ property int posIndex: Positioner.index
+ property bool isFirstItem: Positioner.isFirstItem
+ property bool isLastItem: Positioner.isLastItem
+ }
+
+ Rectangle {
+ width: 100
+ height: 100
+ color: 'blue'
+ visible: false
+ }
+
+ Rectangle {
+ objectName: "yellowRect"
+ width: 100
+ height: 100
+ color: 'yellow'
+
+ property int posIndex: -1
+ property bool isFirstItem: false
+ property bool isLastItem: false
+
+ function onDemandPositioner() {
+ posIndex = Positioner.index;
+ isFirstItem = Positioner.isFirstItem
+ isLastItem = Positioner.isLastItem
+ }
+ }
+ }
+}
diff --git a/tests/auto/quick/qquickpositioners/data/flow-testimplicitsize.qml b/tests/auto/quick/qquickpositioners/data/flow-testimplicitsize.qml
new file mode 100644
index 0000000000..c32b78676c
--- /dev/null
+++ b/tests/auto/quick/qquickpositioners/data/flow-testimplicitsize.qml
@@ -0,0 +1,19 @@
+import QtQuick 2.0
+
+Rectangle {
+ width: 300; height: 200;
+
+ property int flowLayout: 1
+
+ Flow {
+ objectName: "flow"
+ layoutDirection: (flowLayout == 2) ? Qt.RightToLeft : Qt.LeftToRight
+ flow: (flowLayout == 1) ? Flow.TopToBottom : Flow.LeftToRight;
+
+ spacing: 20
+ anchors.horizontalCenter: parent.horizontalCenter
+ Rectangle { color: "red"; width: 100; height: 50 }
+ Rectangle { color: "blue"; width: 100; height: 50 }
+ }
+}
+
diff --git a/tests/auto/quick/qquickpositioners/data/flowtest-toptobottom.qml b/tests/auto/quick/qquickpositioners/data/flowtest-toptobottom.qml
new file mode 100644
index 0000000000..a7d3ee13c7
--- /dev/null
+++ b/tests/auto/quick/qquickpositioners/data/flowtest-toptobottom.qml
@@ -0,0 +1,44 @@
+import QtQuick 2.0
+
+Item {
+ height: 90
+ width: 480
+ property bool testRightToLeft: false
+
+ Flow {
+ objectName: "flow"
+ height: parent.height
+ layoutDirection: testRightToLeft ? Qt.RightToLeft : Qt.LeftToRight
+ flow: Flow.TopToBottom
+ Rectangle {
+ objectName: "one"
+ color: "red"
+ width: 50
+ height: 50
+ }
+ Rectangle {
+ objectName: "two"
+ color: "green"
+ width: 20
+ height: 50
+ }
+ Rectangle {
+ objectName: "three"
+ color: "blue"
+ width: 50
+ height: 20
+ }
+ Rectangle {
+ objectName: "four"
+ color: "cyan"
+ width: 50
+ height: 50
+ }
+ Rectangle {
+ objectName: "five"
+ color: "magenta"
+ width: 10
+ height: 10
+ }
+ }
+}
diff --git a/tests/auto/quick/qquickpositioners/data/flowtest.qml b/tests/auto/quick/qquickpositioners/data/flowtest.qml
new file mode 100644
index 0000000000..40b042dd79
--- /dev/null
+++ b/tests/auto/quick/qquickpositioners/data/flowtest.qml
@@ -0,0 +1,43 @@
+import QtQuick 2.0
+
+Item {
+ width: 90
+ height: 480
+ property bool testRightToLeft: false
+
+ Flow {
+ objectName: "flow"
+ width: parent.width
+ layoutDirection: testRightToLeft ? Qt.RightToLeft : Qt.LeftToRight
+ Rectangle {
+ objectName: "one"
+ color: "red"
+ width: 50
+ height: 50
+ }
+ Rectangle {
+ objectName: "two"
+ color: "green"
+ width: 20
+ height: 50
+ }
+ Rectangle {
+ objectName: "three"
+ color: "blue"
+ width: 50
+ height: 20
+ }
+ Rectangle {
+ objectName: "four"
+ color: "cyan"
+ width: 50
+ height: 50
+ }
+ Rectangle {
+ objectName: "five"
+ color: "magenta"
+ width: 10
+ height: 10
+ }
+ }
+}
diff --git a/tests/auto/quick/qquickpositioners/data/grid-animated.qml b/tests/auto/quick/qquickpositioners/data/grid-animated.qml
new file mode 100644
index 0000000000..b8ee8f9a52
--- /dev/null
+++ b/tests/auto/quick/qquickpositioners/data/grid-animated.qml
@@ -0,0 +1,64 @@
+import QtQuick 2.0
+
+Item {
+ width: 640
+ height: 480
+ property bool testRightToLeft: true
+
+ Grid {
+ objectName: "grid"
+ columns: 3
+ layoutDirection: testRightToLeft ? Qt.RightToLeft : Qt.LeftToRight
+ add: Transition {
+ NumberAnimation {
+ properties: "x,y";
+ }
+ }
+ move: Transition {
+ NumberAnimation {
+ properties: "x,y";
+ }
+ }
+ Rectangle {
+ objectName: "one"
+ color: "red"
+ x: -100
+ y: -100
+ width: 50
+ height: 50
+ }
+ Rectangle {
+ objectName: "two"
+ x: -100
+ y: -100
+ visible: false
+ color: "green"
+ width: 50
+ height: 50
+ }
+ Rectangle {
+ objectName: "three"
+ color: "blue"
+ x: -100
+ y: -100
+ width: 50
+ height: 50
+ }
+ Rectangle {
+ objectName: "four"
+ color: "cyan"
+ x: -100
+ y: -100
+ width: 50
+ height: 50
+ }
+ Rectangle {
+ objectName: "five"
+ color: "magenta"
+ x: -100
+ y: -100
+ width: 50
+ height: 50
+ }
+ }
+}
diff --git a/tests/auto/quick/qquickpositioners/data/grid-row-column-spacing.qml b/tests/auto/quick/qquickpositioners/data/grid-row-column-spacing.qml
new file mode 100644
index 0000000000..49bbd337e7
--- /dev/null
+++ b/tests/auto/quick/qquickpositioners/data/grid-row-column-spacing.qml
@@ -0,0 +1,43 @@
+import QtQuick 2.0
+
+Item {
+ width: 640
+ height: 480
+ Grid {
+ objectName: "grid"
+ columns: 3
+ spacing: 4
+ rowSpacing: 7
+ columnSpacing: 11
+ Rectangle {
+ objectName: "one"
+ color: "red"
+ width: 50
+ height: 50
+ }
+ Rectangle {
+ objectName: "two"
+ color: "green"
+ width: 20
+ height: 50
+ }
+ Rectangle {
+ objectName: "three"
+ color: "blue"
+ width: 50
+ height: 20
+ }
+ Rectangle {
+ objectName: "four"
+ color: "cyan"
+ width: 50
+ height: 50
+ }
+ Rectangle {
+ objectName: "five"
+ color: "magenta"
+ width: 10
+ height: 10
+ }
+ }
+}
diff --git a/tests/auto/quick/qquickpositioners/data/grid-spacing.qml b/tests/auto/quick/qquickpositioners/data/grid-spacing.qml
new file mode 100644
index 0000000000..535a39037f
--- /dev/null
+++ b/tests/auto/quick/qquickpositioners/data/grid-spacing.qml
@@ -0,0 +1,41 @@
+import QtQuick 2.0
+
+Item {
+ width: 640
+ height: 480
+ Grid {
+ objectName: "grid"
+ columns: 3
+ spacing: 4
+ Rectangle {
+ objectName: "one"
+ color: "red"
+ width: 50
+ height: 50
+ }
+ Rectangle {
+ objectName: "two"
+ color: "green"
+ width: 20
+ height: 50
+ }
+ Rectangle {
+ objectName: "three"
+ color: "blue"
+ width: 50
+ height: 20
+ }
+ Rectangle {
+ objectName: "four"
+ color: "cyan"
+ width: 50
+ height: 50
+ }
+ Rectangle {
+ objectName: "five"
+ color: "magenta"
+ width: 10
+ height: 10
+ }
+ }
+}
diff --git a/tests/auto/quick/qquickpositioners/data/grid-toptobottom.qml b/tests/auto/quick/qquickpositioners/data/grid-toptobottom.qml
new file mode 100644
index 0000000000..45559aab5d
--- /dev/null
+++ b/tests/auto/quick/qquickpositioners/data/grid-toptobottom.qml
@@ -0,0 +1,41 @@
+import QtQuick 2.0
+
+Item {
+ width: 640
+ height: 480
+ Grid {
+ objectName: "grid"
+ rows: 3
+ flow: Grid.TopToBottom
+ Rectangle {
+ objectName: "one"
+ color: "red"
+ width: 50
+ height: 50
+ }
+ Rectangle {
+ objectName: "two"
+ color: "green"
+ width: 20
+ height: 50
+ }
+ Rectangle {
+ objectName: "three"
+ color: "blue"
+ width: 50
+ height: 20
+ }
+ Rectangle {
+ objectName: "four"
+ color: "cyan"
+ width: 50
+ height: 50
+ }
+ Rectangle {
+ objectName: "five"
+ color: "magenta"
+ width: 10
+ height: 10
+ }
+ }
+}
diff --git a/tests/auto/quick/qquickpositioners/data/gridtest.qml b/tests/auto/quick/qquickpositioners/data/gridtest.qml
new file mode 100644
index 0000000000..50bec1377b
--- /dev/null
+++ b/tests/auto/quick/qquickpositioners/data/gridtest.qml
@@ -0,0 +1,42 @@
+import QtQuick 2.0
+
+Item {
+ width: 640
+ height: 480
+ property bool testRightToLeft: false
+ Grid {
+ layoutDirection: testRightToLeft ? Qt.RightToLeft : Qt.LeftToRight
+ objectName: "grid"
+ columns: 3
+ Rectangle {
+ objectName: "one"
+ color: "red"
+ width: 50
+ height: 50
+ }
+ Rectangle {
+ objectName: "two"
+ color: "green"
+ width: 20
+ height: 50
+ }
+ Rectangle {
+ objectName: "three"
+ color: "blue"
+ width: 30
+ height: 20
+ }
+ Rectangle {
+ objectName: "four"
+ color: "cyan"
+ width: 50
+ height: 50
+ }
+ Rectangle {
+ objectName: "five"
+ color: "magenta"
+ width: 10
+ height: 10
+ }
+ }
+}
diff --git a/tests/auto/quick/qquickpositioners/data/gridzerocolumns.qml b/tests/auto/quick/qquickpositioners/data/gridzerocolumns.qml
new file mode 100644
index 0000000000..a252f279c3
--- /dev/null
+++ b/tests/auto/quick/qquickpositioners/data/gridzerocolumns.qml
@@ -0,0 +1,40 @@
+import QtQuick 2.0
+
+Item {
+ width: 640
+ height: 480
+ Grid {
+ objectName: "grid"
+ columns: 0
+ Rectangle {
+ objectName: "one"
+ color: "red"
+ width: 50
+ height: 50
+ }
+ Rectangle {
+ objectName: "two"
+ color: "green"
+ width: 20
+ height: 50
+ }
+ Rectangle {
+ objectName: "three"
+ color: "blue"
+ width: 50
+ height: 20
+ }
+ Rectangle {
+ objectName: "four"
+ color: "cyan"
+ width: 50
+ height: 50
+ }
+ Rectangle {
+ objectName: "five"
+ color: "magenta"
+ width: 10
+ height: 10
+ }
+ }
+}
diff --git a/tests/auto/quick/qquickpositioners/data/horizontal-animated-disabled.qml b/tests/auto/quick/qquickpositioners/data/horizontal-animated-disabled.qml
new file mode 100644
index 0000000000..8723ffc78f
--- /dev/null
+++ b/tests/auto/quick/qquickpositioners/data/horizontal-animated-disabled.qml
@@ -0,0 +1,40 @@
+import QtQuick 2.0
+
+Item {
+ width: 640
+ height: 480
+
+ Row {
+ objectName: "row"
+ add: Transition {
+ enabled: false
+ NumberAnimation { properties: "x" }
+ }
+ move: Transition {
+ enabled: false
+ NumberAnimation { properties: "x" }
+ }
+ Rectangle {
+ objectName: "one"
+ color: "red"
+ x: -100;
+ width: 50
+ height: 50
+ }
+ Rectangle {
+ objectName: "two"
+ color: "blue"
+ x: -100;
+ visible: false
+ width: 50
+ height: 50
+ }
+ Rectangle {
+ objectName: "three"
+ x: -100;
+ color: "green"
+ width: 50
+ height: 50
+ }
+ }
+}
diff --git a/tests/auto/quick/qquickpositioners/data/horizontal-animated.qml b/tests/auto/quick/qquickpositioners/data/horizontal-animated.qml
new file mode 100644
index 0000000000..a88c26b66c
--- /dev/null
+++ b/tests/auto/quick/qquickpositioners/data/horizontal-animated.qml
@@ -0,0 +1,47 @@
+import QtQuick 2.0
+
+Item {
+ width: 640
+ height: 480
+ property bool testRightToLeft: false
+ property bool testEnabled: false
+
+ Row {
+ objectName: "row"
+ layoutDirection: testRightToLeft ? Qt.RightToLeft : Qt.LeftToRight
+ add: Transition {
+ enabled: testEnabled ? false : true
+ NumberAnimation {
+ properties: "x";
+ }
+ }
+ move: Transition {
+ enabled: testEnabled ? false : true
+ NumberAnimation {
+ properties: "x";
+ }
+ }
+ Rectangle {
+ objectName: "one"
+ color: "red"
+ x: -100;
+ width: 50
+ height: 50
+ }
+ Rectangle {
+ objectName: "two"
+ color: "blue"
+ x: -100;
+ visible: false
+ width: 50
+ height: 50
+ }
+ Rectangle {
+ objectName: "three"
+ x: -100;
+ color: "green"
+ width: 50
+ height: 50
+ }
+ }
+}
diff --git a/tests/auto/quick/qquickpositioners/data/horizontal-spacing.qml b/tests/auto/quick/qquickpositioners/data/horizontal-spacing.qml
new file mode 100644
index 0000000000..c6ff75ac6b
--- /dev/null
+++ b/tests/auto/quick/qquickpositioners/data/horizontal-spacing.qml
@@ -0,0 +1,31 @@
+import QtQuick 2.0
+
+Item {
+ width: 640
+ height: 480
+ property bool testRightToLeft: false
+
+ Row {
+ objectName: "row"
+ spacing: 10
+ layoutDirection: testRightToLeft ? Qt.RightToLeft : Qt.LeftToRight
+ Rectangle {
+ objectName: "one"
+ color: "red"
+ width: 50
+ height: 50
+ }
+ Rectangle {
+ objectName: "two"
+ color: "red"
+ width: 20
+ height: 10
+ }
+ Rectangle {
+ objectName: "three"
+ color: "red"
+ width: 40
+ height: 20
+ }
+ }
+}
diff --git a/tests/auto/quick/qquickpositioners/data/horizontal.qml b/tests/auto/quick/qquickpositioners/data/horizontal.qml
new file mode 100644
index 0000000000..235ee78c9b
--- /dev/null
+++ b/tests/auto/quick/qquickpositioners/data/horizontal.qml
@@ -0,0 +1,29 @@
+import QtQuick 2.0
+
+Item {
+ width: 640
+ height: 480
+ property bool testRightToLeft: false
+ Row {
+ objectName: "row"
+ layoutDirection: testRightToLeft ? Qt.RightToLeft : Qt.LeftToRight
+ Rectangle {
+ objectName: "one"
+ color: "red"
+ width: 50
+ height: 50
+ }
+ Rectangle {
+ objectName: "two"
+ color: "red"
+ width: 20
+ height: 10
+ }
+ Rectangle {
+ objectName: "three"
+ color: "red"
+ width: 40
+ height: 20
+ }
+ }
+}
diff --git a/tests/auto/quick/qquickpositioners/data/propertychangestest.qml b/tests/auto/quick/qquickpositioners/data/propertychangestest.qml
new file mode 100644
index 0000000000..c9fd62b012
--- /dev/null
+++ b/tests/auto/quick/qquickpositioners/data/propertychangestest.qml
@@ -0,0 +1,39 @@
+import QtQuick 2.0
+
+Grid {
+ id: myGrid
+
+ width: 270
+ height: 270
+ x: 3
+ y: 3
+ columns: 4
+ spacing: 3
+
+ add: columnTransition
+ move: columnTransition
+
+ Repeater {
+ model: 20
+ Rectangle { color: "black"; width: 50; height: 50 }
+ }
+
+ data: [
+ Transition {
+ id: rowTransition
+ objectName: "rowTransition"
+ NumberAnimation {
+ properties: "x,y";
+ easing.type: "OutInCubic"
+ }
+ },
+ Transition {
+ id: columnTransition
+ objectName: "columnTransition"
+ NumberAnimation {
+ properties: "x,y";
+ easing.type: "OutInCubic"
+ }
+ }
+ ]
+}
diff --git a/tests/auto/quick/qquickpositioners/data/rectangleComponent.qml b/tests/auto/quick/qquickpositioners/data/rectangleComponent.qml
new file mode 100644
index 0000000000..de1bb99593
--- /dev/null
+++ b/tests/auto/quick/qquickpositioners/data/rectangleComponent.qml
@@ -0,0 +1,11 @@
+import QtQuick 2.0;
+
+Rectangle {
+ objectName: "rect2"
+ color: "blue"
+ width: 100
+ height: 100
+ property int index: Positioner.index
+ property bool firstItem: Positioner.isFirstItem
+ property bool lastItem: Positioner.isLastItem
+}
diff --git a/tests/auto/quick/qquickpositioners/data/repeatertest.qml b/tests/auto/quick/qquickpositioners/data/repeatertest.qml
new file mode 100644
index 0000000000..d90e1cf160
--- /dev/null
+++ b/tests/auto/quick/qquickpositioners/data/repeatertest.qml
@@ -0,0 +1,38 @@
+import QtQuick 2.0
+
+Item {
+ width: 640
+ height: 480
+ Row {
+ Repeater{ model: 3;
+ delegate: Component {
+ Rectangle {
+ color: "red"
+ width: 50
+ height: 50
+ z: {if(index == 0){2;}else if(index == 1){1;} else{3;}}
+ objectName: {if(index == 0){"one";}else if(index == 1){"two";} else{"three";}}
+ }
+ }
+ }
+ }
+
+ //This crashed once (QTBUG-16959) because the repeater ended up on the end of the list
+ //If this grid just instantiates without crashing, then it has not regressed.
+ Grid {
+ id: grid
+ rows: 2
+ flow: Grid.TopToBottom
+
+ Repeater {
+ model: 13
+ Rectangle {
+ color: "goldenrod"
+ width: 100
+ height: 100
+ radius: 10
+ border.width: 1
+ }
+ }
+ }
+}
diff --git a/tests/auto/quick/qquickpositioners/data/transitions.qml b/tests/auto/quick/qquickpositioners/data/transitions.qml
new file mode 100644
index 0000000000..54f5705c68
--- /dev/null
+++ b/tests/auto/quick/qquickpositioners/data/transitions.qml
@@ -0,0 +1,196 @@
+import QtQuick 2.0
+
+Rectangle {
+ id: root
+ width: 500
+ height: 500
+
+ property int duration: 50
+
+ property int targetTransitionsDone
+ property int displaceTransitionsDone
+
+ property var targetTrans_items: new Object()
+ property var targetTrans_targetIndexes: new Array()
+ property var targetTrans_targetItems: new Array()
+
+ property var displacedTrans_items: new Object()
+ property var displacedTrans_targetIndexes: new Array()
+ property var displacedTrans_targetItems: new Array()
+
+ // for QQmlListProperty types
+ function copyList(propList) {
+ var temp = new Array()
+ for (var i=0; i<propList.length; i++)
+ temp.push(propList[i])
+ return temp
+ }
+
+ function checkPos(x, y, name) {
+ if (Qt.point(x, y) == targetItems_transitionFrom)
+ model_targetItems_transitionFrom.addItem(name, "")
+ if (Qt.point(x, y) == displacedItems_transitionVia)
+ model_displacedItems_transitionVia.addItem(name, "")
+ }
+
+ Transition {
+ id: targetTransition
+ enabled: enableAddTransition
+
+ SequentialAnimation {
+ ScriptAction {
+ script: {
+ root.targetTrans_items[targetTransition.ViewTransition.item.nameData] = targetTransition.ViewTransition.index
+ root.targetTrans_targetIndexes.push(targetTransition.ViewTransition.targetIndexes)
+ root.targetTrans_targetItems.push(root.copyList(targetTransition.ViewTransition.targetItems))
+ }
+ }
+ ParallelAnimation {
+ NumberAnimation { properties: "x"; from: targetItems_transitionFrom.x; duration: root.duration }
+ NumberAnimation { properties: "y"; from: targetItems_transitionFrom.y; duration: root.duration }
+ }
+
+ ScriptAction { script: root.targetTransitionsDone += 1 }
+ }
+ }
+
+ Transition {
+ id: displaced
+
+ SequentialAnimation {
+ ScriptAction {
+ script: {
+ root.displacedTrans_items[displaced.ViewTransition.item.nameData] = displaced.ViewTransition.index
+ root.displacedTrans_targetIndexes.push(displaced.ViewTransition.targetIndexes)
+ root.displacedTrans_targetItems.push(root.copyList(displaced.ViewTransition.targetItems))
+ }
+ }
+ ParallelAnimation {
+ NumberAnimation { properties: "x"; duration: root.duration; to: displacedItems_transitionVia.x }
+ NumberAnimation { properties: "y"; duration: root.duration; to: displacedItems_transitionVia.y }
+ }
+ NumberAnimation { properties: "x,y"; duration: root.duration }
+
+ ScriptAction { script: root.displaceTransitionsDone += 1 }
+ }
+
+ }
+
+ Row {
+ objectName: "row"
+
+ property int count: children.length - 1 // omit Repeater
+
+ x: 50; y: 50
+ width: 400; height: 400
+ Repeater {
+ objectName: "repeater"
+ Rectangle {
+ property string nameData: name
+ objectName: "wrapper"
+ width: 30 + index*5
+ height: 30 + index*5
+ border.width: 1
+ Column {
+ Text { text: index }
+ Text { objectName: "name"; text: name }
+ Text { text: parent.parent.y }
+ }
+ onXChanged: root.checkPos(x, y, name)
+ onYChanged: root.checkPos(x, y, name)
+ }
+ }
+
+ add: targetTransition
+ move: displaced
+ }
+
+ Column {
+ objectName: "column"
+
+ property int count: children.length - 1 // omit Repeater
+
+ x: 50; y: 50
+ width: 400; height: 400
+ Repeater {
+ objectName: "repeater"
+ Rectangle {
+ property string nameData: name
+ objectName: "wrapper"
+ width: 30 + index*5
+ height: 30 + index*5
+ border.width: 1
+ Column {
+ Text { text: index }
+ Text { objectName: "name"; text: name }
+ Text { text: parent.parent.y }
+ }
+ onXChanged: root.checkPos(x, y, name)
+ onYChanged: root.checkPos(x, y, name)
+ }
+ }
+
+ add: targetTransition
+ move: displaced
+ }
+
+ Grid {
+ objectName: "grid"
+
+ property int count: children.length - 1 // omit Repeater
+
+ x: 50; y: 50
+ width: 400; height: 400
+ Repeater {
+ objectName: "repeater"
+ Rectangle {
+ property string nameData: name
+ objectName: "wrapper"
+ width: 30 + index*5
+ height: 30 + index*5
+ border.width: 1
+ Column {
+ Text { text: index }
+ Text { objectName: "name"; text: name }
+ Text { text: parent.parent.y }
+ }
+
+ onXChanged: root.checkPos(x, y, name)
+ onYChanged: root.checkPos(x, y, name)
+ }
+ }
+
+ add: targetTransition
+ move: displaced
+ }
+
+ Flow {
+ objectName: "flow"
+
+ property int count: children.length - 1 // omit Repeater
+
+ x: 50; y: 50
+ width: 400; height: 400
+ Repeater {
+ objectName: "repeater"
+ Rectangle {
+ property string nameData: name
+ objectName: "wrapper"
+ width: 30 + index*5
+ height: 30 + index*5
+ border.width: 1
+ Column {
+ Text { text: index }
+ Text { objectName: "name"; text: name }
+ Text { text: parent.parent.x + " " + parent.parent.y }
+ }
+ onXChanged: root.checkPos(x, y, name)
+ onYChanged: root.checkPos(x, y, name)
+ }
+ }
+
+ add: targetTransition
+ move: displaced
+ }
+}
+
diff --git a/tests/auto/quick/qquickpositioners/data/vertical-animated.qml b/tests/auto/quick/qquickpositioners/data/vertical-animated.qml
new file mode 100644
index 0000000000..ecf593cd70
--- /dev/null
+++ b/tests/auto/quick/qquickpositioners/data/vertical-animated.qml
@@ -0,0 +1,41 @@
+import QtQuick 2.0
+
+Item {
+ width: 640
+ height: 480
+ Column {
+ objectName: "column"
+ add: Transition {
+ NumberAnimation {
+ properties: "y";
+ }
+ }
+ move: Transition {
+ NumberAnimation {
+ properties: "y";
+ }
+ }
+ Rectangle {
+ objectName: "one"
+ color: "red"
+ y: -100
+ width: 50
+ height: 50
+ }
+ Rectangle {
+ objectName: "two"
+ color: "blue"
+ y: -100
+ visible: false
+ width: 50
+ height: 50
+ }
+ Rectangle {
+ objectName: "three"
+ color: "red"
+ y: -100
+ width: 50
+ height: 50
+ }
+ }
+}
diff --git a/tests/auto/quick/qquickpositioners/data/vertical-spacing.qml b/tests/auto/quick/qquickpositioners/data/vertical-spacing.qml
new file mode 100644
index 0000000000..7087961651
--- /dev/null
+++ b/tests/auto/quick/qquickpositioners/data/vertical-spacing.qml
@@ -0,0 +1,28 @@
+import QtQuick 2.0
+
+Item {
+ width: 640
+ height: 480
+ Column {
+ objectName: "column"
+ spacing: 10
+ Rectangle {
+ objectName: "one"
+ color: "red"
+ width: 50
+ height: 50
+ }
+ Rectangle {
+ objectName: "two"
+ color: "red"
+ width: 20
+ height: 10
+ }
+ Rectangle {
+ objectName: "three"
+ color: "red"
+ width: 40
+ height: 20
+ }
+ }
+}
diff --git a/tests/auto/quick/qquickpositioners/data/vertical.qml b/tests/auto/quick/qquickpositioners/data/vertical.qml
new file mode 100644
index 0000000000..0c3a81f008
--- /dev/null
+++ b/tests/auto/quick/qquickpositioners/data/vertical.qml
@@ -0,0 +1,27 @@
+import QtQuick 2.0
+
+Item {
+ width: 640
+ height: 480
+ Column {
+ objectName: "column"
+ Rectangle {
+ objectName: "one"
+ color: "red"
+ width: 50
+ height: 50
+ }
+ Rectangle {
+ objectName: "two"
+ color: "red"
+ width: 20
+ height: 10
+ }
+ Rectangle {
+ objectName: "three"
+ color: "red"
+ width: 40
+ height: 20
+ }
+ }
+}
diff --git a/tests/auto/quick/qquickpositioners/qquickpositioners.pro b/tests/auto/quick/qquickpositioners/qquickpositioners.pro
new file mode 100644
index 0000000000..563379652b
--- /dev/null
+++ b/tests/auto/quick/qquickpositioners/qquickpositioners.pro
@@ -0,0 +1,15 @@
+CONFIG += testcase
+TARGET = tst_qquickpositioners
+SOURCES += tst_qquickpositioners.cpp
+
+include (../shared/util.pri)
+include (../../shared/util.pri)
+
+macx:CONFIG -= app_bundle
+
+testDataFiles.files = data
+testDataFiles.path = .
+DEPLOYMENT += testDataFiles
+
+CONFIG += parallel_test
+QT += core-private gui-private v8-private qml-private quick-private opengl-private testlib
diff --git a/tests/auto/quick/qquickpositioners/tst_qquickpositioners.cpp b/tests/auto/quick/qquickpositioners/tst_qquickpositioners.cpp
new file mode 100644
index 0000000000..8f517a4fe3
--- /dev/null
+++ b/tests/auto/quick/qquickpositioners/tst_qquickpositioners.cpp
@@ -0,0 +1,1927 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#include <QtTest/QtTest>
+#include <private/qlistmodelinterface_p.h>
+#include <QtQuick/qquickview.h>
+#include <qqmlengine.h>
+#include <QtQuick/private/qquickrectangle_p.h>
+#include <QtQuick/private/qquickpositioners_p.h>
+#include <QtQuick/private/qquicktransition_p.h>
+#include <private/qquickitem_p.h>
+#include <qqmlexpression.h>
+#include "../shared/viewtestutil.h"
+#include "../shared/visualtestutil.h"
+#include "../../shared/util.h"
+
+using namespace QQuickViewTestUtil;
+using namespace QQuickVisualTestUtil;
+
+class tst_qquickpositioners : public QQmlDataTest
+{
+ Q_OBJECT
+public:
+ tst_qquickpositioners();
+
+private slots:
+ void test_horizontal();
+ void test_horizontal_rtl();
+ void test_horizontal_spacing();
+ void test_horizontal_spacing_rightToLeft();
+ void test_horizontal_animated();
+ void test_horizontal_animated_rightToLeft();
+ void test_horizontal_animated_disabled();
+ void test_vertical();
+ void test_vertical_spacing();
+ void test_vertical_animated();
+ void test_grid();
+ void test_grid_topToBottom();
+ void test_grid_rightToLeft();
+ void test_grid_spacing();
+ void test_grid_row_column_spacing();
+ void test_grid_animated();
+ void test_grid_animated_rightToLeft();
+ void test_grid_zero_columns();
+ void test_propertychanges();
+ void test_repeater();
+ void test_flow();
+ void test_flow_rightToLeft();
+ void test_flow_topToBottom();
+ void test_flow_resize();
+ void test_flow_resize_rightToLeft();
+ void test_flow_implicit_resize();
+ void test_conflictinganchors();
+ void test_mirroring();
+ void test_allInvisible();
+ void test_attachedproperties();
+ void test_attachedproperties_data();
+ void test_attachedproperties_dynamic();
+ void addTransitions_row();
+ void addTransitions_row_data();
+ void addTransitions_column();
+ void addTransitions_column_data();
+ void addTransitions_grid();
+ void addTransitions_grid_data();
+ void addTransitions_flow();
+ void addTransitions_flow_data();
+ void moveTransitions_row();
+ void moveTransitions_row_data();
+ void moveTransitions_column();
+ void moveTransitions_column_data();
+ void moveTransitions_grid();
+ void moveTransitions_grid_data();
+ void moveTransitions_flow();
+ void moveTransitions_flow_data();
+
+private:
+ QQuickView *createView(const QString &filename, bool wait=true);
+
+ void addTransitions(const QString &positionerObjectName);
+ void addTransitions_data();
+ void moveTransitions(const QString &positionerObjectName);
+ void moveTransitions_data();
+ void matchIndexLists(const QVariantList &indexLists, const QList<int> &expectedIndexes);
+ void matchItemsAndIndexes(const QVariantMap &items, const QaimModel &model, const QList<int> &expectedIndexes);
+ void matchItemLists(const QVariantList &itemLists, const QList<QQuickItem *> &expectedItems);
+ void checkItemPositions(QQuickItem *positioner, QaimModel *model, qreal incrementalSize);
+};
+
+void tst_qquickpositioners::addTransitions_row()
+{
+ addTransitions("row");
+}
+
+void tst_qquickpositioners::addTransitions_row_data()
+{
+ addTransitions_data();
+}
+
+void tst_qquickpositioners::addTransitions_column()
+{
+ addTransitions("column");
+}
+
+void tst_qquickpositioners::addTransitions_column_data()
+{
+ addTransitions_data();
+}
+
+void tst_qquickpositioners::addTransitions_grid()
+{
+ addTransitions("grid");
+}
+
+void tst_qquickpositioners::addTransitions_grid_data()
+{
+ // don't use addTransitions_data() because grid displaces items differently
+ // (adding items further down the grid can cause displace transitions at
+ // previous indexes, since grid is auto-resized to tightly fit all of its items)
+
+ QTest::addColumn<int>("initialItemCount");
+ QTest::addColumn<int>("insertionIndex");
+ QTest::addColumn<int>("insertionCount");
+ QTest::addColumn<ListRange>("expectedDisplacedIndexes");
+
+ QTest::newRow("add one @ start") << 10 << 0 << 1 << ListRange(0, 9);
+ QTest::newRow("add one @ middle") << 10 << 5 << 1 << ListRange(3, 3) + ListRange(5, 9);
+ QTest::newRow("add one @ end") << 10 << 10 << 1 << ListRange(3, 3) + ListRange(7, 7);
+
+ QTest::newRow("add multiple @ start") << 10 << 0 << 3 << ListRange(0, 9);
+ QTest::newRow("add multiple @ middle") << 10 << 5 << 3 << ListRange(1, 3) + ListRange(5, 9);
+ QTest::newRow("add multiple @ end") << 10 << 10 << 3 << ListRange(1, 3) + ListRange(5, 7) + ListRange(9, 9);
+}
+
+void tst_qquickpositioners::addTransitions_flow()
+{
+ addTransitions("flow");
+}
+
+void tst_qquickpositioners::addTransitions_flow_data()
+{
+ addTransitions_data();
+}
+
+void tst_qquickpositioners::moveTransitions_row()
+{
+ moveTransitions("row");
+}
+
+void tst_qquickpositioners::moveTransitions_row_data()
+{
+ moveTransitions_data();
+}
+
+void tst_qquickpositioners::moveTransitions_column()
+{
+ moveTransitions("column");
+}
+
+void tst_qquickpositioners::moveTransitions_column_data()
+{
+ moveTransitions_data();
+}
+
+void tst_qquickpositioners::moveTransitions_grid()
+{
+ moveTransitions("grid");
+}
+
+void tst_qquickpositioners::moveTransitions_grid_data()
+{
+ // don't use moveTransitions_data() because grid displaces items differently
+ // (removing items further down the grid can cause displace transitions at
+ // previous indexes, since grid is auto-resized to tightly fit all of its items)
+
+ QTest::addColumn<int>("initialItemCount");
+ QTest::addColumn<ListChange>("change");
+ QTest::addColumn<ListRange>("expectedDisplacedIndexes");
+
+ QTest::newRow("remove one @ start") << 10 << ListChange::remove(0, 1) << ListRange(1, 9);
+ QTest::newRow("remove one @ middle") << 10 << ListChange::remove(4, 1) << ListRange(2, 3) + ListRange(5, 9);
+ QTest::newRow("remove one @ end") << 10 << ListChange::remove(9, 1) << ListRange(2, 3) + ListRange(6, 7);
+
+ QTest::newRow("remove multiple @ start") << 10 << ListChange::remove(0, 3) << ListRange(3, 9);
+ QTest::newRow("remove multiple @ middle") << 10 << ListChange::remove(4, 3) << ListRange(1, 3) + ListRange(7, 9);
+ QTest::newRow("remove multiple @ end") << 10 << ListChange::remove(7, 3) << ListRange(1, 3) + ListRange(5, 6);
+}
+
+void tst_qquickpositioners::moveTransitions_flow()
+{
+ moveTransitions("flow");
+}
+
+void tst_qquickpositioners::moveTransitions_flow_data()
+{
+ moveTransitions_data();
+}
+
+tst_qquickpositioners::tst_qquickpositioners()
+{
+}
+
+void tst_qquickpositioners::test_horizontal()
+{
+ QQuickView *canvas = createView(testFile("horizontal.qml"));
+
+ canvas->rootObject()->setProperty("testRightToLeft", false);
+
+ QQuickRectangle *one = canvas->rootObject()->findChild<QQuickRectangle*>("one");
+ QVERIFY(one != 0);
+
+ QQuickRectangle *two = canvas->rootObject()->findChild<QQuickRectangle*>("two");
+ QVERIFY(two != 0);
+
+ QQuickRectangle *three = canvas->rootObject()->findChild<QQuickRectangle*>("three");
+ QVERIFY(three != 0);
+
+ QCOMPARE(one->x(), 0.0);
+ QCOMPARE(one->y(), 0.0);
+ QCOMPARE(two->x(), 50.0);
+ QCOMPARE(two->y(), 0.0);
+ QCOMPARE(three->x(), 70.0);
+ QCOMPARE(three->y(), 0.0);
+
+ QQuickItem *row = canvas->rootObject()->findChild<QQuickItem*>("row");
+ QCOMPARE(row->width(), 110.0);
+ QCOMPARE(row->height(), 50.0);
+
+ delete canvas;
+}
+
+void tst_qquickpositioners::test_horizontal_rtl()
+{
+ QQuickView *canvas = createView(testFile("horizontal.qml"));
+
+ canvas->rootObject()->setProperty("testRightToLeft", true);
+
+ QQuickRectangle *one = canvas->rootObject()->findChild<QQuickRectangle*>("one");
+ QVERIFY(one != 0);
+
+ QQuickRectangle *two = canvas->rootObject()->findChild<QQuickRectangle*>("two");
+ QVERIFY(two != 0);
+
+ QQuickRectangle *three = canvas->rootObject()->findChild<QQuickRectangle*>("three");
+ QVERIFY(three != 0);
+
+ QCOMPARE(one->x(), 60.0);
+ QCOMPARE(one->y(), 0.0);
+ QCOMPARE(two->x(), 40.0);
+ QCOMPARE(two->y(), 0.0);
+ QCOMPARE(three->x(), 0.0);
+ QCOMPARE(three->y(), 0.0);
+
+ QQuickItem *row = canvas->rootObject()->findChild<QQuickItem*>("row");
+ QCOMPARE(row->width(), 110.0);
+ QCOMPARE(row->height(), 50.0);
+
+ // Change the width of the row and check that items stay to the right
+ row->setWidth(200);
+ QTRY_COMPARE(one->x(), 150.0);
+ QCOMPARE(one->y(), 0.0);
+ QCOMPARE(two->x(), 130.0);
+ QCOMPARE(two->y(), 0.0);
+ QCOMPARE(three->x(), 90.0);
+ QCOMPARE(three->y(), 0.0);
+
+ delete canvas;
+}
+
+void tst_qquickpositioners::test_horizontal_spacing()
+{
+ QQuickView *canvas = createView(testFile("horizontal-spacing.qml"));
+
+ canvas->rootObject()->setProperty("testRightToLeft", false);
+
+ QQuickRectangle *one = canvas->rootObject()->findChild<QQuickRectangle*>("one");
+ QVERIFY(one != 0);
+
+ QQuickRectangle *two = canvas->rootObject()->findChild<QQuickRectangle*>("two");
+ QVERIFY(two != 0);
+
+ QQuickRectangle *three = canvas->rootObject()->findChild<QQuickRectangle*>("three");
+ QVERIFY(three != 0);
+
+ QCOMPARE(one->x(), 0.0);
+ QCOMPARE(one->y(), 0.0);
+ QCOMPARE(two->x(), 60.0);
+ QCOMPARE(two->y(), 0.0);
+ QCOMPARE(three->x(), 90.0);
+ QCOMPARE(three->y(), 0.0);
+
+ QQuickItem *row = canvas->rootObject()->findChild<QQuickItem*>("row");
+ QCOMPARE(row->width(), 130.0);
+ QCOMPARE(row->height(), 50.0);
+
+ delete canvas;
+}
+
+void tst_qquickpositioners::test_horizontal_spacing_rightToLeft()
+{
+ QQuickView *canvas = createView(testFile("horizontal-spacing.qml"));
+
+ canvas->rootObject()->setProperty("testRightToLeft", true);
+
+ QQuickRectangle *one = canvas->rootObject()->findChild<QQuickRectangle*>("one");
+ QVERIFY(one != 0);
+
+ QQuickRectangle *two = canvas->rootObject()->findChild<QQuickRectangle*>("two");
+ QVERIFY(two != 0);
+
+ QQuickRectangle *three = canvas->rootObject()->findChild<QQuickRectangle*>("three");
+ QVERIFY(three != 0);
+
+ QCOMPARE(one->x(), 80.0);
+ QCOMPARE(one->y(), 0.0);
+ QCOMPARE(two->x(), 50.0);
+ QCOMPARE(two->y(), 0.0);
+ QCOMPARE(three->x(), 00.0);
+ QCOMPARE(three->y(), 0.0);
+
+ QQuickItem *row = canvas->rootObject()->findChild<QQuickItem*>("row");
+ QCOMPARE(row->width(), 130.0);
+ QCOMPARE(row->height(), 50.0);
+
+ delete canvas;
+}
+
+void tst_qquickpositioners::test_horizontal_animated()
+{
+ QQuickView *canvas = createView(testFile("horizontal-animated.qml"), false);
+
+ canvas->rootObject()->setProperty("testRightToLeft", false);
+
+ QQuickRectangle *one = canvas->rootObject()->findChild<QQuickRectangle*>("one");
+ QVERIFY(one != 0);
+
+ QQuickRectangle *two = canvas->rootObject()->findChild<QQuickRectangle*>("two");
+ QVERIFY(two != 0);
+
+ QQuickRectangle *three = canvas->rootObject()->findChild<QQuickRectangle*>("three");
+ QVERIFY(three != 0);
+
+ //Note that they animate in
+ QCOMPARE(one->x(), -100.0);
+ QCOMPARE(two->x(), -100.0);
+ QCOMPARE(three->x(), -100.0);
+
+ QTest::qWaitForWindowShown(canvas); //It may not relayout until the next frame, so it needs to be drawn
+
+ QQuickItem *row = canvas->rootObject()->findChild<QQuickItem*>("row");
+ QVERIFY(row);
+ QCOMPARE(row->width(), 100.0);
+ QCOMPARE(row->height(), 50.0);
+
+ //QTRY_COMPARE used instead of waiting for the expected time of animation completion
+ //Note that this means the duration of the animation is NOT tested
+
+ QTRY_COMPARE(one->x(), 0.0);
+ QTRY_COMPARE(one->y(), 0.0);
+ QTRY_COMPARE(two->isVisible(), false);
+ QTRY_COMPARE(two->x(), -100.0);//Not 'in' yet
+ QTRY_COMPARE(two->y(), 0.0);
+ QTRY_COMPARE(three->x(), 50.0);
+ QTRY_COMPARE(three->y(), 0.0);
+
+ //Add 'two'
+ two->setVisible(true);
+ QTRY_COMPARE(two->isVisible(), true);
+ QTRY_COMPARE(row->width(), 150.0);
+ QTRY_COMPARE(row->height(), 50.0);
+
+ QTest::qWait(0);//Let the animation start
+ QVERIFY(two->x() >= -100.0 && two->x() < 50.0);
+ QVERIFY(three->x() >= 50.0 && three->x() < 100.0);
+
+ QTRY_COMPARE(two->x(), 50.0);
+ QTRY_COMPARE(three->x(), 100.0);
+
+ delete canvas;
+}
+
+void tst_qquickpositioners::test_horizontal_animated_rightToLeft()
+{
+ QQuickView *canvas = createView(testFile("horizontal-animated.qml"), false);
+
+ canvas->rootObject()->setProperty("testRightToLeft", true);
+
+ QQuickRectangle *one = canvas->rootObject()->findChild<QQuickRectangle*>("one");
+ QVERIFY(one != 0);
+
+ QQuickRectangle *two = canvas->rootObject()->findChild<QQuickRectangle*>("two");
+ QVERIFY(two != 0);
+
+ QQuickRectangle *three = canvas->rootObject()->findChild<QQuickRectangle*>("three");
+ QVERIFY(three != 0);
+
+ //Note that they animate in
+ QCOMPARE(one->x(), -100.0);
+ QCOMPARE(two->x(), -100.0);
+ QCOMPARE(three->x(), -100.0);
+
+ QTest::qWaitForWindowShown(canvas); //It may not relayout until the next frame, so it needs to be drawn
+
+ QQuickItem *row = canvas->rootObject()->findChild<QQuickItem*>("row");
+ QVERIFY(row);
+ QCOMPARE(row->width(), 100.0);
+ QCOMPARE(row->height(), 50.0);
+
+ //QTRY_COMPARE used instead of waiting for the expected time of animation completion
+ //Note that this means the duration of the animation is NOT tested
+
+ QTRY_COMPARE(one->x(), 50.0);
+ QTRY_COMPARE(one->y(), 0.0);
+ QTRY_COMPARE(two->isVisible(), false);
+ QTRY_COMPARE(two->x(), -100.0);//Not 'in' yet
+ QTRY_COMPARE(two->y(), 0.0);
+ QTRY_COMPARE(three->x(), 0.0);
+ QTRY_COMPARE(three->y(), 0.0);
+
+ //Add 'two'
+ two->setVisible(true);
+ QTRY_COMPARE(two->isVisible(), true);
+
+ // New size should propagate after visible change
+ QTRY_COMPARE(row->width(), 150.0);
+ QTRY_COMPARE(row->height(), 50.0);
+
+ QTest::qWait(0);//Let the animation start
+ QVERIFY(one->x() >= 50.0 && one->x() < 100);
+ QVERIFY(two->x() >= -100.0 && two->x() < 50.0);
+
+ QTRY_COMPARE(one->x(), 100.0);
+ QTRY_COMPARE(two->x(), 50.0);
+
+ delete canvas;
+}
+
+void tst_qquickpositioners::test_horizontal_animated_disabled()
+{
+ QQuickView *canvas = createView(testFile("horizontal-animated-disabled.qml"));
+
+ QQuickRectangle *one = canvas->rootObject()->findChild<QQuickRectangle*>("one");
+ QVERIFY(one != 0);
+
+ QQuickRectangle *two = canvas->rootObject()->findChild<QQuickRectangle*>("two");
+ QVERIFY(two != 0);
+
+ QQuickRectangle *three = canvas->rootObject()->findChild<QQuickRectangle*>("three");
+ QVERIFY(three != 0);
+
+ QQuickItem *row = canvas->rootObject()->findChild<QQuickItem*>("row");
+ QVERIFY(row);
+
+ qApp->processEvents();
+
+ QCOMPARE(one->x(), 0.0);
+ QCOMPARE(one->y(), 0.0);
+ QCOMPARE(two->isVisible(), false);
+ QCOMPARE(two->x(), -100.0);//Not 'in' yet
+ QCOMPARE(two->y(), 0.0);
+ QCOMPARE(three->x(), 50.0);
+ QCOMPARE(three->y(), 0.0);
+
+ //Add 'two'
+ two->setVisible(true);
+ QCOMPARE(two->isVisible(), true);
+ QTRY_COMPARE(row->width(), 150.0);
+ QTRY_COMPARE(row->height(), 50.0);
+
+ QTRY_COMPARE(two->x(), 50.0);
+ QTRY_COMPARE(three->x(), 100.0);
+
+ delete canvas;
+}
+
+void tst_qquickpositioners::addTransitions(const QString &positionerObjectName)
+{
+ QFETCH(int, initialItemCount);
+ QFETCH(int, insertionIndex);
+ QFETCH(int, insertionCount);
+ QFETCH(ListRange, expectedDisplacedIndexes);
+
+ QPointF targetItems_transitionFrom(-50, -50);
+ QPointF displacedItems_transitionVia(100, 100);
+
+ QaimModel model;
+ for (int i = 0; i < initialItemCount; i++)
+ model.addItem("Original item" + QString::number(i), "");
+ QaimModel model_targetItems_transitionFrom;
+ QaimModel model_displacedItems_transitionVia;
+
+ QQuickView *canvas = QQuickViewTestUtil::createView();
+ QQmlContext *ctxt = canvas->rootContext();
+ ctxt->setContextProperty("enableAddTransition", true);
+ ctxt->setContextProperty("model_targetItems_transitionFrom", &model_targetItems_transitionFrom);
+ ctxt->setContextProperty("model_displacedItems_transitionVia", &model_displacedItems_transitionVia);
+ ctxt->setContextProperty("targetItems_transitionFrom", targetItems_transitionFrom);
+ ctxt->setContextProperty("displacedItems_transitionVia", displacedItems_transitionVia);
+ canvas->setSource(testFile("transitions.qml"));
+ canvas->show();
+ qApp->processEvents();
+
+ QList<QPair<QString,QString> > expectedDisplacedValues = expectedDisplacedIndexes.getModelDataValues(model);
+
+ QQuickItem *positioner = canvas->rootObject()->findChild<QQuickItem*>(positionerObjectName);
+ QVERIFY(positioner);
+ positioner->findChild<QQuickItem*>("repeater")->setProperty("model", QVariant::fromValue(&model));
+
+ QList<QPair<QString, QString> > targetData;
+ QList<int> targetIndexes;
+ for (int i=0; i<model.count(); i++) {
+ targetData << qMakePair(model.name(i), model.number(i));
+ targetIndexes << i;
+ }
+ QList<QQuickItem *> targetItems = findItems<QQuickItem>(positioner, "wrapper", targetIndexes);
+
+ // check initial add transition
+ // (positioners run the add transition on all items that are initially created for the view)
+ QTRY_COMPARE(canvas->rootObject()->property("targetTransitionsDone").toInt(), initialItemCount);
+ QTRY_COMPARE(canvas->rootObject()->property("displaceTransitionsDone").toInt(), 0);
+ model_targetItems_transitionFrom.matchAgainst(targetData, "wasn't animated from target 'from' pos", "shouldn't have been animated from target 'from' pos");
+ matchItemsAndIndexes(canvas->rootObject()->property("targetTrans_items").toMap(), model, targetIndexes);
+ matchIndexLists(canvas->rootObject()->property("targetTrans_targetIndexes").toList(), targetIndexes);
+ matchItemLists(canvas->rootObject()->property("targetTrans_targetItems").toList(), targetItems);
+
+ model_targetItems_transitionFrom.clear();
+ canvas->rootObject()->setProperty("targetTransitionsDone", 0);
+ canvas->rootObject()->setProperty("targetTrans_items", QVariantMap());
+ canvas->rootObject()->setProperty("targetTrans_targetIndexes", QVariantList());
+ canvas->rootObject()->setProperty("targetTrans_targetItems", QVariantList());
+
+ // do insertion
+ targetData.clear();
+ targetIndexes.clear();
+ for (int i=insertionIndex; i<insertionIndex+insertionCount; i++) {
+ targetData << qMakePair(QString("New item %1").arg(i), QString(""));
+ targetIndexes << i;
+ }
+ model.insertItems(insertionIndex, targetData);
+ QTRY_COMPARE(model.count(), positioner->property("count").toInt());
+
+ targetItems = findItems<QQuickItem>(positioner, "wrapper", targetIndexes);
+
+ QTRY_COMPARE(canvas->rootObject()->property("targetTransitionsDone").toInt(), targetData.count());
+ QTRY_COMPARE(canvas->rootObject()->property("displaceTransitionsDone").toInt(), expectedDisplacedIndexes.count());
+
+ // check the target and displaced items were animated
+ model_targetItems_transitionFrom.matchAgainst(targetData, "wasn't animated from target 'from' pos", "shouldn't have been animated from target 'from' pos");
+ model_displacedItems_transitionVia.matchAgainst(expectedDisplacedValues, "wasn't animated with displaced anim", "shouldn't have been animated with displaced anim");
+
+ // check attached properties
+ matchItemsAndIndexes(canvas->rootObject()->property("targetTrans_items").toMap(), model, targetIndexes);
+ matchIndexLists(canvas->rootObject()->property("targetTrans_targetIndexes").toList(), targetIndexes);
+ matchItemLists(canvas->rootObject()->property("targetTrans_targetItems").toList(), targetItems);
+ if (expectedDisplacedIndexes.isValid()) {
+ // adjust expectedDisplacedIndexes to their final values after the move
+ QList<int> displacedIndexes = adjustIndexesForAddDisplaced(expectedDisplacedIndexes.indexes, insertionIndex, insertionCount);
+ matchItemsAndIndexes(canvas->rootObject()->property("displacedTrans_items").toMap(), model, displacedIndexes);
+ matchIndexLists(canvas->rootObject()->property("displacedTrans_targetIndexes").toList(), targetIndexes);
+ matchItemLists(canvas->rootObject()->property("displacedTrans_targetItems").toList(), targetItems);
+ }
+
+ checkItemPositions(positioner, &model, 5.0); // XXX fetch from qml?
+
+ delete canvas;
+}
+
+void tst_qquickpositioners::addTransitions_data()
+{
+ // If this data changes, update addTransitions_grid_data() also
+
+ QTest::addColumn<int>("initialItemCount");
+ QTest::addColumn<int>("insertionIndex");
+ QTest::addColumn<int>("insertionCount");
+ QTest::addColumn<ListRange>("expectedDisplacedIndexes");
+
+ QTest::newRow("add one @ start") << 10 << 0 << 1 << ListRange(0, 9);
+ QTest::newRow("add one @ middle") << 10 << 5 << 1 << ListRange(5, 9);
+ QTest::newRow("add one @ end") << 10 << 10 << 1 << ListRange();
+
+ QTest::newRow("add multiple @ start") << 10 << 0 << 3 << ListRange(0, 9);
+ QTest::newRow("add multiple @ middle") << 10 << 5 << 3 << ListRange(5, 9);
+ QTest::newRow("add multiple @ end") << 10 << 10 << 3 << ListRange();
+}
+
+void tst_qquickpositioners::moveTransitions(const QString &positionerObjectName)
+{
+ QFETCH(int, initialItemCount);
+ QFETCH(ListChange, change);
+ QFETCH(ListRange, expectedDisplacedIndexes);
+
+ QPointF targetItems_transitionFrom(-50, -50);
+ QPointF displacedItems_transitionVia(100, 100);
+
+ QaimModel model;
+ for (int i = 0; i < initialItemCount; i++)
+ model.addItem("Item" + QString::number(i), "");
+ QaimModel model_targetItems_transitionFrom;
+ QaimModel model_displacedItems_transitionVia;
+
+ QQuickView *canvas = QQuickViewTestUtil::createView();
+ QQmlContext *ctxt = canvas->rootContext();
+ ctxt->setContextProperty("enableAddTransition", false);
+ ctxt->setContextProperty("model_targetItems_transitionFrom", &model_targetItems_transitionFrom);
+ ctxt->setContextProperty("model_displacedItems_transitionVia", &model_displacedItems_transitionVia);
+ ctxt->setContextProperty("targetItems_transitionFrom", targetItems_transitionFrom);
+ ctxt->setContextProperty("displacedItems_transitionVia", displacedItems_transitionVia);
+ canvas->setSource(testFile("transitions.qml"));
+ canvas->show();
+ qApp->processEvents();
+
+ QList<QPair<QString,QString> > expectedDisplacedValues = expectedDisplacedIndexes.getModelDataValues(model);
+
+ QQuickItem *positioner = canvas->rootObject()->findChild<QQuickItem*>(positionerObjectName);
+ QVERIFY(positioner);
+ positioner->findChild<QQuickItem*>("repeater")->setProperty("model", QVariant::fromValue(&model));
+ QTRY_COMPARE(QQuickItemPrivate::get(positioner)->polishScheduled, false);
+
+ switch (change.type) {
+ case ListChange::Removed:
+ model.removeItems(change.index, change.count);
+ QTRY_COMPARE(model.count(), positioner->property("count").toInt());
+ break;
+ case ListChange::Moved:
+ model.moveItems(change.index, change.to, change.count);
+ QTRY_COMPARE(QQuickItemPrivate::get(positioner)->polishScheduled, false);
+ break;
+ case ListChange::Inserted:
+ case ListChange::SetCurrent:
+ case ListChange::SetContentY:
+ QVERIFY(false);
+ break;
+ }
+
+ QTRY_COMPARE(canvas->rootObject()->property("displaceTransitionsDone").toInt(), expectedDisplacedIndexes.count());
+ QCOMPARE(canvas->rootObject()->property("targetTransitionsDone").toInt(), 0);
+
+ // check the target and displaced items were animated
+ QCOMPARE(model_targetItems_transitionFrom.count(), 0);
+ model_displacedItems_transitionVia.matchAgainst(expectedDisplacedValues, "wasn't animated with displaced anim", "shouldn't have been animated with displaced anim");
+
+ // check attached properties
+ QCOMPARE(canvas->rootObject()->property("targetTrans_items").toMap().count(), 0);
+ QCOMPARE(canvas->rootObject()->property("targetTrans_targetIndexes").toList().count(), 0);
+ QCOMPARE(canvas->rootObject()->property("targetTrans_targetItems").toList().count(), 0);
+ if (expectedDisplacedIndexes.isValid()) {
+ // adjust expectedDisplacedIndexes to their final values after the move
+ QList<int> displacedIndexes;
+ if (change.type == ListChange::Inserted)
+ displacedIndexes = adjustIndexesForAddDisplaced(expectedDisplacedIndexes.indexes, change.index, change.count);
+ else if (change.type == ListChange::Moved)
+ displacedIndexes = adjustIndexesForMove(expectedDisplacedIndexes.indexes, change.index, change.to, change.count);
+ else if (change.type == ListChange::Removed)
+ displacedIndexes = adjustIndexesForRemoveDisplaced(expectedDisplacedIndexes.indexes, change.index, change.count);
+ else
+ QVERIFY(false);
+ matchItemsAndIndexes(canvas->rootObject()->property("displacedTrans_items").toMap(), model, displacedIndexes);
+
+ QVariantList listOfEmptyIntLists;
+ for (int i=0; i<displacedIndexes.count(); i++)
+ listOfEmptyIntLists << QVariant::fromValue(QList<int>());
+ QCOMPARE(canvas->rootObject()->property("displacedTrans_targetIndexes").toList(), listOfEmptyIntLists);
+ QVariantList listOfEmptyObjectLists;
+ for (int i=0; i<displacedIndexes.count(); i++)
+ listOfEmptyObjectLists.insert(listOfEmptyObjectLists.count(), QVariantList());
+ QCOMPARE(canvas->rootObject()->property("displacedTrans_targetItems").toList(), listOfEmptyObjectLists);
+ }
+
+ checkItemPositions(positioner, &model, 5.0);
+
+ delete canvas;
+}
+
+void tst_qquickpositioners::moveTransitions_data()
+{
+ // If this data changes, update moveTransitions_grid_data() also
+
+ QTest::addColumn<int>("initialItemCount");
+ QTest::addColumn<ListChange>("change");
+ QTest::addColumn<ListRange>("expectedDisplacedIndexes");
+
+ QTest::newRow("remove one @ start") << 10 << ListChange::remove(0, 1) << ListRange(1, 9);
+ QTest::newRow("remove one @ middle") << 10 << ListChange::remove(4, 1) << ListRange(5, 9);
+ QTest::newRow("remove one @ end") << 10 << ListChange::remove(9, 1) << ListRange();
+
+ QTest::newRow("remove multiple @ start") << 10 << ListChange::remove(0, 3) << ListRange(3, 9);
+ QTest::newRow("remove multiple @ middle") << 10 << ListChange::remove(4, 3) << ListRange(7, 9);
+ QTest::newRow("remove multiple @ end") << 10 << ListChange::remove(7, 3) << ListRange();
+}
+
+
+void tst_qquickpositioners::checkItemPositions(QQuickItem *positioner, QaimModel *model, qreal incrementalSize)
+{
+ QVERIFY(model->count() > 0);
+ qreal padding = 0;
+ qreal currentSize = 30;
+ qreal rowX = 0;
+ qreal rowY = 0;
+
+ for (int i=0; i<model->count(); ++i) {
+ QQuickItem *item = findItem<QQuickItem>(positioner, "wrapper", i);
+ QVERIFY2(item, QTest::toString(QString("Item %1 not found").arg(i)));
+
+ QCOMPARE(item->width(), currentSize);
+ QCOMPARE(item->height(), currentSize);
+
+ if (qobject_cast<QQuickRow*>(positioner)) {
+ QCOMPARE(item->x(), (i * 30.0) + padding);
+ QCOMPARE(item->y(), 0.0);
+ } else if (qobject_cast<QQuickColumn*>(positioner)) {
+ QCOMPARE(item->x(), 0.0);
+ QCOMPARE(item->y(), (i * 30.0) + padding);
+ } else if (qobject_cast<QQuickGrid*>(positioner)) {
+ int columns = 4;
+ int rows = qCeil(model->count() / qreal(columns));
+ int lastMatchingRowIndex = (rows * columns) - (columns - i%columns);
+ if (lastMatchingRowIndex >= model->count())
+ lastMatchingRowIndex -= columns;
+ if (i % columns > 0) {
+ QQuickItem *finalAlignedRowItem = findItem<QQuickItem>(positioner, "wrapper", lastMatchingRowIndex);
+ QVERIFY(finalAlignedRowItem);
+ QCOMPARE(item->x(), finalAlignedRowItem->x());
+ } else {
+ QCOMPARE(item->x(), 0.0);
+ }
+ if (i / columns > 0) {
+ QQuickItem *prevRowLastItem = findItem<QQuickItem>(positioner, "wrapper", (i/columns * columns) - 1);
+ QVERIFY(prevRowLastItem);
+ QCOMPARE(item->y(), prevRowLastItem->y() + prevRowLastItem->height());
+ } else {
+ QCOMPARE(item->y(), 0.0);
+ }
+ } else if (qobject_cast<QQuickFlow*>(positioner)) {
+ if (rowX + item->width() > positioner->width()) {
+ QQuickItem *prevItem = findItem<QQuickItem>(positioner, "wrapper", i-1);
+ QVERIFY(prevItem);
+ rowX = 0;
+ rowY = prevItem->y() + prevItem->height();
+ }
+ QCOMPARE(item->x(), rowX);
+ QCOMPARE(item->y(), rowY);
+ rowX += item->width();
+ } else {
+ QVERIFY2(false, "Unknown positioner type");
+ }
+ QQuickText *name = findItem<QQuickText>(positioner, "name", i);
+ QVERIFY(name != 0);
+ QTRY_COMPARE(name->text(), model->name(i));
+
+ padding += i * incrementalSize;
+ currentSize += incrementalSize;
+ }
+}
+
+void tst_qquickpositioners::test_vertical()
+{
+ QQuickView *canvas = createView(testFile("vertical.qml"));
+
+ QQuickRectangle *one = canvas->rootObject()->findChild<QQuickRectangle*>("one");
+ QVERIFY(one != 0);
+
+ QQuickRectangle *two = canvas->rootObject()->findChild<QQuickRectangle*>("two");
+ QVERIFY(two != 0);
+
+ QQuickRectangle *three = canvas->rootObject()->findChild<QQuickRectangle*>("three");
+ QVERIFY(three != 0);
+
+ QCOMPARE(one->x(), 0.0);
+ QCOMPARE(one->y(), 0.0);
+ QCOMPARE(two->x(), 0.0);
+ QCOMPARE(two->y(), 50.0);
+ QCOMPARE(three->x(), 0.0);
+ QCOMPARE(three->y(), 60.0);
+
+ QQuickItem *column = canvas->rootObject()->findChild<QQuickItem*>("column");
+ QVERIFY(column);
+ QCOMPARE(column->height(), 80.0);
+ QCOMPARE(column->width(), 50.0);
+
+ delete canvas;
+}
+
+void tst_qquickpositioners::test_vertical_spacing()
+{
+ QQuickView *canvas = createView(testFile("vertical-spacing.qml"));
+
+ QQuickRectangle *one = canvas->rootObject()->findChild<QQuickRectangle*>("one");
+ QVERIFY(one != 0);
+
+ QQuickRectangle *two = canvas->rootObject()->findChild<QQuickRectangle*>("two");
+ QVERIFY(two != 0);
+
+ QQuickRectangle *three = canvas->rootObject()->findChild<QQuickRectangle*>("three");
+ QVERIFY(three != 0);
+
+ QCOMPARE(one->x(), 0.0);
+ QCOMPARE(one->y(), 0.0);
+ QCOMPARE(two->x(), 0.0);
+ QCOMPARE(two->y(), 60.0);
+ QCOMPARE(three->x(), 0.0);
+ QCOMPARE(three->y(), 80.0);
+
+ QQuickItem *column = canvas->rootObject()->findChild<QQuickItem*>("column");
+ QCOMPARE(column->height(), 100.0);
+ QCOMPARE(column->width(), 50.0);
+
+ delete canvas;
+}
+
+void tst_qquickpositioners::test_vertical_animated()
+{
+ QQuickView *canvas = createView(testFile("vertical-animated.qml"), false);
+
+ //Note that they animate in
+ QQuickRectangle *one = canvas->rootObject()->findChild<QQuickRectangle*>("one");
+ QVERIFY(one != 0);
+ QCOMPARE(one->y(), -100.0);
+
+ QQuickRectangle *two = canvas->rootObject()->findChild<QQuickRectangle*>("two");
+ QVERIFY(two != 0);
+ QCOMPARE(two->y(), -100.0);
+
+ QQuickRectangle *three = canvas->rootObject()->findChild<QQuickRectangle*>("three");
+ QVERIFY(three != 0);
+ QCOMPARE(three->y(), -100.0);
+
+ QTest::qWaitForWindowShown(canvas); //It may not relayout until the next frame, so it needs to be drawn
+
+ QQuickItem *column = canvas->rootObject()->findChild<QQuickItem*>("column");
+ QVERIFY(column);
+ QCOMPARE(column->height(), 100.0);
+ QCOMPARE(column->width(), 50.0);
+
+ //QTRY_COMPARE used instead of waiting for the expected time of animation completion
+ //Note that this means the duration of the animation is NOT tested
+
+ QTRY_COMPARE(one->y(), 0.0);
+ QTRY_COMPARE(one->x(), 0.0);
+ QTRY_COMPARE(two->isVisible(), false);
+ QTRY_COMPARE(two->y(), -100.0);//Not 'in' yet
+ QTRY_COMPARE(two->x(), 0.0);
+ QTRY_COMPARE(three->y(), 50.0);
+ QTRY_COMPARE(three->x(), 0.0);
+
+ //Add 'two'
+ two->setVisible(true);
+ QTRY_COMPARE(two->isVisible(), true);
+ QTRY_COMPARE(column->height(), 150.0);
+ QTRY_COMPARE(column->width(), 50.0);
+ QTest::qWait(0);//Let the animation start
+ QVERIFY(two->y() >= -100.0 && two->y() < 50.0);
+ QVERIFY(three->y() >= 50.0 && three->y() < 100.0);
+
+ QTRY_COMPARE(two->y(), 50.0);
+ QTRY_COMPARE(three->y(), 100.0);
+
+ delete canvas;
+}
+
+void tst_qquickpositioners::test_grid()
+{
+ QQuickView *canvas = createView(testFile("gridtest.qml"));
+
+ QQuickRectangle *one = canvas->rootObject()->findChild<QQuickRectangle*>("one");
+ QVERIFY(one != 0);
+ QQuickRectangle *two = canvas->rootObject()->findChild<QQuickRectangle*>("two");
+ QVERIFY(two != 0);
+ QQuickRectangle *three = canvas->rootObject()->findChild<QQuickRectangle*>("three");
+ QVERIFY(three != 0);
+ QQuickRectangle *four = canvas->rootObject()->findChild<QQuickRectangle*>("four");
+ QVERIFY(four != 0);
+ QQuickRectangle *five = canvas->rootObject()->findChild<QQuickRectangle*>("five");
+ QVERIFY(five != 0);
+
+ QCOMPARE(one->x(), 0.0);
+ QCOMPARE(one->y(), 0.0);
+ QCOMPARE(two->x(), 50.0);
+ QCOMPARE(two->y(), 0.0);
+ QCOMPARE(three->x(), 70.0);
+ QCOMPARE(three->y(), 0.0);
+ QCOMPARE(four->x(), 0.0);
+ QCOMPARE(four->y(), 50.0);
+ QCOMPARE(five->x(), 50.0);
+ QCOMPARE(five->y(), 50.0);
+
+ QQuickGrid *grid = canvas->rootObject()->findChild<QQuickGrid*>("grid");
+ QCOMPARE(grid->flow(), QQuickGrid::LeftToRight);
+ QCOMPARE(grid->width(), 100.0);
+ QCOMPARE(grid->height(), 100.0);
+
+ delete canvas;
+}
+
+void tst_qquickpositioners::test_grid_topToBottom()
+{
+ QQuickView *canvas = createView(testFile("grid-toptobottom.qml"));
+
+ QQuickRectangle *one = canvas->rootObject()->findChild<QQuickRectangle*>("one");
+ QVERIFY(one != 0);
+ QQuickRectangle *two = canvas->rootObject()->findChild<QQuickRectangle*>("two");
+ QVERIFY(two != 0);
+ QQuickRectangle *three = canvas->rootObject()->findChild<QQuickRectangle*>("three");
+ QVERIFY(three != 0);
+ QQuickRectangle *four = canvas->rootObject()->findChild<QQuickRectangle*>("four");
+ QVERIFY(four != 0);
+ QQuickRectangle *five = canvas->rootObject()->findChild<QQuickRectangle*>("five");
+ QVERIFY(five != 0);
+
+ QCOMPARE(one->x(), 0.0);
+ QCOMPARE(one->y(), 0.0);
+ QCOMPARE(two->x(), 0.0);
+ QCOMPARE(two->y(), 50.0);
+ QCOMPARE(three->x(), 0.0);
+ QCOMPARE(three->y(), 100.0);
+ QCOMPARE(four->x(), 50.0);
+ QCOMPARE(four->y(), 0.0);
+ QCOMPARE(five->x(), 50.0);
+ QCOMPARE(five->y(), 50.0);
+
+ QQuickGrid *grid = canvas->rootObject()->findChild<QQuickGrid*>("grid");
+ QCOMPARE(grid->flow(), QQuickGrid::TopToBottom);
+ QCOMPARE(grid->width(), 100.0);
+ QCOMPARE(grid->height(), 120.0);
+
+ delete canvas;
+}
+
+void tst_qquickpositioners::test_grid_rightToLeft()
+{
+ QQuickView *canvas = createView(testFile("gridtest.qml"));
+
+ canvas->rootObject()->setProperty("testRightToLeft", true);
+
+ QQuickRectangle *one = canvas->rootObject()->findChild<QQuickRectangle*>("one");
+ QVERIFY(one != 0);
+ QQuickRectangle *two = canvas->rootObject()->findChild<QQuickRectangle*>("two");
+ QVERIFY(two != 0);
+ QQuickRectangle *three = canvas->rootObject()->findChild<QQuickRectangle*>("three");
+ QVERIFY(three != 0);
+ QQuickRectangle *four = canvas->rootObject()->findChild<QQuickRectangle*>("four");
+ QVERIFY(four != 0);
+ QQuickRectangle *five = canvas->rootObject()->findChild<QQuickRectangle*>("five");
+ QVERIFY(five != 0);
+
+ QCOMPARE(one->x(), 50.0);
+ QCOMPARE(one->y(), 0.0);
+ QCOMPARE(two->x(), 30.0);
+ QCOMPARE(two->y(), 0.0);
+ QCOMPARE(three->x(), 0.0);
+ QCOMPARE(three->y(), 0.0);
+ QCOMPARE(four->x(), 50.0);
+ QCOMPARE(four->y(), 50.0);
+ QCOMPARE(five->x(), 40.0);
+ QCOMPARE(five->y(), 50.0);
+
+ QQuickGrid *grid = canvas->rootObject()->findChild<QQuickGrid*>("grid");
+ QCOMPARE(grid->layoutDirection(), Qt::RightToLeft);
+ QCOMPARE(grid->width(), 100.0);
+ QCOMPARE(grid->height(), 100.0);
+
+ // Change the width of the grid and check that items stay to the right
+ grid->setWidth(200);
+ QTRY_COMPARE(one->x(), 150.0);
+ QCOMPARE(one->y(), 0.0);
+ QCOMPARE(two->x(), 130.0);
+ QCOMPARE(two->y(), 0.0);
+ QCOMPARE(three->x(), 100.0);
+ QCOMPARE(three->y(), 0.0);
+ QCOMPARE(four->x(), 150.0);
+ QCOMPARE(four->y(), 50.0);
+ QCOMPARE(five->x(), 140.0);
+ QCOMPARE(five->y(), 50.0);
+
+ delete canvas;
+}
+
+void tst_qquickpositioners::test_grid_spacing()
+{
+ QQuickView *canvas = createView(testFile("grid-spacing.qml"));
+
+ QQuickRectangle *one = canvas->rootObject()->findChild<QQuickRectangle*>("one");
+ QVERIFY(one != 0);
+ QQuickRectangle *two = canvas->rootObject()->findChild<QQuickRectangle*>("two");
+ QVERIFY(two != 0);
+ QQuickRectangle *three = canvas->rootObject()->findChild<QQuickRectangle*>("three");
+ QVERIFY(three != 0);
+ QQuickRectangle *four = canvas->rootObject()->findChild<QQuickRectangle*>("four");
+ QVERIFY(four != 0);
+ QQuickRectangle *five = canvas->rootObject()->findChild<QQuickRectangle*>("five");
+ QVERIFY(five != 0);
+
+ QCOMPARE(one->x(), 0.0);
+ QCOMPARE(one->y(), 0.0);
+ QCOMPARE(two->x(), 54.0);
+ QCOMPARE(two->y(), 0.0);
+ QCOMPARE(three->x(), 78.0);
+ QCOMPARE(three->y(), 0.0);
+ QCOMPARE(four->x(), 0.0);
+ QCOMPARE(four->y(), 54.0);
+ QCOMPARE(five->x(), 54.0);
+ QCOMPARE(five->y(), 54.0);
+
+ QQuickItem *grid = canvas->rootObject()->findChild<QQuickItem*>("grid");
+ QCOMPARE(grid->width(), 128.0);
+ QCOMPARE(grid->height(), 104.0);
+
+ delete canvas;
+}
+
+void tst_qquickpositioners::test_grid_row_column_spacing()
+{
+ QQuickView *canvas = createView(testFile("grid-row-column-spacing.qml"));
+
+ QQuickRectangle *one = canvas->rootObject()->findChild<QQuickRectangle*>("one");
+ QVERIFY(one != 0);
+ QQuickRectangle *two = canvas->rootObject()->findChild<QQuickRectangle*>("two");
+ QVERIFY(two != 0);
+ QQuickRectangle *three = canvas->rootObject()->findChild<QQuickRectangle*>("three");
+ QVERIFY(three != 0);
+ QQuickRectangle *four = canvas->rootObject()->findChild<QQuickRectangle*>("four");
+ QVERIFY(four != 0);
+ QQuickRectangle *five = canvas->rootObject()->findChild<QQuickRectangle*>("five");
+ QVERIFY(five != 0);
+
+ QCOMPARE(one->x(), 0.0);
+ QCOMPARE(one->y(), 0.0);
+ QCOMPARE(two->x(), 61.0);
+ QCOMPARE(two->y(), 0.0);
+ QCOMPARE(three->x(), 92.0);
+ QCOMPARE(three->y(), 0.0);
+ QCOMPARE(four->x(), 0.0);
+ QCOMPARE(four->y(), 57.0);
+ QCOMPARE(five->x(), 61.0);
+ QCOMPARE(five->y(), 57.0);
+
+ QQuickItem *grid = canvas->rootObject()->findChild<QQuickItem*>("grid");
+ QCOMPARE(grid->width(), 142.0);
+ QCOMPARE(grid->height(), 107.0);
+
+ delete canvas;
+}
+
+void tst_qquickpositioners::test_grid_animated()
+{
+ QQuickView *canvas = createView(testFile("grid-animated.qml"), false);
+
+ canvas->rootObject()->setProperty("testRightToLeft", false);
+
+ //Note that all animate in
+ QQuickRectangle *one = canvas->rootObject()->findChild<QQuickRectangle*>("one");
+ QVERIFY(one != 0);
+ QCOMPARE(one->x(), -100.0);
+ QCOMPARE(one->y(), -100.0);
+
+ QQuickRectangle *two = canvas->rootObject()->findChild<QQuickRectangle*>("two");
+ QVERIFY(two != 0);
+ QCOMPARE(two->x(), -100.0);
+ QCOMPARE(two->y(), -100.0);
+
+ QQuickRectangle *three = canvas->rootObject()->findChild<QQuickRectangle*>("three");
+ QVERIFY(three != 0);
+ QCOMPARE(three->x(), -100.0);
+ QCOMPARE(three->y(), -100.0);
+
+ QQuickRectangle *four = canvas->rootObject()->findChild<QQuickRectangle*>("four");
+ QVERIFY(four != 0);
+ QCOMPARE(four->x(), -100.0);
+ QCOMPARE(four->y(), -100.0);
+
+ QQuickRectangle *five = canvas->rootObject()->findChild<QQuickRectangle*>("five");
+ QVERIFY(five != 0);
+ QCOMPARE(five->x(), -100.0);
+ QCOMPARE(five->y(), -100.0);
+
+ QTest::qWaitForWindowShown(canvas); //It may not relayout until the next frame, so it needs to be drawn
+
+ QQuickItem *grid = canvas->rootObject()->findChild<QQuickItem*>("grid");
+ QVERIFY(grid);
+ QCOMPARE(grid->width(), 150.0);
+ QCOMPARE(grid->height(), 100.0);
+
+ //QTRY_COMPARE used instead of waiting for the expected time of animation completion
+ //Note that this means the duration of the animation is NOT tested
+
+ QTRY_COMPARE(one->y(), 0.0);
+ QTRY_COMPARE(one->x(), 0.0);
+ QTRY_COMPARE(two->isVisible(), false);
+ QTRY_COMPARE(two->y(), -100.0);
+ QTRY_COMPARE(two->x(), -100.0);
+ QTRY_COMPARE(three->y(), 0.0);
+ QTRY_COMPARE(three->x(), 50.0);
+ QTRY_COMPARE(four->y(), 0.0);
+ QTRY_COMPARE(four->x(), 100.0);
+ QTRY_COMPARE(five->y(), 50.0);
+ QTRY_COMPARE(five->x(), 0.0);
+
+ //Add 'two'
+ two->setVisible(true);
+ QCOMPARE(two->isVisible(), true);
+ QCOMPARE(grid->width(), 150.0);
+ QCOMPARE(grid->height(), 100.0);
+ QTest::qWait(0);//Let the animation start
+ QCOMPARE(two->x(), -100.0);
+ QCOMPARE(two->y(), -100.0);
+ QCOMPARE(one->x(), 0.0);
+ QCOMPARE(one->y(), 0.0);
+ QCOMPARE(three->x(), 50.0);
+ QCOMPARE(three->y(), 0.0);
+ QCOMPARE(four->x(), 100.0);
+ QCOMPARE(four->y(), 0.0);
+ QCOMPARE(five->x(), 0.0);
+ QCOMPARE(five->y(), 50.0);
+ //Let the animation complete
+ QTRY_COMPARE(two->x(), 50.0);
+ QTRY_COMPARE(two->y(), 0.0);
+ QTRY_COMPARE(one->x(), 0.0);
+ QTRY_COMPARE(one->y(), 0.0);
+ QTRY_COMPARE(three->x(), 100.0);
+ QTRY_COMPARE(three->y(), 0.0);
+ QTRY_COMPARE(four->x(), 0.0);
+ QTRY_COMPARE(four->y(), 50.0);
+ QTRY_COMPARE(five->x(), 50.0);
+ QTRY_COMPARE(five->y(), 50.0);
+
+ delete canvas;
+}
+
+void tst_qquickpositioners::test_grid_animated_rightToLeft()
+{
+ QQuickView *canvas = createView(testFile("grid-animated.qml"), false);
+
+ canvas->rootObject()->setProperty("testRightToLeft", true);
+
+ //Note that all animate in
+ QQuickRectangle *one = canvas->rootObject()->findChild<QQuickRectangle*>("one");
+ QVERIFY(one != 0);
+ QCOMPARE(one->x(), -100.0);
+ QCOMPARE(one->y(), -100.0);
+
+ QQuickRectangle *two = canvas->rootObject()->findChild<QQuickRectangle*>("two");
+ QVERIFY(two != 0);
+ QCOMPARE(two->x(), -100.0);
+ QCOMPARE(two->y(), -100.0);
+
+ QQuickRectangle *three = canvas->rootObject()->findChild<QQuickRectangle*>("three");
+ QVERIFY(three != 0);
+ QCOMPARE(three->x(), -100.0);
+ QCOMPARE(three->y(), -100.0);
+
+ QQuickRectangle *four = canvas->rootObject()->findChild<QQuickRectangle*>("four");
+ QVERIFY(four != 0);
+ QCOMPARE(four->x(), -100.0);
+ QCOMPARE(four->y(), -100.0);
+
+ QQuickRectangle *five = canvas->rootObject()->findChild<QQuickRectangle*>("five");
+ QVERIFY(five != 0);
+ QCOMPARE(five->x(), -100.0);
+ QCOMPARE(five->y(), -100.0);
+
+ QTest::qWaitForWindowShown(canvas); //It may not relayout until the next frame, so it needs to be drawn
+
+ QQuickItem *grid = canvas->rootObject()->findChild<QQuickItem*>("grid");
+ QVERIFY(grid);
+ QCOMPARE(grid->width(), 150.0);
+ QCOMPARE(grid->height(), 100.0);
+
+ //QTRY_COMPARE used instead of waiting for the expected time of animation completion
+ //Note that this means the duration of the animation is NOT tested
+
+ QTRY_COMPARE(one->y(), 0.0);
+ QTRY_COMPARE(one->x(), 100.0);
+ QTRY_COMPARE(two->isVisible(), false);
+ QTRY_COMPARE(two->y(), -100.0);
+ QTRY_COMPARE(two->x(), -100.0);
+ QTRY_COMPARE(three->y(), 0.0);
+ QTRY_COMPARE(three->x(), 50.0);
+ QTRY_COMPARE(four->y(), 0.0);
+ QTRY_COMPARE(four->x(), 0.0);
+ QTRY_COMPARE(five->y(), 50.0);
+ QTRY_COMPARE(five->x(), 100.0);
+
+ //Add 'two'
+ two->setVisible(true);
+ QCOMPARE(two->isVisible(), true);
+ QCOMPARE(grid->width(), 150.0);
+ QCOMPARE(grid->height(), 100.0);
+ QTest::qWait(0);//Let the animation start
+ QCOMPARE(two->x(), -100.0);
+ QCOMPARE(two->y(), -100.0);
+ QCOMPARE(one->x(), 100.0);
+ QCOMPARE(one->y(), 0.0);
+ QCOMPARE(three->x(), 50.0);
+ QCOMPARE(three->y(), 0.0);
+ QCOMPARE(four->x(), 0.0);
+ QCOMPARE(four->y(), 0.0);
+ QCOMPARE(five->x(), 100.0);
+ QCOMPARE(five->y(), 50.0);
+ //Let the animation complete
+ QTRY_COMPARE(two->x(), 50.0);
+ QTRY_COMPARE(two->y(), 0.0);
+ QTRY_COMPARE(one->x(), 100.0);
+ QTRY_COMPARE(one->y(), 0.0);
+ QTRY_COMPARE(three->x(), 0.0);
+ QTRY_COMPARE(three->y(), 0.0);
+ QTRY_COMPARE(four->x(), 100.0);
+ QTRY_COMPARE(four->y(), 50.0);
+ QTRY_COMPARE(five->x(), 50.0);
+ QTRY_COMPARE(five->y(), 50.0);
+
+ delete canvas;
+}
+
+void tst_qquickpositioners::test_grid_zero_columns()
+{
+ QQuickView *canvas = createView(testFile("gridzerocolumns.qml"));
+
+ QQuickRectangle *one = canvas->rootObject()->findChild<QQuickRectangle*>("one");
+ QVERIFY(one != 0);
+ QQuickRectangle *two = canvas->rootObject()->findChild<QQuickRectangle*>("two");
+ QVERIFY(two != 0);
+ QQuickRectangle *three = canvas->rootObject()->findChild<QQuickRectangle*>("three");
+ QVERIFY(three != 0);
+ QQuickRectangle *four = canvas->rootObject()->findChild<QQuickRectangle*>("four");
+ QVERIFY(four != 0);
+ QQuickRectangle *five = canvas->rootObject()->findChild<QQuickRectangle*>("five");
+ QVERIFY(five != 0);
+
+ QCOMPARE(one->x(), 0.0);
+ QCOMPARE(one->y(), 0.0);
+ QCOMPARE(two->x(), 50.0);
+ QCOMPARE(two->y(), 0.0);
+ QCOMPARE(three->x(), 70.0);
+ QCOMPARE(three->y(), 0.0);
+ QCOMPARE(four->x(), 120.0);
+ QCOMPARE(four->y(), 0.0);
+ QCOMPARE(five->x(), 0.0);
+ QCOMPARE(five->y(), 50.0);
+
+ QQuickItem *grid = canvas->rootObject()->findChild<QQuickItem*>("grid");
+ QCOMPARE(grid->width(), 170.0);
+ QCOMPARE(grid->height(), 60.0);
+
+ delete canvas;
+}
+
+void tst_qquickpositioners::test_propertychanges()
+{
+ QQuickView *canvas = createView(testFile("propertychangestest.qml"));
+
+ QQuickGrid *grid = qobject_cast<QQuickGrid*>(canvas->rootObject());
+ QVERIFY(grid != 0);
+ QQuickTransition *rowTransition = canvas->rootObject()->findChild<QQuickTransition*>("rowTransition");
+ QQuickTransition *columnTransition = canvas->rootObject()->findChild<QQuickTransition*>("columnTransition");
+
+ QSignalSpy addSpy(grid, SIGNAL(addChanged()));
+ QSignalSpy moveSpy(grid, SIGNAL(moveChanged()));
+ QSignalSpy columnsSpy(grid, SIGNAL(columnsChanged()));
+ QSignalSpy rowsSpy(grid, SIGNAL(rowsChanged()));
+
+ QVERIFY(grid);
+ QVERIFY(rowTransition);
+ QVERIFY(columnTransition);
+ QCOMPARE(grid->add(), columnTransition);
+ QCOMPARE(grid->move(), columnTransition);
+ QCOMPARE(grid->columns(), 4);
+ QCOMPARE(grid->rows(), -1);
+
+ grid->setAdd(rowTransition);
+ grid->setMove(rowTransition);
+ QCOMPARE(grid->add(), rowTransition);
+ QCOMPARE(grid->move(), rowTransition);
+ QCOMPARE(addSpy.count(),1);
+ QCOMPARE(moveSpy.count(),1);
+
+ grid->setAdd(rowTransition);
+ grid->setMove(rowTransition);
+ QCOMPARE(addSpy.count(),1);
+ QCOMPARE(moveSpy.count(),1);
+
+ grid->setAdd(0);
+ grid->setMove(0);
+ QCOMPARE(addSpy.count(),2);
+ QCOMPARE(moveSpy.count(),2);
+
+ grid->setColumns(-1);
+ grid->setRows(3);
+ QCOMPARE(grid->columns(), -1);
+ QCOMPARE(grid->rows(), 3);
+ QCOMPARE(columnsSpy.count(),1);
+ QCOMPARE(rowsSpy.count(),1);
+
+ grid->setColumns(-1);
+ grid->setRows(3);
+ QCOMPARE(columnsSpy.count(),1);
+ QCOMPARE(rowsSpy.count(),1);
+
+ grid->setColumns(2);
+ grid->setRows(2);
+ QCOMPARE(columnsSpy.count(),2);
+ QCOMPARE(rowsSpy.count(),2);
+
+ delete canvas;
+}
+
+void tst_qquickpositioners::test_repeater()
+{
+ QQuickView *canvas = createView(testFile("repeatertest.qml"));
+
+ QQuickRectangle *one = canvas->rootObject()->findChild<QQuickRectangle*>("one");
+ QVERIFY(one != 0);
+
+ QQuickRectangle *two = canvas->rootObject()->findChild<QQuickRectangle*>("two");
+ QVERIFY(two != 0);
+
+ QQuickRectangle *three = canvas->rootObject()->findChild<QQuickRectangle*>("three");
+ QVERIFY(three != 0);
+
+ QCOMPARE(one->x(), 0.0);
+ QCOMPARE(one->y(), 0.0);
+ QCOMPARE(two->x(), 50.0);
+ QCOMPARE(two->y(), 0.0);
+ QCOMPARE(three->x(), 100.0);
+ QCOMPARE(three->y(), 0.0);
+
+ delete canvas;
+}
+
+void tst_qquickpositioners::test_flow()
+{
+ QQuickView *canvas = createView(testFile("flowtest.qml"));
+
+ canvas->rootObject()->setProperty("testRightToLeft", false);
+
+ QQuickRectangle *one = canvas->rootObject()->findChild<QQuickRectangle*>("one");
+ QVERIFY(one != 0);
+ QQuickRectangle *two = canvas->rootObject()->findChild<QQuickRectangle*>("two");
+ QVERIFY(two != 0);
+ QQuickRectangle *three = canvas->rootObject()->findChild<QQuickRectangle*>("three");
+ QVERIFY(three != 0);
+ QQuickRectangle *four = canvas->rootObject()->findChild<QQuickRectangle*>("four");
+ QVERIFY(four != 0);
+ QQuickRectangle *five = canvas->rootObject()->findChild<QQuickRectangle*>("five");
+ QVERIFY(five != 0);
+
+ QCOMPARE(one->x(), 0.0);
+ QCOMPARE(one->y(), 0.0);
+ QCOMPARE(two->x(), 50.0);
+ QCOMPARE(two->y(), 0.0);
+ QCOMPARE(three->x(), 0.0);
+ QCOMPARE(three->y(), 50.0);
+ QCOMPARE(four->x(), 0.0);
+ QCOMPARE(four->y(), 70.0);
+ QCOMPARE(five->x(), 50.0);
+ QCOMPARE(five->y(), 70.0);
+
+ QQuickItem *flow = canvas->rootObject()->findChild<QQuickItem*>("flow");
+ QVERIFY(flow);
+ QCOMPARE(flow->width(), 90.0);
+ QCOMPARE(flow->height(), 120.0);
+
+ delete canvas;
+}
+
+void tst_qquickpositioners::test_flow_rightToLeft()
+{
+ QQuickView *canvas = createView(testFile("flowtest.qml"));
+
+ canvas->rootObject()->setProperty("testRightToLeft", true);
+
+ QQuickRectangle *one = canvas->rootObject()->findChild<QQuickRectangle*>("one");
+ QVERIFY(one != 0);
+ QQuickRectangle *two = canvas->rootObject()->findChild<QQuickRectangle*>("two");
+ QVERIFY(two != 0);
+ QQuickRectangle *three = canvas->rootObject()->findChild<QQuickRectangle*>("three");
+ QVERIFY(three != 0);
+ QQuickRectangle *four = canvas->rootObject()->findChild<QQuickRectangle*>("four");
+ QVERIFY(four != 0);
+ QQuickRectangle *five = canvas->rootObject()->findChild<QQuickRectangle*>("five");
+ QVERIFY(five != 0);
+
+ QCOMPARE(one->x(), 40.0);
+ QCOMPARE(one->y(), 0.0);
+ QCOMPARE(two->x(), 20.0);
+ QCOMPARE(two->y(), 0.0);
+ QCOMPARE(three->x(), 40.0);
+ QCOMPARE(three->y(), 50.0);
+ QCOMPARE(four->x(), 40.0);
+ QCOMPARE(four->y(), 70.0);
+ QCOMPARE(five->x(), 30.0);
+ QCOMPARE(five->y(), 70.0);
+
+ QQuickItem *flow = canvas->rootObject()->findChild<QQuickItem*>("flow");
+ QVERIFY(flow);
+ QCOMPARE(flow->width(), 90.0);
+ QCOMPARE(flow->height(), 120.0);
+
+ delete canvas;
+}
+
+void tst_qquickpositioners::test_flow_topToBottom()
+{
+ QQuickView *canvas = createView(testFile("flowtest-toptobottom.qml"));
+
+ canvas->rootObject()->setProperty("testRightToLeft", false);
+
+ QQuickRectangle *one = canvas->rootObject()->findChild<QQuickRectangle*>("one");
+ QVERIFY(one != 0);
+ QQuickRectangle *two = canvas->rootObject()->findChild<QQuickRectangle*>("two");
+ QVERIFY(two != 0);
+ QQuickRectangle *three = canvas->rootObject()->findChild<QQuickRectangle*>("three");
+ QVERIFY(three != 0);
+ QQuickRectangle *four = canvas->rootObject()->findChild<QQuickRectangle*>("four");
+ QVERIFY(four != 0);
+ QQuickRectangle *five = canvas->rootObject()->findChild<QQuickRectangle*>("five");
+ QVERIFY(five != 0);
+
+ QCOMPARE(one->x(), 0.0);
+ QCOMPARE(one->y(), 0.0);
+ QCOMPARE(two->x(), 50.0);
+ QCOMPARE(two->y(), 0.0);
+ QCOMPARE(three->x(), 50.0);
+ QCOMPARE(three->y(), 50.0);
+ QCOMPARE(four->x(), 100.0);
+ QCOMPARE(four->y(), 00.0);
+ QCOMPARE(five->x(), 100.0);
+ QCOMPARE(five->y(), 50.0);
+
+ QQuickItem *flow = canvas->rootObject()->findChild<QQuickItem*>("flow");
+ QVERIFY(flow);
+ QCOMPARE(flow->height(), 90.0);
+ QCOMPARE(flow->width(), 150.0);
+
+ canvas->rootObject()->setProperty("testRightToLeft", true);
+
+ QVERIFY(flow);
+ QCOMPARE(flow->height(), 90.0);
+ QCOMPARE(flow->width(), 150.0);
+
+ QCOMPARE(one->x(), 100.0);
+ QCOMPARE(one->y(), 0.0);
+ QCOMPARE(two->x(), 80.0);
+ QCOMPARE(two->y(), 0.0);
+ QCOMPARE(three->x(), 50.0);
+ QCOMPARE(three->y(), 50.0);
+ QCOMPARE(four->x(), 0.0);
+ QCOMPARE(four->y(), 0.0);
+ QCOMPARE(five->x(), 40.0);
+ QCOMPARE(five->y(), 50.0);
+
+ delete canvas;
+}
+
+void tst_qquickpositioners::test_flow_resize()
+{
+ QQuickView *canvas = createView(testFile("flowtest.qml"));
+
+ QQuickItem *root = qobject_cast<QQuickItem*>(canvas->rootObject());
+ QVERIFY(root);
+ root->setWidth(125);
+ root->setProperty("testRightToLeft", false);
+
+ QQuickRectangle *one = canvas->rootObject()->findChild<QQuickRectangle*>("one");
+ QVERIFY(one != 0);
+ QQuickRectangle *two = canvas->rootObject()->findChild<QQuickRectangle*>("two");
+ QVERIFY(two != 0);
+ QQuickRectangle *three = canvas->rootObject()->findChild<QQuickRectangle*>("three");
+ QVERIFY(three != 0);
+ QQuickRectangle *four = canvas->rootObject()->findChild<QQuickRectangle*>("four");
+ QVERIFY(four != 0);
+ QQuickRectangle *five = canvas->rootObject()->findChild<QQuickRectangle*>("five");
+ QVERIFY(five != 0);
+
+ QTRY_COMPARE(one->x(), 0.0);
+ QTRY_COMPARE(one->y(), 0.0);
+ QTRY_COMPARE(two->x(), 50.0);
+ QTRY_COMPARE(two->y(), 0.0);
+ QTRY_COMPARE(three->x(), 70.0);
+ QTRY_COMPARE(three->y(), 0.0);
+ QTRY_COMPARE(four->x(), 0.0);
+ QTRY_COMPARE(four->y(), 50.0);
+ QTRY_COMPARE(five->x(), 50.0);
+ QTRY_COMPARE(five->y(), 50.0);
+
+ delete canvas;
+}
+
+void tst_qquickpositioners::test_flow_resize_rightToLeft()
+{
+ QQuickView *canvas = createView(testFile("flowtest.qml"));
+
+ QQuickItem *root = qobject_cast<QQuickItem*>(canvas->rootObject());
+ QVERIFY(root);
+ root->setWidth(125);
+ root->setProperty("testRightToLeft", true);
+
+ QQuickRectangle *one = canvas->rootObject()->findChild<QQuickRectangle*>("one");
+ QTRY_VERIFY(one != 0);
+ QQuickRectangle *two = canvas->rootObject()->findChild<QQuickRectangle*>("two");
+ QVERIFY(two != 0);
+ QQuickRectangle *three = canvas->rootObject()->findChild<QQuickRectangle*>("three");
+ QVERIFY(three != 0);
+ QQuickRectangle *four = canvas->rootObject()->findChild<QQuickRectangle*>("four");
+ QVERIFY(four != 0);
+ QQuickRectangle *five = canvas->rootObject()->findChild<QQuickRectangle*>("five");
+ QVERIFY(five != 0);
+
+ QCOMPARE(one->x(), 75.0);
+ QCOMPARE(one->y(), 0.0);
+ QCOMPARE(two->x(), 55.0);
+ QCOMPARE(two->y(), 0.0);
+ QCOMPARE(three->x(), 5.0);
+ QCOMPARE(three->y(), 0.0);
+ QCOMPARE(four->x(), 75.0);
+ QCOMPARE(four->y(), 50.0);
+ QCOMPARE(five->x(), 65.0);
+ QCOMPARE(five->y(), 50.0);
+
+ delete canvas;
+}
+
+void tst_qquickpositioners::test_flow_implicit_resize()
+{
+ QQuickView *canvas = createView(testFile("flow-testimplicitsize.qml"));
+ QVERIFY(canvas->rootObject() != 0);
+
+ QQuickFlow *flow = canvas->rootObject()->findChild<QQuickFlow*>("flow");
+ QVERIFY(flow != 0);
+
+ QCOMPARE(flow->width(), 100.0);
+ QCOMPARE(flow->height(), 120.0);
+
+ canvas->rootObject()->setProperty("flowLayout", 0);
+ QCOMPARE(flow->flow(), QQuickFlow::LeftToRight);
+ QCOMPARE(flow->width(), 220.0);
+ QCOMPARE(flow->height(), 50.0);
+
+ canvas->rootObject()->setProperty("flowLayout", 1);
+ QCOMPARE(flow->flow(), QQuickFlow::TopToBottom);
+ QCOMPARE(flow->width(), 100.0);
+ QCOMPARE(flow->height(), 120.0);
+
+ canvas->rootObject()->setProperty("flowLayout", 2);
+ QCOMPARE(flow->layoutDirection(), Qt::RightToLeft);
+ QCOMPARE(flow->width(), 220.0);
+ QCOMPARE(flow->height(), 50.0);
+
+ delete canvas;
+}
+
+QString warningMessage;
+
+void interceptWarnings(QtMsgType type, const char *msg)
+{
+ Q_UNUSED( type );
+ warningMessage = msg;
+}
+
+void tst_qquickpositioners::test_conflictinganchors()
+{
+ QtMsgHandler oldMsgHandler = qInstallMsgHandler(interceptWarnings);
+ QQmlEngine engine;
+ QQmlComponent component(&engine);
+
+ component.setData("import QtQuick 2.0\nColumn { Item { width: 100; height: 100; } }", QUrl::fromLocalFile(""));
+ QQuickItem *item = qobject_cast<QQuickItem*>(component.create());
+ QVERIFY(item);
+ QVERIFY(warningMessage.isEmpty());
+ delete item;
+
+ component.setData("import QtQuick 2.0\nRow { Item { width: 100; height: 100; } }", QUrl::fromLocalFile(""));
+ item = qobject_cast<QQuickItem*>(component.create());
+ QVERIFY(item);
+ QVERIFY(warningMessage.isEmpty());
+ delete item;
+
+ component.setData("import QtQuick 2.0\nGrid { Item { width: 100; height: 100; } }", QUrl::fromLocalFile(""));
+ item = qobject_cast<QQuickItem*>(component.create());
+ QVERIFY(item);
+ QVERIFY(warningMessage.isEmpty());
+ delete item;
+
+ component.setData("import QtQuick 2.0\nFlow { Item { width: 100; height: 100; } }", QUrl::fromLocalFile(""));
+ item = qobject_cast<QQuickItem*>(component.create());
+ QVERIFY(item);
+ QVERIFY(warningMessage.isEmpty());
+ delete item;
+
+ component.setData("import QtQuick 2.0\nColumn { Item { width: 100; height: 100; anchors.top: parent.top } }", QUrl::fromLocalFile(""));
+ item = qobject_cast<QQuickItem*>(component.create());
+ QVERIFY(item);
+ QCOMPARE(warningMessage, QString("file::2:1: QML Column: Cannot specify top, bottom, verticalCenter, fill or centerIn anchors for items inside Column. Column will not function."));
+ warningMessage.clear();
+ delete item;
+
+ component.setData("import QtQuick 2.0\nColumn { Item { width: 100; height: 100; anchors.centerIn: parent } }", QUrl::fromLocalFile(""));
+ item = qobject_cast<QQuickItem*>(component.create());
+ QVERIFY(item);
+ QCOMPARE(warningMessage, QString("file::2:1: QML Column: Cannot specify top, bottom, verticalCenter, fill or centerIn anchors for items inside Column. Column will not function."));
+ warningMessage.clear();
+ delete item;
+
+ component.setData("import QtQuick 2.0\nColumn { Item { width: 100; height: 100; anchors.left: parent.left } }", QUrl::fromLocalFile(""));
+ item = qobject_cast<QQuickItem*>(component.create());
+ QVERIFY(item);
+ QVERIFY(warningMessage.isEmpty());
+ warningMessage.clear();
+ delete item;
+
+ component.setData("import QtQuick 2.0\nRow { Item { width: 100; height: 100; anchors.left: parent.left } }", QUrl::fromLocalFile(""));
+ item = qobject_cast<QQuickItem*>(component.create());
+ QVERIFY(item);
+ QCOMPARE(warningMessage, QString("file::2:1: QML Row: Cannot specify left, right, horizontalCenter, fill or centerIn anchors for items inside Row. Row will not function."));
+ warningMessage.clear();
+ delete item;
+
+ component.setData("import QtQuick 2.0\nRow { width: 100; height: 100; Item { anchors.fill: parent } }", QUrl::fromLocalFile(""));
+ item = qobject_cast<QQuickItem*>(component.create());
+ QVERIFY(item);
+ QCOMPARE(warningMessage, QString("file::2:1: QML Row: Cannot specify left, right, horizontalCenter, fill or centerIn anchors for items inside Row. Row will not function."));
+ warningMessage.clear();
+ delete item;
+
+ component.setData("import QtQuick 2.0\nRow { Item { width: 100; height: 100; anchors.top: parent.top } }", QUrl::fromLocalFile(""));
+ item = qobject_cast<QQuickItem*>(component.create());
+ QVERIFY(item);
+ QVERIFY(warningMessage.isEmpty());
+ warningMessage.clear();
+ delete item;
+
+ component.setData("import QtQuick 2.0\nGrid { Item { width: 100; height: 100; anchors.horizontalCenter: parent.horizontalCenter } }", QUrl::fromLocalFile(""));
+ item = qobject_cast<QQuickItem*>(component.create());
+ QVERIFY(item);
+ QCOMPARE(warningMessage, QString("file::2:1: QML Grid: Cannot specify anchors for items inside Grid. Grid will not function."));
+ warningMessage.clear();
+ delete item;
+
+ component.setData("import QtQuick 2.0\nGrid { Item { width: 100; height: 100; anchors.centerIn: parent } }", QUrl::fromLocalFile(""));
+ item = qobject_cast<QQuickItem*>(component.create());
+ QVERIFY(item);
+ QCOMPARE(warningMessage, QString("file::2:1: QML Grid: Cannot specify anchors for items inside Grid. Grid will not function."));
+ warningMessage.clear();
+ delete item;
+
+ component.setData("import QtQuick 2.0\nFlow { Item { width: 100; height: 100; anchors.verticalCenter: parent.verticalCenter } }", QUrl::fromLocalFile(""));
+ item = qobject_cast<QQuickItem*>(component.create());
+ QVERIFY(item);
+ QCOMPARE(warningMessage, QString("file::2:1: QML Flow: Cannot specify anchors for items inside Flow. Flow will not function."));
+ delete item;
+
+ component.setData("import QtQuick 2.0\nFlow { width: 100; height: 100; Item { anchors.fill: parent } }", QUrl::fromLocalFile(""));
+ item = qobject_cast<QQuickItem*>(component.create());
+ QVERIFY(item);
+ QCOMPARE(warningMessage, QString("file::2:1: QML Flow: Cannot specify anchors for items inside Flow. Flow will not function."));
+ qInstallMsgHandler(oldMsgHandler);
+ delete item;
+}
+
+void tst_qquickpositioners::test_mirroring()
+{
+ QList<QString> qmlFiles;
+ qmlFiles << "horizontal.qml" << "gridtest.qml" << "flowtest.qml";
+ QList<QString> objectNames;
+ objectNames << "one" << "two" << "three" << "four" << "five";
+
+ foreach (const QString qmlFile, qmlFiles) {
+ QQuickView *canvasA = createView(testFile(qmlFile));
+ QQuickItem *rootA = qobject_cast<QQuickItem*>(canvasA->rootObject());
+
+ QQuickView *canvasB = createView(testFile(qmlFile));
+ QQuickItem *rootB = qobject_cast<QQuickItem*>(canvasB->rootObject());
+
+ rootA->setProperty("testRightToLeft", true); // layoutDirection: Qt.RightToLeft
+
+ // LTR != RTL
+ foreach (const QString objectName, objectNames) {
+ // horizontal.qml only has three items
+ if (qmlFile == QString("horizontal.qml") && objectName == QString("four"))
+ break;
+ QQuickItem *itemA = rootA->findChild<QQuickItem*>(objectName);
+ QQuickItem *itemB = rootB->findChild<QQuickItem*>(objectName);
+ QTRY_VERIFY(itemA->x() != itemB->x());
+ }
+
+ QQmlProperty enabledProp(rootB, "LayoutMirroring.enabled", qmlContext(rootB));
+ enabledProp.write(true);
+ QQmlProperty inheritProp(rootB, "LayoutMirroring.childrenInherit", qmlContext(rootB));
+ inheritProp.write(true);
+
+ // RTL == mirror
+ foreach (const QString objectName, objectNames) {
+ // horizontal.qml only has three items
+ if (qmlFile == QString("horizontal.qml") && objectName == QString("four"))
+ break;
+ QQuickItem *itemA = rootA->findChild<QQuickItem*>(objectName);
+ QQuickItem *itemB = rootB->findChild<QQuickItem*>(objectName);
+ QTRY_COMPARE(itemA->x(), itemB->x());
+ }
+
+ rootA->setProperty("testRightToLeft", false); // layoutDirection: Qt.LeftToRight
+ rootB->setProperty("testRightToLeft", true); // layoutDirection: Qt.RightToLeft
+
+ // LTR == RTL + mirror
+ foreach (const QString objectName, objectNames) {
+ // horizontal.qml only has three items
+ if (qmlFile == QString("horizontal.qml") && objectName == QString("four"))
+ break;
+ QQuickItem *itemA = rootA->findChild<QQuickItem*>(objectName);
+ QQuickItem *itemB = rootB->findChild<QQuickItem*>(objectName);
+ QTRY_COMPARE(itemA->x(), itemB->x());
+ }
+ delete canvasA;
+ delete canvasB;
+ }
+}
+
+void tst_qquickpositioners::test_allInvisible()
+{
+ //QTBUG-19361
+ QQuickView *canvas = createView(testFile("allInvisible.qml"));
+
+ QQuickItem *root = qobject_cast<QQuickItem*>(canvas->rootObject());
+ QVERIFY(root);
+
+ QQuickRow *row = canvas->rootObject()->findChild<QQuickRow*>("row");
+ QVERIFY(row != 0);
+ QVERIFY(row->width() == 0);
+ QVERIFY(row->height() == 0);
+ QQuickColumn *column = canvas->rootObject()->findChild<QQuickColumn*>("column");
+ QVERIFY(column != 0);
+ QVERIFY(column->width() == 0);
+ QVERIFY(column->height() == 0);
+}
+
+void tst_qquickpositioners::test_attachedproperties()
+{
+ QFETCH(QString, filename);
+
+ QQuickView *canvas = createView(filename);
+ QVERIFY(canvas->rootObject() != 0);
+
+ QQuickRectangle *greenRect = canvas->rootObject()->findChild<QQuickRectangle *>("greenRect");
+ QVERIFY(greenRect != 0);
+
+ int posIndex = greenRect->property("posIndex").toInt();
+ QVERIFY(posIndex == 0);
+ bool isFirst = greenRect->property("isFirstItem").toBool();
+ QVERIFY(isFirst == true);
+ bool isLast = greenRect->property("isLastItem").toBool();
+ QVERIFY(isLast == false);
+
+ QQuickRectangle *yellowRect = canvas->rootObject()->findChild<QQuickRectangle *>("yellowRect");
+ QVERIFY(yellowRect != 0);
+
+ posIndex = yellowRect->property("posIndex").toInt();
+ QVERIFY(posIndex == -1);
+ isFirst = yellowRect->property("isFirstItem").toBool();
+ QVERIFY(isFirst == false);
+ isLast = yellowRect->property("isLastItem").toBool();
+ QVERIFY(isLast == false);
+
+ yellowRect->metaObject()->invokeMethod(yellowRect, "onDemandPositioner");
+
+ posIndex = yellowRect->property("posIndex").toInt();
+ QVERIFY(posIndex == 1);
+ isFirst = yellowRect->property("isFirstItem").toBool();
+ QVERIFY(isFirst == false);
+ isLast = yellowRect->property("isLastItem").toBool();
+ QVERIFY(isLast == true);
+
+ delete canvas;
+}
+
+void tst_qquickpositioners::test_attachedproperties_data()
+{
+ QTest::addColumn<QString>("filename");
+
+ QTest::newRow("column") << testFile("attachedproperties-column.qml");
+ QTest::newRow("row") << testFile("attachedproperties-row.qml");
+ QTest::newRow("grid") << testFile("attachedproperties-grid.qml");
+ QTest::newRow("flow") << testFile("attachedproperties-flow.qml");
+}
+
+void tst_qquickpositioners::test_attachedproperties_dynamic()
+{
+ QQuickView *canvas = createView(testFile("attachedproperties-dynamic.qml"));
+ QVERIFY(canvas->rootObject() != 0);
+
+ QQuickRow *row = canvas->rootObject()->findChild<QQuickRow *>("pos");
+ QVERIFY(row != 0);
+
+ QQuickRectangle *rect0 = canvas->rootObject()->findChild<QQuickRectangle *>("rect0");
+ QVERIFY(rect0 != 0);
+
+ int posIndex = rect0->property("index").toInt();
+ QVERIFY(posIndex == 0);
+ bool isFirst = rect0->property("firstItem").toBool();
+ QVERIFY(isFirst == true);
+ bool isLast = rect0->property("lastItem").toBool();
+ QVERIFY(isLast == false);
+
+ QQuickRectangle *rect1 = canvas->rootObject()->findChild<QQuickRectangle *>("rect1");
+ QVERIFY(rect1 != 0);
+
+ posIndex = rect1->property("index").toInt();
+ QVERIFY(posIndex == 1);
+ isFirst = rect1->property("firstItem").toBool();
+ QVERIFY(isFirst == false);
+ isLast = rect1->property("lastItem").toBool();
+ QVERIFY(isLast == true);
+
+ row->metaObject()->invokeMethod(row, "createSubRect");
+
+ QTRY_VERIFY(rect1->property("index").toInt() == 1);
+ QTRY_VERIFY(rect1->property("firstItem").toBool() == false);
+ QTRY_VERIFY(rect1->property("lastItem").toBool() == false);
+
+ QQuickRectangle *rect2 = canvas->rootObject()->findChild<QQuickRectangle *>("rect2");
+ QVERIFY(rect2 != 0);
+
+ posIndex = rect2->property("index").toInt();
+ QVERIFY(posIndex == 2);
+ isFirst = rect2->property("firstItem").toBool();
+ QVERIFY(isFirst == false);
+ isLast = rect2->property("lastItem").toBool();
+ QVERIFY(isLast == true);
+
+ row->metaObject()->invokeMethod(row, "destroySubRect");
+
+ QCoreApplication::sendPostedEvents(0, QEvent::DeferredDelete);
+ QCoreApplication::processEvents();
+
+ QTRY_VERIFY(rect1->property("index").toInt() == 1);
+ QTRY_VERIFY(rect1->property("firstItem").toBool() == false);
+ QTRY_VERIFY(rect1->property("lastItem").toBool() == true);
+
+ delete canvas;
+}
+
+QQuickView *tst_qquickpositioners::createView(const QString &filename, bool wait)
+{
+ QQuickView *canvas = new QQuickView(0);
+
+ canvas->setSource(QUrl::fromLocalFile(filename));
+ canvas->show();
+ if (wait)
+ QTest::qWaitForWindowShown(canvas); //It may not relayout until the next frame, so it needs to be drawn
+
+ return canvas;
+}
+
+void tst_qquickpositioners::matchIndexLists(const QVariantList &indexLists, const QList<int> &expectedIndexes)
+{
+ for (int i=0; i<indexLists.count(); i++) {
+ QSet<int> current = indexLists[i].value<QList<int> >().toSet();
+ if (current != expectedIndexes.toSet())
+ qDebug() << "Cannot match actual targets" << current << "with expected" << expectedIndexes;
+ QCOMPARE(current, expectedIndexes.toSet());
+ }
+}
+
+void tst_qquickpositioners::matchItemsAndIndexes(const QVariantMap &items, const QaimModel &model, const QList<int> &expectedIndexes)
+{
+ for (QVariantMap::const_iterator it = items.begin(); it != items.end(); ++it) {
+ QVERIFY(it.value().type() == QVariant::Int);
+ QString name = it.key();
+ int itemIndex = it.value().toInt();
+ QVERIFY2(expectedIndexes.contains(itemIndex), QTest::toString(QString("Index %1 not found in expectedIndexes").arg(itemIndex)));
+ if (model.name(itemIndex) != name)
+ qDebug() << itemIndex;
+ QCOMPARE(model.name(itemIndex), name);
+ }
+ QCOMPARE(items.count(), expectedIndexes.count());
+}
+
+void tst_qquickpositioners::matchItemLists(const QVariantList &itemLists, const QList<QQuickItem *> &expectedItems)
+{
+ for (int i=0; i<itemLists.count(); i++) {
+ QVERIFY(itemLists[i].type() == QVariant::List);
+ QVariantList current = itemLists[i].toList();
+ for (int j=0; j<current.count(); j++) {
+ QQuickItem *o = qobject_cast<QQuickItem*>(current[j].value<QObject*>());
+ QVERIFY2(o, QTest::toString(QString("Invalid actual item at %1").arg(j)));
+ QVERIFY2(expectedItems.contains(o), QTest::toString(QString("Cannot match item %1").arg(j)));
+ }
+ QCOMPARE(current.count(), expectedItems.count());
+ }
+}
+
+QTEST_MAIN(tst_qquickpositioners)
+
+#include "tst_qquickpositioners.moc"