| /**************************************************************************** |
| ** |
| ** Copyright (C) 2017 The Qt Company Ltd. |
| ** Contact: http://www.qt.io/licensing/ |
| ** |
| ** This file is part of the Qt Quick Templates 2 module of the Qt Toolkit. |
| ** |
| ** $QT_BEGIN_LICENSE:LGPL3$ |
| ** 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 http://www.qt.io/terms-conditions. For further |
| ** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free |
| ** Software Foundation and appearing in the file LICENSE.GPL included in |
| ** the packaging of this file. Please review the following information to |
| ** ensure the GNU General Public License version 2.0 requirements will be |
| ** met: http://www.gnu.org/licenses/gpl-2.0.html. |
| ** |
| ** $QT_END_LICENSE$ |
| ** |
| ****************************************************************************/ |
| |
| #include "qquickpane_p.h" |
| #include "qquickpane_p_p.h" |
| #include "qquickcontentitem_p.h" |
| |
| QT_BEGIN_NAMESPACE |
| |
| /*! |
| \qmltype Pane |
| \inherits Control |
| //! \instantiates QQuickPane |
| \inqmlmodule QtQuick.Controls |
| \since 5.7 |
| \ingroup qtquickcontrols2-containers |
| \ingroup qtquickcontrols2-focusscopes |
| \brief Provides a background matching with the application style and theme. |
| |
| Pane provides a background color that matches with the application style |
| and theme. Pane does not provide a layout of its own, but requires you to |
| position its contents, for instance by creating a \l RowLayout or a |
| \l ColumnLayout. |
| |
| Items declared as children of a Pane are automatically parented to the |
| Pane's \l[QtQuickControls2]{Control::}{contentItem}. Items created |
| dynamically need to be explicitly parented to the contentItem. |
| |
| \section1 Content Sizing |
| |
| If only a single item is used within a Pane, it will resize to fit the |
| implicit size of its contained item. This makes it particularly suitable |
| for use together with layouts. |
| |
| \image qtquickcontrols2-pane.png |
| |
| \snippet qtquickcontrols2-pane.qml 1 |
| |
| Sometimes there might be two items within the pane: |
| |
| \code |
| Pane { |
| SwipeView { |
| // ... |
| } |
| PageIndicator { |
| anchors.horizontalCenter: parent.horizontalCenter |
| anchors.bottom: parent.bottom |
| } |
| } |
| \endcode |
| |
| In this case, Pane cannot calculate a sensible implicit size. Since we're |
| anchoring the \l PageIndicator over the \l SwipeView, we can simply set the |
| content size to the view's implicit size: |
| |
| \code |
| Pane { |
| contentWidth: view.implicitWidth |
| contentHeight: view.implicitHeight |
| |
| SwipeView { |
| id: view |
| // ... |
| } |
| PageIndicator { |
| anchors.horizontalCenter: parent.horizontalCenter |
| anchors.bottom: parent.bottom |
| } |
| } |
| \endcode |
| |
| If the \l contentItem has no implicit size and only one child, Pane will |
| use the implicit size of that child. For example, in the following code, |
| the Pane will assume the size of the Rectangle: |
| |
| \code |
| Pane { |
| Item { |
| Rectangle { |
| implicitWidth: 200 |
| implicitHeight: 200 |
| color: "salmon" |
| } |
| } |
| } |
| \endcode |
| |
| \sa {Customizing Pane}, {Container Controls}, |
| {Focus Management in Qt Quick Controls}, {Event Handling} |
| */ |
| |
| void QQuickPanePrivate::init() |
| { |
| Q_Q(QQuickPane); |
| q->setFlag(QQuickItem::ItemIsFocusScope); |
| q->setAcceptedMouseButtons(Qt::AllButtons); |
| #if QT_CONFIG(cursor) |
| q->setCursor(Qt::ArrowCursor); |
| #endif |
| connect(q, &QQuickControl::implicitContentWidthChanged, this, &QQuickPanePrivate::updateContentWidth); |
| connect(q, &QQuickControl::implicitContentHeightChanged, this, &QQuickPanePrivate::updateContentHeight); |
| } |
| |
| QList<QQuickItem *> QQuickPanePrivate::contentChildItems() const |
| { |
| if (!contentItem) |
| return QList<QQuickItem *>(); |
| |
| return contentItem->childItems(); |
| } |
| |
| QQuickItem *QQuickPanePrivate::getContentItem() |
| { |
| Q_Q(QQuickPane); |
| if (QQuickItem *item = QQuickControlPrivate::getContentItem()) |
| return item; |
| |
| return new QQuickContentItem(q); |
| } |
| |
| void QQuickPanePrivate::itemImplicitWidthChanged(QQuickItem *item) |
| { |
| QQuickControlPrivate::itemImplicitWidthChanged(item); |
| |
| if (item == firstChild) |
| updateImplicitContentWidth(); |
| } |
| |
| void QQuickPanePrivate::itemImplicitHeightChanged(QQuickItem *item) |
| { |
| QQuickControlPrivate::itemImplicitHeightChanged(item); |
| |
| if (item == firstChild) |
| updateImplicitContentHeight(); |
| } |
| |
| void QQuickPanePrivate::contentChildrenChange() |
| { |
| Q_Q(QQuickPane); |
| QQuickItem *newFirstChild = contentChildItems().value(0); |
| if (newFirstChild != firstChild) { |
| if (firstChild) |
| removeImplicitSizeListener(firstChild); |
| if (newFirstChild) |
| addImplicitSizeListener(newFirstChild); |
| firstChild = newFirstChild; |
| } |
| |
| updateImplicitContentSize(); |
| emit q->contentChildrenChanged(); |
| } |
| |
| qreal QQuickPanePrivate::getContentWidth() const |
| { |
| if (!contentItem) |
| return 0; |
| |
| const qreal cw = contentItem->implicitWidth(); |
| if (!qFuzzyIsNull(cw)) |
| return cw; |
| |
| const auto contentChildren = contentChildItems(); |
| if (contentChildren.count() == 1) |
| return contentChildren.first()->implicitWidth(); |
| |
| return 0; |
| } |
| |
| qreal QQuickPanePrivate::getContentHeight() const |
| { |
| if (!contentItem) |
| return 0; |
| |
| const qreal ch = contentItem->implicitHeight(); |
| if (!qFuzzyIsNull(ch)) |
| return ch; |
| |
| const auto contentChildren = contentChildItems(); |
| if (contentChildren.count() == 1) |
| return contentChildren.first()->implicitHeight(); |
| |
| return 0; |
| } |
| |
| void QQuickPanePrivate::updateContentWidth() |
| { |
| Q_Q(QQuickPane); |
| if (hasContentWidth || qFuzzyCompare(contentWidth, implicitContentWidth)) |
| return; |
| |
| const qreal oldContentWidth = contentWidth; |
| contentWidth = implicitContentWidth; |
| q->contentSizeChange(QSizeF(contentWidth, contentHeight), QSizeF(oldContentWidth, contentHeight)); |
| emit q->contentWidthChanged(); |
| } |
| |
| void QQuickPanePrivate::updateContentHeight() |
| { |
| Q_Q(QQuickPane); |
| if (hasContentHeight || qFuzzyCompare(contentHeight, implicitContentHeight)) |
| return; |
| |
| const qreal oldContentHeight = contentHeight; |
| contentHeight = implicitContentHeight; |
| q->contentSizeChange(QSizeF(contentWidth, contentHeight), QSizeF(contentWidth, oldContentHeight)); |
| emit q->contentHeightChanged(); |
| } |
| |
| QQuickPane::QQuickPane(QQuickItem *parent) |
| : QQuickControl(*(new QQuickPanePrivate), parent) |
| { |
| Q_D(QQuickPane); |
| d->init(); |
| } |
| |
| QQuickPane::~QQuickPane() |
| { |
| Q_D(QQuickPane); |
| d->removeImplicitSizeListener(d->contentItem); |
| d->removeImplicitSizeListener(d->firstChild); |
| } |
| |
| QQuickPane::QQuickPane(QQuickPanePrivate &dd, QQuickItem *parent) |
| : QQuickControl(dd, parent) |
| { |
| Q_D(QQuickPane); |
| d->init(); |
| } |
| |
| /*! |
| \qmlproperty real QtQuick.Controls::Pane::contentWidth |
| |
| This property holds the content width. It is used for calculating the total |
| implicit width of the pane. |
| |
| For more information, see \l {Content Sizing}. |
| |
| \sa contentHeight |
| */ |
| qreal QQuickPane::contentWidth() const |
| { |
| Q_D(const QQuickPane); |
| return d->contentWidth; |
| } |
| |
| void QQuickPane::setContentWidth(qreal width) |
| { |
| Q_D(QQuickPane); |
| d->hasContentWidth = true; |
| if (qFuzzyCompare(d->contentWidth, width)) |
| return; |
| |
| const qreal oldWidth = d->contentWidth; |
| d->contentWidth = width; |
| contentSizeChange(QSizeF(width, d->contentHeight), QSizeF(oldWidth, d->contentHeight)); |
| emit contentWidthChanged(); |
| } |
| |
| void QQuickPane::resetContentWidth() |
| { |
| Q_D(QQuickPane); |
| if (!d->hasContentWidth) |
| return; |
| |
| d->hasContentHeight = false; |
| d->updateContentWidth(); |
| } |
| |
| /*! |
| \qmlproperty real QtQuick.Controls::Pane::contentHeight |
| |
| This property holds the content height. It is used for calculating the total |
| implicit height of the pane. |
| |
| For more information, see \l {Content Sizing}. |
| |
| \sa contentWidth |
| */ |
| qreal QQuickPane::contentHeight() const |
| { |
| Q_D(const QQuickPane); |
| return d->contentHeight; |
| } |
| |
| void QQuickPane::setContentHeight(qreal height) |
| { |
| Q_D(QQuickPane); |
| d->hasContentHeight = true; |
| if (qFuzzyCompare(d->contentHeight, height)) |
| return; |
| |
| const qreal oldHeight = d->contentHeight; |
| d->contentHeight = height; |
| contentSizeChange(QSizeF(d->contentWidth, height), QSizeF(d->contentWidth, oldHeight)); |
| emit contentHeightChanged(); |
| } |
| |
| void QQuickPane::resetContentHeight() |
| { |
| Q_D(QQuickPane); |
| if (!d->hasContentHeight) |
| return; |
| |
| d->hasContentHeight = false; |
| d->updateContentHeight(); |
| } |
| |
| /*! |
| \qmlproperty list<Object> QtQuick.Controls::Pane::contentData |
| \default |
| |
| This property holds the list of content data. |
| |
| The list contains all objects that have been declared in QML as children |
| of the pane. |
| |
| \note Unlike \c contentChildren, \c contentData does include non-visual QML |
| objects. |
| |
| \sa Item::data, contentChildren |
| */ |
| QQmlListProperty<QObject> QQuickPanePrivate::contentData() |
| { |
| Q_Q(QQuickPane); |
| return QQmlListProperty<QObject>(q->contentItem(), nullptr, |
| QQuickItemPrivate::data_append, |
| QQuickItemPrivate::data_count, |
| QQuickItemPrivate::data_at, |
| QQuickItemPrivate::data_clear); |
| } |
| |
| /*! |
| \qmlproperty list<Item> QtQuick.Controls::Pane::contentChildren |
| |
| This property holds the list of content children. |
| |
| The list contains all items that have been declared in QML as children |
| of the pane. |
| |
| \note Unlike \c contentData, \c contentChildren does not include non-visual |
| QML objects. |
| |
| \sa Item::children, contentData |
| */ |
| QQmlListProperty<QQuickItem> QQuickPanePrivate::contentChildren() |
| { |
| Q_Q(QQuickPane); |
| return QQmlListProperty<QQuickItem>(q->contentItem(), nullptr, |
| QQuickItemPrivate::children_append, |
| QQuickItemPrivate::children_count, |
| QQuickItemPrivate::children_at, |
| QQuickItemPrivate::children_clear); |
| } |
| |
| void QQuickPane::componentComplete() |
| { |
| Q_D(QQuickPane); |
| QQuickControl::componentComplete(); |
| d->updateImplicitContentSize(); |
| } |
| |
| void QQuickPane::contentItemChange(QQuickItem *newItem, QQuickItem *oldItem) |
| { |
| Q_D(QQuickPane); |
| QQuickControl::contentItemChange(newItem, oldItem); |
| if (oldItem) { |
| d->removeImplicitSizeListener(oldItem); |
| QObjectPrivate::disconnect(oldItem, &QQuickItem::childrenChanged, d, &QQuickPanePrivate::contentChildrenChange); |
| } |
| if (newItem) { |
| d->addImplicitSizeListener(newItem); |
| QObjectPrivate::connect(newItem, &QQuickItem::childrenChanged, d, &QQuickPanePrivate::contentChildrenChange); |
| } |
| d->contentChildrenChange(); |
| } |
| |
| void QQuickPane::contentSizeChange(const QSizeF &newSize, const QSizeF &oldSize) |
| { |
| Q_UNUSED(newSize) |
| Q_UNUSED(oldSize) |
| } |
| |
| #if QT_CONFIG(accessibility) |
| QAccessible::Role QQuickPane::accessibleRole() const |
| { |
| return QAccessible::Pane; |
| } |
| #endif |
| |
| QT_END_NAMESPACE |
| |
| #include "moc_qquickpane_p.cpp" |