diff --git a/examples/basiclayouts/main.qml b/examples/basiclayouts/main.qml index d2b37204ab4e7d33b56c87721c132212d5d03cfc..fd107cc17709e8b650b01db36546e53b4e93e7a3 100644 --- a/examples/basiclayouts/main.qml +++ b/examples/basiclayouts/main.qml @@ -58,7 +58,6 @@ ApplicationWindow { id: mainLayout anchors.fill: parent anchors.margins: margin - spacing: 6 GroupBox { id: rowBox title: "Row layout" @@ -68,22 +67,13 @@ ApplicationWindow { RowLayout { id: rowLayout - spacing: 6 anchors.fill: parent - Button { - text: "Button 1" - } - Button { - text: "Button 2" - } - Button { - text: "Button 3" + TextField { + placeholderText: "This wants to grow horizontally" + Layout.fillWidth: true } Button { - text: "Button 4" - } - Item { - Layout.fillWidth: true + text: "Button" } } } @@ -97,49 +87,30 @@ ApplicationWindow { GridLayout { id: gridLayout - rowSpacing: 6 - columnSpacing: 6 + rows: 3 + flow: GridLayout.TopToBottom anchors.fill: parent - Label { - text: "Line 1" - Layout.row: 0 - Layout.column: 0 - } - Label { - text: "Line 2" - Layout.row: 1 - Layout.column: 0 - } - Label { - text: "Line 3" - Layout.row: 2 - Layout.column: 0 - } - TextField { - Layout.row: 0 - Layout.column: 1 - } - TextField { - Layout.row: 1 - Layout.column: 1 - } - TextField { - Layout.row: 2 - Layout.column: 1 - } + + Label { text: "Line 1" } + Label { text: "Line 2" } + Label { text: "Line 3" } + + TextField { } + TextField { } + TextField { } + TextArea { - text: "This widget spans over three rows in the grid layout" - Layout.row: 0 - Layout.column: 2 + text: "This widget spans over three rows in the GridLayout.\n" + + "All items in the GridLayout are implicitly positioned from top to bottom." Layout.rowSpan: 3 Layout.fillHeight: true Layout.fillWidth: true } } } - TextField { + TextArea { id: t3 - placeholderText: "This is a placeholder for a TextField" + text: "This fills the whole cell" width: 200 height: 400 Layout.fillHeight: true diff --git a/src/layouts/qquicklayout.cpp b/src/layouts/qquicklayout.cpp index 77c3d4431d1fea03e879fba08a843b384b199873..68e6b6b3ed8e8e00867914f6fd420f049967b95d 100644 --- a/src/layouts/qquicklayout.cpp +++ b/src/layouts/qquicklayout.cpp @@ -54,8 +54,8 @@ QQuickLayoutAttached::QQuickLayoutAttached(QObject *parent) m_preferredHeight(0), m_maximumWidth(q_declarativeLayoutMaxSize), m_maximumHeight(q_declarativeLayoutMaxSize), - m_row(0), - m_column(0), + m_row(-1), + m_column(-1), m_rowSpan(1), m_columnSpan(1), m_fillWidth(false), @@ -149,6 +149,18 @@ void QQuickLayoutAttached::setFillHeight(bool fill) } } +void QQuickLayoutAttached::setRow(int row) +{ + if (row >= 0 && row != m_row) + m_row = row; +} + +void QQuickLayoutAttached::setColumn(int column) +{ + if (column >= 0 && column != m_column) + m_column = column; +} + void QQuickLayoutAttached::invalidateItem() { quickLayoutDebug() << "QQuickLayoutAttached::invalidateItem"; diff --git a/src/layouts/qquicklayout_p.h b/src/layouts/qquicklayout_p.h index ad1f2df585e08699415a15e7e8c2ebfe3cca99c9..a13d79e3dac421e6d153adb41ab0aa97d491a3c9 100644 --- a/src/layouts/qquicklayout_p.h +++ b/src/layouts/qquicklayout_p.h @@ -150,10 +150,12 @@ public: void setFillHeight(bool fill); bool isFillHeightSet() const { return m_isFillHeightSet; } - int row() const { return m_row; } - void setRow(int row) { m_row = row; } - int column() const { return m_column; } - void setColumn(int column) { m_column = column; } + int row() const { return qMax(m_row, 0); } + void setRow(int row); + bool isRowSet() const { return m_row >= 0; } + int column() const { return qMax(m_column, 0); } + void setColumn(int column); + bool isColumnSet() const { return m_column >= 0; } int rowSpan() const { return m_rowSpan; } void setRowSpan(int span) { m_rowSpan = span; } diff --git a/src/layouts/qquicklinearlayout.cpp b/src/layouts/qquicklinearlayout.cpp index a0cb633569701cf9c5e6fbe196c51c62f4f5ccc5..635bb576fd355300ff73c9fe82f0b3ac7d2fd78d 100644 --- a/src/layouts/qquicklinearlayout.cpp +++ b/src/layouts/qquicklinearlayout.cpp @@ -42,6 +42,7 @@ #include "qquicklinearlayout_p.h" #include <QtCore/qnumeric.h> #include "qdebug.h" +#include <limits> /*! \qmltype RowLayout \instantiates QQuickRowLayout @@ -158,10 +159,7 @@ void QQuickGridLayoutBase::updateLayoutItems() return; quickLayoutDebug() << "QQuickGridLayoutBase::updateLayoutItems"; d->engine.deleteItems(); - foreach (QQuickItem *child, childItems()) { - if (child->isVisible()) - insertLayoutItem(child); - } + insertLayoutItems(); invalidate(); quickLayoutDebug() << "QQuickGridLayoutBase::updateLayoutItems LEAVING"; @@ -223,41 +221,6 @@ void QQuickGridLayoutBase::geometryChanged(const QRectF &newGeometry, const QRec rearrange(newGeometry.size()); } -void QQuickGridLayoutBase::insertLayoutItem(QQuickItem *item) -{ - Q_D(QQuickGridLayoutBase); - if (!item) { - qWarning("QGraphicsGridLayout::addItem: cannot add null item"); - return; - } - QQuickLayoutAttached *info = attachedLayoutObject(item, false); - int row = 0; - int column = 0; - int rowSpan = 1; - int columnSpan = 1; - Qt::Alignment alignment = 0; - if (info) { - row = info->row(); - column = info->column(); - rowSpan = info->rowSpan(); - columnSpan = info->columnSpan(); - } - if (row < 0 || column < 0) { - qWarning("QQuickGridLayoutBase::insertLayoutItemAt: invalid row/column: %d", - row < 0 ? row : column); - return; - } - if (columnSpan < 1 || rowSpan < 1) { - qWarning("QQuickGridLayoutBase::addItem: invalid row span/column span: %d", - rowSpan < 1 ? rowSpan : columnSpan); - return; - } - QQuickGridLayoutItem *layoutItem = new QQuickGridLayoutItem(item, row, column, rowSpan, columnSpan, alignment); - d->engine.insertItem(layoutItem, -1); - - setupItemLayout(item); -} - void QQuickGridLayoutBase::removeGridItem(QGridLayoutItem *gridItem) { Q_D(QQuickGridLayoutBase); @@ -378,6 +341,168 @@ void QQuickGridLayout::setRowSpacing(qreal spacing) invalidate(); } +int QQuickGridLayout::columns() const +{ + Q_D(const QQuickGridLayout); + return d->columns; +} + +void QQuickGridLayout::setColumns(int columns) +{ + Q_D(QQuickGridLayout); + if (d->columns == columns) + return; + d->columns = columns; + invalidate(); + emit columnsChanged(); +} + +int QQuickGridLayout::rows() const +{ + Q_D(const QQuickGridLayout); + return d->rows; +} + +void QQuickGridLayout::setRows(int rows) +{ + Q_D(QQuickGridLayout); + if (d->rows == rows) + return; + d->rows = rows; + invalidate(); + emit rowsChanged(); +} + +QQuickGridLayout::Flow QQuickGridLayout::flow() const +{ + Q_D(const QQuickGridLayout); + return d->flow; +} + +void QQuickGridLayout::setFlow(QQuickGridLayout::Flow flow) +{ + Q_D(QQuickGridLayout); + if (d->flow == flow) + return; + d->flow = flow; + invalidate(); + emit flowChanged(); +} + +void QQuickGridLayout::insertLayoutItems() +{ + Q_D(QQuickGridLayout); + + int nextCellPos[2] = {0,0}; + int &nextColumn = nextCellPos[0]; + int &nextRow = nextCellPos[1]; + + const int flowOrientation = flow(); + int &flowColumn = nextCellPos[flowOrientation]; + int &flowRow = nextCellPos[1 - flowOrientation]; + int flowBound = (flowOrientation == QQuickGridLayout::LeftToRight) ? columns() : rows(); + + if (flowBound < 0) + flowBound = std::numeric_limits<int>::max(); + + foreach (QQuickItem *child, childItems()) { + if (child->isVisible()) { + QQuickLayoutAttached *info = attachedLayoutObject(child, false); + + // Will skip Repeater among other things + const bool skipItem = !info && (!child->width() || !child->height()) + && (!child->implicitWidth() || !child->implicitHeight()); + if (skipItem) + continue; + + int row = -1; + int column = -1; + int span[2] = {1,1}; + int &columnSpan = span[0]; + int &rowSpan = span[1]; + + bool invalidRowColumn = false; + if (info) { + if (info->isRowSet() || info->isColumnSet()) { + // If row is specified and column is not specified (or vice versa), + // the unspecified component of the cell position should default to 0 + row = column = 0; + if (info->isRowSet()) { + row = info->row(); + invalidRowColumn = row < 0; + } + if (info->isColumnSet()) { + column = info->column(); + invalidRowColumn = column < 0; + } + } + if (invalidRowColumn) { + qWarning("QQuickGridLayoutBase::insertLayoutItems: invalid row/column: %d", + row < 0 ? row : column); + return; + } + rowSpan = info->rowSpan(); + columnSpan = info->columnSpan(); + if (columnSpan < 1 || rowSpan < 1) { + qWarning("QQuickGridLayoutBase::addItem: invalid row span/column span: %d", + rowSpan < 1 ? rowSpan : columnSpan); + return; + } + } + + Q_ASSERT(columnSpan >= 1); + Q_ASSERT(rowSpan >= 1); + + if (row >= 0) + nextRow = row; + if (column >= 0) + nextColumn = column; + + if (row < 0 || column < 0) { + /* if row or column is not specified, find next position by + advancing in the flow direction until there is a cell that + can accept the item. + + The acceptance rules are pretty simple, but complexity arises + when an item requires several cells (due to spans): + 1. Check if the cells that the item will require + does not extend beyond columns (for LeftToRight) or + rows (for TopToBottom). + 2. Check if the cells that the item will require is not already + taken by another item. + */ + bool cellAcceptsItem; + while (true) { + // Check if the item does not span beyond the layout bound + cellAcceptsItem = (flowColumn + span[flowOrientation]) <= flowBound; + + // Check if all the required cells are not taken + for (int rs = 0; cellAcceptsItem && rs < rowSpan; ++rs) { + for (int cs = 0; cellAcceptsItem && cs < columnSpan; ++cs) { + if (d->engine.itemAt(nextRow + rs, nextColumn + cs)) { + cellAcceptsItem = false; + } + } + } + if (cellAcceptsItem) + break; + ++flowColumn; + if (flowColumn == flowBound) { + flowColumn = 0; + ++flowRow; + } + } + } + column = nextColumn; + row = nextRow; + QQuickGridLayoutItem *layoutItem = new QQuickGridLayoutItem(child, row, column, rowSpan, columnSpan); + + d->engine.insertItem(layoutItem, -1); + + setupItemLayout(child); + } + } +} /********************************** ** @@ -410,23 +535,25 @@ void QQuickLinearLayout::setSpacing(qreal spacing) invalidate(); } - -void QQuickLinearLayout::insertLayoutItem(QQuickItem *item) +void QQuickLinearLayout::insertLayoutItems() { Q_D(QQuickLinearLayout); - const int index = d->engine.rowCount(d->orientation); - d->engine.insertRow(index, d->orientation); - - int gridRow = 0; - int gridColumn = index; - if (d->orientation == Qt::Vertical) - qSwap(gridRow, gridColumn); - QQuickGridLayoutItem *layoutItem = new QQuickGridLayoutItem(item, gridRow, gridColumn, 1, 1, 0); - d->engine.insertItem(layoutItem, index); - - setupItemLayout(item); + foreach (QQuickItem *child, childItems()) { + Q_ASSERT(child); + if (child->isVisible()) { + const int index = d->engine.rowCount(d->orientation); + d->engine.insertRow(index, d->orientation); + + int gridRow = 0; + int gridColumn = index; + if (d->orientation == Qt::Vertical) + qSwap(gridRow, gridColumn); + QQuickGridLayoutItem *layoutItem = new QQuickGridLayoutItem(child, gridRow, gridColumn, 1, 1, 0); + d->engine.insertItem(layoutItem, index); + + setupItemLayout(child); + } + } } - - QT_END_NAMESPACE diff --git a/src/layouts/qquicklinearlayout_p.h b/src/layouts/qquicklinearlayout_p.h index a4773d0483a2d4623a87137bda8a8900869cd095..ea418790ec99efe34314763d95c02e53c86639f7 100644 --- a/src/layouts/qquicklinearlayout_p.h +++ b/src/layouts/qquicklinearlayout_p.h @@ -71,7 +71,7 @@ public: protected: void updateLayoutItems(); void rearrange(const QSizeF &size); - virtual void insertLayoutItem(QQuickItem *item); + virtual void insertLayoutItems() = 0; void removeLayoutItem(QQuickItem *item); void itemChange(ItemChange change, const ItemChangeData &data); void geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry); @@ -111,16 +111,36 @@ class QQuickGridLayout : public QQuickGridLayoutBase Q_OBJECT Q_PROPERTY(qreal columnSpacing READ columnSpacing WRITE setColumnSpacing NOTIFY columnSpacingChanged) Q_PROPERTY(qreal rowSpacing READ rowSpacing WRITE setRowSpacing NOTIFY rowSpacingChanged) + Q_PROPERTY(int columns READ columns WRITE setColumns NOTIFY columnsChanged) + Q_PROPERTY(int rows READ rows WRITE setRows NOTIFY rowsChanged) + Q_PROPERTY(Flow flow READ flow WRITE setFlow NOTIFY flowChanged) public: explicit QQuickGridLayout(QQuickItem *parent = 0); qreal columnSpacing() const; void setColumnSpacing(qreal spacing); qreal rowSpacing() const; void setRowSpacing(qreal spacing); + + int columns() const; + void setColumns(int columns); + int rows() const; + void setRows(int rows); + + Q_ENUMS(Flow) + enum Flow { LeftToRight, TopToBottom }; + Flow flow() const; + void setFlow(Flow flow); + + void insertLayoutItems(); + signals: void columnSpacingChanged(); void rowSpacingChanged(); + void columnsChanged(); + void rowsChanged(); + + void flowChanged(); private: Q_DECLARE_PRIVATE(QQuickGridLayout) }; @@ -129,9 +149,12 @@ class QQuickGridLayoutPrivate : public QQuickGridLayoutBasePrivate { Q_DECLARE_PUBLIC(QQuickGridLayout) public: - QQuickGridLayoutPrivate() {} + QQuickGridLayoutPrivate(): columns(-1), rows(-1), flow(QQuickGridLayout::LeftToRight) {} qreal columnSpacing; qreal rowSpacing; + int columns; + int rows; + QQuickGridLayout::Flow flow; }; @@ -152,6 +175,8 @@ public: qreal spacing() const; void setSpacing(qreal spacing); + void insertLayoutItems(); + signals: void spacingChanged(); private: diff --git a/tests/auto/controls/controls.pro b/tests/auto/controls/controls.pro index 8db8bf8f0e5be1c4976ebe0980b660038314e573..4d37c8544e466b70fae11eb9dac519d9ba67c545 100644 --- a/tests/auto/controls/controls.pro +++ b/tests/auto/controls/controls.pro @@ -30,6 +30,7 @@ OTHER_FILES += \ $$PWD/data/tst_page.qml \ $$PWD/data/tst_menubar.qml \ $$PWD/data/tst_rowlayout.qml \ + $$PWD/data/tst_gridlayout.qml \ $$PWD/data/tst_slider.qml \ $$PWD/data/tst_statusbar.qml \ $$PWD/data/tst_tab.qml \ diff --git a/tests/auto/controls/data/tst_gridlayout.qml b/tests/auto/controls/data/tst_gridlayout.qml new file mode 100644 index 0000000000000000000000000000000000000000..da1cd81495ac6bc2928570b205d8af9ffc4fedff --- /dev/null +++ b/tests/auto/controls/data/tst_gridlayout.qml @@ -0,0 +1,326 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the Qt Quick Controls module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** 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 Digia Plc and its Subsidiary(-ies) 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.1 +import QtTest 1.0 +import QtQuick.Layouts 1.0 + +Item { + id: container + width: 200 + height: 200 + TestCase { + id: testCase + name: "Tests_GridLayout" + when: windowShown + width: 200 + height: 200 + + 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 = layout_flowLeftToRight_Component.createObject(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); + + layout.destroy(); + } + + + 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 = layout_flowLeftToRightDefaultPositions_Component.createObject(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); + layout.destroy(); + } + + + 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 = layout_flowTopToBottom_Component.createObject(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); + + layout.destroy(); + } + + } +} diff --git a/tests/manual/Layout.qml b/tests/manual/Layout.qml index 2fe822223263886c47ee0aeb423d81dfb5b6250c..2b4bd2004838cd51e225e9bfe8228bd152075acd 100644 --- a/tests/manual/Layout.qml +++ b/tests/manual/Layout.qml @@ -719,6 +719,67 @@ Item { Text { text: "Norwegian flag" } + // [1] + GridLayout { + columns: 4 + flow: GridLayout.LeftToRight + anchors.left: parent.left + anchors.right: parent.right + Rectangle { + color: "green" + width: 20 + height: 20 + Layout.horizontalSizePolicy: Layout.Expanding + Layout.verticalSizePolicy: Layout.Expanding + } + Rectangle { + color: "green" + width: 20 + height: 20 + Layout.row: 1 + Layout.column: 1 + Layout.rowSpan: 2 + Layout.columnSpan: 2 + Layout.horizontalSizePolicy: Layout.Expanding + Layout.verticalSizePolicy: Layout.Expanding + } + Rectangle { + color: "green" + width: 20 + height: 20 + Layout.row: 0 + Layout.column: 1 + Layout.horizontalSizePolicy: Layout.Expanding + Layout.verticalSizePolicy: Layout.Expanding + } + Rectangle { + color: "green" + width: 20 + height: 20 + Layout.rowSpan: 2 + Layout.horizontalSizePolicy: Layout.Expanding + Layout.verticalSizePolicy: Layout.Expanding + } + Repeater { + model: 10 + Rectangle { + color: Qt.rgba(1, 0, 0, 1 - (index/10.0)) + width: 20 + height: 20 + Layout.horizontalSizePolicy: Layout.Expanding + Layout.verticalSizePolicy: Layout.Expanding + Text { text: index } + } + } + Rectangle { + color: "green" + width: 20 + Layout.columnSpan:2 + height: 20 + Layout.horizontalSizePolicy: Layout.Expanding + Layout.verticalSizePolicy: Layout.Expanding + } + } } } }