| /**************************************************************************** |
| ** |
| ** Copyright (C) 2020 The Qt Company Ltd. |
| ** Contact: https://www.qt.io/licensing/ |
| ** |
| ** This file is part of the test suite of the Qt Toolkit. |
| ** |
| ** $QT_BEGIN_LICENSE:BSD$ |
| ** Commercial License Usage |
| ** Licensees holding valid commercial Qt licenses may use this file in |
| ** accordance with the commercial license agreement provided with the |
| ** Software or, alternatively, in accordance with the terms contained in |
| ** a written agreement between you and The Qt Company. For licensing terms |
| ** and conditions see https://www.qt.io/terms-conditions. For further |
| ** information use the contact form at https://www.qt.io/contact-us. |
| ** |
| ** BSD License Usage |
| ** Alternatively, you may use this file under the terms of the BSD license |
| ** as follows: |
| ** |
| ** "Redistribution and use in source and binary forms, with or without |
| ** modification, are permitted provided that the following conditions are |
| ** met: |
| ** * Redistributions of source code must retain the above copyright |
| ** notice, this list of conditions and the following disclaimer. |
| ** * Redistributions in binary form must reproduce the above copyright |
| ** notice, this list of conditions and the following disclaimer in |
| ** the documentation and/or other materials provided with the |
| ** distribution. |
| ** * Neither the name of The Qt Company Ltd nor the names of its |
| ** contributors may be used to endorse or promote products derived |
| ** from this software without specific prior written permission. |
| ** |
| ** |
| ** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
| ** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
| ** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
| ** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
| ** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
| ** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
| ** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
| ** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
| ** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
| ** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
| ** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." |
| ** |
| ** $QT_END_LICENSE$ |
| ** |
| ****************************************************************************/ |
| |
| import QtQuick 2.6 |
| import QtTest 1.0 |
| import QtQuick.Layouts 1.1 |
| |
| Item { |
| id: container |
| width: 200 |
| height: 200 |
| TestCase { |
| id: testCase |
| name: "Tests_GridLayout" |
| when: windowShown |
| width: parent.width |
| height: parent.height |
| |
| Component { |
| id: layout_flow_Component |
| GridLayout { |
| columns: 4 |
| columnSpacing: 0 |
| rowSpacing: 0 |
| Repeater { |
| model: 6 |
| Rectangle { |
| property var itemRect: [x, y, width, height] |
| color: "red" |
| Layout.preferredWidth: 10 |
| Layout.preferredHeight: 10 |
| Text { text: index } |
| } |
| } |
| } |
| } |
| |
| function test_flow() |
| { |
| var layout = createTemporaryObject(layout_flow_Component, container); |
| tryCompare(layout.children[0], "itemRect", [ 0, 0, 10, 10]) |
| tryCompare(layout.children[1], "itemRect", [10, 0, 10, 10]) |
| tryCompare(layout.children[2], "itemRect", [20, 0, 10, 10]) |
| tryCompare(layout.children[3], "itemRect", [30, 0, 10, 10]) |
| |
| tryCompare(layout.children[4], "itemRect", [ 0, 10, 10, 10]) |
| tryCompare(layout.children[5], "itemRect", [10, 10, 10, 10]) |
| |
| layout.rows = 4 |
| layout.flow = GridLayout.TopToBottom |
| tryCompare(layout.children[0], "itemRect", [ 0, 0, 10, 10]) |
| tryCompare(layout.children[1], "itemRect", [ 0, 10, 10, 10]) |
| tryCompare(layout.children[2], "itemRect", [ 0, 20, 10, 10]) |
| tryCompare(layout.children[3], "itemRect", [ 0, 30, 10, 10]) |
| |
| tryCompare(layout.children[4], "itemRect", [10, 0, 10, 10]) |
| tryCompare(layout.children[5], "itemRect", [10, 10, 10, 10]) |
| } |
| |
| Component { |
| id: layout_flowLeftToRight_Component |
| GridLayout { |
| columns: 4 |
| columnSpacing: 0 |
| rowSpacing: 0 |
| // red rectangles are auto-positioned |
| // black rectangles are explicitly positioned with row,column |
| Rectangle { |
| // First one should auto position itself at (0,0) |
| id: r1 |
| color: "red" |
| width: 20 |
| height: 20 |
| } |
| Rectangle { |
| // (1,1) |
| id: r2 |
| color: "black" |
| width: 20 |
| height: 20 |
| Layout.row: 1 |
| Layout.column: 1 |
| Layout.rowSpan: 2 |
| Layout.columnSpan: 2 |
| Layout.fillHeight: true |
| Layout.fillWidth: true |
| } |
| Rectangle { |
| // (0,1) |
| id: r3 |
| color: "black" |
| width: 20 |
| height: 20 |
| Layout.row: 0 |
| Layout.column: 1 |
| } |
| Rectangle { |
| // This one won't fit on the left and right sides of the big black box |
| // inserted at (3,0) |
| id: r4 |
| color: "red" |
| width: 20 |
| height: 20 |
| Layout.columnSpan: 2 |
| Layout.rowSpan: 2 |
| Layout.fillHeight: true |
| Layout.fillWidth: true |
| } |
| Rectangle { |
| // continue flow from (0,2) |
| id: r5 |
| color: "black" |
| width: 20 |
| height: 20 |
| Layout.row: 0 |
| Layout.column: 2 |
| } |
| Repeater { |
| // ...and let the rest of the items automatically fill in the empty cells |
| model: 8 |
| Rectangle { |
| color: "red" |
| width: 20 |
| height: 20 |
| Text { text: index } |
| } |
| } |
| } |
| } |
| |
| function test_flowLeftToRight() { |
| var layout = createTemporaryObject(layout_flowLeftToRight_Component, container); |
| compare(layout.implicitWidth, 80); |
| compare(layout.children[0].x, 0); |
| compare(layout.children[0].y, 0); |
| compare(layout.children[1].x, 20); |
| compare(layout.children[1].y, 20); |
| compare(layout.children[2].x, 20); |
| compare(layout.children[2].y, 0); |
| compare(layout.children[3].x, 0); |
| compare(layout.children[3].y, 60); |
| compare(layout.children[4].x, 40); |
| compare(layout.children[4].y, 0); |
| |
| // assumes that the repeater is the last item among the items it creates |
| compare(layout.children[5].x, 60); |
| compare(layout.children[5].y, 00); |
| compare(layout.children[6].x, 00); |
| compare(layout.children[6].y, 20); |
| compare(layout.children[7].x, 60); |
| compare(layout.children[7].y, 20); |
| compare(layout.children[8].x, 00); |
| compare(layout.children[8].y, 40); |
| compare(layout.children[9].x, 60); |
| compare(layout.children[9].y, 40); |
| compare(layout.children[10].x, 40); |
| compare(layout.children[10].y, 60); |
| compare(layout.children[11].x, 60); |
| compare(layout.children[11].y, 60); |
| compare(layout.children[12].x, 40); |
| compare(layout.children[12].y, 80); |
| } |
| |
| |
| Component { |
| id: layout_flowLeftToRightDefaultPositions_Component |
| GridLayout { |
| columns: 2 |
| columnSpacing: 0 |
| rowSpacing: 0 |
| // red rectangles are auto-positioned |
| // black rectangles are explicitly positioned with row,column |
| // gray rectangles are items with just one row or just one column specified |
| Rectangle { |
| // First one should auto position itself at (0,0) |
| id: r1 |
| color: "red" |
| width: 20 |
| height: 20 |
| } |
| Rectangle { |
| // (1,0) |
| id: r2 |
| color: "gray" |
| width: 20 |
| height: 20 |
| Layout.row: 1 |
| } |
| Rectangle { |
| // (1,1) |
| id: r3 |
| color: "black" |
| width: 20 |
| height: 20 |
| Layout.row: 1 |
| Layout.column: 1 |
| } |
| Rectangle { |
| // (1,0), warning emitted |
| id: r4 |
| color: "gray" |
| width: 20 |
| height: 20 |
| Layout.row: 1 |
| } |
| } |
| } |
| |
| function test_flowLeftToRightDefaultPositions() { |
| ignoreWarning("QGridLayoutEngine::addItem: Cell (1, 0) already taken"); |
| var layout = createTemporaryObject(layout_flowLeftToRightDefaultPositions_Component, container); |
| compare(layout.implicitWidth, 40); |
| compare(layout.children[0].x, 0); |
| compare(layout.children[0].y, 0); |
| compare(layout.children[1].x, 0); |
| compare(layout.children[1].y, 20); |
| compare(layout.children[2].x, 20); |
| compare(layout.children[2].y, 20); |
| } |
| |
| |
| Component { |
| id: layout_flowTopToBottom_Component |
| GridLayout { |
| rows: 4 |
| columnSpacing: 0 |
| rowSpacing: 0 |
| flow: GridLayout.TopToBottom |
| // red rectangles are auto-positioned |
| // black rectangles are explicitly positioned with row,column |
| Rectangle { |
| // First one should auto position itself at (0,0) |
| id: r1 |
| color: "red" |
| width: 20 |
| height: 20 |
| } |
| Rectangle { |
| // (1,1) |
| id: r2 |
| color: "black" |
| width: 20 |
| height: 20 |
| Layout.row: 1 |
| Layout.column: 1 |
| Layout.rowSpan: 2 |
| Layout.columnSpan: 2 |
| Layout.fillHeight: true |
| Layout.fillWidth: true |
| } |
| Rectangle { |
| // (2,0) |
| id: r3 |
| color: "black" |
| width: 20 |
| height: 20 |
| Layout.row: 2 |
| Layout.column: 0 |
| } |
| Rectangle { |
| // This one won't fit on the left and right sides of the big black box |
| // inserted at (0,3) |
| id: r4 |
| color: "red" |
| width: 20 |
| height: 20 |
| Layout.rowSpan: 2 |
| Layout.fillHeight: true |
| } |
| Rectangle { |
| // continue flow from (1,0) |
| id: r5 |
| color: "black" |
| width: 20 |
| height: 20 |
| Layout.row: 1 |
| Layout.column: 0 |
| } |
| Repeater { |
| // ...and let the rest of the items automatically fill in the empty cells |
| model: 8 |
| Rectangle { |
| color: "red" |
| width: 20 |
| height: 20 |
| Text { text: index } |
| } |
| } |
| } |
| } |
| |
| function test_flowTopToBottom() { |
| var layout = createTemporaryObject(layout_flowTopToBottom_Component, container); |
| compare(layout.children[0].x, 0); |
| compare(layout.children[0].y, 0); |
| compare(layout.children[1].x, 20); |
| compare(layout.children[1].y, 20); |
| compare(layout.children[2].x, 0); |
| compare(layout.children[2].y, 40); |
| compare(layout.children[3].x, 60); |
| compare(layout.children[3].y, 0); |
| compare(layout.children[4].x, 0); |
| compare(layout.children[4].y, 20); |
| |
| // The repeated items |
| compare(layout.children[5].x, 0); |
| compare(layout.children[5].y, 60); |
| compare(layout.children[6].x, 20); |
| compare(layout.children[6].y, 0); |
| compare(layout.children[7].x, 20); |
| compare(layout.children[7].y, 60); |
| compare(layout.children[8].x, 40); |
| compare(layout.children[8].y, 0); |
| compare(layout.children[9].x, 40); |
| compare(layout.children[9].y, 60); |
| compare(layout.children[10].x, 60); |
| compare(layout.children[10].y, 40); |
| compare(layout.children[11].x, 60); |
| compare(layout.children[11].y, 60); |
| compare(layout.children[12].x, 80); |
| compare(layout.children[12].y, 0); |
| } |
| |
| Component { |
| id: layout_spanAcrossEmptyRows_Component |
| /* This test has a large number of empty rows and columns, but there is one item |
| that spans across some of these empty rows/columns. |
| Do not modify (especially do not add items unless you understand what this is |
| testing) |
| */ |
| |
| GridLayout { |
| columnSpacing: 0 |
| rowSpacing: 0 |
| // black rectangles are explicitly positioned with row,column |
| Rectangle { |
| // (0,0) |
| id: r0 |
| color: "black" |
| Layout.row: 0 |
| Layout.column: 0 |
| Layout.preferredWidth: 20 |
| Layout.preferredHeight: 20 |
| Layout.maximumWidth: 40 |
| Layout.maximumHeight: 40 |
| Layout.fillWidth: true |
| Layout.fillHeight: true |
| } |
| Rectangle { |
| // (0,1) |
| id: r1 |
| color: "black" |
| Layout.row: 0 |
| Layout.column: 1 |
| Layout.columnSpan: 2 |
| Layout.rowSpan: 2 |
| Layout.preferredWidth: 20 |
| Layout.preferredHeight: 20 |
| Layout.maximumWidth: 40 |
| Layout.maximumHeight: 40 |
| Layout.fillWidth: true |
| Layout.fillHeight: true |
| } |
| Rectangle { |
| // (0,99) |
| id: r2 |
| color: "black" |
| Layout.row: 0 |
| Layout.column: 99 |
| Layout.preferredWidth: 20 |
| Layout.preferredHeight: 20 |
| Layout.maximumWidth: 40 |
| Layout.maximumHeight: 40 |
| Layout.fillWidth: true |
| Layout.fillHeight: true |
| } |
| } |
| } |
| |
| function test_spanAcrossEmptyRows() { |
| var layout = createTemporaryObject(layout_spanAcrossEmptyRows_Component, container); |
| compare(layout.children[0].x, 0); |
| compare(layout.children[0].y, 0); |
| compare(layout.children[1].x, 20); |
| compare(layout.children[1].y, 0); |
| compare(layout.children[2].x, 40); |
| compare(layout.children[2].y, 0); |
| |
| compare(layout.implicitWidth, 60); |
| compare(layout.Layout.maximumWidth, 120); |
| } |
| |
| Component { |
| id: layout_spanIsMoreThanColumns_Component |
| |
| GridLayout { |
| columnSpacing: 1 |
| rowSpacing: 1 |
| columns: 2 |
| |
| Rectangle { |
| implicitWidth: 10 |
| implicitHeight: 10 |
| Layout.columnSpan: 3 |
| } |
| } |
| } |
| |
| function test_spanIsMoreThanColumns() { |
| var layout = createTemporaryObject(layout_spanIsMoreThanColumns_Component, container); |
| // item was not added, therefore implicit width is 0 |
| compare(layout.implicitWidth, 0); |
| } |
| |
| function test_sizeHints() { |
| var layout = createTemporaryObject(layout_spanAcrossEmptyRows_Component, container); |
| compare(layout.visible, true) |
| |
| var minWidth = layout.Layout.minimumWidth |
| var minHeight = layout.Layout.minimumHeight |
| |
| var prefWidth = layout.implicitWidth |
| var prefHeight = layout.implicitHeight |
| |
| var maxWidth = layout.Layout.maximumWidth |
| var maxHeight = layout.Layout.maximumHeight |
| |
| layout.visible = false |
| compare(minWidth, layout.Layout.minimumWidth) |
| compare(minHeight, layout.Layout.minimumHeight) |
| compare(prefWidth, layout.implicitWidth) |
| compare(prefHeight, layout.implicitHeight) |
| compare(maxWidth, layout.Layout.maximumWidth) |
| compare(maxHeight, layout.Layout.maximumHeight) |
| } |
| |
| Component { |
| id: layout_alignment_Component |
| GridLayout { |
| columns: 2 |
| columnSpacing: 0 |
| rowSpacing: 0 |
| Rectangle { |
| // First one should auto position itself at (0,0) |
| property var itemRect: [x, y, width, height] |
| color: "red" |
| Layout.preferredWidth: 20 |
| Layout.preferredHeight: 20 |
| Layout.fillWidth: true |
| Layout.fillHeight: true |
| } |
| Rectangle { |
| // (0,1) |
| property var itemRect: [x, y, width, height] |
| color: "red" |
| Layout.preferredWidth: 20 |
| Layout.preferredHeight: 20 |
| Layout.alignment: Qt.AlignBottom |
| } |
| Rectangle { |
| // (1,0) |
| property var itemRect: [x, y, width, height] |
| color: "red" |
| Layout.preferredWidth: 20 |
| Layout.preferredHeight: 20 |
| Layout.alignment: Qt.AlignRight |
| } |
| Rectangle { |
| // (1,1) |
| property var itemRect: [x, y, width, height] |
| color: "red" |
| Layout.preferredWidth: 10 |
| Layout.preferredHeight: 10 |
| Layout.alignment: Qt.AlignHCenter | Qt.AlignTop |
| } |
| Rectangle { |
| // (2,0) |
| property var itemRect: [x, y, width, height] |
| color: "red" |
| Layout.preferredWidth: 30 |
| Layout.preferredHeight: 30 |
| Layout.alignment: Qt.AlignRight |
| Layout.columnSpan: 2 |
| } |
| Rectangle { |
| // (3,0) |
| property var itemRect: [x, y, width, height] |
| baselineOffset: 7 |
| color: "red" |
| Layout.row: 3 |
| Layout.column: 0 |
| Layout.preferredWidth: 10 |
| Layout.preferredHeight: 10 |
| Layout.alignment: Qt.AlignLeft | Qt.AlignBaseline |
| } |
| Rectangle { |
| // (3,1) |
| property var itemRect: [x, y, width, height] |
| baselineOffset: 7 |
| color: "red" |
| Layout.preferredWidth: 10 |
| Layout.preferredHeight: 10 |
| Layout.alignment: Qt.AlignRight | Qt.AlignBaseline |
| } |
| |
| } |
| } |
| |
| function test_alignment() |
| { |
| var layout = createTemporaryObject(layout_alignment_Component, container); |
| layout.width = 60; |
| layout.height = 100; |
| |
| |
| tryCompare(layout.children[0], "itemRect", [ 0, 0, 40, 40]); |
| tryCompare(layout.children[1], "itemRect", [40, 20, 20, 20]); |
| tryCompare(layout.children[2], "itemRect", [20, 40, 20, 20]); |
| tryCompare(layout.children[3], "itemRect", [45, 40, 10, 10]); |
| tryCompare(layout.children[4], "itemRect", [30, 60, 30, 30]); |
| tryCompare(layout.children[5], "itemRect", [ 0, 90, 10, 10]); |
| tryCompare(layout.children[6], "itemRect", [50, 90, 10, 10]); |
| |
| |
| layout.children[1].Layout.alignment = Qt.AlignTop |
| tryCompare(layout.children[1], "x", 40); |
| tryCompare(layout.children[1], "y", 0); |
| |
| layout.children[2].Layout.alignment = Qt.AlignLeft |
| tryCompare(layout.children[2], "x", 0); |
| tryCompare(layout.children[2], "y", 40); |
| |
| layout.children[3].Layout.alignment = Qt.AlignLeft|Qt.AlignVCenter |
| tryCompare(layout.children[3], "x", 40); |
| tryCompare(layout.children[3], "y", 45); |
| |
| layout.children[4].Layout.alignment = Qt.AlignLeft |
| tryCompare(layout.children[4], "x", 0); |
| tryCompare(layout.children[4], "y", 60); |
| } |
| |
| |
| Component { |
| id: layout_rightToLeft_Component |
| GridLayout { |
| layoutDirection: Qt.RightToLeft |
| columnSpacing: 0 |
| rowSpacing: 0 |
| columns: 3 |
| Rectangle { |
| property var itemRect: [x, y, width, height] |
| color: "#cbffc4" |
| Layout.preferredWidth: 50 |
| Layout.preferredHeight: 50 |
| Layout.alignment: Qt.AlignCenter |
| } |
| Rectangle { |
| property var itemRect: [x, y, width, height] |
| color: "#c4d1ff" |
| Layout.preferredWidth: 50 |
| Layout.preferredHeight: 50 |
| Layout.alignment: Qt.AlignRight |
| } |
| Rectangle { |
| property var itemRect: [x, y, width, height] |
| color: "#ffd5c4" |
| Layout.preferredWidth: 50 |
| Layout.preferredHeight: 50 |
| Layout.alignment: Qt.AlignLeft |
| } |
| } |
| } |
| |
| function verifyIsRightToLeft(layout) |
| { |
| tryCompare(layout.children[0], "itemRect", [125, 0, 50, 50]); |
| tryCompare(layout.children[1], "itemRect", [60, 0, 50, 50]); |
| tryCompare(layout.children[2], "itemRect", [10, 0, 50, 50]); |
| } |
| |
| function verifyIsLeftToRight(layout) |
| { |
| tryCompare(layout.children[0], "itemRect", [5, 0, 50, 50]); |
| tryCompare(layout.children[1], "itemRect", [70, 0, 50, 50]); |
| tryCompare(layout.children[2], "itemRect", [120, 0, 50, 50]); |
| } |
| |
| function test_rightToLeft() |
| { |
| var layout = createTemporaryObject(layout_rightToLeft_Component, container); |
| layout.width = 180; |
| layout.height = 50; |
| |
| // Right To Left |
| verifyIsRightToLeft(layout) |
| layout.LayoutMirroring.enabled = true |
| layout.layoutDirection = Qt.LeftToRight |
| verifyIsRightToLeft(layout) |
| |
| // Left To Right |
| layout.LayoutMirroring.enabled = false |
| layout.layoutDirection = Qt.LeftToRight |
| verifyIsLeftToRight(layout); |
| layout.LayoutMirroring.enabled = true |
| layout.layoutDirection = Qt.RightToLeft |
| verifyIsLeftToRight(layout); |
| |
| layout.LayoutMirroring.enabled = false |
| verifyIsRightToLeft(layout) |
| |
| layout.layoutDirection = Qt.LeftToRight |
| verifyIsLeftToRight(layout); |
| |
| layout.LayoutMirroring.enabled = true |
| verifyIsRightToLeft(layout) |
| } |
| |
| Component { |
| id: layout_columnsOrRowsChanged_Component |
| GridLayout { |
| id: layout |
| rowSpacing: 0 |
| columnSpacing: 0 |
| Repeater { |
| model: 4 |
| Rectangle { |
| property var itemRect: [x, y, width, height] |
| width: 10 |
| height: 10 |
| color: "#ff0000" |
| } |
| } |
| } |
| } |
| |
| function test_columnsChanged() |
| { |
| var layout = createTemporaryObject(layout_columnsOrRowsChanged_Component, container); |
| layout.width = 40; |
| layout.height = 20; |
| tryCompare(layout.children[0], "itemRect", [ 0, 5, 10, 10]) |
| tryCompare(layout.children[1], "itemRect", [10, 5, 10, 10]) |
| tryCompare(layout.children[2], "itemRect", [20, 5, 10, 10]) |
| tryCompare(layout.children[3], "itemRect", [30, 5, 10, 10]) |
| |
| layout.columns = 2 |
| tryCompare(layout.children[0], "itemRect", [ 0, 0, 10, 10]) |
| tryCompare(layout.children[1], "itemRect", [20, 0, 10, 10]) |
| tryCompare(layout.children[2], "itemRect", [ 0, 10, 10, 10]) |
| tryCompare(layout.children[3], "itemRect", [20, 10, 10, 10]) |
| } |
| |
| function test_rowsChanged() |
| { |
| var layout = createTemporaryObject(layout_columnsOrRowsChanged_Component, container); |
| layout.flow = GridLayout.TopToBottom |
| layout.width = 20; |
| layout.height = 40; |
| tryCompare(layout.children[0], "itemRect", [ 0, 0, 10, 10]) |
| tryCompare(layout.children[1], "itemRect", [ 0, 10, 10, 10]) |
| tryCompare(layout.children[2], "itemRect", [ 0, 20, 10, 10]) |
| tryCompare(layout.children[3], "itemRect", [ 0, 30, 10, 10]) |
| |
| layout.rows = 2 |
| tryCompare(layout.children[0], "itemRect", [ 0, 5, 10, 10]) |
| tryCompare(layout.children[1], "itemRect", [ 0, 25, 10, 10]) |
| tryCompare(layout.children[2], "itemRect", [10, 5, 10, 10]) |
| tryCompare(layout.children[3], "itemRect", [10, 25, 10, 10]) |
| } |
| |
| Component { |
| id: layout_columnOrRowChanged_Component |
| GridLayout { |
| id: layout |
| rowSpacing: 0 |
| columnSpacing: 0 |
| Rectangle { |
| property var itemRect: [x, y, width, height] |
| width: 10 |
| height: 10 |
| Layout.column: 0 |
| color: "#ff0000" |
| } |
| Rectangle { |
| property var itemRect: [x, y, width, height] |
| Layout.column: 1 |
| width: 10 |
| height: 10 |
| color: "#ff0000" |
| } |
| Rectangle { |
| property var itemRect: [x, y, width, height] |
| //Layout.column: 2 |
| width: 10 |
| height: 10 |
| color: "#ff0000" |
| } |
| } |
| } |
| |
| function test_columnOrRowChanged() |
| { |
| var layout = createTemporaryObject(layout_columnOrRowChanged_Component, container); |
| layout.width = layout.implicitWidth |
| layout.height = layout.implicitHeight |
| // c0-c1-c2 |
| tryCompare(layout.children[0], "itemRect", [ 0, 0, 10, 10]) |
| tryCompare(layout.children[1], "itemRect", [10, 0, 10, 10]) |
| tryCompare(layout.children[2], "itemRect", [20, 0, 10, 10]) |
| |
| layout.children[0].Layout.column = 3 |
| //c1-c2-c0 |
| tryCompare(layout.children[0], "itemRect", [20, 0, 10, 10]) |
| tryCompare(layout.children[1], "itemRect", [ 0, 0, 10, 10]) |
| tryCompare(layout.children[2], "itemRect", [10, 0, 10, 10]) |
| |
| layout.children[2].Layout.column = 4 |
| //c1-c0-c2 |
| tryCompare(layout.children[0], "itemRect", [10, 0, 10, 10]) |
| tryCompare(layout.children[1], "itemRect", [ 0, 0, 10, 10]) |
| tryCompare(layout.children[2], "itemRect", [20, 0, 10, 10]) |
| |
| layout.children[0].Layout.row = 1 |
| // two rows, so we adjust it to its new implicitHeight |
| layout.height = layout.implicitHeight |
| //c1 c2 |
| // c0 |
| tryCompare(layout.children[0], "itemRect", [10, 10, 10, 10]) |
| tryCompare(layout.children[1], "itemRect", [ 0, 0, 10, 10]) |
| tryCompare(layout.children[2], "itemRect", [20, 0, 10, 10]) |
| } |
| |
| Component { |
| id: layout_baselines_Component |
| GridLayout { |
| id: layout |
| columnSpacing: 0 |
| Rectangle { |
| property var itemRect: [x, y, width, height] |
| implicitWidth: 10 |
| implicitHeight: 10 |
| baselineOffset: 10 |
| } |
| Rectangle { |
| property var itemRect: [x, y, width, height] |
| implicitWidth: 10 |
| implicitHeight: 10 |
| } |
| } |
| } |
| function test_baselines() |
| { |
| var layout = createTemporaryObject(layout_baselines_Component, container); |
| tryCompare(layout.children[0], "itemRect", [ 0, 0, 10, 10]) |
| tryCompare(layout.children[1], "itemRect", [10, 0, 10, 10]) |
| compare(layout.implicitWidth, 20) |
| compare(layout.implicitHeight, 10) |
| |
| layout.children[0].Layout.alignment = Qt.AlignBaseline |
| layout.children[1].Layout.alignment = Qt.AlignBaseline |
| |
| tryCompare(layout.children[0], "itemRect", [ 0, 0, 10, 10]) |
| tryCompare(layout.children[1], "itemRect", [10, 10, 10, 10]) |
| compare(layout.implicitWidth, 20) |
| compare(layout.implicitHeight, 20) |
| } |
| |
| Component { |
| id: layout_spacings_Component |
| GridLayout { |
| id: layout |
| Repeater { |
| model: 2 |
| Rectangle { |
| property var itemRect: [x, y, width, height] |
| implicitWidth: 10 |
| implicitHeight: 10 |
| } |
| } |
| } |
| } |
| |
| function test_spacings_data() |
| { |
| let data = [ |
| { spacing: Number.NaN }, |
| { spacing: 0 }, |
| { spacing: 10 }, |
| { spacing: -5 }, |
| { spacing: -19 } |
| ] |
| for (let i = 0; i < data.length; ++i) { |
| data[i].tag = data[i].spacing.toString() |
| } |
| return data |
| } |
| |
| function test_spacings(data) |
| { |
| var layout = createTemporaryObject(layout_spacings_Component, container); |
| |
| // breaks down below -19. This is acceptable, since it means that the implicit size of the layout is negative |
| var testSpacings = [Number.NaN, 0, 10, -5, -19] |
| layout.rowSpacing = 0 |
| var spacing = data.spacing |
| if (isNaN(spacing)) { |
| spacing = 5 // Test defaults |
| } else { |
| layout.columnSpacing = spacing |
| } |
| tryCompare(layout.children[0], "itemRect", [ 0, 0, 10, 10]) |
| tryCompare(layout.children[1], "itemRect", [10 + spacing, 0, 10, 10]) |
| compare(layout.implicitWidth, 20 + spacing) |
| |
| // do not crash |
| layout.columnSpacing = -100 |
| waitForRendering(layout) |
| verify(isFinite(layout.implicitWidth)) |
| } |
| |
| Component { |
| id: layout_alignToPixelGrid_Component |
| GridLayout { |
| columns: 3 |
| rowSpacing: 0 |
| columnSpacing: 2 |
| Repeater { |
| model: 3*3 |
| Rectangle { |
| color: "red" |
| Layout.fillWidth: true |
| Layout.fillHeight: true |
| } |
| } |
| } |
| } |
| |
| function test_alignToPixelGrid() |
| { |
| var layout = layout_alignToPixelGrid_Component.createObject(container) |
| layout.width = 30 |
| layout.height = 28 |
| |
| var rectWidth = (layout.width - 2 * layout.columnSpacing)/3 |
| var rectHeight = layout.height/3 |
| |
| waitForRendering(layout); |
| |
| var sp = layout.columnSpacing |
| var idealGeom = [0,0,rectWidth,rectHeight] |
| for (var r = 0; r < 3; ++r) { |
| idealGeom[0] = 0 |
| idealGeom[2] = rectWidth |
| for (var c = 0; c < 3; ++c) { |
| var child = layout.children[3*r + c] |
| var visualGeom = [child.x, child.y, child.x + child.width, child.y + child.height] |
| |
| // verify that visualGeom is an integer number |
| for (var i = 0; i < 2; ++i) |
| compare(visualGeom[i] % 1, 0) |
| |
| // verify that x,y is no more than one pixel from idealGeom |
| fuzzyCompare(visualGeom[0], idealGeom[0], 1) |
| fuzzyCompare(visualGeom[1], idealGeom[1], 1) |
| |
| // verify that the visual size is no more than 1 pixel taller/wider than the ideal size. |
| verify(visualGeom[2] <= idealGeom[2] + 1) |
| verify(visualGeom[3] <= idealGeom[3] + 1) |
| idealGeom[0] = idealGeom[2] + sp |
| idealGeom[2] = idealGeom[0] + rectWidth |
| } |
| idealGeom[1] = idealGeom[3] |
| idealGeom[3] = idealGeom[1] + rectHeight |
| } |
| |
| layout.destroy() |
| } |
| |
| Component { |
| |
| id: layout_Margins_Component |
| GridLayout { |
| columns: 2 |
| rowSpacing: 0 |
| columnSpacing: 0 |
| Rectangle { |
| color: "red" |
| Layout.preferredWidth: 20 |
| Layout.preferredHeight: 20 |
| Layout.margins: 10 |
| Layout.leftMargin: 2 |
| Layout.topMargin: 3 |
| Layout.rightMargin: 4 |
| Layout.bottomMargin: 4 |
| } |
| Rectangle { |
| color: "red" |
| Layout.preferredWidth: 20 |
| Layout.preferredHeight: 20 |
| Layout.leftMargin: 4 |
| Layout.topMargin: 5 |
| Layout.rightMargin: 6 |
| Layout.bottomMargin: 6 |
| } |
| Rectangle { |
| color: "red" |
| Layout.preferredWidth: 20 |
| Layout.preferredHeight: 20 |
| Layout.leftMargin: 3 |
| Layout.topMargin: 4 |
| Layout.rightMargin: 5 |
| Layout.bottomMargin: 5 |
| } |
| } |
| } |
| |
| function test_Margins() |
| { |
| var layout = layout_Margins_Component.createObject(container) |
| |
| compare(layout.implicitWidth, 3 + 20 + 5 + 4 + 20 + 6) |
| compare(layout.implicitHeight, 5 + 20 + 6 + 4 + 20 + 5) |
| layout.width = layout.implicitWidth |
| layout.height = layout.implicitHeight |
| |
| waitForRendering(layout) |
| |
| var c0 = layout.children[0] |
| var c1 = layout.children[1] |
| var c2 = layout.children[2] |
| |
| compare(c0.x, 2) |
| compare(c0.y, 5) |
| compare(c1.x, 3 + 20 + 5 + 4) |
| compare(c1.y, 5) |
| compare(c2.x, 3) |
| compare(c2.y, 5 + 20 + 6 + 4) |
| |
| // reset left|rightMargin. It should then use the generic "margins" property |
| c0.Layout.leftMargin = undefined |
| compare(layout.implicitWidth, 10 + 20 + 4 + 4 + 20 + 6) |
| c0.Layout.bottomMargin = undefined |
| compare(layout.implicitHeight, 3 + 20 + 10 + 4 + 20 + 5) |
| } |
| |
| Component { |
| id: layout_invalidateWhileRearranging_Component |
| |
| GridLayout { |
| columns: 1 |
| Rectangle { |
| height: 50 |
| Layout.fillWidth: true |
| color: 'blue' |
| } |
| |
| Rectangle { |
| height: 50 |
| Layout.fillWidth: true |
| color: 'red' |
| onYChanged: { |
| visible = false; |
| } |
| } |
| } |
| } |
| |
| function test_invalidateWhileRearranging_QTBUG_44139() |
| { |
| var layout = createTemporaryObject(layout_invalidateWhileRearranging_Component, container) |
| |
| waitForRendering(layout); |
| verify(layout.children[1].visible == false); |
| } |
| |
| |
| |
| Component { |
| id: gridlayout_propertyChanges_Component |
| GridLayout { |
| columns: 1 |
| property alias spy : signalSpy |
| SignalSpy { |
| id: signalSpy |
| target: parent |
| } |
| } |
| } |
| |
| Component { |
| id: rowlayout_propertyChanges_Component |
| RowLayout { |
| property alias spy : signalSpy |
| SignalSpy { |
| id: signalSpy |
| target: parent |
| } |
| } |
| } |
| |
| function test_propertyChanges_data() |
| { |
| let data = [ |
| { tag: "columnSpacing", value: 9 }, |
| { tag: "rowSpacing", value: 9 }, |
| { tag: "columns", value: 2 }, |
| { tag: "rows", value: 2 }, |
| { tag: "flow", value: GridLayout.TopToBottom}, |
| { tag: "layoutDirection", value: Qt.RightToLeft }, |
| { tag: "spacing", value: 9 } |
| ] |
| return data |
| } |
| |
| function test_propertyChanges(data) |
| { |
| var propName = data.tag |
| var layout = createTemporaryObject(propName === "spacing" |
| ? rowlayout_propertyChanges_Component |
| : gridlayout_propertyChanges_Component |
| , container) |
| |
| layout.spy.signalName = propName + "Changed" |
| verify(layout.spy.valid) |
| |
| layout[propName] = data.value |
| compare(layout.spy.count, 1) |
| } |
| |
| Component { |
| id: layout_columnIsOutsideGrid_Component |
| GridLayout { |
| columns: 2 |
| Item { |
| Layout.row: 0 |
| Layout.column: 1 |
| } |
| Item { |
| implicitWidth: 10 |
| implicitHeight: 10 |
| Layout.row: 0 |
| Layout.column: 2 |
| } |
| Item { |
| Layout.columnSpan: 2 |
| Layout.fillWidth: true |
| Layout.fillHeight: true |
| } |
| } |
| } |
| |
| function test_columnIsOutsideGrid() |
| { |
| ignoreWarning(/QML Item: Layout: column \(2\) should be less than the number of columns \(2\)/); |
| var layout = layout_columnIsOutsideGrid_Component.createObject(container); |
| layout.width = layout.implicitWidth |
| layout.height = layout.implicitHeight |
| waitForRendering(layout); |
| layout.destroy() |
| } |
| |
| // ------------------ |
| Component { |
| id: replaceCell_QTBUG_65121 |
| GridLayout { |
| id: gridLayout |
| anchors.fill: parent |
| columns: 2 |
| property var categories: ['one', 'two', 'three'] |
| property var values: [1, 2, 3] |
| Repeater { |
| model: gridLayout.categories |
| Item { |
| Layout.row: index |
| Layout.column: 0 |
| Layout.preferredWidth: label.width |
| Layout.fillHeight: true |
| Text { |
| id: label |
| height: parent.height |
| anchors.right: parent.right |
| text: modelData |
| verticalAlignment: Text.AlignVCenter |
| font.pointSize: 27 |
| leftPadding: 10 |
| } |
| } |
| } |
| Repeater { |
| model: gridLayout.values |
| Item { |
| Layout.row: index |
| Layout.column: 1 |
| Layout.preferredWidth: label.width |
| Layout.fillHeight: true |
| Text { |
| id: label |
| height: parent.height |
| anchors.right: parent.right |
| text: modelData |
| verticalAlignment: Text.AlignVCenter |
| font.pointSize: 27 |
| leftPadding: 10 |
| } |
| } |
| } |
| } |
| } |
| function test_replaceCell_QTBUG_65121() { |
| var layout = createTemporaryObject(replaceCell_QTBUG_65121, container) |
| verify(layout) |
| layout.categories = ["eleven", "twelve"] |
| layout.values = [11, 12] |
| verify(isPolishScheduled(layout)) |
| verify(waitForItemPolished(layout)) |
| // Shouldn't be any warnings, but no way to verify this currently: QTBUG-70029 |
| } |
| } |
| } |