From 12115bbda219a651ef86a4e91fd5e52eb54ed29b Mon Sep 17 00:00:00 2001 From: Fabian Kosmale Date: Fri, 15 Jan 2021 10:45:18 +0100 Subject: Quick.Layouts: Make plugin optional This moves the Layouts types into a new library and is meant to make them availabe to the QML compiler at some point in the future. Change-Id: I9b2b31a78b0e9ca8b6c0db1fc9272d9941c61814 Reviewed-by: Maximilian Goldstein Reviewed-by: Ulf Hermann --- src/imports/layouts/CMakeLists.txt | 16 +- src/imports/layouts/plugin.cpp | 6 +- src/imports/layouts/qquickgridlayoutengine.cpp | 61 -- src/imports/layouts/qquickgridlayoutengine_p.h | 165 --- src/imports/layouts/qquicklayout.cpp | 1308 ------------------------ src/imports/layouts/qquicklayout_p.h | 366 ------- src/imports/layouts/qquicklayoutstyleinfo.cpp | 80 -- src/imports/layouts/qquicklayoutstyleinfo_p.h | 60 -- src/imports/layouts/qquicklinearlayout.cpp | 888 ---------------- src/imports/layouts/qquicklinearlayout_p.h | 260 ----- src/imports/layouts/qquickstacklayout.cpp | 489 --------- src/imports/layouts/qquickstacklayout_p.h | 149 --- 12 files changed, 6 insertions(+), 3842 deletions(-) delete mode 100644 src/imports/layouts/qquickgridlayoutengine.cpp delete mode 100644 src/imports/layouts/qquickgridlayoutengine_p.h delete mode 100644 src/imports/layouts/qquicklayout.cpp delete mode 100644 src/imports/layouts/qquicklayout_p.h delete mode 100644 src/imports/layouts/qquicklayoutstyleinfo.cpp delete mode 100644 src/imports/layouts/qquicklayoutstyleinfo_p.h delete mode 100644 src/imports/layouts/qquicklinearlayout.cpp delete mode 100644 src/imports/layouts/qquicklinearlayout_p.h delete mode 100644 src/imports/layouts/qquickstacklayout.cpp delete mode 100644 src/imports/layouts/qquickstacklayout_p.h (limited to 'src/imports') diff --git a/src/imports/layouts/CMakeLists.txt b/src/imports/layouts/CMakeLists.txt index 1beb4ee126..f0f957c024 100644 --- a/src/imports/layouts/CMakeLists.txt +++ b/src/imports/layouts/CMakeLists.txt @@ -4,30 +4,24 @@ ## qquicklayoutsplugin Plugin: ##################################################################### + qt_internal_add_qml_module(qquicklayoutsplugin URI "QtQuick.Layouts" VERSION "${CMAKE_PROJECT_VERSION}" DESIGNER_SUPPORTED CLASSNAME QtQuickLayoutsPlugin SKIP_TYPE_REGISTRATION - GENERATE_QMLTYPES - INSTALL_QMLTYPES + PLUGIN_OPTIONAL SOURCES plugin.cpp - qquickgridlayoutengine.cpp qquickgridlayoutengine_p.h - qquicklayout.cpp qquicklayout_p.h - qquicklayoutstyleinfo.cpp qquicklayoutstyleinfo_p.h - qquicklinearlayout.cpp qquicklinearlayout_p.h - qquickstacklayout.cpp qquickstacklayout_p.h PUBLIC_LIBRARIES Qt::Core - Qt::CorePrivate Qt::Gui - Qt::GuiPrivate - Qt::QmlPrivate - Qt::QuickPrivate + Qt::Qml + Qt::QuickLayoutsPrivate ) + #### Keys ignored in scope 1:.:.:layouts.pro:: # CXX_MODULE = "qml" # QML_IMPORT_VERSION = "$$QT_VERSION" diff --git a/src/imports/layouts/plugin.cpp b/src/imports/layouts/plugin.cpp index af270c1732..7e0c4ef053 100644 --- a/src/imports/layouts/plugin.cpp +++ b/src/imports/layouts/plugin.cpp @@ -38,11 +38,7 @@ ****************************************************************************/ #include - -#include "qquicklinearlayout_p.h" -#include "qquickstacklayout_p.h" - -extern void qml_register_types_QtQuick_Layouts(); +#include QT_BEGIN_NAMESPACE diff --git a/src/imports/layouts/qquickgridlayoutengine.cpp b/src/imports/layouts/qquickgridlayoutengine.cpp deleted file mode 100644 index 5275d70c39..0000000000 --- a/src/imports/layouts/qquickgridlayoutengine.cpp +++ /dev/null @@ -1,61 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Quick Layouts module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** 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. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qquickitem.h" -#include "qquickgridlayoutengine_p.h" -#include "qquicklayout_p.h" - -QT_BEGIN_NAMESPACE - -void QQuickGridLayoutEngine::setAlignment(QQuickItem *quickItem, Qt::Alignment alignment) -{ - if (QQuickGridLayoutItem *item = findLayoutItem(quickItem)) { - item->setAlignment(alignment); - invalidate(); - } -} - -Qt::Alignment QQuickGridLayoutEngine::alignment(QQuickItem *quickItem) const -{ - if (QGridLayoutItem *item = findLayoutItem(quickItem)) - return item->alignment(); - return {}; -} - -QT_END_NAMESPACE diff --git a/src/imports/layouts/qquickgridlayoutengine_p.h b/src/imports/layouts/qquickgridlayoutengine_p.h deleted file mode 100644 index ff42fa4d43..0000000000 --- a/src/imports/layouts/qquickgridlayoutengine_p.h +++ /dev/null @@ -1,165 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Quick Layouts module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** 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. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QQUICKGRIDLAYOUTENGINE_P_H -#define QQUICKGRIDLAYOUTENGINE_P_H - -// -// W A R N I N G -// ------------- -// -// This file is not part of the Qt API. It exists for the convenience -// of the graphics view layout classes. This header -// file may change from version to version without notice, or even be removed. -// -// We mean it. -// - -#include -#include -#include - -#include "qquickitem.h" -#include "qquicklayout_p.h" -#include "qdebug.h" -QT_BEGIN_NAMESPACE - -class QQuickGridLayoutItem : public QGridLayoutItem { -public: - QQuickGridLayoutItem(QQuickItem *item, int row, int column, - int rowSpan = 1, int columnSpan = 1, Qt::Alignment alignment = { }) - : QGridLayoutItem(row, column, rowSpan, columnSpan, alignment), m_item(item), sizeHintCacheDirty(true), useFallbackToWidthOrHeight(true) {} - - - QSizeF sizeHint(Qt::SizeHint which, const QSizeF &constraint) const override - { - Q_UNUSED(constraint); // Quick Layouts does not support constraint atm - return effectiveSizeHints()[which]; - } - - QSizeF *effectiveSizeHints() const - { - if (!sizeHintCacheDirty) - return cachedSizeHints; - - QQuickLayout::effectiveSizeHints_helper(m_item, cachedSizeHints, 0, useFallbackToWidthOrHeight); - useFallbackToWidthOrHeight = false; - - sizeHintCacheDirty = false; - return cachedSizeHints; - } - - void setCachedSizeHints(QSizeF *sizeHints) - { - for (int i = 0; i < Qt::NSizeHints; ++i) { - cachedSizeHints[i] = sizeHints[i]; - } - sizeHintCacheDirty = false; - } - - void invalidate() - { - qCDebug(lcQuickLayouts) << "QQuickGridLayoutItem::invalidate()"; - sizeHintCacheDirty = true; - } - - QLayoutPolicy::Policy sizePolicy(Qt::Orientation orientation) const override - { - return QQuickLayout::effectiveSizePolicy_helper(m_item, orientation, attachedLayoutObject(m_item, false)); - } - - void setGeometry(const QRectF &rect) override - { - QQuickLayoutAttached *info = attachedLayoutObject(m_item, false); - const QRectF r = info ? rect.marginsRemoved(info->effectiveQMargins()) : rect; - const QSizeF oldSize(m_item->width(), m_item->height()); - const QSizeF newSize = r.size(); - m_item->setPosition(r.topLeft()); - if (newSize == oldSize) { - // We need to enforce a rearrange when the geometry is the same - if (QQuickLayout *lay = qobject_cast(m_item)) { - if (lay->invalidatedArrangement()) - lay->rearrange(newSize); - } - } else { - m_item->setSize(newSize); - } - } - - QQuickItem *layoutItem() const { return m_item; } - - QQuickItem *m_item; -private: - mutable QSizeF cachedSizeHints[Qt::NSizeHints]; - mutable unsigned sizeHintCacheDirty : 1; - mutable unsigned useFallbackToWidthOrHeight : 1; -}; - -class QQuickGridLayoutEngine : public QGridLayoutEngine { -public: - QQuickGridLayoutEngine() : QGridLayoutEngine(Qt::AlignVCenter, true /*snapToPixelGrid*/) { } - - int indexOf(QQuickItem *item) const { - for (int i = 0; i < q_items.size(); ++i) { - if (item == static_cast(q_items.at(i))->layoutItem()) - return i; - } - return -1; - } - - QQuickGridLayoutItem *findLayoutItem(QQuickItem *layoutItem) const - { - for (int i = q_items.count() - 1; i >= 0; --i) { - QQuickGridLayoutItem *item = static_cast(q_items.at(i)); - if (item->layoutItem() == layoutItem) - return item; - } - return 0; - } - - void setAlignment(QQuickItem *quickItem, Qt::Alignment alignment); - Qt::Alignment alignment(QQuickItem *quickItem) const; - -}; - - - -QT_END_NAMESPACE - -#endif // QQUICKGRIDLAYOUTENGINE_P_H diff --git a/src/imports/layouts/qquicklayout.cpp b/src/imports/layouts/qquicklayout.cpp deleted file mode 100644 index dbbd25de85..0000000000 --- a/src/imports/layouts/qquicklayout.cpp +++ /dev/null @@ -1,1308 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Quick Layouts module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** 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. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qquicklayout_p.h" -#include -#include -#include -#include -#include -#include -#include - -/*! - \qmltype Layout - \instantiates QQuickLayoutAttached - \inqmlmodule QtQuick.Layouts - \ingroup layouts - \brief Provides attached properties for items pushed onto a \l GridLayout, - \l RowLayout or \l ColumnLayout. - - An object of type Layout is attached to children of the layout to provide layout specific - information about the item. - The properties of the attached object influence how the layout will arrange the items. - - For instance, you can specify \l minimumWidth, \l preferredWidth, and - \l maximumWidth if the default values are not satisfactory. - - 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}. - - If minimum size has not been explicitly specified on an item, the size is set to \c 0. - If maximum size has not been explicitly specified on an item, the size is set to - \c Number.POSITIVE_INFINITY. - - For layouts, the implicit minimum and maximum sizes depend on the content of the layouts. - - The \l fillWidth and \l fillHeight properties can either be \c true or \c false. If they are \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 Do not bind to the x, y, width, or height properties of items in a layout, - as this would conflict with the goals of Layout, and can also cause binding loops. - The width and height properties are used by the layout engine to store the current - size of items as calculated from the minimum/preferred/maximum attached properties, - and can be ovewritten each time the items are laid out. Use - \l {Layout::preferredWidth}{Layout.preferredWidth} and - \l {Layout::preferredHeight}{Layout.preferredHeight}, or \l {Item::}{implicitWidth} - and \l {Item::}{implicitHeight} to specify the preferred size of items. - - \sa GridLayout - \sa RowLayout - \sa ColumnLayout -*/ - -QT_BEGIN_NAMESPACE - -Q_LOGGING_CATEGORY(lcQuickLayouts, "qt.quick.layouts") - -QQuickLayoutAttached::QQuickLayoutAttached(QObject *parent) - : QObject(parent), - m_minimumWidth(0), - m_minimumHeight(0), - m_preferredWidth(-1), - m_preferredHeight(-1), - m_maximumWidth(std::numeric_limits::infinity()), - m_maximumHeight(std::numeric_limits::infinity()), - m_defaultMargins(0), - m_fallbackWidth(-1), - m_fallbackHeight(-1), - m_row(-1), - m_column(-1), - m_rowSpan(1), - m_columnSpan(1), - m_fillWidth(false), - m_fillHeight(false), - m_isFillWidthSet(false), - m_isFillHeightSet(false), - m_isMinimumWidthSet(false), - m_isMinimumHeightSet(false), - m_isMaximumWidthSet(false), - m_isMaximumHeightSet(false), - m_changesNotificationEnabled(true), - m_isLeftMarginSet(false), - m_isTopMarginSet(false), - m_isRightMarginSet(false), - m_isBottomMarginSet(false) -{ - -} - -/*! - \qmlattachedproperty real Layout::minimumWidth - - This property holds the minimum width of an item in a layout. - The default value is the item's implicit minimum width. - - If the item is a layout, the implicit minimum width will be the minimum width the layout can - have without any of its items shrinking below their minimum width. - The implicit minimum width for any other item is \c 0. - - Setting this value to -1 will reset the width back to its implicit minimum width. - - - \sa preferredWidth - \sa maximumWidth -*/ -void QQuickLayoutAttached::setMinimumWidth(qreal width) -{ - if (qt_is_nan(width)) - return; - m_isMinimumWidthSet = width >= 0; - if (m_minimumWidth == width) - return; - - m_minimumWidth = width; - invalidateItem(); - emit minimumWidthChanged(); -} - -/*! - \qmlattachedproperty real Layout::minimumHeight - - This property holds the minimum height of an item in a layout. - The default value is the item's implicit minimum height. - - If the item is a layout, the implicit minimum height will be the minimum height the layout can - have without any of its items shrinking below their minimum height. - The implicit minimum height for any other item is \c 0. - - Setting this value to -1 will reset the height back to its implicit minimum height. - - \sa preferredHeight - \sa maximumHeight -*/ -void QQuickLayoutAttached::setMinimumHeight(qreal height) -{ - if (qt_is_nan(height)) - return; - m_isMinimumHeightSet = height >= 0; - if (m_minimumHeight == height) - return; - - m_minimumHeight = height; - invalidateItem(); - emit minimumHeightChanged(); -} - -/*! - \qmlattachedproperty real Layout::preferredWidth - - This property holds the preferred width of an item in a layout. - If the preferred width is \c -1 it will be ignored, and the layout - will use \l{Item::implicitWidth}{implicitWidth} instead. - The default is \c -1. - - \sa minimumWidth - \sa maximumWidth -*/ -void QQuickLayoutAttached::setPreferredWidth(qreal width) -{ - if (qt_is_nan(width) || m_preferredWidth == width) - return; - - m_preferredWidth = width; - invalidateItem(); - emit preferredWidthChanged(); -} - -/*! - \qmlattachedproperty real Layout::preferredHeight - - This property holds the preferred height of an item in a layout. - If the preferred height is \c -1 it will be ignored, and the layout - will use \l{Item::implicitHeight}{implicitHeight} instead. - The default is \c -1. - - \sa minimumHeight - \sa maximumHeight -*/ -void QQuickLayoutAttached::setPreferredHeight(qreal height) -{ - if (qt_is_nan(height) || m_preferredHeight == height) - return; - - m_preferredHeight = height; - invalidateItem(); - emit preferredHeightChanged(); -} - -/*! - \qmlattachedproperty real Layout::maximumWidth - - This property holds the maximum width of an item in a layout. - The default value is the item's 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 growing beyond their maximum width. - The implicit maximum width for any other item is \c Number.POSITIVE_INFINITY. - - Setting this value to \c -1 will reset the width back to its implicit maximum width. - - \sa minimumWidth - \sa preferredWidth -*/ -void QQuickLayoutAttached::setMaximumWidth(qreal width) -{ - if (qt_is_nan(width)) - return; - m_isMaximumWidthSet = width >= 0; - if (m_maximumWidth == width) - return; - - m_maximumWidth = width; - invalidateItem(); - emit maximumWidthChanged(); -} - -/*! - \qmlattachedproperty real Layout::maximumHeight - - The default value is the item's 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 growing beyond their maximum height. - The implicit maximum height for any other item is \c Number.POSITIVE_INFINITY. - - Setting this value to \c -1 will reset the height back to its implicit maximum height. - - \sa minimumHeight - \sa preferredHeight -*/ -void QQuickLayoutAttached::setMaximumHeight(qreal height) -{ - if (qt_is_nan(height)) - return; - m_isMaximumHeightSet = height >= 0; - if (m_maximumHeight == height) - return; - - m_maximumHeight = height; - invalidateItem(); - emit maximumHeightChanged(); -} - -void QQuickLayoutAttached::setMinimumImplicitSize(const QSizeF &sz) -{ - bool emitWidthChanged = false; - bool emitHeightChanged = false; - if (!m_isMinimumWidthSet && m_minimumWidth != sz.width()) { - m_minimumWidth = sz.width(); - emitWidthChanged = true; - } - if (!m_isMinimumHeightSet && m_minimumHeight != sz.height()) { - m_minimumHeight = sz.height(); - emitHeightChanged = true; - } - // Only invalidate the item once, and make sure we emit signal changed after the call to - // invalidateItem() - if (emitWidthChanged || emitHeightChanged) { - invalidateItem(); - if (emitWidthChanged) - emit minimumWidthChanged(); - if (emitHeightChanged) - emit minimumHeightChanged(); - } -} - -void QQuickLayoutAttached::setMaximumImplicitSize(const QSizeF &sz) -{ - bool emitWidthChanged = false; - bool emitHeightChanged = false; - if (!m_isMaximumWidthSet && m_maximumWidth != sz.width()) { - m_maximumWidth = sz.width(); - emitWidthChanged = true; - } - if (!m_isMaximumHeightSet && m_maximumHeight != sz.height()) { - m_maximumHeight = sz.height(); - emitHeightChanged = true; - } - // Only invalidate the item once, and make sure we emit changed signal after the call to - // invalidateItem() - if (emitWidthChanged || emitHeightChanged) { - invalidateItem(); - if (emitWidthChanged) - emit maximumWidthChanged(); - if (emitHeightChanged) - emit maximumHeightChanged(); - } -} - -/*! - \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 - set to the preferred width. - The default is \c false, except for layouts themselves, which default to \c true. - - \sa fillHeight -*/ -void QQuickLayoutAttached::setFillWidth(bool fill) -{ - m_isFillWidthSet = true; - if (m_fillWidth != fill) { - m_fillWidth = fill; - invalidateItem(); - emit fillWidthChanged(); - } -} - -/*! - \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 - set to the preferred height. - The default is \c false, except for layouts themselves, which default to \c true. - - \sa fillWidth -*/ -void QQuickLayoutAttached::setFillHeight(bool fill) -{ - m_isFillHeightSet = true; - if (m_fillHeight != fill) { - m_fillHeight = fill; - invalidateItem(); - emit fillHeightChanged(); - } -} - -/*! - \qmlattachedproperty int Layout::row - - This property allows you to specify the row position of an item in a \l GridLayout. - - If both \l column and this property are not set, it is up to the layout to assign a cell to the item. - - The default value is \c 0. - - \sa column - \sa rowSpan -*/ -void QQuickLayoutAttached::setRow(int row) -{ - if (row >= 0 && row != m_row) { - m_row = row; - invalidateItem(); - emit rowChanged(); - } -} - -/*! - \qmlattachedproperty int Layout::column - - This property allows you to specify the column position of an item in a \l GridLayout. - - If both \l row and this property are not set, it is up to the layout to assign a cell to the item. - - The default value is \c 0. - - \sa row - \sa columnSpan -*/ -void QQuickLayoutAttached::setColumn(int column) -{ - if (column >= 0 && column != m_column) { - m_column = column; - invalidateItem(); - emit columnChanged(); - } -} - - -/*! - \qmlattachedproperty Qt.Alignment Layout::alignment - - This property allows you to specify the alignment of an item within the cell(s) it occupies. - - The default value is \c 0, which means it will be \c{Qt.AlignVCenter | Qt.AlignLeft}. - These defaults also apply if only a horizontal or vertical flag is specified: - if only a horizontal flag is specified, the default vertical flag will be - \c Qt.AlignVCenter, and if only a vertical flag is specified, the default - horizontal flag will be \c Qt.AlignLeft. - - A valid alignment is a combination of the following flags: - \list - \li Qt::AlignLeft - \li Qt::AlignHCenter - \li Qt::AlignRight - \li Qt::AlignTop - \li Qt::AlignVCenter - \li Qt::AlignBottom - \li Qt::AlignBaseline - \endlist - -*/ -void QQuickLayoutAttached::setAlignment(Qt::Alignment align) -{ - if (align != m_alignment) { - m_alignment = align; - if (QQuickLayout *layout = parentLayout()) { - layout->setAlignment(item(), align); - invalidateItem(); - } - emit alignmentChanged(); - } -} - -/*! - \qmlattachedproperty real Layout::margins - - Sets the margins outside of an item to all have the same value. The item - itself does not evaluate its own margins. It is the parent's responsibility - to decide if it wants to evaluate the margins. - - Specifically, margins are only evaluated by ColumnLayout, RowLayout, - GridLayout, and other layout-like containers, such as SplitView, where the - effective cell size of an item will be increased as the margins are - increased. - - Therefore, if an item with margins is a child of another \c Item, its - position, size and implicit size will remain unchanged. - - Combining margins with alignment will align the item \e including its - margins. For instance, a vertically-centered Item with a top margin of \c 1 - and a bottom margin of \c 9 will cause the Items effective alignment within - the cell to be 4 pixels above the center. - - The default value is \c 0. - - \sa leftMargin - \sa topMargin - \sa rightMargin - \sa bottomMargin - - \since QtQuick.Layouts 1.2 -*/ -void QQuickLayoutAttached::setMargins(qreal m) -{ - if (m == m_defaultMargins) - return; - - m_defaultMargins = m; - invalidateItem(); - if (!m_isLeftMarginSet && m_margins.left() != m) - emit leftMarginChanged(); - if (!m_isTopMarginSet && m_margins.top() != m) - emit topMarginChanged(); - if (!m_isRightMarginSet && m_margins.right() != m) - emit rightMarginChanged(); - if (!m_isBottomMarginSet && m_margins.bottom() != m) - emit bottomMarginChanged(); - emit marginsChanged(); -} - -/*! - \qmlattachedproperty real Layout::leftMargin - - Specifies the left margin outside of an item. - If the value is not set, it will use the value from \l margins. - - \sa margins - - \since QtQuick.Layouts 1.2 -*/ -void QQuickLayoutAttached::setLeftMargin(qreal m) -{ - const bool changed = leftMargin() != m; - m_margins.setLeft(m); - m_isLeftMarginSet = true; - if (changed) { - invalidateItem(); - emit leftMarginChanged(); - } -} - -void QQuickLayoutAttached::resetLeftMargin() -{ - const bool changed = m_isLeftMarginSet && (m_defaultMargins != m_margins.left()); - m_isLeftMarginSet = false; - if (changed) { - invalidateItem(); - emit leftMarginChanged(); - } -} - -/*! - \qmlattachedproperty real Layout::topMargin - - Specifies the top margin outside of an item. - If the value is not set, it will use the value from \l margins. - - \sa margins - - \since QtQuick.Layouts 1.2 -*/ -void QQuickLayoutAttached::setTopMargin(qreal m) -{ - const bool changed = topMargin() != m; - m_margins.setTop(m); - m_isTopMarginSet = true; - if (changed) { - invalidateItem(); - emit topMarginChanged(); - } -} - -void QQuickLayoutAttached::resetTopMargin() -{ - const bool changed = m_isTopMarginSet && (m_defaultMargins != m_margins.top()); - m_isTopMarginSet = false; - if (changed) { - invalidateItem(); - emit topMarginChanged(); - } -} - -/*! - \qmlattachedproperty real Layout::rightMargin - - Specifies the right margin outside of an item. - If the value is not set, it will use the value from \l margins. - - \sa margins - - \since QtQuick.Layouts 1.2 -*/ -void QQuickLayoutAttached::setRightMargin(qreal m) -{ - const bool changed = rightMargin() != m; - m_margins.setRight(m); - m_isRightMarginSet = true; - if (changed) { - invalidateItem(); - emit rightMarginChanged(); - } -} - -void QQuickLayoutAttached::resetRightMargin() -{ - const bool changed = m_isRightMarginSet && (m_defaultMargins != m_margins.right()); - m_isRightMarginSet = false; - if (changed) { - invalidateItem(); - emit rightMarginChanged(); - } -} - -/*! - \qmlattachedproperty real Layout::bottomMargin - - Specifies the bottom margin outside of an item. - If the value is not set, it will use the value from \l margins. - - \sa margins - - \since QtQuick.Layouts 1.2 -*/ -void QQuickLayoutAttached::setBottomMargin(qreal m) -{ - const bool changed = bottomMargin() != m; - m_margins.setBottom(m); - m_isBottomMarginSet = true; - if (changed) { - invalidateItem(); - emit bottomMarginChanged(); - } -} - -void QQuickLayoutAttached::resetBottomMargin() -{ - const bool changed = m_isBottomMarginSet && (m_defaultMargins != m_margins.bottom()); - m_isBottomMarginSet = false; - if (changed) { - invalidateItem(); - emit bottomMarginChanged(); - } -} - - -/*! - \qmlattachedproperty int Layout::rowSpan - - This property allows you to specify the row span of an item in a \l GridLayout. - - The default value is \c 1. - - \sa columnSpan - \sa row -*/ -void QQuickLayoutAttached::setRowSpan(int span) -{ - if (span != m_rowSpan) { - m_rowSpan = span; - invalidateItem(); - emit rowSpanChanged(); - } -} - - -/*! - \qmlattachedproperty int Layout::columnSpan - - This property allows you to specify the column span of an item in a \l GridLayout. - - The default value is \c 1. - - \sa rowSpan - \sa column -*/ -void QQuickLayoutAttached::setColumnSpan(int span) -{ - if (span != m_columnSpan) { - m_columnSpan = span; - invalidateItem(); - emit columnSpanChanged(); - } -} - - -qreal QQuickLayoutAttached::sizeHint(Qt::SizeHint which, Qt::Orientation orientation) const -{ - qreal result = 0; - if (QQuickLayout *layout = qobject_cast(item())) { - const QSizeF sz = layout->sizeHint(which); - result = (orientation == Qt::Horizontal ? sz.width() : sz.height()); - } else { - if (which == Qt::MaximumSize) - result = std::numeric_limits::infinity(); - } - return result; -} - -void QQuickLayoutAttached::invalidateItem() -{ - qCDebug(lcQuickLayouts) << "QQuickLayoutAttached::invalidateItem"; - if (QQuickLayout *layout = parentLayout()) { - layout->invalidate(item()); - } -} - -QQuickLayout *QQuickLayoutAttached::parentLayout() const -{ - QQuickItem *parentItem = item(); - if (parentItem) { - parentItem = parentItem->parentItem(); - return qobject_cast(parentItem); - } else { - qmlWarning(parent()) << "Layout must be attached to Item elements"; - } - return nullptr; -} - -QQuickItem *QQuickLayoutAttached::item() const -{ - return qobject_cast(parent()); -} - -qreal QQuickLayoutPrivate::getImplicitWidth() const -{ - Q_Q(const QQuickLayout); - if (q->invalidated()) { - QQuickLayoutPrivate *that = const_cast(this); - that->implicitWidth = q->sizeHint(Qt::PreferredSize).width(); - } - return implicitWidth; -} - -qreal QQuickLayoutPrivate::getImplicitHeight() const -{ - Q_Q(const QQuickLayout); - if (q->invalidated()) { - QQuickLayoutPrivate *that = const_cast(this); - that->implicitHeight = q->sizeHint(Qt::PreferredSize).height(); - } - return implicitHeight; -} - -void QQuickLayoutPrivate::applySizeHints() const { - Q_Q(const QQuickLayout); - QQuickLayout *that = const_cast(q); - QQuickLayoutAttached *info = attachedLayoutObject(that, true); - - const QSizeF min = q->sizeHint(Qt::MinimumSize); - const QSizeF max = q->sizeHint(Qt::MaximumSize); - const QSizeF pref = q->sizeHint(Qt::PreferredSize); - info->setMinimumImplicitSize(min); - info->setMaximumImplicitSize(max); - that->setImplicitSize(pref.width(), pref.height()); -} - -QQuickLayout::QQuickLayout(QQuickLayoutPrivate &dd, QQuickItem *parent) - : QQuickItem(dd, parent) - , m_inUpdatePolish(false) - , m_polishInsideUpdatePolish(0) -{ -} - -static QQuickItemPrivate::ChangeTypes changeTypes = - QQuickItemPrivate::SiblingOrder - | QQuickItemPrivate::ImplicitWidth - | QQuickItemPrivate::ImplicitHeight - | QQuickItemPrivate::Destroyed - | QQuickItemPrivate::Visibility; - -QQuickLayout::~QQuickLayout() -{ - d_func()->m_isReady = false; - - const auto childItems = d_func()->childItems; - for (QQuickItem *child : childItems) - QQuickItemPrivate::get(child)->removeItemChangeListener(this, changeTypes); -} - -QQuickLayoutAttached *QQuickLayout::qmlAttachedProperties(QObject *object) -{ - return new QQuickLayoutAttached(object); -} - -void QQuickLayout::updatePolish() -{ - qCDebug(lcQuickLayouts) << "updatePolish() ENTERING" << this; - m_inUpdatePolish = true; - - // Might have become "undirty" before we reach this updatePolish() - // (e.g. if somebody queried for implicitWidth it will immediately - // calculate size hints) - if (invalidated()) { - // Ensure that all invalidated layouts are synced and valid again. Since - // ensureLayoutItemsUpdated() will also call applySizeHints(), and sizeHint() will call its - // childrens sizeHint(), and sizeHint() will call ensureLayoutItemsUpdated(), this will be done - // recursive as we want. - // Note that we need to call ensureLayoutItemsUpdated() *before* we query width() and height(), - // because width()/height() might return their implicitWidth/implicitHeight (e.g. for a layout - // with no explicitly specified size, (nor anchors.fill: parent)) - ensureLayoutItemsUpdated(); - } - rearrange(QSizeF(width(), height())); - m_inUpdatePolish = false; - qCDebug(lcQuickLayouts) << "updatePolish() LEAVING" << this; -} - -void QQuickLayout::componentComplete() -{ - Q_D(QQuickLayout); - d->m_disableRearrange = true; - QQuickItem::componentComplete(); // will call our geometryChange(), (where isComponentComplete() == true) - d->m_disableRearrange = false; - d->m_isReady = true; -} - -void QQuickLayout::invalidate(QQuickItem * /*childItem*/) -{ - Q_D(QQuickLayout); - if (invalidated()) - return; - - qCDebug(lcQuickLayouts) << "QQuickLayout::invalidate()" << this; - d->m_dirty = true; - d->m_dirtyArrangement = true; - - if (!qobject_cast(parentItem())) { - - if (m_inUpdatePolish) - ++m_polishInsideUpdatePolish; - else - m_polishInsideUpdatePolish = 0; - - if (m_polishInsideUpdatePolish <= 2) { - // allow at most two consecutive loops in order to respond to height-for-width - // (e.g QQuickText changes implicitHeight when its width gets changed) - qCDebug(lcQuickLayouts) << "QQuickLayout::invalidate(), polish()"; - polish(); - } else { - qWarning() << "Qt Quick Layouts: Polish loop detected. Aborting after two iterations."; - } - } -} - -bool QQuickLayout::shouldIgnoreItem(QQuickItem *child, QQuickLayoutAttached *&info, QSizeF *sizeHints) const -{ - bool ignoreItem = true; - QQuickItemPrivate *childPrivate = QQuickItemPrivate::get(child); - if (childPrivate->explicitVisible) { - effectiveSizeHints_helper(child, sizeHints, &info, true); - QSizeF effectiveMaxSize = sizeHints[Qt::MaximumSize]; - if (!effectiveMaxSize.isNull()) { - QSizeF &prefS = sizeHints[Qt::PreferredSize]; - if (effectiveSizePolicy_helper(child, Qt::Horizontal, info) == QLayoutPolicy::Fixed) - effectiveMaxSize.setWidth(prefS.width()); - if (effectiveSizePolicy_helper(child, Qt::Vertical, info) == QLayoutPolicy::Fixed) - effectiveMaxSize.setHeight(prefS.height()); - } - ignoreItem = effectiveMaxSize.isNull(); - } - - if (!ignoreItem && childPrivate->isTransparentForPositioner()) - ignoreItem = true; - - return ignoreItem; -} - -void QQuickLayout::checkAnchors(QQuickItem *item) const -{ - QQuickAnchors *anchors = QQuickItemPrivate::get(item)->_anchors; - if (anchors && anchors->activeDirections()) - qmlWarning(item) << "Detected anchors on an item that is managed by a layout. This is undefined behavior; use Layout.alignment instead."; -} - -void QQuickLayout::ensureLayoutItemsUpdated() const -{ - Q_D(const QQuickLayout); - if (!invalidated()) - return; - const_cast(this)->updateLayoutItems(); - d->m_dirty = false; - d->applySizeHints(); -} - - -void QQuickLayout::itemChange(ItemChange change, const ItemChangeData &value) -{ - if (change == ItemChildAddedChange) { - Q_D(QQuickLayout); - QQuickItem *item = value.item; - qmlobject_connect(item, QQuickItem, SIGNAL(baselineOffsetChanged(qreal)), this, QQuickLayout, SLOT(invalidateSenderItem())); - QQuickItemPrivate::get(item)->addItemChangeListener(this, changeTypes); - d->m_hasItemChangeListeners = true; - qCDebug(lcQuickLayouts) << "ChildAdded" << item; - if (isReady()) - invalidate(); - } else if (change == ItemChildRemovedChange) { - QQuickItem *item = value.item; - qmlobject_disconnect(item, QQuickItem, SIGNAL(baselineOffsetChanged(qreal)), this, QQuickLayout, SLOT(invalidateSenderItem())); - QQuickItemPrivate::get(item)->removeItemChangeListener(this, changeTypes); - qCDebug(lcQuickLayouts) << "ChildRemoved" << item; - if (isReady()) - invalidate(); - } - QQuickItem::itemChange(change, value); -} - -void QQuickLayout::geometryChange(const QRectF &newGeometry, const QRectF &oldGeometry) -{ - Q_D(QQuickLayout); - QQuickItem::geometryChange(newGeometry, oldGeometry); - if (d->m_disableRearrange || !isReady() || !newGeometry.isValid()) - return; - - qCDebug(lcQuickLayouts) << "QQuickLayout::geometryChange" << newGeometry << oldGeometry; - rearrange(newGeometry.size()); -} - -void QQuickLayout::invalidateSenderItem() -{ - if (!isReady()) - return; - QQuickItem *item = static_cast(sender()); - Q_ASSERT(item); - invalidate(item); -} - -bool QQuickLayout::isReady() const -{ - return d_func()->m_isReady; -} - -/*! - * \brief QQuickLayout::deactivateRecur - * \internal - * - * Call this from the dtor of the top-level layout. - * Otherwise, it will trigger lots of unneeded item change listeners (itemVisibleChanged()) for all its descendants - * that will have its impact thrown away. - */ -void QQuickLayout::deactivateRecur() -{ - if (d_func()->m_hasItemChangeListeners) { - for (int i = 0; i < itemCount(); ++i) { - QQuickItem *item = itemAt(i); - // When deleting a layout with children, there is no reason for the children to inform the layout that their - // e.g. visibility got changed. The layout already knows that all its children will eventually become invisible, so - // we therefore remove its change listener. - QQuickItemPrivate::get(item)->removeItemChangeListener(this, changeTypes); - if (QQuickLayout *layout = qobject_cast(item)) - layout->deactivateRecur(); - } - d_func()->m_hasItemChangeListeners = false; - } -} - -bool QQuickLayout::invalidated() const -{ - return d_func()->m_dirty; -} - -bool QQuickLayout::invalidatedArrangement() const -{ - return d_func()->m_dirtyArrangement; -} - -bool QQuickLayout::isMirrored() const -{ - return d_func()->isMirrored(); -} - -void QQuickLayout::itemSiblingOrderChanged(QQuickItem *item) -{ - Q_UNUSED(item); - invalidate(); -} - -void QQuickLayout::itemImplicitWidthChanged(QQuickItem *item) -{ - if (!isReady() || item->signalsBlocked()) - return; - invalidate(item); -} - -void QQuickLayout::itemImplicitHeightChanged(QQuickItem *item) -{ - if (!isReady() || item->signalsBlocked()) - return; - invalidate(item); -} - -void QQuickLayout::itemDestroyed(QQuickItem *item) -{ - Q_UNUSED(item); -} - -void QQuickLayout::itemVisibilityChanged(QQuickItem *item) -{ - Q_UNUSED(item); -} - -void QQuickLayout::rearrange(const QSizeF &/*size*/) -{ - d_func()->m_dirtyArrangement = false; -} - - -/* - The layout engine assumes: - 1. minimum <= preferred <= maximum - 2. descent is within minimum and maximum bounds (### verify) - - This function helps to ensure that by the following rules (in the following order): - 1. If minimum > maximum, set minimum = maximum - 2. Clamp preferred to be between the [minimum,maximum] range. - 3. If descent > minimum, set descent = minimum (### verify if this is correct, it might - need some refinements to multiline texts) - - If any values are "not set" (i.e. negative), they will be left untouched, so that we - know which values needs to be fetched from the implicit hints (not user hints). - */ -static void normalizeHints(qreal &minimum, qreal &preferred, qreal &maximum, qreal &descent) -{ - if (minimum >= 0 && maximum >= 0 && minimum > maximum) - minimum = maximum; - - if (preferred >= 0) { - if (minimum >= 0 && preferred < minimum) { - preferred = minimum; - } else if (maximum >= 0 && preferred > maximum) { - preferred = maximum; - } - } - - if (minimum >= 0 && descent > minimum) - descent = minimum; -} - -static void boundSize(QSizeF &result, const QSizeF &size) -{ - if (size.width() >= 0 && size.width() < result.width()) - result.setWidth(size.width()); - if (size.height() >= 0 && size.height() < result.height()) - result.setHeight(size.height()); -} - -static void expandSize(QSizeF &result, const QSizeF &size) -{ - if (size.width() >= 0 && size.width() > result.width()) - result.setWidth(size.width()); - if (size.height() >= 0 && size.height() > result.height()) - result.setHeight(size.height()); -} - -static inline void combineHints(qreal ¤t, qreal fallbackHint) -{ - if (current < 0) - 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()); -} - -typedef qreal (QQuickLayoutAttached::*SizeGetter)() const; - -/*! - \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. - - Fractional size hints will be ceiled to the closest integer. This is in order to give some - slack when the items are snapped to the pixel grid. - - | *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 QQuickLayout::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) { - struct Getters { - SizeGetter call[NSizes]; - }; - - static Getters horGetters = { - {&QQuickLayoutAttached::minimumWidth, &QQuickLayoutAttached::preferredWidth, &QQuickLayoutAttached::maximumWidth}, - }; - - static Getters verGetters = { - {&QQuickLayoutAttached::minimumHeight, &QQuickLayoutAttached::preferredHeight, &QQuickLayoutAttached::maximumHeight} - }; - for (int i = 0; i < NSizes; ++i) { - SizeGetter getter = horGetters.call[i]; - Q_ASSERT(getter); - - if (info->isExtentExplicitlySet(Qt::Horizontal, (Qt::SizeHint)i)) - cachedSizeHints[i].setWidth((info->*getter)()); - - getter = verGetters.call[i]; - Q_ASSERT(getter); - if (info->isExtentExplicitlySet(Qt::Vertical, (Qt::SizeHint)i)) - cachedSizeHints[i].setHeight((info->*getter)()); - } - } - - QSizeF &minS = cachedSizeHints[Qt::MinimumSize]; - QSizeF &prefS = cachedSizeHints[Qt::PreferredSize]; - QSizeF &maxS = cachedSizeHints[Qt::MaximumSize]; - QSizeF &descentS = cachedSizeHints[Qt::MinimumDescent]; - - // For instance, will normalize the following user-set hints - // from: [10, 5, 60] - // to: [10, 10, 60] - normalizeHints(minS.rwidth(), prefS.rwidth(), maxS.rwidth(), descentS.rwidth()); - normalizeHints(minS.rheight(), prefS.rheight(), maxS.rheight(), descentS.rheight()); - - // 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::infinity(), std::numeric_limits::infinity())); - // implicit max or min sizes should not limit an explicitly set preferred size - expandSize(maxS, prefS); - expandSize(maxS, minS); - - //--- GATHER MINIMUM SIZE HINTS --- - combineImplicitHints(info, Qt::MinimumSize, &minS); - expandSize(minS, QSizeF(0,0)); - boundSize(minS, prefS); - boundSize(minS, maxS); - - //--- GATHER PREFERRED SIZE HINTS --- - // First, from implicitWidth/Height - qreal &prefWidth = prefS.rwidth(); - qreal &prefHeight = prefS.rheight(); - if (prefWidth < 0 && item->implicitWidth() > 0) - prefWidth = qCeil(item->implicitWidth()); - if (prefHeight < 0 && item->implicitHeight() > 0) - prefHeight = qCeil(item->implicitHeight()); - - // If that fails, make an ultimate fallback to width/height - if (useFallbackToWidthOrHeight && !prefS.isValid()) { - /* If we want to support using width/height as preferred size hints in - layouts, (which we think most people expect), we only want to use the - initial width. - This is because the width will change due to layout rearrangement, - and the preferred width should return the same value, regardless of - the current width. - We therefore store this initial width in the attached layout object - and reuse it if needed rather than querying the width another time. - That means we need to ensure that an Layout attached object is available - by creating one if necessary. - */ - if (!info) - info = attachedLayoutObject(item); - - auto updatePreferredSizes = [](qreal &cachedSize, qreal &attachedSize, qreal size) { - if (cachedSize < 0) { - if (attachedSize < 0) - attachedSize = size; - - cachedSize = attachedSize; - } - }; - updatePreferredSizes(prefWidth, info->m_fallbackWidth, item->width()); - updatePreferredSizes(prefHeight, info->m_fallbackHeight, item->height()); - } - - // Normalize again after the implicit hints have been gathered - expandSize(prefS, minS); - boundSize(prefS, maxS); - - //--- GATHER DESCENT - // Minimum descent is only applicable for the effective minimum height, - // so we gather the descent last. - const qreal minimumDescent = minS.height() - item->baselineOffset(); - descentS.setHeight(minimumDescent); - - if (info) { - QMarginsF margins = info->qMargins(); - QSizeF extraMargins(margins.left() + margins.right(), margins.top() + margins.bottom()); - minS += extraMargins; - prefS += extraMargins; - maxS += extraMargins; - descentS += extraMargins; - } - if (attachedInfo) - *attachedInfo = info; -} - -/*! - \internal - - Assumes \a info is set (if the object has an attached property) - */ -QLayoutPolicy::Policy QQuickLayout::effectiveSizePolicy_helper(QQuickItem *item, Qt::Orientation orientation, QQuickLayoutAttached *info) -{ - bool fillExtent = false; - bool isSet = false; - if (info) { - if (orientation == Qt::Horizontal) { - isSet = info->isFillWidthSet(); - if (isSet) fillExtent = info->fillWidth(); - } else { - isSet = info->isFillHeightSet(); - if (isSet) fillExtent = info->fillHeight(); - } - } - if (!isSet && qobject_cast(item)) - fillExtent = true; - return fillExtent ? QLayoutPolicy::Preferred : QLayoutPolicy::Fixed; - -} - -void QQuickLayout::_q_dumpLayoutTree() const -{ - QString buf; - dumpLayoutTreeRecursive(0, buf); - qDebug("\n%s", qPrintable(buf)); -} - -void QQuickLayout::dumpLayoutTreeRecursive(int level, QString &buf) const -{ - auto formatLine = [&level](const char *fmt) { - QString ss(level *4, QLatin1Char(' ')); - return QString::fromLatin1("%1%2\n").arg(ss).arg(fmt); - }; - - auto f2s = [](qreal f) { - return QString::number(f); - }; - auto b2s = [](bool b) { - static const char *strBool[] = {"false", "true"}; - return QLatin1String(strBool[int(b)]); - }; - - buf += formatLine("%1 {").arg(QQmlMetaType::prettyTypeName(this)); - ++level; - buf += formatLine("// Effective calculated values:"); - buf += formatLine("sizeHintDirty: %2").arg(invalidated()); - QSizeF min = sizeHint(Qt::MinimumSize); - buf += formatLine("sizeHint.min : [%1, %2]").arg(f2s(min.width()), 5).arg(min.height(), 5); - QSizeF pref = sizeHint(Qt::PreferredSize); - buf += formatLine("sizeHint.pref: [%1, %2]").arg(pref.width(), 5).arg(pref.height(), 5); - QSizeF max = sizeHint(Qt::MaximumSize); - buf += formatLine("sizeHint.max : [%1, %2]").arg(f2s(max.width()), 5).arg(f2s(max.height()), 5); - - for (QQuickItem *item : childItems()) { - buf += QLatin1Char('\n'); - if (QQuickLayout *childLayout = qobject_cast(item)) { - childLayout->dumpLayoutTreeRecursive(level, buf); - } else { - buf += formatLine("%1 {").arg(QQmlMetaType::prettyTypeName(item)); - ++level; - if (item->implicitWidth() > 0) - buf += formatLine("implicitWidth: %1").arg(f2s(item->implicitWidth())); - if (item->implicitHeight() > 0) - buf += formatLine("implicitHeight: %1").arg(f2s(item->implicitHeight())); - QSizeF min; - QSizeF pref; - QSizeF max; - QQuickLayoutAttached *info = attachedLayoutObject(item, false); - if (info) { - min = QSizeF(info->minimumWidth(), info->minimumHeight()); - pref = QSizeF(info->preferredWidth(), info->preferredHeight()); - max = QSizeF(info->maximumWidth(), info->maximumHeight()); - if (info->isExtentExplicitlySet(Qt::Horizontal, Qt::MinimumSize)) - buf += formatLine("Layout.minimumWidth: %1").arg(f2s(min.width())); - if (info->isExtentExplicitlySet(Qt::Vertical, Qt::MinimumSize)) - buf += formatLine("Layout.minimumHeight: %1").arg(f2s(min.height())); - if (pref.width() >= 0) - buf += formatLine("Layout.preferredWidth: %1").arg(f2s(pref.width())); - if (pref.height() >= 0) - buf += formatLine("Layout.preferredHeight: %1").arg(f2s(pref.height())); - if (info->isExtentExplicitlySet(Qt::Horizontal, Qt::MaximumSize)) - buf += formatLine("Layout.maximumWidth: %1").arg(f2s(max.width())); - if (info->isExtentExplicitlySet(Qt::Vertical, Qt::MaximumSize)) - buf += formatLine("Layout.maximumHeight: %1").arg(f2s(max.height())); - - if (info->isFillWidthSet()) - buf += formatLine("Layout.fillWidth: %1").arg(b2s(info->fillWidth())); - if (info->isFillHeightSet()) - buf += formatLine("Layout.fillHeight: %1").arg(b2s(info->fillHeight())); - } - --level; - buf += formatLine("}"); - } - } - --level; - buf += formatLine("}"); -} - -QT_END_NAMESPACE diff --git a/src/imports/layouts/qquicklayout_p.h b/src/imports/layouts/qquicklayout_p.h deleted file mode 100644 index db883245e5..0000000000 --- a/src/imports/layouts/qquicklayout_p.h +++ /dev/null @@ -1,366 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Quick Layouts module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** 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. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QQUICKLAYOUT_P_H -#define QQUICKLAYOUT_P_H - -#include -#include -#include -#include -#include - -QT_BEGIN_NAMESPACE - -class QQuickLayoutAttached; -Q_DECLARE_LOGGING_CATEGORY(lcQuickLayouts) - -class QQuickLayoutPrivate; -class QQuickLayout : public QQuickItem, public QQuickItemChangeListener - -{ - Q_OBJECT - QML_NAMED_ELEMENT(Layout) - QML_ADDED_IN_VERSION(1, 0) - QML_UNCREATABLE("Do not create objects of type Layout.") - QML_ATTACHED(QQuickLayoutAttached) - -public: - enum SizeHint { - MinimumSize = 0, - PreferredSize, - MaximumSize, - NSizes - }; - - explicit QQuickLayout(QQuickLayoutPrivate &dd, QQuickItem *parent = 0); - ~QQuickLayout(); - - static QQuickLayoutAttached *qmlAttachedProperties(QObject *object); - - - void componentComplete() override; - virtual QSizeF sizeHint(Qt::SizeHint whichSizeHint) const = 0; - virtual void setAlignment(QQuickItem *item, Qt::Alignment align) = 0; - virtual void invalidate(QQuickItem * childItem = 0); - virtual void updateLayoutItems() = 0; - void ensureLayoutItemsUpdated() const; - - // iterator - virtual QQuickItem *itemAt(int index) const = 0; - virtual int itemCount() const = 0; - - virtual void rearrange(const QSizeF &); - - static void effectiveSizeHints_helper(QQuickItem *item, QSizeF *cachedSizeHints, QQuickLayoutAttached **info, bool useFallbackToWidthOrHeight); - static QLayoutPolicy::Policy effectiveSizePolicy_helper(QQuickItem *item, Qt::Orientation orientation, QQuickLayoutAttached *info); - bool shouldIgnoreItem(QQuickItem *child, QQuickLayoutAttached *&info, QSizeF *sizeHints) const; - void checkAnchors(QQuickItem *item) const; - - void itemChange(ItemChange change, const ItemChangeData &value) override; - void geometryChange(const QRectF &newGeometry, const QRectF &oldGeometry) override; - bool isReady() const; - void deactivateRecur(); - - bool invalidated() const; - bool invalidatedArrangement() const; - bool isMirrored() const; - - /* QQuickItemChangeListener */ - void itemSiblingOrderChanged(QQuickItem *item) override; - void itemImplicitWidthChanged(QQuickItem *item) override; - void itemImplicitHeightChanged(QQuickItem *item) override; - void itemDestroyed(QQuickItem *item) override; - void itemVisibilityChanged(QQuickItem *item) override; - - Q_INVOKABLE void _q_dumpLayoutTree() const; - void dumpLayoutTreeRecursive(int level, QString &buf) const; - -protected: - void updatePolish() override; - - enum Orientation { - Vertical = 0, - Horizontal, - NOrientations - }; - -protected slots: - void invalidateSenderItem(); - -private: - unsigned m_inUpdatePolish : 1; - unsigned m_polishInsideUpdatePolish : 2; - - Q_DECLARE_PRIVATE(QQuickLayout) - - friend class QQuickLayoutAttached; -}; - - -class QQuickLayoutPrivate : public QQuickItemPrivate -{ - Q_DECLARE_PUBLIC(QQuickLayout) -public: - QQuickLayoutPrivate() : m_dirty(true), m_dirtyArrangement(true), m_isReady(false), m_disableRearrange(true), m_hasItemChangeListeners(false) {} - - qreal getImplicitWidth() const override; - qreal getImplicitHeight() const override; - - void applySizeHints() const; - -protected: - /* m_dirty == true means that something in the layout was changed, - but its state has not been synced to the internal grid layout engine. It is usually: - 1. A child item was added or removed from the layout (or made visible/invisble) - 2. A child item got one of its size hints changed - */ - mutable unsigned m_dirty : 1; - /* m_dirtyArrangement == true means that the layout still needs a rearrange despite that - * m_dirty == false. This is only used for the case that a layout has been invalidated, - * but its new size is the same as the old size (in that case the child layout won't get - * a geometryChanged() notification, which rearrange() usually reacts to) - */ - mutable unsigned m_dirtyArrangement : 1; - unsigned m_isReady : 1; - unsigned m_disableRearrange : 1; - unsigned m_hasItemChangeListeners : 1; // if false, we don't need to remove its item change listeners... - mutable QSet m_ignoredItems; -}; - - -class QQuickLayoutAttached : public QObject -{ - Q_OBJECT - Q_PROPERTY(qreal minimumWidth READ minimumWidth WRITE setMinimumWidth NOTIFY minimumWidthChanged) - Q_PROPERTY(qreal minimumHeight READ minimumHeight WRITE setMinimumHeight NOTIFY minimumHeightChanged) - Q_PROPERTY(qreal preferredWidth READ preferredWidth WRITE setPreferredWidth NOTIFY preferredWidthChanged) - Q_PROPERTY(qreal preferredHeight READ preferredHeight WRITE setPreferredHeight NOTIFY preferredHeightChanged) - Q_PROPERTY(qreal maximumWidth READ maximumWidth WRITE setMaximumWidth NOTIFY maximumWidthChanged) - Q_PROPERTY(qreal maximumHeight READ maximumHeight WRITE setMaximumHeight NOTIFY maximumHeightChanged) - Q_PROPERTY(bool fillHeight READ fillHeight WRITE setFillHeight NOTIFY fillHeightChanged) - Q_PROPERTY(bool fillWidth READ fillWidth WRITE setFillWidth NOTIFY fillWidthChanged) - Q_PROPERTY(int row READ row WRITE setRow NOTIFY rowChanged) - Q_PROPERTY(int column READ column WRITE setColumn NOTIFY columnChanged) - Q_PROPERTY(int rowSpan READ rowSpan WRITE setRowSpan NOTIFY rowSpanChanged) - Q_PROPERTY(int columnSpan READ columnSpan WRITE setColumnSpan NOTIFY columnSpanChanged) - Q_PROPERTY(Qt::Alignment alignment READ alignment WRITE setAlignment NOTIFY alignmentChanged) - - Q_PROPERTY(qreal margins READ margins WRITE setMargins NOTIFY marginsChanged) - Q_PROPERTY(qreal leftMargin READ leftMargin WRITE setLeftMargin RESET resetLeftMargin NOTIFY leftMarginChanged) - Q_PROPERTY(qreal topMargin READ topMargin WRITE setTopMargin RESET resetTopMargin NOTIFY topMarginChanged) - Q_PROPERTY(qreal rightMargin READ rightMargin WRITE setRightMargin RESET resetRightMargin NOTIFY rightMarginChanged) - Q_PROPERTY(qreal bottomMargin READ bottomMargin WRITE setBottomMargin RESET resetBottomMargin NOTIFY bottomMarginChanged) - -public: - QQuickLayoutAttached(QObject *object); - - qreal minimumWidth() const { return !m_isMinimumWidthSet ? sizeHint(Qt::MinimumSize, Qt::Horizontal) : m_minimumWidth; } - void setMinimumWidth(qreal width); - - qreal minimumHeight() const { return !m_isMinimumHeightSet ? sizeHint(Qt::MinimumSize, Qt::Vertical) : m_minimumHeight; } - void setMinimumHeight(qreal height); - - qreal preferredWidth() const { return m_preferredWidth; } - void setPreferredWidth(qreal width); - - qreal preferredHeight() const { return m_preferredHeight; } - void setPreferredHeight(qreal width); - - qreal maximumWidth() const { return !m_isMaximumWidthSet ? sizeHint(Qt::MaximumSize, Qt::Horizontal) : m_maximumWidth; } - void setMaximumWidth(qreal width); - - qreal maximumHeight() const { return !m_isMaximumHeightSet ? sizeHint(Qt::MaximumSize, Qt::Vertical) : m_maximumHeight; } - void setMaximumHeight(qreal height); - - void setMinimumImplicitSize(const QSizeF &sz); - void setMaximumImplicitSize(const QSizeF &sz); - - bool fillWidth() const { return m_fillWidth; } - void setFillWidth(bool fill); - bool isFillWidthSet() const { return m_isFillWidthSet; } - - bool fillHeight() const { return m_fillHeight; } - void setFillHeight(bool fill); - bool isFillHeightSet() const { return m_isFillHeightSet; } - - 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); - int columnSpan() const { return m_columnSpan; } - void setColumnSpan(int span); - - Qt::Alignment alignment() const { return m_alignment; } - void setAlignment(Qt::Alignment align); - - qreal margins() const { return m_defaultMargins; } - void setMargins(qreal m); - - qreal leftMargin() const { return m_isLeftMarginSet ? m_margins.left() : m_defaultMargins; } - void setLeftMargin(qreal m); - void resetLeftMargin(); - - qreal topMargin() const { return m_isTopMarginSet ? m_margins.top() : m_defaultMargins; } - void setTopMargin(qreal m); - void resetTopMargin(); - - qreal rightMargin() const { return m_isRightMarginSet ? m_margins.right() : m_defaultMargins; } - void setRightMargin(qreal m); - void resetRightMargin(); - - qreal bottomMargin() const { return m_isBottomMarginSet ? m_margins.bottom() : m_defaultMargins; } - void setBottomMargin(qreal m); - void resetBottomMargin(); - - QMarginsF qMargins() const { - return QMarginsF(leftMargin(), topMargin(), rightMargin(), bottomMargin()); - } - - QMarginsF effectiveQMargins() const { - bool mirrored = parentLayout() && parentLayout()->isMirrored(); - if (mirrored) - return QMarginsF(rightMargin(), topMargin(), leftMargin(), bottomMargin()); - else - return qMargins(); - } - - bool setChangesNotificationEnabled(bool enabled) - { - const bool old = m_changesNotificationEnabled; - m_changesNotificationEnabled = enabled; - return old; - } - - 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(); - void preferredWidthChanged(); - void preferredHeightChanged(); - void maximumWidthChanged(); - void maximumHeightChanged(); - void fillWidthChanged(); - void fillHeightChanged(); - void leftMarginChanged(); - void topMarginChanged(); - void rightMarginChanged(); - void bottomMarginChanged(); - void marginsChanged(); - void rowChanged(); - void columnChanged(); - void rowSpanChanged(); - void columnSpanChanged(); - void alignmentChanged(); - -private: - void invalidateItem(); - QQuickLayout *parentLayout() const; - QQuickItem *item() const; -private: - qreal m_minimumWidth; - qreal m_minimumHeight; - qreal m_preferredWidth; - qreal m_preferredHeight; - qreal m_maximumWidth; - qreal m_maximumHeight; - - qreal m_defaultMargins; - QMarginsF m_margins; - - qreal m_fallbackWidth; - qreal m_fallbackHeight; - - // GridLayout specific properties - int m_row; - int m_column; - int m_rowSpan; - int m_columnSpan; - - unsigned m_fillWidth : 1; - unsigned m_fillHeight : 1; - unsigned m_isFillWidthSet : 1; - unsigned m_isFillHeightSet : 1; - unsigned m_isMinimumWidthSet : 1; - unsigned m_isMinimumHeightSet : 1; - // preferredWidth and preferredHeight are always explicit, since - // their implicit equivalent is implicitWidth and implicitHeight - unsigned m_isMaximumWidthSet : 1; - unsigned m_isMaximumHeightSet : 1; - unsigned m_changesNotificationEnabled : 1; - unsigned m_isLeftMarginSet : 1; - unsigned m_isTopMarginSet : 1; - unsigned m_isRightMarginSet : 1; - unsigned m_isBottomMarginSet : 1; - Qt::Alignment m_alignment; - friend class QQuickLayout; -}; - -inline QQuickLayoutAttached *attachedLayoutObject(QQuickItem *item, bool create = true) -{ - return static_cast(qmlAttachedPropertiesObject(item, create)); -} - -QT_END_NAMESPACE - -QML_DECLARE_TYPE(QQuickLayout) - -#endif // QQUICKLAYOUT_P_H diff --git a/src/imports/layouts/qquicklayoutstyleinfo.cpp b/src/imports/layouts/qquicklayoutstyleinfo.cpp deleted file mode 100644 index 1632c1ce20..0000000000 --- a/src/imports/layouts/qquicklayoutstyleinfo.cpp +++ /dev/null @@ -1,80 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Quick Layouts module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** 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. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include - -#include "qquicklayoutstyleinfo_p.h" - - -QT_BEGIN_NAMESPACE - -QQuickLayoutStyleInfo::QQuickLayoutStyleInfo() -{ -} - -qreal QQuickLayoutStyleInfo::spacing(Qt::Orientation /*orientation*/) const -{ -#if defined(Q_OS_ANDROID) || defined(Q_OS_IOS) || defined(Q_OS_QNX) - // On Android and iOS the default spacing between each UI element is 8dp - qreal spacing = 8.0; -#else - qreal spacing = 5.0; -#endif - -#ifndef Q_OS_OSX - // On OS X the DPI is always 72 so we should not scale it - spacing = qRound(spacing * (qreal(qt_defaultDpiX()) / 96.0)); -#endif - - return spacing; -} - -qreal QQuickLayoutStyleInfo::windowMargin(Qt::Orientation /*orientation*/) const -{ - return 0; -} - -bool QQuickLayoutStyleInfo::hasChangedCore() const -{ - // never changes - return false; -} - -QT_END_NAMESPACE - diff --git a/src/imports/layouts/qquicklayoutstyleinfo_p.h b/src/imports/layouts/qquicklayoutstyleinfo_p.h deleted file mode 100644 index 79f4ce2962..0000000000 --- a/src/imports/layouts/qquicklayoutstyleinfo_p.h +++ /dev/null @@ -1,60 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Quick Layouts module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** 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. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QQUICKLAYOUTSTYLEINFO_P_H -#define QQUICKLAYOUTSTYLEINFO_P_H - -#include - -QT_BEGIN_NAMESPACE - -class QQuickLayoutStyleInfo : public QAbstractLayoutStyleInfo -{ -public: - QQuickLayoutStyleInfo(); - - qreal spacing(Qt::Orientation orientation) const override; - qreal windowMargin(Qt::Orientation orientation) const override; - bool hasChangedCore() const override; - -}; - -QT_END_NAMESPACE - -#endif // QQUICKLAYOUTSTYLEINFO_P_H diff --git a/src/imports/layouts/qquicklinearlayout.cpp b/src/imports/layouts/qquicklinearlayout.cpp deleted file mode 100644 index 760700beaf..0000000000 --- a/src/imports/layouts/qquicklinearlayout.cpp +++ /dev/null @@ -1,888 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Quick Layouts module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** 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. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qquicklinearlayout_p.h" -#include "qquickgridlayoutengine_p.h" -#include "qquicklayoutstyleinfo_p.h" -#include -#include -#include "qdebug.h" -#include - -/*! - \qmltype RowLayout - \instantiates QQuickRowLayout - \inherits Item - \inqmlmodule QtQuick.Layouts - \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 - \input layout.qdocinc attached-properties - \endlist - - \image rowlayout.png - - \code - RowLayout { - id: layout - anchors.fill: parent - spacing: 6 - Rectangle { - color: 'teal' - 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 - } - } - } - \endcode - - 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 - \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 - \input layout.qdocinc attached-properties - \endlist - - \image columnlayout.png - - \code - ColumnLayout{ - spacing: 2 - - Rectangle { - Layout.alignment: Qt.AlignCenter - color: "red" - Layout.preferredWidth: 40 - Layout.preferredHeight: 40 - } - - Rectangle { - Layout.alignment: Qt.AlignRight - color: "green" - Layout.preferredWidth: 40 - Layout.preferredHeight: 70 - } - - Rectangle { - Layout.alignment: Qt.AlignBottom - Layout.fillHeight: true - color: "blue" - Layout.preferredWidth: 70 - Layout.preferredHeight: 40 - } - } - \endcode - - 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 - \ingroup layouts - \brief Provides a way of dynamically arranging items in a grid. - - - - If the GridLayout is resized, all items in the layout will be rearranged. It is similar - to the widget-based QGridLayout. All visible children of the GridLayout element will belong to - the layout. If you want a layout with just one row or one column, you can use the - \l RowLayout or \l ColumnLayout. These offer a bit more convenient API, and improve - readability. - - By default items will be arranged according to the \l flow property. The default value of - the \l flow property is \c GridLayout.LeftToRight. - - If the \l columns property is specified, it will be treated as a maximum limit of how many - columns the layout can have, before the auto-positioning wraps back to the beginning of the - next row. The \l columns property is only used when \l flow is \c GridLayout.LeftToRight. - - \image gridlayout.png - - \code - GridLayout { - id: grid - columns: 3 - - Text { text: "Three"; font.bold: true; } - Text { text: "words"; color: "red" } - Text { text: "in"; font.underline: true } - Text { text: "a"; font.pixelSize: 20 } - Text { text: "row"; font.strikeout: true } - } - \endcode - - The \l rows property works in a similar way, but items are auto-positioned vertically. The \l - rows property is only used when \l flow is \c GridLayout.TopToBottom. - - You can specify which cell you want an item to occupy by setting the - \l{Layout::row}{Layout.row} and \l{Layout::column}{Layout.column} properties. You can also - specify the row span or column span by setting the \l{Layout::rowSpan}{Layout.rowSpan} or - \l{Layout::columnSpan}{Layout.columnSpan} properties. - - - 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} - \input layout.qdocinc attached-properties - \endlist - - Read more about attached properties \l{QML Object Attributes}{here}. - - \sa RowLayout - \sa ColumnLayout - \sa Grid -*/ - - - -QT_BEGIN_NAMESPACE - -QQuickGridLayoutBase::QQuickGridLayoutBase() - : QQuickLayout(*new QQuickGridLayoutBasePrivate) -{ - -} - -QQuickGridLayoutBase::QQuickGridLayoutBase(QQuickGridLayoutBasePrivate &dd, - Qt::Orientation orientation, - QQuickItem *parent /*= 0*/) - : QQuickLayout(dd, parent) -{ - Q_D(QQuickGridLayoutBase); - d->orientation = orientation; - d->styleInfo = new QQuickLayoutStyleInfo; -} - -Qt::Orientation QQuickGridLayoutBase::orientation() const -{ - Q_D(const QQuickGridLayoutBase); - return d->orientation; -} - -void QQuickGridLayoutBase::setOrientation(Qt::Orientation orientation) -{ - Q_D(QQuickGridLayoutBase); - if (d->orientation == orientation) - return; - - d->orientation = orientation; - invalidate(); -} - -QSizeF QQuickGridLayoutBase::sizeHint(Qt::SizeHint whichSizeHint) const -{ - Q_D(const QQuickGridLayoutBase); - ensureLayoutItemsUpdated(); - return d->engine.sizeHint(whichSizeHint, QSizeF(), d->styleInfo); -} - -/*! - \qmlproperty enumeration GridLayout::layoutDirection - \since QtQuick.Layouts 1.1 - - This property holds the layout direction of the grid layout - it controls whether items are - laid out from left to right or right to left. If \c Qt.RightToLeft is specified, - left-aligned items will be right-aligned and right-aligned items will be left-aligned. - - Possible values: - - \list - \li Qt.LeftToRight (default) - Items are laid out from left to right. - \li Qt.RightToLeft - Items are laid out from right to left. - \endlist - - \sa RowLayout::layoutDirection, ColumnLayout::layoutDirection -*/ -Qt::LayoutDirection QQuickGridLayoutBase::layoutDirection() const -{ - Q_D(const QQuickGridLayoutBase); - return d->m_layoutDirection; -} - -void QQuickGridLayoutBase::setLayoutDirection(Qt::LayoutDirection dir) -{ - Q_D(QQuickGridLayoutBase); - if (d->m_layoutDirection == dir) - return; - d->m_layoutDirection = dir; - invalidate(); - emit layoutDirectionChanged(); -} - -Qt::LayoutDirection QQuickGridLayoutBase::effectiveLayoutDirection() const -{ - Q_D(const QQuickGridLayoutBase); - return !d->effectiveLayoutMirror == (layoutDirection() == Qt::LeftToRight) - ? Qt::LeftToRight : Qt::RightToLeft; -} - -void QQuickGridLayoutBase::setAlignment(QQuickItem *item, Qt::Alignment alignment) -{ - Q_D(QQuickGridLayoutBase); - d->engine.setAlignment(item, alignment); -} - -QQuickGridLayoutBase::~QQuickGridLayoutBase() -{ - Q_D(QQuickGridLayoutBase); - - // Remove item listeners so we do not act on signalling unnecessarily - // (there is no point, as the layout will be torn down anyway). - deactivateRecur(); - delete d->styleInfo; -} - -void QQuickGridLayoutBase::componentComplete() -{ - qCDebug(lcQuickLayouts) << "QQuickGridLayoutBase::componentComplete()" << this << parent(); - QQuickLayout::componentComplete(); - - /* The layout is invalid when it is constructed, but during construction of the layout and - its children (in the "static/from QML" case which this is trying to cover) things - change and as a consequence invalidate() and ensureLayoutItemsUpdated() might be called. - As soon as ensureLayoutItemsUpdated() is called it will set d->dirty = false. - However, a subsequent invalidate() will return early if the component is not completed - because it knows that componentComplete() will take care of doing the proper layouting - (so it won't set d->dirty = true). When we then call ensureLayoutItemsUpdated() again here - it sees that its not dirty and assumes everything up-to-date. For those cases we therefore - need to call invalidate() in advance - */ - invalidate(); - ensureLayoutItemsUpdated(); - - QQuickItem *par = parentItem(); - if (qobject_cast(par)) - return; - rearrange(QSizeF(width(), height())); - qCDebug(lcQuickLayouts) << "QQuickGridLayoutBase::componentComplete(). COMPLETED" << this << parent(); -} - -/* - Invalidation happens like this as a reaction to that a size hint changes on an item "a": - - Suppose we have the following Qml document: - RowLayout { - id: l1 - RowLayout { - id: l2 - Item { - id: a - } - Item { - id: b - } - } - } - - 1. l2->invalidate(a) is called on l2, where item refers to "a". - (this will dirty the cached size hints of item "a") - 2. The layout engine will invalidate: - i) invalidate the layout engine - ii) dirty the cached size hints of item "l2" (by calling parentLayout()->invalidate(l2) - The recursion continues to the topmost layout - */ -/*! - \internal - - Invalidates \a childItem and this layout. - After a call to invalidate, the next call to retrieve e.g. sizeHint will be up-to date. - This function will also call QQuickLayout::invalidate(0), to ensure that the parent layout - is invalidated. - */ -void QQuickGridLayoutBase::invalidate(QQuickItem *childItem) -{ - Q_D(QQuickGridLayoutBase); - if (!isReady()) - return; - qCDebug(lcQuickLayouts) << "QQuickGridLayoutBase::invalidate()" << this << ", invalidated:" << invalidated(); - if (invalidated()) { - return; - } - qCDebug(lcQuickLayouts) << "d->m_rearranging:" << d->m_rearranging; - if (d->m_rearranging) { - d->m_invalidateAfterRearrange << childItem; - return; - } - - if (childItem) { - if (QQuickGridLayoutItem *layoutItem = d->engine.findLayoutItem(childItem)) - layoutItem->invalidate(); - } - // invalidate engine - d->engine.invalidate(); - - qCDebug(lcQuickLayouts) << "calling QQuickLayout::invalidate();"; - QQuickLayout::invalidate(); - - if (QQuickLayout *parentLayout = qobject_cast(parentItem())) - parentLayout->invalidate(this); - qCDebug(lcQuickLayouts) << "QQuickGridLayoutBase::invalidate() LEAVING" << this; -} - -void QQuickGridLayoutBase::updateLayoutItems() -{ - Q_D(QQuickGridLayoutBase); - if (!isReady()) - return; - if (d->m_rearranging) { - d->m_updateAfterRearrange = true; - return; - } - - qCDebug(lcQuickLayouts) << "QQuickGridLayoutBase::updateLayoutItems ENTERING" << this; - d->engine.deleteItems(); - insertLayoutItems(); - qCDebug(lcQuickLayouts) << "QQuickGridLayoutBase::updateLayoutItems() LEAVING" << this; -} - -QQuickItem *QQuickGridLayoutBase::itemAt(int index) const -{ - Q_D(const QQuickGridLayoutBase); - qCDebug(lcQuickLayouts).nospace() << "QQuickGridLayoutBase::itemAt(" << index << ")"; - ensureLayoutItemsUpdated(); - qCDebug(lcQuickLayouts).nospace() << "QQuickGridLayoutBase::itemAt(" << index << ") LEAVING"; - return static_cast(d->engine.itemAt(index))->layoutItem(); -} - -int QQuickGridLayoutBase::itemCount() const -{ - Q_D(const QQuickGridLayoutBase); - ensureLayoutItemsUpdated(); - return d->engine.itemCount(); -} - -void QQuickGridLayoutBase::removeGridItem(QGridLayoutItem *gridItem) -{ - Q_D(QQuickGridLayoutBase); - const int index = gridItem->firstRow(d->orientation); - d->engine.removeItem(gridItem); - d->engine.removeRows(index, 1, d->orientation); -} - -void QQuickGridLayoutBase::itemDestroyed(QQuickItem *item) -{ - if (!isReady()) - return; - Q_D(QQuickGridLayoutBase); - qCDebug(lcQuickLayouts) << "QQuickGridLayoutBase::itemDestroyed"; - if (QQuickGridLayoutItem *gridItem = d->engine.findLayoutItem(item)) { - removeGridItem(gridItem); - delete gridItem; - invalidate(); - } -} - -void QQuickGridLayoutBase::itemVisibilityChanged(QQuickItem *item) -{ - Q_UNUSED(item); - - if (!isReady()) - return; - qCDebug(lcQuickLayouts) << "QQuickGridLayoutBase::itemVisibilityChanged()"; - invalidate(item); -} - -void QQuickGridLayoutBase::rearrange(const QSizeF &size) -{ - Q_D(QQuickGridLayoutBase); - if (!isReady()) - return; - - qCDebug(lcQuickLayouts) << "QQuickGridLayoutBase::rearrange" << d->m_recurRearrangeCounter << this; - const auto refCounter = qScopeGuard([&d] { - --(d->m_recurRearrangeCounter); - }); - if (d->m_recurRearrangeCounter++ == 2) { - // allow a recursive depth of two in order to respond to height-for-width - // (e.g QQuickText changes implicitHeight when its width gets changed) - qWarning() << "Qt Quick Layouts: Detected recursive rearrange. Aborting after two iterations."; - return; - } - - ensureLayoutItemsUpdated(); - - d->m_rearranging = true; - qCDebug(lcQuickLayouts) << objectName() << "QQuickGridLayoutBase::rearrange()" << size; - Qt::LayoutDirection visualDir = effectiveLayoutDirection(); - d->engine.setVisualDirection(visualDir); - - /* - qreal left, top, right, bottom; - left = top = right = bottom = 0; // ### support for margins? - if (visualDir == Qt::RightToLeft) - qSwap(left, right); - */ - - // Set m_dirty to false in case size hint changes during arrangement. - // This could happen if there is a binding like implicitWidth: height - QQuickLayout::rearrange(size); - d->engine.setGeometries(QRectF(QPointF(0,0), size), d->styleInfo); - d->m_rearranging = false; - - for (QQuickItem *invalid : qAsConst(d->m_invalidateAfterRearrange)) - invalidate(invalid); - d->m_invalidateAfterRearrange.clear(); - - if (d->m_updateAfterRearrange) { - ensureLayoutItemsUpdated(); - d->m_updateAfterRearrange = false; - } -} - -/********************************** - ** - ** QQuickGridLayout - ** - **/ -QQuickGridLayout::QQuickGridLayout(QQuickItem *parent /* = 0*/) - : QQuickGridLayoutBase(*new QQuickGridLayoutPrivate, Qt::Horizontal, parent) -{ -} - -/*! - \qmlproperty real GridLayout::columnSpacing - - This property holds the spacing between each column. - The default value is \c 5. -*/ -qreal QQuickGridLayout::columnSpacing() const -{ - Q_D(const QQuickGridLayout); - return d->engine.spacing(Qt::Horizontal, d->styleInfo); -} - -void QQuickGridLayout::setColumnSpacing(qreal spacing) -{ - Q_D(QQuickGridLayout); - if (qt_is_nan(spacing) || columnSpacing() == spacing) - return; - - d->engine.setSpacing(spacing, Qt::Horizontal); - invalidate(); - emit columnSpacingChanged(); -} - -/*! - \qmlproperty real GridLayout::rowSpacing - - This property holds the spacing between each row. - The default value is \c 5. -*/ -qreal QQuickGridLayout::rowSpacing() const -{ - Q_D(const QQuickGridLayout); - return d->engine.spacing(Qt::Vertical, d->styleInfo); -} - -void QQuickGridLayout::setRowSpacing(qreal spacing) -{ - Q_D(QQuickGridLayout); - if (qt_is_nan(spacing) || rowSpacing() == spacing) - return; - - d->engine.setSpacing(spacing, Qt::Vertical); - invalidate(); - emit rowSpacingChanged(); -} - -/*! - \qmlproperty int GridLayout::columns - - This property holds the column limit for items positioned if \l flow is - \c GridLayout.LeftToRight. - The default value is that there is no limit. -*/ -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(); -} - - -/*! - \qmlproperty int GridLayout::rows - - This property holds the row limit for items positioned if \l flow is \c GridLayout.TopToBottom. - The default value is that there is no limit. -*/ -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(); -} - - -/*! - \qmlproperty enumeration GridLayout::flow - - This property holds the flow direction of items that does not have an explicit cell - position set. - It is used together with the \l columns or \l rows property, where - they specify when flow is reset to the next row or column respectively. - - Possible values are: - - \list - \li GridLayout.LeftToRight (default) - Items are positioned next to - each other, then wrapped to the next line. - \li GridLayout.TopToBottom - Items are positioned next to each - other from top to bottom, then wrapped to the next column. - \endlist - - \sa rows - \sa columns -*/ -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; - // If flow is changed, the layout needs to be repopulated - invalidate(); - emit flowChanged(); -} - -void QQuickGridLayout::insertLayoutItems() -{ - Q_D(QQuickGridLayout); - - int nextCellPos[2] = {0,0}; - int &nextColumn = nextCellPos[0]; - int &nextRow = nextCellPos[1]; - - const QSize gridSize(columns(), rows()); - 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::max(); - - QSizeF sizeHints[Qt::NSizeHints]; - const auto items = childItems(); - for (QQuickItem *child : items) { - checkAnchors(child); - QQuickLayoutAttached *info = nullptr; - - // Will skip all items with effective maximum width/height == 0 - if (shouldIgnoreItem(child, info, sizeHints)) - continue; - - Qt::Alignment alignment; - int row = -1; - int column = -1; - int span[2] = {1,1}; - int &columnSpan = span[0]; - int &rowSpan = span[1]; - - 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 - // The getters do this for us, as they will return 0 for an - // unset (or negative) value. - // In addition, if \a rows is less than Layout.row, treat Layout.row as if it was not set - // This will basically make it find the next available cell (potentially wrapping to - // the next line). Likewise for an invalid Layout.column - - if (gridSize.height() >= 0 && row >= gridSize.height()) { - qmlWarning(child) << QString::fromLatin1("Layout: row (%1) should be less than the number of rows (%2)").arg(info->row()).arg(rows()); - } else { - row = info->row(); - } - - if (gridSize.width() >= 0 && info->column() >= gridSize.width()) { - qmlWarning(child) << QString::fromLatin1("Layout: column (%1) should be less than the number of columns (%2)").arg(info->column()).arg(columns()); - } else { - column = info->column(); - } - } - rowSpan = info->rowSpan(); - columnSpan = info->columnSpan(); - if (columnSpan < 1) { - qmlWarning(child) << "Layout: invalid column span: " << columnSpan; - return; - - } else if (rowSpan < 1) { - qmlWarning(child) << "Layout: invalid row span: " << rowSpan; - return; - } - alignment = info->alignment(); - } - - Q_ASSERT(columnSpan >= 1); - Q_ASSERT(rowSpan >= 1); - const int sp = span[flowOrientation]; - if (sp > flowBound) - return; - - 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 + sp) <= 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, alignment); - layoutItem->setCachedSizeHints(sizeHints); - - d->engine.insertItem(layoutItem, -1); - } -} - -/********************************** - ** - ** QQuickLinearLayout - ** - **/ -QQuickLinearLayout::QQuickLinearLayout(Qt::Orientation orientation, - QQuickItem *parent /*= 0*/) - : QQuickGridLayoutBase(*new QQuickLinearLayoutPrivate, orientation, parent) -{ -} - -/*! - \qmlproperty enumeration RowLayout::layoutDirection - \since QtQuick.Layouts 1.1 - - This property holds the layout direction of the row layout - it controls whether items are laid - out from left to right or right to left. If \c Qt.RightToLeft is specified, - left-aligned items will be right-aligned and right-aligned items will be left-aligned. - - Possible values: - - \list - \li Qt.LeftToRight (default) - Items are laid out from left to right. - \li Qt.RightToLeft - Items are laid out from right to left - \endlist - - \sa GridLayout::layoutDirection, ColumnLayout::layoutDirection -*/ -/*! - \qmlproperty enumeration ColumnLayout::layoutDirection - \since QtQuick.Layouts 1.1 - - This property holds the layout direction of the column layout - it controls whether items are laid - out from left to right or right to left. If \c Qt.RightToLeft is specified, - left-aligned items will be right-aligned and right-aligned items will be left-aligned. - - Possible values: - - \list - \li Qt.LeftToRight (default) - Items are laid out from left to right. - \li Qt.RightToLeft - Items are laid out from right to left - \endlist - - \sa GridLayout::layoutDirection, RowLayout::layoutDirection -*/ - - -/*! - \qmlproperty real RowLayout::spacing - - This property holds the spacing between each cell. - The default value is \c 5. -*/ -/*! - \qmlproperty real ColumnLayout::spacing - - This property holds the spacing between each cell. - The default value is \c 5. -*/ - -qreal QQuickLinearLayout::spacing() const -{ - Q_D(const QQuickLinearLayout); - return d->engine.spacing(d->orientation, d->styleInfo); -} - -void QQuickLinearLayout::setSpacing(qreal space) -{ - Q_D(QQuickLinearLayout); - if (qt_is_nan(space) || spacing() == space) - return; - - d->engine.setSpacing(space, Qt::Horizontal | Qt::Vertical); - invalidate(); - emit spacingChanged(); -} - -void QQuickLinearLayout::insertLayoutItems() -{ - Q_D(QQuickLinearLayout); - QSizeF sizeHints[Qt::NSizeHints]; - const auto items = childItems(); - for (QQuickItem *child : items) { - Q_ASSERT(child); - checkAnchors(child); - QQuickLayoutAttached *info = nullptr; - - // Will skip all items with effective maximum width/height == 0 - if (shouldIgnoreItem(child, info, sizeHints)) - continue; - - Qt::Alignment alignment; - if (info) - alignment = info->alignment(); - - 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, alignment); - layoutItem->setCachedSizeHints(sizeHints); - d->engine.insertItem(layoutItem, index); - } -} - -QT_END_NAMESPACE - -#include "moc_qquicklinearlayout_p.cpp" diff --git a/src/imports/layouts/qquicklinearlayout_p.h b/src/imports/layouts/qquicklinearlayout_p.h deleted file mode 100644 index 1780ba8807..0000000000 --- a/src/imports/layouts/qquicklinearlayout_p.h +++ /dev/null @@ -1,260 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Quick Layouts module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** 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. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QQUICKLINEARLAYOUT_P_H -#define QQUICKLINEARLAYOUT_P_H - -#include "qquicklayout_p.h" -#include "qquickgridlayoutengine_p.h" - -QT_BEGIN_NAMESPACE - -/********************************** - ** - ** QQuickGridLayoutBase - ** - **/ -class QQuickGridLayoutBasePrivate; - -class QQuickGridLayoutBase : public QQuickLayout -{ - Q_OBJECT - - Q_PROPERTY(Qt::LayoutDirection layoutDirection READ layoutDirection WRITE setLayoutDirection - NOTIFY layoutDirectionChanged REVISION(1, 1)) - QML_ANONYMOUS - QML_ADDED_IN_VERSION(1, 1) - -public: - - QQuickGridLayoutBase(); - - explicit QQuickGridLayoutBase(QQuickGridLayoutBasePrivate &dd, - Qt::Orientation orientation, - QQuickItem *parent = 0); - - ~QQuickGridLayoutBase(); - void componentComplete() override; - void invalidate(QQuickItem *childItem = 0) override; - Qt::Orientation orientation() const; - void setOrientation(Qt::Orientation orientation); - QSizeF sizeHint(Qt::SizeHint whichSizeHint) const override; - Qt::LayoutDirection layoutDirection() const; - void setLayoutDirection(Qt::LayoutDirection dir); - Qt::LayoutDirection effectiveLayoutDirection() const; - void setAlignment(QQuickItem *item, Qt::Alignment align) override; - - /* QQuickItemChangeListener */ - void itemDestroyed(QQuickItem *item) override; - void itemVisibilityChanged(QQuickItem *item) override; - -protected: - void updateLayoutItems() override; - QQuickItem *itemAt(int index) const override; - int itemCount() const override; - - void rearrange(const QSizeF &size) override; - virtual void insertLayoutItems() {} - -signals: - Q_REVISION(1, 1) void layoutDirectionChanged(); - -private: - void removeGridItem(QGridLayoutItem *gridItem); - Q_DECLARE_PRIVATE(QQuickGridLayoutBase) -}; - -class QQuickLayoutStyleInfo; - -class QQuickGridLayoutBasePrivate : public QQuickLayoutPrivate -{ - Q_DECLARE_PUBLIC(QQuickGridLayoutBase) - -public: - QQuickGridLayoutBasePrivate() : m_recurRearrangeCounter(0) - , m_rearranging(false) - , m_updateAfterRearrange(false) - , m_layoutDirection(Qt::LeftToRight) - {} - - void mirrorChange() override - { - Q_Q(QQuickGridLayoutBase); - q->invalidate(); - } - - QQuickGridLayoutEngine engine; - Qt::Orientation orientation; - unsigned m_recurRearrangeCounter : 2; - unsigned m_rearranging : 1; - unsigned m_updateAfterRearrange : 1; - QVector m_invalidateAfterRearrange; - Qt::LayoutDirection m_layoutDirection : 2; - - QQuickLayoutStyleInfo *styleInfo; -}; - -/********************************** - ** - ** QQuickGridLayout - ** - **/ -class QQuickGridLayoutPrivate; -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) - QML_NAMED_ELEMENT(GridLayout) - QML_ADDED_IN_VERSION(1, 0) -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); - - enum Flow { LeftToRight, TopToBottom }; - Q_ENUM(Flow) - Flow flow() const; - void setFlow(Flow flow); - - void insertLayoutItems() override; - -signals: - void columnSpacingChanged(); - void rowSpacingChanged(); - - void columnsChanged(); - void rowsChanged(); - - void flowChanged(); -private: - Q_DECLARE_PRIVATE(QQuickGridLayout) -}; - -class QQuickGridLayoutPrivate : public QQuickGridLayoutBasePrivate -{ - Q_DECLARE_PUBLIC(QQuickGridLayout) -public: - QQuickGridLayoutPrivate(): columns(-1), rows(-1), flow(QQuickGridLayout::LeftToRight) {} - int columns; - int rows; - QQuickGridLayout::Flow flow; -}; - - -/********************************** - ** - ** QQuickLinearLayout - ** - **/ -class QQuickLinearLayoutPrivate; -class QQuickLinearLayout : public QQuickGridLayoutBase -{ - Q_OBJECT - Q_PROPERTY(qreal spacing READ spacing WRITE setSpacing NOTIFY spacingChanged) -public: - explicit QQuickLinearLayout(Qt::Orientation orientation, - QQuickItem *parent = 0); - void insertLayoutItem(QQuickItem *item); - qreal spacing() const; - void setSpacing(qreal spacing); - - void insertLayoutItems() override; - -signals: - void spacingChanged(); -private: - Q_DECLARE_PRIVATE(QQuickLinearLayout) -}; - -class QQuickLinearLayoutPrivate : public QQuickGridLayoutBasePrivate -{ - Q_DECLARE_PUBLIC(QQuickLinearLayout) -public: - QQuickLinearLayoutPrivate() {} -}; - - -/********************************** - ** - ** QQuickRowLayout - ** - **/ -class QQuickRowLayout : public QQuickLinearLayout -{ - Q_OBJECT - QML_NAMED_ELEMENT(RowLayout) - QML_ADDED_IN_VERSION(1, 0) - -public: - explicit QQuickRowLayout(QQuickItem *parent = 0) - : QQuickLinearLayout(Qt::Horizontal, parent) {} -}; - - -/********************************** - ** - ** QQuickColumnLayout - ** - **/ -class QQuickColumnLayout : public QQuickLinearLayout -{ - Q_OBJECT - QML_NAMED_ELEMENT(ColumnLayout) - QML_ADDED_IN_VERSION(1, 0) - -public: - explicit QQuickColumnLayout(QQuickItem *parent = 0) - : QQuickLinearLayout(Qt::Vertical, parent) {} -}; - -QT_END_NAMESPACE - -#endif // QQUICKLINEARLAYOUT_P_H diff --git a/src/imports/layouts/qquickstacklayout.cpp b/src/imports/layouts/qquickstacklayout.cpp deleted file mode 100644 index 3a7e28789d..0000000000 --- a/src/imports/layouts/qquickstacklayout.cpp +++ /dev/null @@ -1,489 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Quick Layouts module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** 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. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qquickstacklayout_p.h" - -#include - -#include - -/*! - \qmltype StackLayout - \instantiates QQuickStackLayout - \inherits Item - \inqmlmodule QtQuick.Layouts - \ingroup layouts - \brief The StackLayout class provides a stack of items where - only one item is visible at a time. - - The current visible item can be modified by setting the \l currentIndex property. - The index corresponds to the order of the StackLayout's children. - - In contrast to most other layouts, child Items' \l{Layout::fillWidth}{Layout.fillWidth} and \l{Layout::fillHeight}{Layout.fillHeight} properties - default to \c true. As a consequence, child items are by default filled to match the size of the StackLayout as long as their - \l{Layout::maximumWidth}{Layout.maximumWidth} or \l{Layout::maximumHeight}{Layout.maximumHeight} does not prevent it. - - Items are added to the layout by reparenting the item to the layout. Similarly, removal is done by reparenting the item from the layout. - Both of these operations will affect the layout's \l count property. - - The following code will create a StackLayout where only the 'plum' rectangle is visible. - \code - StackLayout { - id: layout - anchors.fill: parent - currentIndex: 1 - Rectangle { - color: 'teal' - implicitWidth: 200 - implicitHeight: 200 - } - Rectangle { - color: 'plum' - implicitWidth: 300 - implicitHeight: 200 - } - } - \endcode - - Items in a StackLayout 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} - \endlist - - Read more about attached properties \l{QML Object Attributes}{here}. - \sa ColumnLayout - \sa GridLayout - \sa RowLayout - \sa {QtQuick.Controls::StackView}{StackView} -*/ - -QT_BEGIN_NAMESPACE - -static QQuickStackLayoutAttached *attachedStackLayoutObject(QQuickItem *item, bool create = false) -{ - return static_cast( - qmlAttachedPropertiesObject(item, create)); -} - -QQuickStackLayout::QQuickStackLayout(QQuickItem *parent) : - QQuickLayout(*new QQuickStackLayoutPrivate, parent) -{ -} - -/*! - \qmlproperty int StackLayout::count - - This property holds the number of items that belong to the layout. - - Only items that are children of the StackLayout will be candidates for layouting. -*/ -int QQuickStackLayout::count() const -{ - Q_D(const QQuickStackLayout); - ensureLayoutItemsUpdated(); - return d->count; -} - -/*! - \qmlproperty int StackLayout::currentIndex - - This property holds the index of the child item that is currently visible in the StackLayout. - By default it will be \c -1 for an empty layout, otherwise the default is \c 0 (referring to the first item). -*/ -int QQuickStackLayout::currentIndex() const -{ - Q_D(const QQuickStackLayout); - ensureLayoutItemsUpdated(); - return d->currentIndex; -} - -void QQuickStackLayout::setCurrentIndex(int index) -{ - Q_D(QQuickStackLayout); - ensureLayoutItemsUpdated(); - if (index == d->currentIndex) - return; - - QQuickItem *prev = itemAt(d->currentIndex); - QQuickItem *next = itemAt(index); - d->currentIndex = index; - d->explicitCurrentIndex = true; - if (prev) - prev->setVisible(false); - if (next) - next->setVisible(true); - - if (isComponentComplete()) { - rearrange(QSizeF(width(), height())); - emit currentIndexChanged(); - } - - // Update attached properties after emitting currentIndexChanged() - // to maintain a more sensible emission order. - if (prev) { - auto stackLayoutAttached = attachedStackLayoutObject(prev); - if (stackLayoutAttached) - stackLayoutAttached->setIsCurrentItem(false); - } - if (next) { - auto stackLayoutAttached = attachedStackLayoutObject(next); - if (stackLayoutAttached) - stackLayoutAttached->setIsCurrentItem(true); - } -} - -void QQuickStackLayout::componentComplete() -{ - QQuickLayout::componentComplete(); // will call our geometryChange(), (where isComponentComplete() == true) - - ensureLayoutItemsUpdated(); - - QQuickItem *par = parentItem(); - if (qobject_cast(par)) - return; - - rearrange(QSizeF(width(), height())); -} - -void QQuickStackLayout::itemChange(QQuickItem::ItemChange change, const QQuickItem::ItemChangeData &value) -{ - QQuickLayout::itemChange(change, value); - - if (change == ItemChildRemovedChange) { - QQuickItem *item = value.item; - auto stackLayoutAttached = attachedStackLayoutObject(item); - if (stackLayoutAttached) { - stackLayoutAttached->setLayout(nullptr); - stackLayoutAttached->setIndex(-1); - stackLayoutAttached->setIsCurrentItem(false); - } - invalidate(); - } else if (change == ItemChildAddedChange) { - invalidate(); - } -} - -QSizeF QQuickStackLayout::sizeHint(Qt::SizeHint whichSizeHint) const -{ - Q_D(const QQuickStackLayout); - ensureLayoutItemsUpdated(); - QSizeF &askingFor = m_cachedSizeHints[whichSizeHint]; - if (!askingFor.isValid()) { - QSizeF &minS = m_cachedSizeHints[Qt::MinimumSize]; - QSizeF &prefS = m_cachedSizeHints[Qt::PreferredSize]; - QSizeF &maxS = m_cachedSizeHints[Qt::MaximumSize]; - - minS = QSizeF(0,0); - prefS = QSizeF(0,0); - maxS = QSizeF(std::numeric_limits::infinity(), std::numeric_limits::infinity()); - - const int count = itemCount(); - m_cachedItemSizeHints.resize(count); - for (int i = 0; i < count; ++i) { - SizeHints &hints = m_cachedItemSizeHints[i]; - QQuickStackLayout::collectItemSizeHints(itemAt(i), hints.array); - minS = minS.expandedTo(hints.min()); - prefS = prefS.expandedTo(hints.pref()); - //maxS = maxS.boundedTo(hints.max()); // Can be resized to be larger than any of its items. - // This is the same as QStackLayout does it. - // Not sure how descent makes sense here... - } - } - d->m_dirty = false; - return askingFor; -} - -int QQuickStackLayout::indexOf(QQuickItem *childItem) const -{ - ensureLayoutItemsUpdated(); - if (childItem) { - int indexOfItem = 0; - const auto items = childItems(); - for (QQuickItem *item : items) { - if (shouldIgnoreItem(item)) - continue; - if (childItem == item) - return indexOfItem; - ++indexOfItem; - } - } - return -1; -} - -QQuickStackLayoutAttached *QQuickStackLayout::qmlAttachedProperties(QObject *object) -{ - return new QQuickStackLayoutAttached(object); -} - -QQuickItem *QQuickStackLayout::itemAt(int index) const -{ - const auto items = childItems(); - for (QQuickItem *item : items) { - if (shouldIgnoreItem(item)) - continue; - if (index == 0) - return item; - --index; - } - return nullptr; -} - -int QQuickStackLayout::itemCount() const -{ - int count = 0; - const auto items = childItems(); - for (QQuickItem *item : items) { - if (shouldIgnoreItem(item)) - continue; - ++count; - } - return count; -} - -void QQuickStackLayout::setAlignment(QQuickItem * /*item*/, Qt::Alignment /*align*/) -{ - // ### Do we have to respect alignment? -} - -void QQuickStackLayout::invalidate(QQuickItem *childItem) -{ - const int indexOfChild = indexOf(childItem); - if (indexOfChild >= 0 && indexOfChild < m_cachedItemSizeHints.count()) { - m_cachedItemSizeHints[indexOfChild].min() = QSizeF(); - m_cachedItemSizeHints[indexOfChild].pref() = QSizeF(); - m_cachedItemSizeHints[indexOfChild].max() = QSizeF(); - } - - for (int i = 0; i < Qt::NSizeHints; ++i) - m_cachedSizeHints[i] = QSizeF(); - QQuickLayout::invalidate(this); - - if (QQuickLayout *parentLayout = qobject_cast(parentItem())) - parentLayout->invalidate(this); -} - -void QQuickStackLayout::updateLayoutItems() -{ - Q_D(QQuickStackLayout); - d->m_ignoredItems.clear(); - const int count = itemCount(); - int oldIndex = d->currentIndex; - if (!d->explicitCurrentIndex) - d->currentIndex = (count > 0 ? 0 : -1); - - if (d->currentIndex != oldIndex) - emit currentIndexChanged(); - - if (count != d->count) { - d->count = count; - emit countChanged(); - } - for (int i = 0; i < count; ++i) { - QQuickItem *child = itemAt(i); - checkAnchors(child); - child->setVisible(d->currentIndex == i); - - auto stackLayoutAttached = attachedStackLayoutObject(child); - if (stackLayoutAttached) { - stackLayoutAttached->setLayout(this); - stackLayoutAttached->setIndex(i); - stackLayoutAttached->setIsCurrentItem(d->currentIndex == i); - } - } -} - -void QQuickStackLayout::rearrange(const QSizeF &newSize) -{ - Q_D(QQuickStackLayout); - if (newSize.isNull() || !newSize.isValid()) - return; - - qCDebug(lcQuickLayouts) << "QQuickStackLayout::rearrange"; - ensureLayoutItemsUpdated(); - - if (d->currentIndex == -1 || d->currentIndex >= m_cachedItemSizeHints.count()) - return; - QQuickStackLayout::SizeHints &hints = m_cachedItemSizeHints[d->currentIndex]; - QQuickItem *item = itemAt(d->currentIndex); - Q_ASSERT(item); - item->setPosition(QPointF(0,0)); // ### respect alignment? - const QSizeF oldSize(item->width(), item->height()); - const QSizeF effectiveNewSize = newSize.expandedTo(hints.min()).boundedTo(hints.max()); - item->setSize(effectiveNewSize); - if (effectiveNewSize == oldSize) - item->polish(); - QQuickLayout::rearrange(newSize); -} - -void QQuickStackLayout::collectItemSizeHints(QQuickItem *item, QSizeF *sizeHints) -{ - QQuickLayoutAttached *info = nullptr; - QQuickLayout::effectiveSizeHints_helper(item, sizeHints, &info, true); - if (!info) - return; - if (info->isFillWidthSet() && !info->fillWidth()) { - const qreal pref = sizeHints[Qt::PreferredSize].width(); - sizeHints[Qt::MinimumSize].setWidth(pref); - sizeHints[Qt::MaximumSize].setWidth(pref); - } - - if (info->isFillHeightSet() && !info->fillHeight()) { - const qreal pref = sizeHints[Qt::PreferredSize].height(); - sizeHints[Qt::MinimumSize].setHeight(pref); - sizeHints[Qt::MaximumSize].setHeight(pref); - } -} - -bool QQuickStackLayout::shouldIgnoreItem(QQuickItem *item) const -{ - const bool ignored = QQuickItemPrivate::get(item)->isTransparentForPositioner(); - if (ignored) - d_func()->m_ignoredItems << item; - return ignored; -} - -QQuickStackLayoutAttached::QQuickStackLayoutAttached(QObject *object) -{ - auto item = qobject_cast(object); - if (!item) { - qmlWarning(object) << "StackLayout must be attached to an Item"; - return; - } - - auto stackLayout = qobject_cast(item->parentItem()); - if (!stackLayout) { - // It might not be a child of a StackLayout yet, and that's OK. - // The index will get set by updateLayoutItems() when it's reparented. - return; - } - - if (!stackLayout->isComponentComplete()) { - // Don't try to get the index if the StackLayout itself hasn't loaded yet. - return; - } - - // If we got this far, the item was added as a child to the StackLayout after it loaded. - const int index = stackLayout->indexOf(item); - setLayout(stackLayout); - setIndex(index); - setIsCurrentItem(stackLayout->currentIndex() == index); -} - -/*! - \qmlattachedproperty int StackLayout::index - - This attached property holds the index of each child item in the - \l StackLayout. - - \sa isCurrentItem, layout - - \since QtQuick.Layouts 1.15 -*/ -int QQuickStackLayoutAttached::index() const -{ - return m_index; -} - -void QQuickStackLayoutAttached::setIndex(int index) -{ - if (index == m_index) - return; - - m_index = index; - emit indexChanged(); -} - -/*! - \qmlattachedproperty bool StackLayout::isCurrentItem - - This attached property is \c true if this child is the current item - in the \l StackLayout. - - \sa index, layout - - \since QtQuick.Layouts 1.15 -*/ -bool QQuickStackLayoutAttached::isCurrentItem() const -{ - return m_isCurrentItem; -} - -void QQuickStackLayoutAttached::setIsCurrentItem(bool isCurrentItem) -{ - if (isCurrentItem == m_isCurrentItem) - return; - - m_isCurrentItem = isCurrentItem; - emit isCurrentItemChanged(); -} - -/*! - \qmlattachedproperty StackLayout StackLayout::layout - - This attached property holds the \l StackLayout that manages this child - item. - - \sa index, isCurrentItem - - \since QtQuick.Layouts 1.15 -*/ -QQuickStackLayout *QQuickStackLayoutAttached::layout() const -{ - return m_layout; -} - -void QQuickStackLayoutAttached::setLayout(QQuickStackLayout *layout) -{ - if (layout == m_layout) - return; - - m_layout = layout; - emit layoutChanged(); -} - -QT_END_NAMESPACE - -#include "moc_qquickstacklayout_p.cpp" diff --git a/src/imports/layouts/qquickstacklayout_p.h b/src/imports/layouts/qquickstacklayout_p.h deleted file mode 100644 index a10f85ce43..0000000000 --- a/src/imports/layouts/qquickstacklayout_p.h +++ /dev/null @@ -1,149 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Quick Layouts module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** 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. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QQUICKSTACKLAYOUT_H -#define QQUICKSTACKLAYOUT_H - -#include - -QT_BEGIN_NAMESPACE - -class QQuickStackLayoutPrivate; -class QQuickStackLayoutAttached; - -class QQuickStackLayout : public QQuickLayout -{ - Q_OBJECT - Q_PROPERTY(int count READ count NOTIFY countChanged) - Q_PROPERTY(int currentIndex READ currentIndex WRITE setCurrentIndex NOTIFY currentIndexChanged) - QML_NAMED_ELEMENT(StackLayout) - QML_ADDED_IN_VERSION(1, 3) - QML_ATTACHED(QQuickStackLayoutAttached) - -public: - explicit QQuickStackLayout(QQuickItem *parent = 0); - int count() const; - int currentIndex() const; - void setCurrentIndex(int index); - - void componentComplete() override; - void itemChange(ItemChange change, const ItemChangeData &value) override; - QSizeF sizeHint(Qt::SizeHint whichSizeHint) const override; - void setAlignment(QQuickItem *item, Qt::Alignment align) override; - void invalidate(QQuickItem *childItem = 0) override; - void updateLayoutItems() override; - void rearrange(const QSizeF &) override; - - // iterator - Q_INVOKABLE QQuickItem *itemAt(int index) const override; - int itemCount() const override; - int indexOf(QQuickItem *item) const; - - static QQuickStackLayoutAttached *qmlAttachedProperties(QObject *object); - -signals: - void currentIndexChanged(); - void countChanged(); - -public slots: - -private: - static void collectItemSizeHints(QQuickItem *item, QSizeF *sizeHints); - bool shouldIgnoreItem(QQuickItem *item) const; - Q_DECLARE_PRIVATE(QQuickStackLayout) - - friend class QQuickStackLayoutAttached; - - QList m_items; - - struct SizeHints { - inline QSizeF &min() { return array[Qt::MinimumSize]; } - inline QSizeF &pref() { return array[Qt::PreferredSize]; } - inline QSizeF &max() { return array[Qt::MaximumSize]; } - QSizeF array[Qt::NSizeHints]; - }; - - mutable QVector m_cachedItemSizeHints; - mutable QSizeF m_cachedSizeHints[Qt::NSizeHints]; -}; - -class QQuickStackLayoutPrivate : public QQuickLayoutPrivate -{ - Q_DECLARE_PUBLIC(QQuickStackLayout) -public: - QQuickStackLayoutPrivate() : count(0), currentIndex(-1), explicitCurrentIndex(false) {} -private: - int count; - int currentIndex; - bool explicitCurrentIndex; -}; - -class QQuickStackLayoutAttached : public QObject -{ - Q_OBJECT - Q_PROPERTY(int index READ index NOTIFY indexChanged) - Q_PROPERTY(bool isCurrentItem READ isCurrentItem NOTIFY isCurrentItemChanged) - Q_PROPERTY(QQuickStackLayout *layout READ layout NOTIFY layoutChanged) - -public: - QQuickStackLayoutAttached(QObject *object); - - int index() const; - void setIndex(int index); - - bool isCurrentItem() const; - void setIsCurrentItem(bool isCurrentItem); - - QQuickStackLayout *layout() const; - void setLayout(QQuickStackLayout *layout); - -signals: - void indexChanged(); - void isCurrentItemChanged(); - void layoutChanged(); - -private: - int m_index = -1; - bool m_isCurrentItem = false; - QQuickStackLayout *m_layout = nullptr; -}; - -QT_END_NAMESPACE - -#endif // QQUICKSTACKLAYOUT_H -- cgit v1.2.3