diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/imports/controls/qtquickcontrols2plugin.cpp | 2 | ||||
-rw-r--r-- | src/quickcontrols2/qquickdisplaylayout.cpp | 412 | ||||
-rw-r--r-- | src/quickcontrols2/qquickdisplaylayout_p.h | 138 | ||||
-rw-r--r-- | src/quickcontrols2/qquickdisplaylayout_p_p.h | 90 | ||||
-rw-r--r-- | src/quickcontrols2/quickcontrols2.pri | 3 |
5 files changed, 645 insertions, 0 deletions
diff --git a/src/imports/controls/qtquickcontrols2plugin.cpp b/src/imports/controls/qtquickcontrols2plugin.cpp index 2cd97daa..3a131511 100644 --- a/src/imports/controls/qtquickcontrols2plugin.cpp +++ b/src/imports/controls/qtquickcontrols2plugin.cpp @@ -39,6 +39,7 @@ #include <QtQuickControls2/private/qquickcolor_p.h> #include <QtQuickControls2/private/qquickiconimage_p.h> #include <QtQuickControls2/private/qquickplaceholdertext_p.h> +#include <QtQuickControls2/private/qquickdisplaylayout_p.h> #include <QtQuickControls2/private/qquickstyle_p.h> #include <QtQuickControls2/private/qquickstyleplugin_p.h> #include <QtQuickControls2/private/qquickstyleselector_p.h> @@ -193,6 +194,7 @@ void QtQuickControls2Plugin::initializeEngine(QQmlEngine *engine, const char *ur qmlRegisterType<QQuickIconImage>(import, 2, 3, "IconImage"); qmlRegisterSingletonType<QQuickColor>(import, 2, 3, "Color", colorSingleton); + qmlRegisterType<QQuickDisplayLayout>(import, 2, 3, "DisplayLayout"); } QT_END_NAMESPACE diff --git a/src/quickcontrols2/qquickdisplaylayout.cpp b/src/quickcontrols2/qquickdisplaylayout.cpp new file mode 100644 index 00000000..dba5d604 --- /dev/null +++ b/src/quickcontrols2/qquickdisplaylayout.cpp @@ -0,0 +1,412 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 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 "qquickdisplaylayout_p.h" +#include "qquickdisplaylayout_p_p.h" + +#include <QtQuick/private/qquickitem_p.h> + +QT_BEGIN_NAMESPACE + +QQuickDisplayLayoutPrivate::QQuickDisplayLayoutPrivate() + : icon(nullptr), + text(nullptr), + display(QQuickDisplayLayout::TextBesideIcon), + spacing(0), + mirrored(false), + topPadding(0), + leftPadding(0), + rightPadding(0), + bottomPadding(0) +{ +} + +void QQuickDisplayLayoutPrivate::updateImplicitSize() +{ + Q_Q(QQuickDisplayLayout); + if (!q->isComponentComplete()) + return; + + const bool showIcon = icon && display != QQuickDisplayLayout::TextOnly; + const bool showText = text && display != QQuickDisplayLayout::IconOnly; + const qreal horizontalPadding = leftPadding + rightPadding; + const qreal verticalPadding = topPadding + bottomPadding; + const qreal iconImplicitWidth = showIcon ? icon->implicitWidth() : 0; + const qreal iconImplicitHeight = showIcon ? icon->implicitHeight() : 0; + const qreal textImplicitWidth = showText ? text->implicitWidth() : 0; + const qreal textImplicitHeight = showText ? text->implicitHeight() : 0; + const qreal effectiveSpacing = showText && showIcon ? spacing : 0; + const qreal implicitWidth = iconImplicitWidth + textImplicitWidth + effectiveSpacing + horizontalPadding; + const qreal implicitHeight = qMax(iconImplicitHeight, textImplicitHeight) + verticalPadding; + q->setImplicitSize(implicitWidth, implicitHeight); +} + +void QQuickDisplayLayoutPrivate::layout() +{ + Q_Q(QQuickDisplayLayout); + if (!q->isComponentComplete()) + return; + + const qreal horizontalPadding = leftPadding + rightPadding; + const qreal verticalPadding = topPadding + bottomPadding; + const qreal w = q->width(); + const qreal h = q->height(); + const qreal availableWidth = w - horizontalPadding; + const qreal availableHeight = h - verticalPadding; + const qreal horizontalCenter = w / 2; + const qreal verticalCenter = h / 2; + + switch (display) { + case QQuickDisplayLayout::IconOnly: + if (icon) { + icon->setWidth(qMin(icon->implicitWidth(), availableWidth)); + icon->setHeight(qMin(icon->implicitHeight(), availableHeight)); + icon->setX(horizontalCenter - icon->width() / 2); + icon->setY(verticalCenter - icon->height() / 2); + icon->setVisible(true); + } + if (text) + text->setVisible(false); + break; + case QQuickDisplayLayout::TextOnly: + if (text) { + text->setWidth(qMin(text->implicitWidth(), availableWidth)); + text->setHeight(qMin(text->implicitHeight(), availableHeight)); + text->setX(horizontalCenter - text->width() / 2); + text->setY(verticalCenter - text->height() / 2); + text->setVisible(true); + } + if (icon) + icon->setVisible(false); + break; + case QQuickDisplayLayout::TextBesideIcon: + default: + // Work out the sizes first, as the positions depend on them. + qreal iconWidth = 0; + qreal textWidth = 0; + if (icon) { + icon->setWidth(qMin(icon->implicitWidth(), availableWidth)); + icon->setHeight(qMin(icon->implicitHeight(), availableHeight)); + iconWidth = icon->width(); + } + if (text) { + text->setWidth(qMin(text->implicitWidth(), availableWidth - iconWidth - spacing)); + text->setHeight(qMin(text->implicitHeight(), availableHeight)); + textWidth = text->width(); + } + + const qreal combinedWidth = iconWidth + spacing + textWidth; + const qreal contentX = horizontalCenter - combinedWidth / 2; + if (icon) { + icon->setX(mirrored ? contentX + combinedWidth - iconWidth : contentX); + icon->setY(verticalCenter - icon->height() / 2); + icon->setVisible(true); + } + if (text) { + text->setX(mirrored ? contentX : contentX + combinedWidth - text->width()); + text->setY(verticalCenter - text->height() / 2); + text->setVisible(true); + } + break; + } +} + +static const QQuickItemPrivate::ChangeTypes itemChangeTypes = + QQuickItemPrivate::ImplicitWidth + | QQuickItemPrivate::ImplicitHeight + | QQuickItemPrivate::Destroyed; + +void QQuickDisplayLayoutPrivate::watchChanges(QQuickItem *item) +{ + QQuickItemPrivate *itemPrivate = QQuickItemPrivate::get(item); + itemPrivate->addItemChangeListener(this, itemChangeTypes); +} + +void QQuickDisplayLayoutPrivate::unwatchChanges(QQuickItem* item) +{ + QQuickItemPrivate *itemPrivate = QQuickItemPrivate::get(item); + itemPrivate->removeItemChangeListener(this, itemChangeTypes); +} + +void QQuickDisplayLayoutPrivate::itemImplicitWidthChanged(QQuickItem *) +{ + updateImplicitSize(); +} + +void QQuickDisplayLayoutPrivate::itemImplicitHeightChanged(QQuickItem *) +{ + updateImplicitSize(); +} + +void QQuickDisplayLayoutPrivate::itemDestroyed(QQuickItem *item) +{ + unwatchChanges(item); + if (item == icon) + icon = nullptr; + else if (item == text) + text = nullptr; +} + +QQuickDisplayLayout::QQuickDisplayLayout(QQuickItem *parent) + : QQuickItem(*(new QQuickDisplayLayoutPrivate), parent) +{ +} + +QQuickDisplayLayout::~QQuickDisplayLayout() +{ + Q_D(QQuickDisplayLayout); + if (d->icon) + d->unwatchChanges(d->icon); + if (d->text) + d->unwatchChanges(d->text); +} + +QQuickItem *QQuickDisplayLayout::icon() const +{ + Q_D(const QQuickDisplayLayout); + return d->icon; +} + +void QQuickDisplayLayout::setIcon(QQuickItem *icon) +{ + Q_D(QQuickDisplayLayout); + if (d->icon == icon) + return; + + if (d->icon) + d->unwatchChanges(d->icon); + + d->icon = icon; + if (d->icon) { + d->icon->setParentItem(this); + d->watchChanges(d->icon); + } + + d->updateImplicitSize(); + d->layout(); + + emit iconChanged(); +} + +QQuickItem *QQuickDisplayLayout::text() const +{ + Q_D(const QQuickDisplayLayout); + return d->text; +} + +void QQuickDisplayLayout::setText(QQuickItem *text) +{ + Q_D(QQuickDisplayLayout); + if (d->text == text) + return; + + if (d->text) + d->unwatchChanges(d->text); + + d->text = text; + if (d->text) { + d->text->setParentItem(this); + d->watchChanges(d->text); + } + + d->updateImplicitSize(); + d->layout(); + + emit textChanged(); +} + +QQuickDisplayLayout::Display QQuickDisplayLayout::display() const +{ + Q_D(const QQuickDisplayLayout); + return d->display; +} + +void QQuickDisplayLayout::setDisplay(Display display) +{ + Q_D(QQuickDisplayLayout); + if (d->display == display) + return; + + d->display = display; + d->updateImplicitSize(); + d->layout(); + emit displayChanged(); +} + +qreal QQuickDisplayLayout::spacing() const +{ + Q_D(const QQuickDisplayLayout); + return d->spacing; +} + +void QQuickDisplayLayout::setSpacing(qreal spacing) +{ + Q_D(QQuickDisplayLayout); + if (qFuzzyCompare(d->spacing, spacing)) + return; + + d->spacing = spacing; + d->updateImplicitSize(); + d->layout(); + emit spacingChanged(); +} + +bool QQuickDisplayLayout::isMirrored() const +{ + Q_D(const QQuickDisplayLayout); + return d->mirrored; +} + +void QQuickDisplayLayout::setMirrored(bool mirrored) +{ + Q_D(QQuickDisplayLayout); + if (d->mirrored == mirrored) + return; + + d->mirrored = mirrored; + d->updateImplicitSize(); + d->layout(); + emit mirroredChanged(); +} + +qreal QQuickDisplayLayout::topPadding() const +{ + Q_D(const QQuickDisplayLayout); + return d->topPadding; +} + +void QQuickDisplayLayout::setTopPadding(qreal padding) +{ + Q_D(QQuickDisplayLayout); + if (qFuzzyCompare(d->topPadding, padding)) + return; + + d->topPadding = padding; + d->updateImplicitSize(); + d->layout(); + emit topPaddingChanged(); +} + +void QQuickDisplayLayout::resetTopPadding() +{ + setTopPadding(0); +} + +qreal QQuickDisplayLayout::leftPadding() const +{ + Q_D(const QQuickDisplayLayout); + return d->leftPadding; +} + +void QQuickDisplayLayout::setLeftPadding(qreal padding) +{ + Q_D(QQuickDisplayLayout); + if (qFuzzyCompare(d->leftPadding, padding)) + return; + + d->leftPadding = padding; + d->updateImplicitSize(); + d->layout(); + emit leftPaddingChanged(); +} + +void QQuickDisplayLayout::resetLeftPadding() +{ + setLeftPadding(0); +} + +qreal QQuickDisplayLayout::rightPadding() const +{ + Q_D(const QQuickDisplayLayout); + return d->rightPadding; +} + +void QQuickDisplayLayout::setRightPadding(qreal padding) +{ + Q_D(QQuickDisplayLayout); + if (qFuzzyCompare(d->rightPadding, padding)) + return; + + d->rightPadding = padding; + d->updateImplicitSize(); + d->layout(); + emit rightPaddingChanged(); +} + +void QQuickDisplayLayout::resetRightPadding() +{ + setRightPadding(0); +} + +qreal QQuickDisplayLayout::bottomPadding() const +{ + Q_D(const QQuickDisplayLayout); + return d->bottomPadding; +} + +void QQuickDisplayLayout::setBottomPadding(qreal padding) +{ + Q_D(QQuickDisplayLayout); + if (qFuzzyCompare(d->bottomPadding, padding)) + return; + + d->bottomPadding = padding; + d->updateImplicitSize(); + d->layout(); + emit bottomPaddingChanged(); +} + +void QQuickDisplayLayout::resetBottomPadding() +{ + setBottomPadding(0); +} + +void QQuickDisplayLayout::componentComplete() +{ + Q_D(QQuickDisplayLayout); + QQuickItem::componentComplete(); + d->updateImplicitSize(); + d->layout(); +} + +void QQuickDisplayLayout::geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry) +{ + Q_D(QQuickDisplayLayout); + QQuickItem::geometryChanged(newGeometry, oldGeometry); + d->layout(); +} + +QT_END_NAMESPACE diff --git a/src/quickcontrols2/qquickdisplaylayout_p.h b/src/quickcontrols2/qquickdisplaylayout_p.h new file mode 100644 index 00000000..dde0aaf8 --- /dev/null +++ b/src/quickcontrols2/qquickdisplaylayout_p.h @@ -0,0 +1,138 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 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$ +** +****************************************************************************/ + +#ifndef QQUICKDISPLAYLAYOUT_P_H +#define QQUICKDISPLAYLAYOUT_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <QtQuick/qquickitem.h> +#include <QtQuickControls2/private/qtquickcontrols2global_p.h> + +QT_BEGIN_NAMESPACE + +class QQuickDisplayLayoutPrivate; + +class Q_QUICKCONTROLS2_PRIVATE_EXPORT QQuickDisplayLayout : public QQuickItem +{ + Q_OBJECT + Q_PROPERTY(QQuickItem *icon READ icon WRITE setIcon NOTIFY iconChanged FINAL) + Q_PROPERTY(QQuickItem *text READ text WRITE setText NOTIFY textChanged FINAL) + Q_PROPERTY(Display display READ display WRITE setDisplay NOTIFY displayChanged FINAL) + Q_PROPERTY(qreal spacing READ spacing WRITE setSpacing NOTIFY spacingChanged) + Q_PROPERTY(bool mirrored READ isMirrored WRITE setMirrored NOTIFY mirroredChanged) + Q_PROPERTY(qreal topPadding READ topPadding WRITE setTopPadding RESET resetTopPadding NOTIFY topPaddingChanged) + Q_PROPERTY(qreal leftPadding READ leftPadding WRITE setLeftPadding RESET resetLeftPadding NOTIFY leftPaddingChanged) + Q_PROPERTY(qreal rightPadding READ rightPadding WRITE setRightPadding RESET resetRightPadding NOTIFY rightPaddingChanged) + Q_PROPERTY(qreal bottomPadding READ bottomPadding WRITE setBottomPadding RESET resetBottomPadding NOTIFY bottomPaddingChanged) + +public: + enum Display { + IconOnly, + TextOnly, + TextBesideIcon, + TextUnderIcon // unused, but reserved for future use + }; + Q_ENUM(Display) + + explicit QQuickDisplayLayout(QQuickItem *parent = nullptr); + ~QQuickDisplayLayout(); + + QQuickItem *icon() const; + void setIcon(QQuickItem *icon); + + QQuickItem *text() const; + void setText(QQuickItem *text); + + Display display() const; + void setDisplay(Display display); + + qreal spacing() const; + void setSpacing(qreal spacing); + + bool isMirrored() const; + void setMirrored(bool mirrored); + + qreal topPadding() const; + void setTopPadding(qreal padding); + void resetTopPadding(); + + qreal leftPadding() const; + void setLeftPadding(qreal padding); + void resetLeftPadding(); + + qreal rightPadding() const; + void setRightPadding(qreal padding); + void resetRightPadding(); + + qreal bottomPadding() const; + void setBottomPadding(qreal padding); + void resetBottomPadding(); + +Q_SIGNALS: + void iconChanged(); + void textChanged(); + void displayChanged(); + void spacingChanged(); + void mirroredChanged(); + void topPaddingChanged(); + void leftPaddingChanged(); + void rightPaddingChanged(); + void bottomPaddingChanged(); + +protected: + void componentComplete() override; + void geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry) override; + +private: + Q_DISABLE_COPY(QQuickDisplayLayout) + Q_DECLARE_PRIVATE(QQuickDisplayLayout) +}; + +QT_END_NAMESPACE + +QML_DECLARE_TYPE(QQuickDisplayLayout) + +#endif // QQUICKDISPLAYLAYOUT_P_H diff --git a/src/quickcontrols2/qquickdisplaylayout_p_p.h b/src/quickcontrols2/qquickdisplaylayout_p_p.h new file mode 100644 index 00000000..1397b93a --- /dev/null +++ b/src/quickcontrols2/qquickdisplaylayout_p_p.h @@ -0,0 +1,90 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 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$ +** +****************************************************************************/ + +#ifndef QQUICKDISPLAYLAYOUT_P_P_H +#define QQUICKDISPLAYLAYOUT_P_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <QtQuick/private/qquickitem_p.h> +#include <QtQuickControls2/private/qtquickcontrols2global_p.h> +#include <QtQuickControls2/private/qquickdisplaylayout_p.h> + +QT_BEGIN_NAMESPACE + +class QQuickDisplayLayoutPrivate : public QQuickItemPrivate, public QQuickItemChangeListener +{ + Q_DECLARE_PUBLIC(QQuickDisplayLayout) + +public: + explicit QQuickDisplayLayoutPrivate(); + + void updateImplicitSize(); + void layout(); + + void watchChanges(QQuickItem *item); + void unwatchChanges(QQuickItem *item); + void setPositioningDirty(); + + bool isLeftToRight() const; + + void itemImplicitWidthChanged(QQuickItem *) override; + void itemImplicitHeightChanged(QQuickItem *) override; + void itemDestroyed(QQuickItem *item) override; + + QQuickItem *icon; + QQuickItem *text; + QQuickDisplayLayout::Display display; + qreal spacing; + bool mirrored; + qreal topPadding; + qreal leftPadding; + qreal rightPadding; + qreal bottomPadding; +}; + +QT_END_NAMESPACE + +#endif // QQUICKDISPLAYLAYOUT_P_P_H diff --git a/src/quickcontrols2/quickcontrols2.pri b/src/quickcontrols2/quickcontrols2.pri index ed01660e..83ffb687 100644 --- a/src/quickcontrols2/quickcontrols2.pri +++ b/src/quickcontrols2/quickcontrols2.pri @@ -2,6 +2,8 @@ HEADERS += \ $$PWD/qquickanimatednode_p.h \ $$PWD/qquickcolor_p.h \ $$PWD/qquickcolorimageprovider_p.h \ + $$PWD/qquickdisplaylayout_p.h \ + $$PWD/qquickdisplaylayout_p_p.h \ $$PWD/qquickiconimage_p.h \ $$PWD/qquickiconimage_p_p.h \ $$PWD/qquickplaceholdertext_p.h \ @@ -18,6 +20,7 @@ SOURCES += \ $$PWD/qquickanimatednode.cpp \ $$PWD/qquickcolor.cpp \ $$PWD/qquickcolorimageprovider.cpp \ + $$PWD/qquickdisplaylayout.cpp \ $$PWD/qquickiconimage.cpp \ $$PWD/qquickplaceholdertext.cpp \ $$PWD/qquickproxytheme.cpp \ |