diff options
author | Richard Dale <richard.dale@codethink.co.uk> | 2013-07-04 09:56:52 +0100 |
---|---|---|
committer | Richard Dale <richard.dale@codethink.co.uk> | 2013-07-04 09:56:52 +0100 |
commit | acf9e50d52c4d09a1aed9490bb2f3c5de7dce9bb (patch) | |
tree | 5b05df5a9e67f397bc7629f0921bc30c64bcc03e /src/layouts | |
parent | a7e874ddf3496766903fc88e52fb61573c3d3f74 (diff) | |
parent | aa4ddfd8443f07badc0899d835027e46c6e0dfd8 (diff) | |
download | qtquickcontrols-acf9e50d52c4d09a1aed9490bb2f3c5de7dce9bb.tar.gz |
Merge v5.1.0 releasebaserock/morph
Diffstat (limited to 'src/layouts')
-rw-r--r-- | src/layouts/doc/images/rowlayout-minimum.png | bin | 0 -> 5481 bytes | |||
-rw-r--r-- | src/layouts/doc/qtquicklayouts.qdocconf | 35 | ||||
-rw-r--r-- | src/layouts/doc/src/qtquicklayouts-index.qdoc | 26 | ||||
-rw-r--r-- | src/layouts/doc/src/qtquicklayouts-overview.qdoc | 135 | ||||
-rw-r--r-- | src/layouts/doc/src/qtquicklayouts.qdoc | 46 | ||||
-rw-r--r-- | src/layouts/doc/src/snippets/windowconstraints.qml | 89 | ||||
-rw-r--r-- | src/layouts/plugins.qmltypes | 6 | ||||
-rw-r--r-- | src/layouts/qquickgridlayoutengine.cpp | 95 | ||||
-rw-r--r-- | src/layouts/qquickgridlayoutengine_p.h | 10 | ||||
-rw-r--r-- | src/layouts/qquicklayout.cpp | 60 | ||||
-rw-r--r-- | src/layouts/qquicklayout_p.h | 19 | ||||
-rw-r--r-- | src/layouts/qquicklinearlayout.cpp | 121 | ||||
-rw-r--r-- | src/layouts/qquicklinearlayout_p.h | 7 |
13 files changed, 536 insertions, 113 deletions
diff --git a/src/layouts/doc/images/rowlayout-minimum.png b/src/layouts/doc/images/rowlayout-minimum.png Binary files differnew file mode 100644 index 00000000..5875325c --- /dev/null +++ b/src/layouts/doc/images/rowlayout-minimum.png diff --git a/src/layouts/doc/qtquicklayouts.qdocconf b/src/layouts/doc/qtquicklayouts.qdocconf index b5649044..85cb0a57 100644 --- a/src/layouts/doc/qtquicklayouts.qdocconf +++ b/src/layouts/doc/qtquicklayouts.qdocconf @@ -5,31 +5,30 @@ description = Qt Quick Layouts Reference Documentation url = http://qt-project.org/doc/qt-$QT_VER/qtquicklayouts/ version = $QT_VERSION -qhp.projects = qtquicklayouts +qhp.projects = QtQuickLayouts -qhp.qtquicklayouts.file = qtquicklayouts.qhp -qhp.qtquicklayouts.namespace = org.qt-project.qtquicklayouts.$QT_VERSION_TAG -qhp.qtquicklayouts.virtualFolder = qtquicklayouts -qhp.qtquicklayouts.indexTitle = Qt Quick Layouts -qhp.qtquicklayouts.indexRoot = +qhp.QtQuickLayouts.file = qtquicklayouts.qhp +qhp.QtQuickLayouts.namespace = org.qt-project.qtquicklayouts.$QT_VERSION_TAG +qhp.QtQuickLayouts.virtualFolder = qtquicklayouts +qhp.QtQuickLayouts.indexTitle = Qt Quick Layouts +qhp.QtQuickLayouts.indexRoot = -qhp.qtquicklayouts.filterAttributes = qtquicklayouts $QT_VERSION qtrefdoc -qhp.qtquicklayouts.customFilters.Qt.name = QtQuickLayouts $QT_VERSION -qhp.qtquicklayouts.customFilters.Qt.filterAttributes = qtquicklayouts $QT_VERSION +qhp.QtQuickLayouts.filterAttributes = qtquicklayouts $QT_VERSION qtrefdoc +qhp.QtQuickLayouts.customFilters.Qt.name = QtQuickLayouts $QT_VERSION +qhp.QtQuickLayouts.customFilters.Qt.filterAttributes = qtquicklayouts $QT_VERSION -qhp.qtquicklayouts.subprojects = qtquicklayoutsqmltypes -qhp.qtquicklayouts.subprojects.qtquicklayoutsqmltypes.title = QML Types -qhp.qtquicklayouts.subprojects.qtquicklayoutsqmltypes.indexTitle = Qt Quick Layouts -qhp.qtquicklayouts.subprojects.qtquicklayoutsqmltypes.selectors = class fake:headerfile -qhp.qtquicklayouts.subprojects.qtquicklayoutsqmltypes.sortPages = true -qhp.qtquicklayouts.subprojects.qtquicklayoutsqmltypes.type = manual +qhp.QtQuickLayouts.subprojects = qtquicklayoutsqmltypes +qhp.QtQuickLayouts.subprojects.qtquicklayoutsqmltypes.title = QML Types +qhp.QtQuickLayouts.subprojects.qtquicklayoutsqmltypes.indexTitle = Qt Quick Layouts QML Types +qhp.QtQuickLayouts.subprojects.qtquicklayoutsqmltypes.selectors = class fake:qmlclass +qhp.QtQuickLayouts.subprojects.qtquicklayoutsqmltypes.sortPages = true depends = qtqml qtquick qtwidgets qtdoc qtquickcontrols -exampledirs += ../../../examples/quick/controls/ +exampledirs += src/snippets -headerdirs += ../ +headerdirs += .. -sourcedirs += ../ +sourcedirs += .. imagedirs += images diff --git a/src/layouts/doc/src/qtquicklayouts-index.qdoc b/src/layouts/doc/src/qtquicklayouts-index.qdoc index 433de433..58d7fb8c 100644 --- a/src/layouts/doc/src/qtquicklayouts-index.qdoc +++ b/src/layouts/doc/src/qtquicklayouts-index.qdoc @@ -28,23 +28,29 @@ /*! \page qtquicklayouts-index.html \title Qt Quick Layouts - \ingroup qmlmodules - \brief A module with a set of QML elements that arranges QML items in an user interface. + \brief A module with a set of QML elements that arrange QML items in a user interface. - \section1 Getting started + Qt Quick Layouts are a set of QML types used to arrange items in a user interface. In contrast + to \l{Item Positioners}{positioners}, Qt Quick Layouts can also resize their items. This makes + them well suited for resizable user interfaces. Since layouts are items they can consequently + be nested. - The QML types can be imported into your application using the following import statement in your \c {.qml} file. + The module is new in Qt 5.1 and requires \l{Qt Quick} 2.1. - \code - import QtQuick.Layouts 1.0 - \endcode + Visit the \l{Qt Quick Layouts Overview} page to get started. \section1 Layouts - Layouts are items that are used to arrange items in the user interface. The layout is dynamic - - when the layout changes geometry it will typically influence the arrangement of its child - items. Since a layout is an item, layouts can consequently be nested. \annotatedlist layouts + \section1 Related information + + \list + \li \l{Qt Quick} + \li \l{Qt Quick Controls} + \li \l{Qt Quick Layouts Overview} + \li \l{Qt Quick Controls - Basic Layouts Example} + \li \l{Qt Quick Layouts QML Types}{Qt Quick Layouts QML Types} + \endlist */ diff --git a/src/layouts/doc/src/qtquicklayouts-overview.qdoc b/src/layouts/doc/src/qtquicklayouts-overview.qdoc new file mode 100644 index 00000000..3eeb98d2 --- /dev/null +++ b/src/layouts/doc/src/qtquicklayouts-overview.qdoc @@ -0,0 +1,135 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:FDL$ +** 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 Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Free Documentation License Usage +** Alternatively, this file may be used under the terms of the GNU Free +** Documentation License version 1.3 as published by the Free Software +** Foundation and appearing in the file included in the packaging of +** this file. Please review the following information to ensure +** the GNU Free Documentation License version 1.3 requirements +** will be met: http://www.gnu.org/copyleft/fdl.html. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \page qtquicklayouts-overview.html + \title Qt Quick Layouts Overview + \brief A set of APIs for arranging QML items in a user interface. + + Qt Quick Layouts are items that are used to arrange items in a user interface. Since Qt Quick + Layouts also resize their items, they are well suited for resizable user interfaces. + + \section1 Getting started + + The QML types can be imported into your application using the following import statement in your \c {.qml} file. + + \code + import QtQuick.Layouts 1.0 + \endcode + + \section1 Key Features + + + Some of the key features are: + + \list + \li \l{Layout::alignment}{Alignment} of items can be specified with the + \l{Layout::alignment}{Layout.alignment} property + \li \l{Layout::fillWidth}{Resizable items} can be specified with the + \l{Layout::fillWidth}{Layout.fillWidth} and \l{Layout::fillHeight}{Layout.fillHeight} + properties. + \li \l{Size constraints} can be specified with + \l{Layout::minimumWidth}{Layout.minimumWidth}, + \l{Layout::preferredWidth}{Layout.preferredWidth}, and + \l{Layout::maximumWidth}{Layout.maximumWidth} properties ("Width" can be replaced + with "Height" for specifying similar constraints to the height). + \li \l{RowLayout::spacing}{Spacings} can be specified with \l{RowLayout::spacing}{spacing}, + \l{GridLayout::rowSpacing}{rowSpacing} or \l{GridLayout::columnSpacing}{columnSpacing} + \endlist + + In addition to the above features, GridLayout adds these features: + \list + \li \l{Layout::row}{Grid coordinates} can be specified with the \l{Layout::row}{Layout.row} and + \l{Layout::column}{Layout.column}. + \li \l{GridLayout::flow}{Automatic grid coordinates} used together with the + \l{GridLayout::flow}{flow}, \l{GridLayout::rows}{rows}, and + \l{GridLayout::columns}{columns} properties. + \li \l{Layout::columnSpan}{Spans} across rows or columns can be specified with the + \l{Layout::rowSpan}{Layout.rowSpan} and \l{Layout::columnSpan}{Layout.columnSpan} + properties. + \endlist + + + + \section1 Size Constraints + Since an item can be resized by its layout, the layout needs to know the + \l{Layout::minimumWidth}{minimum}, \l{Layout::preferredWidth}{preferred}, + and \l{Layout::maximumWidth}{maximum} sizes of all items where \l{Layout::fillWidth}{Layout.fillWidth} or + \l{Layout::fillHeight}{Layout.fillHeight} is set to \c true. + For instance, the following will produce a layout with two rectangles lying side-by-side that + stretches horizontally. The azure rectangle can be resized from 50x150 to 300x150, and the plum + rectangle can be resized from 100x100 to ∞x100. + + \snippet windowconstraints.qml rowlayout + + \image rowlayout-minimum.png "RowLayout at its minimum" + + Combining each item's constraints will give these implicit constraints to the layout element: + + \table + \header + \li + \li minimum + \li preferred + \li maximum + \row + \li implicit constraints (width) + \li 156 + \li 306 + \li ∞ (\c Number.POSITIVE_INFINITY) + \row + \li implicit constraints (heights) + \li 150 + \li 150 + \li 150 + \endtable + + Thus, the layout cannot be narrower than 156 or be taller or shorter than 150 without breaking + any of the constraints of its child items. + + \section1 Connecting windows and layouts + You can just use normal anchoring concepts to ensure that the layout will follow the window + resizing. + + \snippet windowconstraints.qml anchoring + + The size constraints of layouts can be used to ensure that the window cannot be resized beyond + the layout constraints. You can take the size constraints from the layout and set these + constraints on the minimumWidth, minimumHeight, maximumWidth, and maximumHeight of the Window + element. The following code ensures that the window cannot be resized beyond the constraints of + the layout: + + \snippet windowconstraints.qml bindconstraints + + \note Since layout.Layout.maximumWidth is infinite in this case, we cannot bind that to the + maximumWidth property of Window, since that is an integer number. We therefore set a fixed + maximum width to 1000. + + Finally, you usually want the initial size of the window to be the layout's implicit size: + + \snippet windowconstraints.qml binddefaultsize +*/ diff --git a/src/layouts/doc/src/qtquicklayouts.qdoc b/src/layouts/doc/src/qtquicklayouts.qdoc new file mode 100644 index 00000000..b03ff69b --- /dev/null +++ b/src/layouts/doc/src/qtquicklayouts.qdoc @@ -0,0 +1,46 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:FDL$ +** 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 Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Free Documentation License Usage +** Alternatively, this file may be used under the terms of the GNU Free +** Documentation License version 1.3 as published by the Free Software +** Foundation and appearing in the file included in the packaging of +** this file. Please review the following information to ensure +** the GNU Free Documentation License version 1.3 requirements +** will be met: http://www.gnu.org/copyleft/fdl.html. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \qmlmodule QtQuick.Layouts 1 + \title Qt Quick Layouts QML Types + \ingroup qmlmodules + \brief Provides QML types for arranging QML items in a user interface. + + The \l{Qt Quick Layouts} module provides QML types for arranging + QML items in a user interface. + These QML types work in conjunction with \l{Qt Quick} and + \l{Qt Quick Controls}. + + The QML types can be imported into your application using the + following import statement in your .qml file. + + \code + import QtQuick.Layouts 1.0 + \endcode + +*/ diff --git a/src/layouts/doc/src/snippets/windowconstraints.qml b/src/layouts/doc/src/snippets/windowconstraints.qml new file mode 100644 index 00000000..673169a3 --- /dev/null +++ b/src/layouts/doc/src/snippets/windowconstraints.qml @@ -0,0 +1,89 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the documentation 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.0 +import QtQuick.Controls 1.0 +import QtQuick.Layouts 1.0 + +ApplicationWindow { + //! [binddefaultsize] + width: layout.implicitWidth + height: layout.implicitHeight + //! [binddefaultsize] + //! [bindconstraints] + minimumWidth: layout.Layout.minimumWidth + minimumHeight: layout.Layout.minimumHeight + maximumWidth: 1000 + maximumHeight: layout.Layout.maximumHeight + //! [bindconstraints] + + //! [rowlayout] + //! [anchoring] + RowLayout { + id: layout + anchors.fill: parent + //! [anchoring] + spacing: 6 + Rectangle { + color: 'azure' + Layout.fillWidth: true + Layout.minimumWidth: 50 + Layout.preferredWidth: 100 + Layout.maximumWidth: 300 + Layout.minimumHeight: 150 + Text { + anchors.centerIn: parent + text: parent.width + 'x' + parent.height + } + } + Rectangle { + color: 'plum' + Layout.fillWidth: true + Layout.minimumWidth: 100 + Layout.preferredWidth: 200 + Layout.preferredHeight: 100 + Text { + anchors.centerIn: parent + text: parent.width + 'x' + parent.height + } + } + } + //! [rowlayout] +} diff --git a/src/layouts/plugins.qmltypes b/src/layouts/plugins.qmltypes index c3f1c77c..a0744951 100644 --- a/src/layouts/plugins.qmltypes +++ b/src/layouts/plugins.qmltypes @@ -3,7 +3,7 @@ import QtQuick.tooling 1.1 // This file describes the plugin-supplied types contained in the library. // It is used for QML tooling purposes only. // -// This file was auto-generated with the command '/Users/thohartm/dev/qt5/qtbase/bin/qmlplugindump.app/Contents/MacOS/qmlplugindump QtQuick.Layouts 1.0 -notrelocatable'. +// This file was auto-generated with the command 'qmlplugindump QtQuick.Layouts 1.0 -notrelocatable'. Module { Component { @@ -11,12 +11,14 @@ Module { defaultProperty: "data" prototype: "QQuickLinearLayout" exports: ["QtQuick.Layouts/ColumnLayout 1.0"] + exportMetaObjectRevisions: [0] } Component { name: "QQuickGridLayout" defaultProperty: "data" prototype: "QQuickGridLayoutBase" exports: ["QtQuick.Layouts/GridLayout 1.0"] + exportMetaObjectRevisions: [0] Enum { name: "Flow" values: { @@ -36,6 +38,7 @@ Module { defaultProperty: "data" prototype: "QQuickItem" exports: ["QtQuick.Layouts/Layout 1.0"] + exportMetaObjectRevisions: [0] attachedType: "QQuickLayoutAttached" } Component { @@ -66,5 +69,6 @@ Module { defaultProperty: "data" prototype: "QQuickLinearLayout" exports: ["QtQuick.Layouts/RowLayout 1.0"] + exportMetaObjectRevisions: [0] } } diff --git a/src/layouts/qquickgridlayoutengine.cpp b/src/layouts/qquickgridlayoutengine.cpp index bacfd965..7f65d0d5 100644 --- a/src/layouts/qquickgridlayoutengine.cpp +++ b/src/layouts/qquickgridlayoutengine.cpp @@ -98,14 +98,62 @@ static inline void combineHints(qreal ¤t, qreal fallbackHint) current = fallbackHint; } +static inline void combineSize(QSizeF &result, const QSizeF &fallbackSize) +{ + combineHints(result.rwidth(), fallbackSize.width()); + combineHints(result.rheight(), fallbackSize.height()); +} + +static inline void combineImplicitHints(QQuickLayoutAttached *info, Qt::SizeHint which, QSizeF *size) +{ + if (!info) return; + + Q_ASSERT(which == Qt::MinimumSize || which == Qt::MaximumSize); + + const QSizeF constraint(which == Qt::MinimumSize + ? QSizeF(info->minimumWidth(), info->minimumHeight()) + : QSizeF(info->maximumWidth(), info->maximumHeight())); + + if (!info->isExtentExplicitlySet(Qt::Horizontal, which)) + combineHints(size->rwidth(), constraint.width()); + if (!info->isExtentExplicitlySet(Qt::Vertical, which)) + combineHints(size->rheight(), constraint.height()); +} + /*! \internal Note: Can potentially return the attached QQuickLayoutAttached object through \a attachedInfo. It is like this is because it enables it to be reused. + + The goal of this function is to return the effective minimum, preferred and maximum size hints + that the layout will use for this item. + This function takes care of gathering all explicitly set size hints, normalizes them so + that min < pref < max. + Further, the hints _not_explicitly_ set will then be initialized with the implicit size hints, + which is usually derived from the content of the layouts (or items). + + The following table illustrates the preference of the properties used for measuring layout + items. If present, the USER properties will be preferred. If USER properties are not present, + the HINT properties will be preferred. Finally, the FALLBACK properties will be used as an + ultimate fallback. + + Note that one can query if the value of Layout.minimumWidth or Layout.maximumWidth has been + explicitly or implicitly set with QQuickLayoutAttached::isExtentExplicitlySet(). This + determines if it should be used as a USER or as a HINT value. + + + | *Minimum* | *Preferred* | *Maximum* | ++----------------+----------------------+-----------------------+--------------------------+ +|USER (explicit) | Layout.minimumWidth | Layout.preferredWidth | Layout.maximumWidth | +|HINT (implicit) | Layout.minimumWidth | implicitWidth | Layout.maximumWidth | +|FALLBACK | 0 | width | Number.POSITIVE_INFINITY | ++----------------+----------------------+-----------------------+--------------------------+ */ void QQuickGridLayoutItem::effectiveSizeHints_helper(QQuickItem *item, QSizeF *cachedSizeHints, QQuickLayoutAttached **attachedInfo, bool useFallbackToWidthOrHeight) { + for (int i = 0; i < Qt::NSizeHints; ++i) + cachedSizeHints[i] = QSizeF(); QQuickLayoutAttached *info = attachedLayoutObject(item, false); // First, retrieve the user-specified hints from the attached "Layout." properties if (info) { @@ -123,16 +171,16 @@ void QQuickGridLayoutItem::effectiveSizeHints_helper(QQuickItem *item, QSizeF *c for (int i = 0; i < NSizes; ++i) { SizeGetter getter = horGetters.call[i]; Q_ASSERT(getter); - cachedSizeHints[i].setWidth((info->*getter)()); + + if (info->isExtentExplicitlySet(Qt::Horizontal, (Qt::SizeHint)i)) + cachedSizeHints[i].setWidth((info->*getter)()); + getter = verGetters.call[i]; Q_ASSERT(getter); - cachedSizeHints[i].setHeight((info->*getter)()); + if (info->isExtentExplicitlySet(Qt::Vertical, (Qt::SizeHint)i)) + cachedSizeHints[i].setHeight((info->*getter)()); } - } else { - for (int i = 0; i < NSizes; ++i) - cachedSizeHints[i] = QSize(); } - cachedSizeHints[Qt::MinimumDescent] = QSize(); //### FIXME when baseline support is added QSizeF &minS = cachedSizeHints[Qt::MinimumSize]; QSizeF &prefS = cachedSizeHints[Qt::PreferredSize]; @@ -144,23 +192,21 @@ void QQuickGridLayoutItem::effectiveSizeHints_helper(QQuickItem *item, QSizeF *c // to: [10, 10, 60] normalizeHints(minS.rwidth(), prefS.rwidth(), maxS.rwidth(), descentS.rwidth()); normalizeHints(minS.rheight(), prefS.rheight(), maxS.rheight(), descentS.rheight()); -/* - The following table illustrates the preference of the properties used for measuring layout - items. If present, the USER properties will be preferred. If USER properties are not present, - the HINT 1 properties will be preferred. Finally, the HINT 2 properties will be used as an - ultimate fallback. - - | USER | HINT 1 | HINT 2 - -----+--------------------------------+-------------------+------- - MIN | Layout.minimumWidth | | 0 - PREF | Layout.preferredWidth | implicitWidth | width - MAX | Layout.maximumWidth | | 1000000000 (-1) - -----+--------------------------------+-------------------+-------- -Fixed | Layout.fillWidth | Expanding if layout, Fixed if item | - -*/ + + // All explicit values gathered, now continue to gather the implicit sizes + + //--- GATHER MAXIMUM SIZE HINTS --- + combineImplicitHints(info, Qt::MaximumSize, &maxS); + combineSize(maxS, QSizeF(std::numeric_limits<qreal>::infinity(), std::numeric_limits<qreal>::infinity())); + // implicit max or min sizes should not limit an explicitly set preferred size + expandSize(maxS, prefS); + expandSize(maxS, minS); + //--- GATHER MINIMUM SIZE HINTS --- - // They are always 0 + combineImplicitHints(info, Qt::MinimumSize, &minS); + expandSize(minS, QSizeF(0,0)); + boundSize(minS, prefS); + boundSize(minS, maxS); //--- GATHER PREFERRED SIZE HINTS --- // First, from implicitWidth/Height @@ -203,17 +249,12 @@ Fixed | Layout.fillWidth | Expanding if layout, Fixed if item | item->blockSignals(false); } } - //--- GATHER MAXIMUM SIZE HINTS --- - combineHints(cachedSizeHints[Qt::MaximumSize].rwidth(), std::numeric_limits<qreal>::infinity()); - combineHints(cachedSizeHints[Qt::MaximumSize].rheight(), std::numeric_limits<qreal>::infinity()); //--- GATHER DESCENT // ### Not implemented // Normalize again after the implicit hints have been gathered - expandSize(minS, QSizeF(0,0)); - boundSize(minS, maxS); expandSize(prefS, minS); boundSize(prefS, maxS); diff --git a/src/layouts/qquickgridlayoutengine_p.h b/src/layouts/qquickgridlayoutengine_p.h index 29317ffb..8842d36a 100644 --- a/src/layouts/qquickgridlayoutengine_p.h +++ b/src/layouts/qquickgridlayoutengine_p.h @@ -112,8 +112,16 @@ public: void setGeometry(const QRectF &rect) { const QRect r(rect.toRect()); + const QSize newSize(r.size()); m_item->setPosition(r.topLeft()); - m_item->setSize(r.size()); + QSizeF oldSize(m_item->width(), m_item->height()); + if (newSize == oldSize) { + if (QQuickLayout *lay = qobject_cast<QQuickLayout *>(m_item)) + if (lay->arrangementIsDirty()) + lay->rearrange(newSize); + } else { + m_item->setSize(newSize); + } } QQuickItem *layoutItem() const { return m_item; } diff --git a/src/layouts/qquicklayout.cpp b/src/layouts/qquicklayout.cpp index 48b80255..86eac072 100644 --- a/src/layouts/qquicklayout.cpp +++ b/src/layouts/qquicklayout.cpp @@ -60,11 +60,33 @@ For instance, you can specify \l minimumWidth, \l preferredWidth, and \l maximumWidth if the default values are not satisfactory. - \l fillWidth and \l fillHeight allows you to specify whether an item should - fill the cell(s) it occupies. This allows it to stretch between \l minimumWidth - and \l maximumWidth (or \l minimumHeight and \l maximumHeight if \l fillHeight is \c true). + When a layout is resized, items may grow or shrink. Due to this, items have a + \l{Layout::minimumWidth}{minimum size}, \l{Layout::preferredWidth}{preferred size} and a + \l{Layout::maximumWidth}{maximum size}. + + For each item, preferred size may come from one of several sources. It can be specified with + the \l preferredWidth and \l preferredHeight properties. If these properties are not + specified, it will use the item's \l{Item::implicitWidth}{implicitWidth} or + \l{Item::implicitHeight}{implicitHeight} as the preferred size. + Finally, if neither of these properties are set, it will use the \l{Item::width}{width} and + \l{Item::height}{height} properties of the item. Note that is provided only as a final + fallback. If you want to override the preferred size, you should use + \l preferredWidth or \l preferredHeight. + + If minimum size have not been explicitly specified on an item, the size is set to \c 0. + If maximum size have not been explicitly specified on an item, the size is set to + \c Number.POSITIVE_INFINITY. + + For layouts, the implicit minimum and maximum size depends on the content of the layouts. + + The \l fillWidth and \l fillHeight properties can either be \c true or \c false. If it is \c + false, the item's size will be fixed to its preferred size. Otherwise, it will grow or shrink + between its minimum and maximum size as the layout is resized. + + \note It is not recommended to have bindings to the x, y, width, or height properties of items + in a layout, since this would conflict with the goal of the Layout, and also cause binding + loops. - If \l fillWidth or \l fillHeight is \c false, the items' size will be fixed to its preferred size. \sa GridLayout \sa RowLayout @@ -100,7 +122,7 @@ QQuickLayoutAttached::QQuickLayoutAttached(QObject *parent) } /*! - \qmlproperty real Layout::minimumWidth + \qmlattachedproperty real Layout::minimumWidth This property holds the maximum width of an item in a layout. The default value is the items implicit minimum width. @@ -129,7 +151,7 @@ void QQuickLayoutAttached::setMinimumWidth(qreal width) } /*! - \qmlproperty real Layout::minimumHeight + \qmlattachedproperty real Layout::minimumHeight The default value is the items implicit minimum height. @@ -156,7 +178,7 @@ void QQuickLayoutAttached::setMinimumHeight(qreal height) } /*! - \qmlproperty real Layout::preferredWidth + \qmlattachedproperty real Layout::preferredWidth This property holds the preferred width of an item in a layout. If the preferred width is -1 it will be ignored, and the layout @@ -177,7 +199,7 @@ void QQuickLayoutAttached::setPreferredWidth(qreal width) } /*! - \qmlproperty real Layout::preferredHeight + \qmlattachedproperty real Layout::preferredHeight This property holds the preferred height of an item in a layout. If the preferred height is -1 it will be ignored, and the layout @@ -198,14 +220,14 @@ void QQuickLayoutAttached::setPreferredHeight(qreal height) } /*! - \qmlproperty real Layout::maximumWidth + \qmlattachedproperty real Layout::maximumWidth This property holds the maximum width of an item in a layout. The default value is the items implicit maximum width. If the item is a layout, the implicit maximum width will be the maximum width the layout can have without any of its items grow beyond their maximum width. - The implicit maximum width for any other item is \c Number.POSITIVE_INFINITE. + The implicit maximum width for any other item is \c Number.POSITIVE_INFINITY. Setting this value to -1 will reset the width back to its implicit maximum width. @@ -226,13 +248,13 @@ void QQuickLayoutAttached::setMaximumWidth(qreal width) } /*! - \qmlproperty real Layout::maximumHeight + \qmlattachedproperty real Layout::maximumHeight The default value is the items implicit maximum height. If the item is a layout, the implicit maximum height will be the maximum height the layout can have without any of its items grow beyond their maximum height. - The implicit maximum height for any other item is \c Number.POSITIVE_INFINITE. + The implicit maximum height for any other item is \c Number.POSITIVE_INFINITY. Setting this value to -1 will reset the height back to its implicit maximum height. @@ -299,7 +321,7 @@ void QQuickLayoutAttached::setMaximumImplicitSize(const QSizeF &sz) } /*! - \qmlproperty bool Layout::fillWidth + \qmlattachedproperty bool Layout::fillWidth If this property is \c true, the item will be as wide as possible while respecting the given constraints. If the property is \c false, the item will have a fixed width @@ -319,7 +341,7 @@ void QQuickLayoutAttached::setFillWidth(bool fill) } /*! - \qmlproperty bool Layout::fillHeight + \qmlattachedproperty bool Layout::fillHeight If this property is \c true, the item will be as tall as possible while respecting the given constraints. If the property is \c false, the item will have a fixed height @@ -339,7 +361,7 @@ void QQuickLayoutAttached::setFillHeight(bool fill) } /*! - \qmlproperty int Layout::row + \qmlattachedproperty int Layout::row This property allows you to specify the row position of an item in a \l GridLayout. @@ -357,7 +379,7 @@ void QQuickLayoutAttached::setRow(int row) } /*! - \qmlproperty int Layout::column + \qmlattachedproperty int Layout::column This property allows you to specify the column position of an item in a \l GridLayout. @@ -376,7 +398,7 @@ void QQuickLayoutAttached::setColumn(int column) /*! - \qmlproperty Qt.Alignment Layout::alignment + \qmlattachedproperty Qt.Alignment Layout::alignment This property allows you to specify the alignment of an item within the cell(s) it occupies. @@ -385,7 +407,7 @@ void QQuickLayoutAttached::setColumn(int column) /*! - \qmlproperty int Layout::rowSpan + \qmlattachedproperty int Layout::rowSpan This property allows you to specify the row span of an item in a \l GridLayout. @@ -397,7 +419,7 @@ void QQuickLayoutAttached::setColumn(int column) /*! - \qmlproperty int Layout::columnSpan + \qmlattachedproperty int Layout::columnSpan This property allows you to specify the column span of an item in a \l GridLayout. diff --git a/src/layouts/qquicklayout_p.h b/src/layouts/qquicklayout_p.h index 8a334677..76c19717 100644 --- a/src/layouts/qquicklayout_p.h +++ b/src/layouts/qquicklayout_p.h @@ -77,9 +77,10 @@ public: void componentComplete(); virtual QSizeF sizeHint(Qt::SizeHint whichSizeHint) const = 0; virtual void invalidate(QQuickItem * childItem = 0); + virtual void rearrange(const QSizeF &); + bool arrangementIsDirty() const { return m_dirty; } protected: bool event(QEvent *e); - virtual void rearrange(const QSizeF &); enum Orientation { Vertical = 0, @@ -175,6 +176,22 @@ public: qreal sizeHint(Qt::SizeHint which, Qt::Orientation orientation) const; + bool isExtentExplicitlySet(Qt::Orientation o, Qt::SizeHint whichSize) const + { + switch (whichSize) { + case Qt::MinimumSize: + return o == Qt::Horizontal ? m_isMinimumWidthSet : m_isMinimumHeightSet; + case Qt::MaximumSize: + return o == Qt::Horizontal ? m_isMaximumWidthSet : m_isMaximumHeightSet; + case Qt::PreferredSize: + return true; // Layout.preferredWidth is always explicitly set + case Qt::MinimumDescent: // Not supported + case Qt::NSizeHints: + return false; + } + return false; + } + signals: void minimumWidthChanged(); void minimumHeightChanged(); diff --git a/src/layouts/qquicklinearlayout.cpp b/src/layouts/qquicklinearlayout.cpp index 541e4aca..931bfed5 100644 --- a/src/layouts/qquicklinearlayout.cpp +++ b/src/layouts/qquicklinearlayout.cpp @@ -48,33 +48,67 @@ /*! \qmltype RowLayout \instantiates QQuickRowLayout + \inherits Item \inqmlmodule QtQuick.Layouts 1.0 \ingroup layouts \brief Identical to \l GridLayout, but having only one row. It is available as a convenience for developers, as it offers a cleaner API. + Items in a RowLayout support these attached properties: + \list + \li \l{Layout::minimumWidth}{Layout.minimumWidth} + \li \l{Layout::minimumHeight}{Layout.minimumHeight} + \li \l{Layout::preferredWidth}{Layout.preferredWidth} + \li \l{Layout::preferredHeight}{Layout.preferredHeight} + \li \l{Layout::maximumWidth}{Layout.maximumWidth} + \li \l{Layout::maximumHeight}{Layout.maximumHeight} + \li \l{Layout::fillWidth}{Layout.fillWidth} + \li \l{Layout::fillHeight}{Layout.fillHeight} + \li \l{Layout::alignment}{Layout.alignment} + \endlist + + Read more about attached properties \l{QML Object Attributes}{here}. \sa ColumnLayout \sa GridLayout + \sa Row */ /*! \qmltype ColumnLayout \instantiates QQuickColumnLayout + \inherits Item \inqmlmodule QtQuick.Layouts 1.0 \ingroup layouts \brief Identical to \l GridLayout, but having only one column. It is available as a convenience for developers, as it offers a cleaner API. + Items in a ColumnLayout support these attached properties: + \list + \li \l{Layout::minimumWidth}{Layout.minimumWidth} + \li \l{Layout::minimumHeight}{Layout.minimumHeight} + \li \l{Layout::preferredWidth}{Layout.preferredWidth} + \li \l{Layout::preferredHeight}{Layout.preferredHeight} + \li \l{Layout::maximumWidth}{Layout.maximumWidth} + \li \l{Layout::maximumHeight}{Layout.maximumHeight} + \li \l{Layout::fillWidth}{Layout.fillWidth} + \li \l{Layout::fillHeight}{Layout.fillHeight} + \li \l{Layout::alignment}{Layout.alignment} + \endlist + + Read more about attached properties \l{QML Object Attributes}{here}. + \sa RowLayout \sa GridLayout + \sa Column */ /*! \qmltype GridLayout \instantiates QQuickGridLayout + \inherits Item \inqmlmodule QtQuick.Layouts 1.0 \ingroup layouts \brief Provides a way of dynamically arranging items in a grid. @@ -112,39 +146,44 @@ specify the row span or column span by setting the \l{Layout::rowSpan}{Layout.rowSpan} or \l{Layout::columnSpan}{Layout.columnSpan} properties. - When the layout is resized, items may grow or shrink. Due to this, items have a - \l{Layout::minimumWidth}{minimum size}, \l{Layout::preferredWidth}{preferred size} and a - \l{Layout::maximumWidth}{maximum size}. - - Preferred size may come from one of several sources. It can be specified with the - \l{Layout::preferredWidth}{Layout.preferredWidth} and - \l{Layout::preferredHeight}{Layout.preferredHeight} properties. If these properties are not - specified, it will use the items' \l{Item::implicitWidth}{implicitWidth} or - \l{Item::implicitHeight}{implicitHeight} as the preferred size. - Finally, if neither of these properties are set, it will use the \l{Item::width}{width} and - \l{Item::height}{height} properties of the item. Note that is provided only as a final - fallback. If you want to override the preferred size, you should use - \l{Layout::preferredWidth}{Layout.preferredWidth} or - \l{Layout::preferredHeight}{Layout.preferredHeight}. - The \l{Layout::fillWidth}{Layout.fillWidth} and \l{Layout::fillHeight}{Layout.fillHeight} can - either be \c true or \c false. If it is \c false, the items size will be fixed to its preferred - size. Otherwise, it will grow or shrink between its minimum and maximum size. + Items in a GridLayout support these attached properties: + \list + \li \l{Layout::row}{Layout.row} + \li \l{Layout::column}{Layout.column} + \li \l{Layout::rowSpan}{Layout.rowSpan} + \li \l{Layout::columnSpan}{Layout.columnSpan} + \li \l{Layout::minimumWidth}{Layout.minimumWidth} + \li \l{Layout::minimumHeight}{Layout.minimumHeight} + \li \l{Layout::preferredWidth}{Layout.preferredWidth} + \li \l{Layout::preferredHeight}{Layout.preferredHeight} + \li \l{Layout::maximumWidth}{Layout.maximumWidth} + \li \l{Layout::maximumHeight}{Layout.maximumHeight} + \li \l{Layout::fillWidth}{Layout.fillWidth} + \li \l{Layout::fillHeight}{Layout.fillHeight} + \li \l{Layout::alignment}{Layout.alignment} + \endlist - \note It is not recommended to have bindings to the width and height properties of items in a - GridLayout, since this would conflict with the goal of the GridLayout. + Read more about attached properties \l{QML Object Attributes}{here}. \sa RowLayout \sa ColumnLayout - + \sa Grid */ QT_BEGIN_NAMESPACE -static const qreal q_declarativeLayoutDefaultSpacing = 4.0; - +static qreal quickLayoutDefaultSpacing() +{ + qreal spacing = 5.0; +#ifndef Q_OS_MAC + // On mac the DPI is always 72 so we should not scale it + spacing = qRound(spacing * (qreal(qt_defaultDpiX()) / 96.0)); +#endif + return spacing; +} QQuickGridLayoutBase::QQuickGridLayoutBase(QQuickGridLayoutBasePrivate &dd, Qt::Orientation orientation, @@ -177,12 +216,18 @@ QSizeF QQuickGridLayoutBase::sizeHint(Qt::SizeHint whichSizeHint) const return d->engine.sizeHint(whichSizeHint, QSizeF()); } +QQuickGridLayoutBase::~QQuickGridLayoutBase() +{ + d_func()->m_isReady = false; +} + void QQuickGridLayoutBase::componentComplete() { Q_D(QQuickGridLayoutBase); quickLayoutDebug() << objectName() << "QQuickGridLayoutBase::componentComplete()" << parent(); d->m_disableRearrange = true; QQuickLayout::componentComplete(); // will call our geometryChange(), (where isComponentComplete() == true) + d->m_isReady = true; d->m_disableRearrange = false; updateLayoutItems(); @@ -228,7 +273,7 @@ void QQuickGridLayoutBase::componentComplete() void QQuickGridLayoutBase::invalidate(QQuickItem *childItem) { Q_D(QQuickGridLayoutBase); - if (!isComponentComplete()) + if (!isReady()) return; quickLayoutDebug() << "QQuickGridLayoutBase::invalidate()"; @@ -267,7 +312,7 @@ void QQuickGridLayoutBase::invalidate(QQuickItem *childItem) void QQuickGridLayoutBase::updateLayoutItems() { Q_D(QQuickGridLayoutBase); - if (!isComponentComplete() || !isVisible()) + if (!isReady() || !isVisible()) return; quickLayoutDebug() << "QQuickGridLayoutBase::updateLayoutItems"; d->engine.deleteItems(); @@ -287,7 +332,7 @@ void QQuickGridLayoutBase::itemChange(ItemChange change, const ItemChangeData &v QObject::connect(item, SIGNAL(implicitWidthChanged()), this, SLOT(onItemImplicitSizeChanged())); QObject::connect(item, SIGNAL(implicitHeightChanged()), this, SLOT(onItemImplicitSizeChanged())); - if (isComponentComplete() && isVisible()) + if (isReady() && isVisible()) updateLayoutItems(); } else if (change == ItemChildRemovedChange) { quickLayoutDebug() << "ItemChildRemovedChange"; @@ -296,7 +341,7 @@ void QQuickGridLayoutBase::itemChange(ItemChange change, const ItemChangeData &v QObject::disconnect(item, SIGNAL(visibleChanged()), this, SLOT(onItemVisibleChanged())); QObject::disconnect(item, SIGNAL(implicitWidthChanged()), this, SLOT(onItemImplicitSizeChanged())); QObject::disconnect(item, SIGNAL(implicitHeightChanged()), this, SLOT(onItemImplicitSizeChanged())); - if (isComponentComplete() && isVisible()) + if (isReady() && isVisible()) updateLayoutItems(); } @@ -307,7 +352,7 @@ void QQuickGridLayoutBase::geometryChanged(const QRectF &newGeometry, const QRec { Q_D(QQuickGridLayoutBase); QQuickLayout::geometryChanged(newGeometry, oldGeometry); - if (d->m_disableRearrange || !isComponentComplete() || !newGeometry.isValid()) + if (d->m_disableRearrange || !isReady() || !newGeometry.isValid()) return; quickLayoutDebug() << "QQuickGridLayoutBase::geometryChanged" << newGeometry << oldGeometry; rearrange(newGeometry.size()); @@ -321,6 +366,11 @@ void QQuickGridLayoutBase::removeGridItem(QGridLayoutItem *gridItem) d->engine.removeRows(index, 1, d->orientation); } +bool QQuickGridLayoutBase::isReady() const +{ + return d_func()->m_isReady; +} + void QQuickGridLayoutBase::removeLayoutItem(QQuickItem *item) { Q_D(QQuickGridLayoutBase); @@ -334,7 +384,7 @@ void QQuickGridLayoutBase::removeLayoutItem(QQuickItem *item) void QQuickGridLayoutBase::onItemVisibleChanged() { - if (!isComponentComplete()) + if (!isReady()) return; quickLayoutDebug() << "QQuickGridLayoutBase::onItemVisibleChanged"; updateLayoutItems(); @@ -342,6 +392,8 @@ void QQuickGridLayoutBase::onItemVisibleChanged() void QQuickGridLayoutBase::onItemDestroyed() { + if (!isReady()) + return; Q_D(QQuickGridLayoutBase); quickLayoutDebug() << "QQuickGridLayoutBase::onItemDestroyed"; QQuickItem *inDestruction = static_cast<QQuickItem *>(sender()); @@ -354,6 +406,8 @@ void QQuickGridLayoutBase::onItemDestroyed() void QQuickGridLayoutBase::onItemImplicitSizeChanged() { + if (!isReady()) + return; QQuickItem *item = static_cast<QQuickItem *>(sender()); Q_ASSERT(item); invalidate(item); @@ -362,7 +416,7 @@ void QQuickGridLayoutBase::onItemImplicitSizeChanged() void QQuickGridLayoutBase::rearrange(const QSizeF &size) { Q_D(QQuickGridLayoutBase); - if (!isComponentComplete()) + if (!isReady()) return; quickLayoutDebug() << objectName() << "QQuickGridLayoutBase::rearrange()" << size; @@ -412,9 +466,10 @@ QQuickGridLayout::QQuickGridLayout(QQuickItem *parent /* = 0*/) : QQuickGridLayoutBase(*new QQuickGridLayoutPrivate, Qt::Horizontal, parent) { Q_D(QQuickGridLayout); - d->columnSpacing = q_declarativeLayoutDefaultSpacing; - d->rowSpacing = q_declarativeLayoutDefaultSpacing; - d->engine.setSpacing(q_declarativeLayoutDefaultSpacing, Qt::Horizontal | Qt::Vertical); + const qreal defaultSpacing = quickLayoutDefaultSpacing(); + d->columnSpacing = defaultSpacing; + d->rowSpacing = defaultSpacing; + d->engine.setSpacing(defaultSpacing, Qt::Horizontal | Qt::Vertical); } /*! @@ -672,7 +727,7 @@ QQuickLinearLayout::QQuickLinearLayout(Qt::Orientation orientation, : QQuickGridLayoutBase(*new QQuickLinearLayoutPrivate, orientation, parent) { Q_D(QQuickLinearLayout); - d->spacing = q_declarativeLayoutDefaultSpacing; + d->spacing = quickLayoutDefaultSpacing(); d->engine.setSpacing(d->spacing, Qt::Horizontal | Qt::Vertical); } diff --git a/src/layouts/qquicklinearlayout_p.h b/src/layouts/qquicklinearlayout_p.h index 76cc206b..b38bd97f 100644 --- a/src/layouts/qquicklinearlayout_p.h +++ b/src/layouts/qquicklinearlayout_p.h @@ -62,8 +62,7 @@ public: explicit QQuickGridLayoutBase(QQuickGridLayoutBasePrivate &dd, Qt::Orientation orientation, QQuickItem *parent = 0); - ~QQuickGridLayoutBase() {} - + ~QQuickGridLayoutBase(); void componentComplete(); void invalidate(QQuickItem *childItem = 0); Qt::Orientation orientation() const; @@ -86,6 +85,7 @@ protected slots: private: void removeGridItem(QGridLayoutItem *gridItem); + bool isReady() const; Q_DECLARE_PRIVATE(QQuickGridLayoutBase) }; @@ -95,10 +95,11 @@ class QQuickGridLayoutBasePrivate : public QQuickLayoutPrivate Q_DECLARE_PUBLIC(QQuickGridLayoutBase) public: - QQuickGridLayoutBasePrivate() : m_disableRearrange(true) { } + QQuickGridLayoutBasePrivate() : m_disableRearrange(true), m_isReady(false) { } QQuickGridLayoutEngine engine; Qt::Orientation orientation; bool m_disableRearrange; + bool m_isReady; QSet<QQuickItem *> m_ignoredItems; }; |