diff options
45 files changed, 2824 insertions, 30 deletions
diff --git a/src/quick/CMakeLists.txt b/src/quick/CMakeLists.txt index bffe111828..d7ea3d1df5 100644 --- a/src/quick/CMakeLists.txt +++ b/src/quick/CMakeLists.txt @@ -80,6 +80,11 @@ qt_add_module(Quick items/qquickwindow.cpp items/qquickwindow.h items/qquickwindow_p.h items/qquickwindowattached.cpp items/qquickwindowattached_p.h items/qquickwindowmodule.cpp items/qquickwindowmodule_p.h + items/qquickwindowmodule_p_p.h + items/qquickpalette.cpp items/qquickpalette_p.h + items/qquickcolorgroup.cpp items/qquickcolorgroup_p.h + items/qquickpalettecolorprovider.cpp items/qquickpalettecolorprovider_p.h + items/qquickpaletteproviderprivatebase_p.h qtquick2.cpp qtquick2_p.h qtquickglobal.h qtquickglobal_p.h scenegraph/adaptations/software/qsgabstractsoftwarerenderer.cpp scenegraph/adaptations/software/qsgabstractsoftwarerenderer_p.h diff --git a/src/quick/designer/qquickdesignerwindowmanager.cpp b/src/quick/designer/qquickdesignerwindowmanager.cpp index 9648a40a23..bca89f3e14 100644 --- a/src/quick/designer/qquickdesignerwindowmanager.cpp +++ b/src/quick/designer/qquickdesignerwindowmanager.cpp @@ -39,6 +39,7 @@ #include "qquickdesignerwindowmanager_p.h" #include "private/qquickwindow_p.h" +#include "private/qquickitem_p.h" #include <QtQuick/QQuickWindow> #if QT_CONFIG(opengl) #include <private/qsgdefaultrendercontext_p.h> diff --git a/src/quick/items/items.pri b/src/quick/items/items.pri index 6f2f9fbd8e..c2078b0e04 100644 --- a/src/quick/items/items.pri +++ b/src/quick/items/items.pri @@ -1,4 +1,5 @@ HEADERS += \ + $$PWD/qquickabstractpaletteprovider_p.h \ $$PWD/qquickevents_p_p.h \ $$PWD/qquickanchors_p.h \ $$PWD/qquickanchors_p_p.h \ @@ -56,10 +57,15 @@ HEADERS += \ $$PWD/qquickscreen_p.h \ $$PWD/qquickwindowattached_p.h \ $$PWD/qquickwindowmodule_p.h \ + $$PWD/qquickwindowmodule_p_p.h \ $$PWD/qquickrendercontrol.h \ $$PWD/qquickrendercontrol_p.h \ $$PWD/qquickgraphicsinfo_p.h \ - $$PWD/qquickitemgrabresult.h + $$PWD/qquickitemgrabresult.h \ + $$PWD/qquickpalette_p.h \ + $$PWD/qquickcolorgroup_p.h \ + $$PWD/qquickpalettecolorprovider_p.h \ + $$PWD/qquickpaletteproviderprivatebase_p.h SOURCES += \ $$PWD/qquickevents.cpp \ @@ -99,7 +105,10 @@ SOURCES += \ $$PWD/qquickwindowattached.cpp \ $$PWD/qquickrendercontrol.cpp \ $$PWD/qquickgraphicsinfo.cpp \ - $$PWD/qquickitemgrabresult.cpp + $$PWD/qquickitemgrabresult.cpp \ + $$PWD/qquickpalettecolorprovider.cpp \ + $$PWD/qquickcolorgroup.cpp \ + $$PWD/qquickpalette.cpp qtConfig(quick-draganddrop) { HEADERS += \ diff --git a/src/quick/items/qquickabstractpaletteprovider_p.h b/src/quick/items/qquickabstractpaletteprovider_p.h new file mode 100644 index 0000000000..8336d88418 --- /dev/null +++ b/src/quick/items/qquickabstractpaletteprovider_p.h @@ -0,0 +1,64 @@ +/**************************************************************************** +** +** Copyright (C) 2020 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the QtQuick 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 QQUICKABSTRACTPALETTEPROVIDER_P_H +#define QQUICKABSTRACTPALETTEPROVIDER_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/qtquickglobal_p.h> + +QT_BEGIN_NAMESPACE + +class QQuickAbstractPaletteProvider +{ +public: + virtual ~QQuickAbstractPaletteProvider() = default; + virtual QPalette defaultPalette() const = 0; + virtual QPalette parentPalette() const = 0; +}; + +QT_END_NAMESPACE + +#endif // QQUICKABSTRACTPALETTEPROVIDER_P_H diff --git a/src/quick/items/qquickcolorgroup.cpp b/src/quick/items/qquickcolorgroup.cpp new file mode 100644 index 0000000000..5eedefea83 --- /dev/null +++ b/src/quick/items/qquickcolorgroup.cpp @@ -0,0 +1,571 @@ +/**************************************************************************** +** +** Copyright (C) 2020 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the QtQuick 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 "qquickcolorgroup_p.h" + +#include <QScopeGuard> + +#include <QtQuick/private/qquickabstractpaletteprovider_p.h> +#include <QtQuick/private/qquickpalette_p.h> +#include <QtQuick/private/qquickpalettecolorprovider_p.h> + +QT_BEGIN_NAMESPACE + +/*! + \class QQuickColorGroup + \brief The QQuickColorGroup class represents a set of colors. + \inmodule QtQuick + \since 6.0 + + Used by QQuickPalette to provide different groups of colors by roles. + + \sa QQuickPalette, QQuickAbstractPaletteProvider, QPalette::ColorRole + */ + +/*! + \qmltype ColorGroup + \instantiates QQuickColorGroup + \inherits QtObject + \inqmlmodule QtQuick + \ingroup qtquick-visual + \brief The set of colors by roles. + + The ColorGroup type is used to define a set of colors with certain roles. Although a ColorGroup + has no visual appearance, it defines colors used to customize rendered items. + + Default values of colors are equal to active group colors of default-constructed \c QPalette. + + The following code can be used to create a color group with some colors specified: + + \code + ColorGroup { + alternateBase: "red" + base: "green" + } + \endcode + */ + +/*! + \qmlproperty color QtQuick::ColorGroup::alternateBase + + Used as the alternate background color in item views with alternating row colors. +*/ + +/*! + \qmlproperty color QtQuick::ColorGroup::base + + Used mostly as the background color for text editor controls and item views. + It is usually white or another light color. +*/ + +/*! + \qmlproperty color QtQuick::ColorGroup::brightText + + A text color that is very different from \c windowText, and contrasts + well with e.g. \c dark. Typically used for text that needs to be drawn + where \c text, \c windowText or \c buttonText would + give poor contrast, such as on highlighted buttons. +*/ + +/*! + \qmlproperty color QtQuick::ColorGroup::button + + The general button background color. This background can be different from + \c window as some styles require a different background color for buttons. +*/ + +/*! + \qmlproperty color QtQuick::ColorGroup::buttonText + + A foreground color used with the \c palette color. +*/ + +/*! + \qmlproperty color QtQuick::ColorGroup::dark + + A foreground color used with the \c palette color. +*/ + +/*! + \qmlproperty color QtQuick::ColorGroup::highlight + + A color to indicate a selected item or the current item. +*/ + +/*! + \qmlproperty color QtQuick::ColorGroup::highlightedText + + A text color that contrasts with \c highlight. +*/ + +/*! + \qmlproperty color QtQuick::ColorGroup::light + + Lighter than \c button. +*/ + +/*! + \qmlproperty color QtQuick::ColorGroup::link + + A text color used for hyperlinks. +*/ + +/*! + \qmlproperty color QtQuick::ColorGroup::linkVisited + + A text color used for already visited hyperlinks. +*/ + +/*! + \qmlproperty color QtQuick::ColorGroup::mid + + Between \c palette.button and \c dark. +*/ + +/*! + \qmlproperty color QtQuick::ColorGroup::midlight + + Between \c button and \c light. +*/ + +/*! + \qmlproperty color QtQuick::ColorGroup::shadow + + A very dark color. +*/ + +/*! + \qmlproperty color QtQuick::ColorGroup::text + + The foreground color used with \c base. This is usually the same as + the \c windowText, in which case it must provide good contrast with + \c window and \c base. +*/ + +/*! + \qmlproperty color QtQuick::ColorGroup::toolTipBase + + Used as the background color for tooltips. +*/ + +/*! + \qmlproperty color QtQuick::ColorGroup::toolTipText + + Used as the foreground color for tooltips. +*/ + +/*! + \qmlproperty color QtQuick::ColorGroup::window + + A general background color. +*/ + +/*! + \qmlproperty color QtQuick::ColorGroup::windowText + + A general foreground color. +*/ + +/*! + \qmlsignal QtQuick::ColorGroup::changed + + Additional signal indicates that the current state of this color group + has been changed. Usually it means that one of the colors is changed. + + \sa QtQuick::Palette::changed +*/ + +/*! + Construct object in default state. + */ +QQuickColorGroup::QQuickColorGroup(QQuickPalette &parent) + : QObject(&parent) + , m_groupTag(defaultGroupTag()) + , m_colorProvider(parent.colorProvider().shared_from_this()) +{ +} + +QPalette::ColorGroup QQuickColorGroup::currentColorGroup() const +{ + return groupTag(); +} + +QColor QQuickColorGroup::alternateBase() const +{ + return color(QPalette::AlternateBase); +} + +void QQuickColorGroup::setAlternateBase(const QColor &color) +{ + setColor(QPalette::AlternateBase, color, &QQuickColorGroup::alternateBaseChanged); +} + +void QQuickColorGroup::resetAlternateBase() +{ + resetColor(QPalette::AlternateBase, &QQuickColorGroup::alternateBaseChanged); +} + +QColor QQuickColorGroup::base() const +{ + return color(QPalette::Base); +} + +void QQuickColorGroup::setBase(const QColor &color) +{ + setColor(QPalette::Base, color, &QQuickColorGroup::baseChanged); +} + +void QQuickColorGroup::resetBase() +{ + resetColor(QPalette::Base, &QQuickColorGroup::baseChanged); +} + +QColor QQuickColorGroup::brightText() const +{ + return color(QPalette::BrightText); +} + +void QQuickColorGroup::setBrightText(const QColor &color) +{ + setColor(QPalette::BrightText, color, &QQuickColorGroup::brightTextChanged); +} + +void QQuickColorGroup::resetBrightText() +{ + resetColor(QPalette::BrightText, &QQuickColorGroup::brightTextChanged); +} + +QColor QQuickColorGroup::button() const +{ + return color(QPalette::Button); +} + +void QQuickColorGroup::setButton(const QColor &color) +{ + setColor(QPalette::Button, color, &QQuickColorGroup::buttonChanged); +} + +void QQuickColorGroup::resetButton() +{ + resetColor(QPalette::Button, &QQuickColorGroup::buttonChanged); +} + +QColor QQuickColorGroup::buttonText() const +{ + return color(QPalette::ButtonText); +} + +void QQuickColorGroup::setButtonText(const QColor &color) +{ + setColor(QPalette::ButtonText, color, &QQuickColorGroup::buttonTextChanged); +} + +void QQuickColorGroup::resetButtonText() +{ + resetColor(QPalette::ButtonText, &QQuickColorGroup::buttonTextChanged); +} + +QColor QQuickColorGroup::dark() const +{ + return color(QPalette::Dark); +} + +void QQuickColorGroup::setDark(const QColor &color) +{ + setColor(QPalette::Dark, color, &QQuickColorGroup::darkChanged); +} + +void QQuickColorGroup::resetDark() +{ + resetColor(QPalette::Dark, &QQuickColorGroup::darkChanged); +} + +QColor QQuickColorGroup::highlight() const +{ + return color(QPalette::Highlight); +} + +void QQuickColorGroup::setHighlight(const QColor &color) +{ + setColor(QPalette::Highlight, color, &QQuickColorGroup::highlightChanged); +} + +void QQuickColorGroup::resetHighlight() +{ + resetColor(QPalette::Highlight, &QQuickColorGroup::highlightChanged); +} + +QColor QQuickColorGroup::highlightedText() const +{ + return color(QPalette::HighlightedText); +} + +void QQuickColorGroup::setHighlightedText(const QColor &color) +{ + setColor(QPalette::HighlightedText, color, &QQuickColorGroup::highlightedTextChanged); +} + +void QQuickColorGroup::resetHighlightedText() +{ + resetColor(QPalette::HighlightedText, &QQuickColorGroup::highlightedTextChanged); +} + +QColor QQuickColorGroup::light() const +{ + return color(QPalette::Light); +} + +void QQuickColorGroup::setLight(const QColor &color) +{ + setColor(QPalette::Light, color, &QQuickColorGroup::lightChanged); +} + +void QQuickColorGroup::resetLight() +{ + resetColor(QPalette::Light, &QQuickColorGroup::lightChanged); +} + +QColor QQuickColorGroup::link() const +{ + return color(QPalette::Link); +} + +void QQuickColorGroup::setLink(const QColor &color) +{ + setColor(QPalette::Link, color, &QQuickColorGroup::linkChanged); +} + +void QQuickColorGroup::resetLink() +{ + resetColor(QPalette::Link, &QQuickColorGroup::linkChanged); +} + +QColor QQuickColorGroup::linkVisited() const +{ + return color(QPalette::LinkVisited); +} + +void QQuickColorGroup::setLinkVisited(const QColor &color) +{ + setColor(QPalette::LinkVisited, color, &QQuickColorGroup::linkVisitedChanged); +} + +void QQuickColorGroup::resetLinkVisited() +{ + resetColor(QPalette::LinkVisited, &QQuickColorGroup::linkVisitedChanged); +} + +QColor QQuickColorGroup::mid() const +{ + return color(QPalette::Mid); +} + +void QQuickColorGroup::setMid(const QColor &color) +{ + setColor(QPalette::Mid, color, &QQuickColorGroup::midChanged); +} + +void QQuickColorGroup::resetMid() +{ + resetColor(QPalette::Mid, &QQuickColorGroup::midChanged); +} + +QColor QQuickColorGroup::midlight() const +{ + return color(QPalette::Midlight); +} + +void QQuickColorGroup::setMidlight(const QColor &color) +{ + setColor(QPalette::Midlight, color, &QQuickColorGroup::midlightChanged); +} + +void QQuickColorGroup::resetMidlight() +{ + resetColor(QPalette::Midlight, &QQuickColorGroup::midlightChanged); +} + +QColor QQuickColorGroup::shadow() const +{ + return color(QPalette::Shadow); +} + +void QQuickColorGroup::setShadow(const QColor &color) +{ + setColor(QPalette::Shadow, color, &QQuickColorGroup::shadowChanged); +} + +void QQuickColorGroup::resetShadow() +{ + resetColor(QPalette::Shadow, &QQuickColorGroup::shadowChanged); +} + +QColor QQuickColorGroup::text() const +{ + return color(QPalette::Text); +} + +void QQuickColorGroup::setText(const QColor &color) +{ + setColor(QPalette::Text, color, &QQuickColorGroup::textChanged); +} + +void QQuickColorGroup::resetText() +{ + resetColor(QPalette::Text, &QQuickColorGroup::textChanged); +} + +QColor QQuickColorGroup::toolTipBase() const +{ + return color(QPalette::ToolTipBase); +} + +void QQuickColorGroup::setToolTipBase(const QColor &color) +{ + setColor(QPalette::ToolTipBase, color, &QQuickColorGroup::toolTipBaseChanged); +} + +void QQuickColorGroup::resetToolTipBase() +{ + resetColor(QPalette::ToolTipBase, &QQuickColorGroup::toolTipBaseChanged); +} + +QColor QQuickColorGroup::toolTipText() const +{ + return color(QPalette::ToolTipText); +} + +void QQuickColorGroup::setToolTipText(const QColor &color) +{ + setColor(QPalette::ToolTipText, color, &QQuickColorGroup::toolTipTextChanged); +} + +void QQuickColorGroup::resetToolTipText() +{ + resetColor(QPalette::ToolTipText, &QQuickColorGroup::toolTipTextChanged); +} + +QColor QQuickColorGroup::window() const +{ + return color(QPalette::Window); +} + +void QQuickColorGroup::setWindow(const QColor &color) +{ + setColor(QPalette::Window, color, &QQuickColorGroup::windowChanged); +} + +void QQuickColorGroup::resetWindow() +{ + resetColor(QPalette::Window, &QQuickColorGroup::windowChanged); +} + +QColor QQuickColorGroup::windowText() const +{ + return color(QPalette::WindowText); +} + +void QQuickColorGroup::setWindowText(const QColor &color) +{ + setColor(QPalette::WindowText, color, &QQuickColorGroup::windowTextChanged); +} + +void QQuickColorGroup::resetWindowText() +{ + resetColor(QPalette::WindowText, &QQuickColorGroup::windowTextChanged); +} + +QPalette::ColorGroup QQuickColorGroup::groupTag() const +{ + return m_groupTag; +} + +QQuickColorGroup::QQuickColorGroup(QObject *parent) + : QObject(parent) + , m_groupTag(defaultGroupTag()) + , m_colorProvider(std::make_shared<QQuickPaletteColorProvider>()) +{ +} + +void QQuickColorGroup::setGroupTag(QPalette::ColorGroup tag) +{ + if (m_groupTag != tag) { + m_groupTag = tag; + Q_EMIT changed(); + } +} + +const QQuickPaletteColorProvider &QQuickColorGroup::colorProvider() const +{ + Q_ASSERT(m_colorProvider); + return *m_colorProvider; +} + +QQuickPaletteColorProvider &QQuickColorGroup::colorProvider() +{ + return const_cast<QQuickPaletteColorProvider &>( + const_cast<const QQuickColorGroup*>(this)->colorProvider()); +} + +QQuickColorGroup *QQuickColorGroup::createWithParent(QQuickPalette &parent) +{ + return new QQuickColorGroup(parent); +} + +QColor QQuickColorGroup::color(QPalette::ColorRole role) const +{ + return colorProvider().color(currentColorGroup(), role); +} + +void QQuickColorGroup::setColor(QPalette::ColorRole role, QColor color, Notifier notifier) +{ + if (colorProvider().setColor(groupTag(), role, color)) { + Q_EMIT (this->*notifier)(); + Q_EMIT changed(); + } +} + +void QQuickColorGroup::resetColor(QPalette::ColorRole role, Notifier notifier) +{ + if (colorProvider().resetColor(groupTag(), role)) { + Q_EMIT (this->*notifier)(); + Q_EMIT changed(); + } +} + +QT_END_NAMESPACE diff --git a/src/quick/items/qquickcolorgroup_p.h b/src/quick/items/qquickcolorgroup_p.h new file mode 100644 index 0000000000..9d60c9aef2 --- /dev/null +++ b/src/quick/items/qquickcolorgroup_p.h @@ -0,0 +1,231 @@ +/**************************************************************************** +** +** Copyright (C) 2020 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the QtQuick 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 QQUICKCOLORGROUP_H +#define QQUICKCOLORGROUP_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists for the convenience +// of QQuickColorGroup. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <QtGui/qpalette.h> + +#include <QtCore/private/qobject_p.h> + +#include <QtQuick/private/qtquickglobal_p.h> + +#include <QtQml/qqml.h> + +QT_BEGIN_NAMESPACE + +class QQuickPalette; +class QQuickPaletteColorProvider; + +class Q_QUICK_PRIVATE_EXPORT QQuickColorGroup : public QObject +{ + Q_OBJECT + + Q_PROPERTY(QColor alternateBase READ alternateBase WRITE setAlternateBase RESET resetAlternateBase NOTIFY alternateBaseChanged FINAL) + Q_PROPERTY(QColor base READ base WRITE setBase RESET resetBase NOTIFY baseChanged FINAL) + Q_PROPERTY(QColor brightText READ brightText WRITE setBrightText RESET resetBrightText NOTIFY brightTextChanged FINAL) + Q_PROPERTY(QColor button READ button WRITE setButton RESET resetButton NOTIFY buttonChanged FINAL) + Q_PROPERTY(QColor buttonText READ buttonText WRITE setButtonText RESET resetButtonText NOTIFY buttonTextChanged FINAL) + Q_PROPERTY(QColor dark READ dark WRITE setDark RESET resetDark NOTIFY darkChanged FINAL) + Q_PROPERTY(QColor highlight READ highlight WRITE setHighlight RESET resetHighlight NOTIFY highlightChanged FINAL) + Q_PROPERTY(QColor highlightedText READ highlightedText WRITE setHighlightedText RESET resetHighlightedText NOTIFY highlightedTextChanged FINAL) + Q_PROPERTY(QColor light READ light WRITE setLight RESET resetLight NOTIFY lightChanged FINAL) + Q_PROPERTY(QColor link READ link WRITE setLink RESET resetLink NOTIFY linkChanged FINAL) + Q_PROPERTY(QColor linkVisited READ linkVisited WRITE setLinkVisited RESET resetLinkVisited NOTIFY linkVisitedChanged FINAL) + Q_PROPERTY(QColor mid READ mid WRITE setMid RESET resetMid NOTIFY midChanged FINAL) + Q_PROPERTY(QColor midlight READ midlight WRITE setMidlight RESET resetMidlight NOTIFY midlightChanged FINAL) + Q_PROPERTY(QColor shadow READ shadow WRITE setShadow RESET resetShadow NOTIFY shadowChanged FINAL) + Q_PROPERTY(QColor text READ text WRITE setText RESET resetText NOTIFY textChanged FINAL) + Q_PROPERTY(QColor toolTipBase READ toolTipBase WRITE setToolTipBase RESET resetToolTipBase NOTIFY toolTipBaseChanged FINAL) + Q_PROPERTY(QColor toolTipText READ toolTipText WRITE setToolTipText RESET resetToolTipText NOTIFY toolTipTextChanged FINAL) + Q_PROPERTY(QColor window READ window WRITE setWindow RESET resetWindow NOTIFY windowChanged FINAL) + Q_PROPERTY(QColor windowText READ windowText WRITE setWindowText RESET resetWindowText NOTIFY windowTextChanged FINAL) + + QML_NAMED_ELEMENT(ColorGroup) + QML_ADDED_IN_VERSION(6, 0) + +public: // Types + using GroupPtr = QPointer<QQuickColorGroup>; + +public: + Q_DISABLE_COPY_MOVE(QQuickColorGroup) + + explicit QQuickColorGroup(QObject *parent = nullptr); + + QColor alternateBase() const; + void setAlternateBase(const QColor &color); + void resetAlternateBase(); + + QColor base() const; + void setBase(const QColor &color); + void resetBase(); + + QColor brightText() const; + void setBrightText(const QColor &color); + void resetBrightText(); + + QColor button() const; + void setButton(const QColor &color); + void resetButton(); + + QColor buttonText() const; + void setButtonText(const QColor &color); + void resetButtonText(); + + QColor dark() const; + void setDark(const QColor &color); + void resetDark(); + + QColor highlight() const; + void setHighlight(const QColor &color); + void resetHighlight(); + + QColor highlightedText() const; + void setHighlightedText(const QColor &color); + void resetHighlightedText(); + + QColor light() const; + void setLight(const QColor &color); + void resetLight(); + + QColor link() const; + void setLink(const QColor &color); + void resetLink(); + + QColor linkVisited() const; + void setLinkVisited(const QColor &color); + void resetLinkVisited(); + + QColor mid() const; + void setMid(const QColor &color); + void resetMid(); + + QColor midlight() const; + void setMidlight(const QColor &color); + void resetMidlight(); + + QColor shadow() const; + void setShadow(const QColor &color); + void resetShadow(); + + QColor text() const; + void setText(const QColor &color); + void resetText(); + + QColor toolTipBase() const; + void setToolTipBase(const QColor &color); + void resetToolTipBase(); + + QColor toolTipText() const; + void setToolTipText(const QColor &color); + void resetToolTipText(); + + QColor window() const; + void setWindow(const QColor &color); + void resetWindow(); + + QColor windowText() const; + void setWindowText(const QColor &color); + void resetWindowText(); + + QPalette::ColorGroup groupTag() const; + void setGroupTag(QPalette::ColorGroup tag); + + const QQuickPaletteColorProvider &colorProvider() const; + QQuickPaletteColorProvider &colorProvider(); + + static QQuickColorGroup* createWithParent(QQuickPalette &parent); + +Q_SIGNALS: + void alternateBaseChanged(); + void baseChanged(); + void brightTextChanged(); + void buttonChanged(); + void buttonTextChanged(); + void darkChanged(); + void highlightChanged(); + void highlightedTextChanged(); + void lightChanged(); + void linkChanged(); + void linkVisitedChanged(); + void midChanged(); + void midlightChanged(); + void shadowChanged(); + void textChanged(); + void toolTipBaseChanged(); + void toolTipTextChanged(); + void windowChanged(); + void windowTextChanged(); + + void changed(); + +protected: + explicit QQuickColorGroup(QQuickPalette &parent); + + static constexpr QPalette::ColorGroup defaultGroupTag() { return QPalette::All; } + + virtual QPalette::ColorGroup currentColorGroup() const; + +private: + using Notifier = void (QQuickColorGroup::* )(); + + QColor color(QPalette::ColorRole role) const; + void setColor(QPalette::ColorRole role, QColor color, Notifier notifier); + void resetColor(QPalette::ColorRole role, Notifier notifier); + +private: + QPalette::ColorGroup m_groupTag; + std::shared_ptr<QQuickPaletteColorProvider> m_colorProvider; +}; + +QT_END_NAMESPACE + +QML_DECLARE_TYPE(QQuickColorGroup) + +#endif // QQUICKCOLORGROUP_H diff --git a/src/quick/items/qquickitem.cpp b/src/quick/items/qquickitem.cpp index 4b635ac7b8..93f1765811 100644 --- a/src/quick/items/qquickitem.cpp +++ b/src/quick/items/qquickitem.cpp @@ -8258,6 +8258,48 @@ QSGTextureProvider *QQuickItem::textureProvider() const } /*! + \since 6.0 + \qmlproperty Palette QtQuick::Item::palette + + This property holds the palette currently set for the item. + + This property describes the item's requested palette. The palette is used by the item's style + when rendering all controls, and is available as a means to ensure that custom controls can + maintain consistency with the native platform's native look and feel. It's common that + different platforms, or different styles, define different palettes for an application. + + The default palette depends on the system environment. ApplicationWindow maintains a + system/theme palette which serves as a default for all controls. There may also be special + palette defaults for certain types of controls. You can also set the default palette for + controls by either: + + \list + \li passing a custom palette to QGuiApplication::setPalette(), before loading any QML; or + \li specifying the colors in the \l {Qt Quick Controls 2 Configuration File} + {qtquickcontrols2.conf file}. + \endlist + + Items propagate explicit palette properties from parents to children. If you change a specific + property on a items's palette, that property propagates to all of the item's children, + overriding any system defaults for that property. + + \code + Item { + palette { + buttonText: "maroon" + button: "lavender" + } + + Button { + text: "Click Me" + } + } + \endcode + + \sa Window::palette, Popup::palette, QQuickAbstractPaletteProvider, ColorGroup, Palette +*/ + +/*! \property QQuickItem::layer \internal */ diff --git a/src/quick/items/qquickitem.h b/src/quick/items/qquickitem.h index ca0c2f4764..801dfe5edd 100644 --- a/src/quick/items/qquickitem.h +++ b/src/quick/items/qquickitem.h @@ -50,7 +50,6 @@ #include <QtGui/qfont.h> #include <QtGui/qaccessible.h> - QT_BEGIN_NAMESPACE class QQuickItem; @@ -94,6 +93,7 @@ class QSGNode; class QSGTransformNode; class QSGTextureProvider; class QQuickItemGrabResult; +class QQuickPalette; class Q_QUICK_EXPORT QQuickItem : public QObject, public QQmlParserStatus { @@ -114,6 +114,7 @@ class Q_QUICK_EXPORT QQuickItem : public QObject, public QQmlParserStatus Q_PROPERTY(qreal opacity READ opacity WRITE setOpacity NOTIFY opacityChanged FINAL) Q_PROPERTY(bool enabled READ isEnabled WRITE setEnabled NOTIFY enabledChanged) Q_PROPERTY(bool visible READ isVisible WRITE setVisible NOTIFY visibleChanged FINAL) + Q_PRIVATE_PROPERTY(QQuickItem::d_func(), QQuickPalette *palette READ palette WRITE setPalette RESET resetPalette NOTIFY paletteChanged REVISION(6, 0)) Q_PRIVATE_PROPERTY(QQuickItem::d_func(), QQmlListProperty<QQuickItem> visibleChildren READ visibleChildren NOTIFY visibleChildrenChanged DESIGNABLE false) Q_PRIVATE_PROPERTY(QQuickItem::d_func(), QQmlListProperty<QQuickState> states READ states DESIGNABLE false) @@ -400,6 +401,9 @@ Q_SIGNALS: void implicitHeightChanged(); Q_REVISION(2, 11) void containmentMaskChanged(); + Q_REVISION(6, 0) void paletteChanged(); + Q_REVISION(6, 0) void paletteCreated(); + protected: bool event(QEvent *) override; diff --git a/src/quick/items/qquickitem_p.h b/src/quick/items/qquickitem_p.h index a8958dfd59..6f39f3bdd2 100644 --- a/src/quick/items/qquickitem_p.h +++ b/src/quick/items/qquickitem_p.h @@ -75,7 +75,7 @@ #include <QtCore/qlist.h> #include <QtCore/qdebug.h> #include <QtCore/qelapsedtimer.h> -#include <QtCore/qpointer.h> +#include <QtQuick/private/qquickpaletteproviderprivatebase_p.h> #if QT_CONFIG(quick_shadereffect) #include <QtQuick/private/qquickshadereffectsource_p.h> @@ -249,7 +249,9 @@ private: #endif -class Q_QUICK_PRIVATE_EXPORT QQuickItemPrivate : public QObjectPrivate +class Q_QUICK_PRIVATE_EXPORT QQuickItemPrivate + : public QObjectPrivate + , public QQuickPaletteProviderPrivateBase<QQuickItem, QQuickItemPrivate> { Q_DECLARE_PUBLIC(QQuickItem) diff --git a/src/quick/items/qquickopenglinfo.cpp b/src/quick/items/qquickopenglinfo.cpp index 3e634725f4..294572e693 100644 --- a/src/quick/items/qquickopenglinfo.cpp +++ b/src/quick/items/qquickopenglinfo.cpp @@ -41,7 +41,9 @@ #include "qquickopenglinfo_p.h" #include "qopenglcontext.h" #include "qquickwindow.h" +#include "qquickwindow_p.h" #include "qquickitem.h" +#include "qquickitem_p.h" QT_BEGIN_NAMESPACE diff --git a/src/quick/items/qquickpalette.cpp b/src/quick/items/qquickpalette.cpp new file mode 100644 index 0000000000..f5c0aa8b04 --- /dev/null +++ b/src/quick/items/qquickpalette.cpp @@ -0,0 +1,328 @@ +/**************************************************************************** +** +** Copyright (C) 2020 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the QtQuick 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 "qquickpalette_p.h" + +#include <QtQuick/private/qquickpalettecolorprovider_p.h> + +QT_BEGIN_NAMESPACE + +/*! + \internal + + \class QQuickPalette + \brief The QQuickPalette class contains color groups for each QML item state. + \inmodule QtQuick + \since 6.0 + + This class is the wrapper around QPalette. + + \sa QQuickColorGroup, QQuickAbstractPaletteProvider, QPalette + */ + +/*! + \qmltype Palette + \instantiates QQuickPalette + \inherits QQuickColorGroup + \inqmlmodule QtQuick + \ingroup qtquick-visual + \brief The QQuickPalette class contains color groups for each QML item state. + + A palette consists of three color groups: Active, Disabled, and Inactive. + Active color group is the default group, its colors are used for other groups + if colors of these groups aren't explicitly specified. + + In the following example, color is applied for all color groups: + \code + ApplicationWindow { + palette.buttonText: "salmon" + + ColumnLayout { + Button { + text: qsTr("Disabled button") + enabled: false + } + + Button { + text: qsTr("Enabled button") + } + } + } + \endcode + It means that text color will be the same for both buttons. + + In the following example, colors will be different for enabled and disabled states: + \code + ApplicationWindow { + palette.buttonText: "salmon" + palette.disabled.buttonText: "lavender" + + ColumnLayout { + Button { + text: qsTr("Disabled button") + enabled: false + } + + Button { + text: qsTr("Enabled button") + } + } + } + \endcode + + It is also possible to specify colors like this: + \code + palette { + buttonText: "azure" + button: "khaki" + + disabled { + buttonText: "lavender" + button: "coral" + } + } + \endcode + This approach is convenient when you need to specify a whole palette with all color groups. +*/ + +/*! + \qmlproperty QQuickColorGroup QtQuick::QQuickPalette::inactive + + The Inactive group is used for windows that have no keyboard focus. + + \sa QPalette::Inactive +*/ + +/*! + \qmlproperty QQuickColorGroup QtQuick::QQuickPalette::disabled + + The Disabled group is used for elements that are disabled for some reason. + + \sa QPalette::Disabled +*/ + +QQuickPalette::QQuickPalette(QObject *parent) + : QQuickColorGroup(parent) + , m_currentGroup(defaultCurrentGroup()) +{ +} + +QQuickColorGroup *QQuickPalette::active() const +{ + return colorGroup(QPalette::Active); +} + +QQuickColorGroup *QQuickPalette::inactive() const +{ + return colorGroup(QPalette::Inactive); +} + +QQuickColorGroup *QQuickPalette::disabled() const +{ + return colorGroup(QPalette::Disabled); +} + +/*! + \internal + + Returns the palette's current color group. + The default value is Active. + */ +QPalette::ColorGroup QQuickPalette::currentColorGroup() const +{ + return m_currentGroup; +} + +/*! + \internal + + Sets \a currentGroup for this palette. + + The current color group is used when accessing colors of this palette. + For example, if color group is Disabled, color accessors will be + returning colors form the respective group. + \code + QQuickPalette palette; + + palette.setAlternateBase(Qt::green); + palette.disabled()->setAlternateBase(Qt::red); + + auto color = palette.alternateBase(); // Qt::green + + palette.setCurrentGroup(QPalette::Disabled); + color = palette.alternateBase(); // Qt::red + \endcode + + Emits QColorGroup::changed(). + */ +void QQuickPalette::setCurrentGroup(QPalette::ColorGroup currentGroup) +{ + if (m_currentGroup != currentGroup) { + m_currentGroup = currentGroup; + Q_EMIT changed(); + } +} + +void QQuickPalette::fromQPalette(QPalette palette) +{ + if (colorProvider().fromQPalette(std::move(palette))) { + Q_EMIT changed(); + } +} + +QPalette QQuickPalette::toQPalette() const +{ + return colorProvider().palette(); +} + +const QQuickAbstractPaletteProvider *QQuickPalette::paletteProvider() const +{ + return colorProvider().paletteProvider(); +} + +void QQuickPalette::setPaletteProvider(const QQuickAbstractPaletteProvider *paletteProvider) +{ + colorProvider().setPaletteProvider(paletteProvider); +} + +void QQuickPalette::reset() +{ + if (colorProvider().reset()) { + Q_EMIT changed(); + } +} + +void QQuickPalette::inheritPalette(const QPalette &palette) +{ + if (colorProvider().inheritPalette(palette)) { + Q_EMIT changed(); + } +} + +void QQuickPalette::setActive(QQuickColorGroup *active) +{ + setColorGroup(QPalette::Active, active, &QQuickPalette::activeChanged); +} + +void QQuickPalette::setInactive(QQuickColorGroup *inactive) +{ + setColorGroup(QPalette::Inactive, inactive, &QQuickPalette::inactiveChanged); +} + +void QQuickPalette::setDisabled(QQuickColorGroup *disabled) +{ + setColorGroup(QPalette::Disabled, disabled, &QQuickPalette::disabledChanged); +} + + +void QQuickPalette::setColorGroup(QPalette::ColorGroup groupTag, + const QQuickColorGroup::GroupPtr &group, + void (QQuickPalette::*notifier)()) +{ + if (isValidColorGroup(groupTag, group)) { + if (colorProvider().copyColorGroup(groupTag, group->colorProvider())) { + Q_EMIT (this->*notifier)(); + Q_EMIT changed(); + } + } +} + +QQuickColorGroup::GroupPtr QQuickPalette::colorGroup(QPalette::ColorGroup groupTag) const +{ + if (auto group = findColorGroup(groupTag)) { + return group; + } + + auto group = QQuickColorGroup::createWithParent(*const_cast<QQuickPalette*>(this)); + const_cast<QQuickPalette*>(this)->registerColorGroup(group, groupTag); + return group; +} + +QQuickColorGroup::GroupPtr QQuickPalette::findColorGroup(QPalette::ColorGroup groupTag) const +{ + if (auto it = m_colorGroups.find(groupTag); it != m_colorGroups.end()) { + return it->second; + } + + return nullptr; +} + +void QQuickPalette::registerColorGroup(QQuickColorGroup *group, QPalette::ColorGroup groupTag) +{ + if (auto it = m_colorGroups.find(groupTag); it != m_colorGroups.end() && it->second) { + it->second->deleteLater(); + } + + m_colorGroups[groupTag] = group; + + group->setGroupTag(groupTag); + + QQuickColorGroup::connect(group, &QQuickColorGroup::changed, this, &QQuickPalette::changed); +} + +bool QQuickPalette::isValidColorGroup(QPalette::ColorGroup groupTag, + const QQuickColorGroup::GroupPtr &colorGroup) const +{ + if (!colorGroup) { + qWarning("Color group cannot be null."); + return false; + } + + if (!colorGroup->parent()) { + qWarning("Color group should have a parent."); + return false; + } + + if (colorGroup->parent() && !qobject_cast<QQuickPalette*>(colorGroup->parent())) { + qWarning("Color group should be a part of QQuickPalette."); + return false; + } + + if (groupTag == defaultGroupTag()) { + qWarning("Register %i color group is not allowed." + " QQuickPalette is %i color group itself.", groupTag, groupTag); + return false; + } + + if (findColorGroup(groupTag) == colorGroup) { + qWarning("The color group is already a part of the current palette."); + return false; + } + + return true; +} + +QT_END_NAMESPACE diff --git a/src/quick/items/qquickpalette_p.h b/src/quick/items/qquickpalette_p.h new file mode 100644 index 0000000000..11688048ed --- /dev/null +++ b/src/quick/items/qquickpalette_p.h @@ -0,0 +1,127 @@ +/**************************************************************************** +** +** Copyright (C) 2020 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the QtQuick 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 QQUICKPALETTE_H +#define QQUICKPALETTE_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists for the convenience +// of QQuickPalette. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <vector> // Workaround: I think we should include vector to qflatmap_p.h +#include <QtCore/private/qflatmap_p.h> + +#include <QtQuick/private/qquickcolorgroup_p.h> + +QT_BEGIN_NAMESPACE + +class QQuickAbstractPaletteProvider; + +class Q_QUICK_PRIVATE_EXPORT QQuickPalette : public QQuickColorGroup +{ + Q_OBJECT + + Q_PROPERTY(QQuickColorGroup *active READ active WRITE setActive NOTIFY activeChanged) + Q_PROPERTY(QQuickColorGroup *inactive READ inactive WRITE setInactive NOTIFY inactiveChanged) + Q_PROPERTY(QQuickColorGroup *disabled READ disabled WRITE setDisabled NOTIFY disabledChanged) + + QML_NAMED_ELEMENT(Palette) + QML_ADDED_IN_VERSION(6, 0) + +public: // Types + using PalettePtr = QPointer<QQuickPalette>; + +public: + Q_DISABLE_COPY_MOVE(QQuickPalette) + explicit QQuickPalette(QObject *parent = nullptr); + + QQuickColorGroup *active() const; + QQuickColorGroup *inactive() const; + QQuickColorGroup *disabled() const; + + QPalette::ColorGroup currentColorGroup() const; + void setCurrentGroup(QPalette::ColorGroup currentGroup); + + void fromQPalette(QPalette palette); + QPalette toQPalette() const; + + const QQuickAbstractPaletteProvider *paletteProvider() const; + void setPaletteProvider(const QQuickAbstractPaletteProvider *paletteProvider); + + void reset(); + + void inheritPalette(const QPalette &palette); + +public Q_SLOTS: + void setActive(QQuickColorGroup *active); + void setInactive(QQuickColorGroup *inactive); + void setDisabled(QQuickColorGroup *disabled); + +Q_SIGNALS: + void activeChanged(); + void inactiveChanged(); + void disabledChanged(); + +private: + void setColorGroup(QPalette::ColorGroup groupTag, + const QQuickColorGroup::GroupPtr &group, + void (QQuickPalette::*notifier)()); + QQuickColorGroup::GroupPtr colorGroup(QPalette::ColorGroup groupTag) const; + QQuickColorGroup::GroupPtr findColorGroup(QPalette::ColorGroup groupTag) const; + + void registerColorGroup(QQuickColorGroup *group, QPalette::ColorGroup groupTag); + + bool isValidColorGroup(QPalette::ColorGroup groupTag, + const QQuickColorGroup::GroupPtr &colorGroup) const; + + static constexpr QPalette::ColorGroup defaultCurrentGroup() { return QPalette::Active; } + +private: + QFlatMap<QPalette::ColorGroup, QQuickColorGroup::GroupPtr> m_colorGroups; + QPalette::ColorGroup m_currentGroup; +}; + +QT_END_NAMESPACE + +QML_DECLARE_TYPE(QQuickPalette) + +#endif // QQUICKPALETTE_H diff --git a/src/quick/items/qquickpalettecolorprovider.cpp b/src/quick/items/qquickpalettecolorprovider.cpp new file mode 100644 index 0000000000..6808e8843a --- /dev/null +++ b/src/quick/items/qquickpalettecolorprovider.cpp @@ -0,0 +1,149 @@ +/**************************************************************************** +** +** Copyright (C) 2020 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the QtQuick 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 "qquickpalettecolorprovider_p.h" + +#include <QtQuick/private/qquickabstractpaletteprovider_p.h> + +QT_BEGIN_NAMESPACE + +static bool notEq(const QPalette &p1, const QPalette &p2) +{ + return p1.resolve() != p2.resolve() || p1 != p2; +} + +static QPalette::ColorGroup adjustCg(QPalette::ColorGroup group) +{ + return group == QPalette::All ? QPalette::Active : group; +} + +class DefaultPalettesProvider : public QQuickAbstractPaletteProvider +{ +public: + QPalette defaultPalette() const override { static QPalette p; return p; } + QPalette parentPalette() const override { return defaultPalette(); } +}; + +static std::default_delete<const QQuickAbstractPaletteProvider> defaultDeleter() { return {}; } + +QQuickPaletteColorProvider::QQuickPaletteColorProvider() + : m_paletteProvider(ProviderPtr(new DefaultPalettesProvider, defaultDeleter())) +{ +} + +const QColor &QQuickPaletteColorProvider::color(QPalette::ColorGroup group, QPalette::ColorRole role) const +{ + return m_resolvedPalette.color(adjustCg(group), role); +} + +bool QQuickPaletteColorProvider::setColor(QPalette::ColorGroup g, QPalette::ColorRole r, QColor c) +{ + m_requestedPalette.value() = m_resolvedPalette; + m_requestedPalette->setColor(g, r, c); + + return inheritPalette(paletteProvider()->parentPalette()); +} + +bool QQuickPaletteColorProvider::resetColor(QPalette::ColorGroup group, QPalette::ColorRole role) +{ + const auto &defaultPalette = paletteProvider()->defaultPalette() ; + const auto &defaultColor = defaultPalette.color(adjustCg(group), role); + + return setColor(group, role, defaultColor); +} + +bool QQuickPaletteColorProvider::fromQPalette(QPalette p) +{ + m_requestedPalette.value() = std::move(p); + return inheritPalette(paletteProvider()->parentPalette()); +} + +QPalette QQuickPaletteColorProvider::palette() const +{ + return m_resolvedPalette; +} + +const QQuickAbstractPaletteProvider *QQuickPaletteColorProvider::paletteProvider() const +{ + Q_ASSERT(m_paletteProvider); + return m_paletteProvider.get(); +} + +void QQuickPaletteColorProvider::setPaletteProvider(const QQuickAbstractPaletteProvider *paletteProvider) +{ + static const auto emptyDeleter = [](auto &&){}; + m_paletteProvider = ProviderPtr(paletteProvider, emptyDeleter); +} + +bool QQuickPaletteColorProvider::copyColorGroup(QPalette::ColorGroup cg, + const QQuickPaletteColorProvider &p) +{ + m_requestedPalette.value() = m_resolvedPalette; + + auto srcPalette = p.palette(); + for (int roleIndex = QPalette::WindowText; roleIndex < QPalette::NColorRoles; ++roleIndex) { + const auto cr = QPalette::ColorRole(roleIndex); + if (srcPalette.isBrushSet(cg, cr)) { + m_requestedPalette->setBrush(cg, cr, srcPalette.brush(cg, cr)); + } + } + + return inheritPalette(paletteProvider()->parentPalette()); +} + +bool QQuickPaletteColorProvider::reset() +{ + return fromQPalette(QPalette()); +} + +bool QQuickPaletteColorProvider::inheritPalette(const QPalette &p) +{ + QPalette parentPalette = m_requestedPalette.isAllocated() ? m_requestedPalette->resolve(p) : p; + parentPalette.resolve(m_requestedPalette.isAllocated() ? m_requestedPalette->resolve() | p.resolve() : p.resolve()); + + auto tmpResolvedPalette = parentPalette.resolve(paletteProvider()->defaultPalette()); + + bool changed = notEq(tmpResolvedPalette, m_resolvedPalette); + if (changed) { + std::swap(tmpResolvedPalette, m_resolvedPalette); + } + + return changed; +} + +QT_END_NAMESPACE diff --git a/src/quick/items/qquickpalettecolorprovider_p.h b/src/quick/items/qquickpalettecolorprovider_p.h new file mode 100644 index 0000000000..952c74aa0d --- /dev/null +++ b/src/quick/items/qquickpalettecolorprovider_p.h @@ -0,0 +1,94 @@ +/**************************************************************************** +** +** Copyright (C) 2020 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the QtQuick 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 QQUICKPALETTECOLORPROVIDER_P_H +#define QQUICKPALETTECOLORPROVIDER_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 <QtGui/QPalette> + +#include <QtQuick/qtquickglobal.h> + +#include <QtQuick/private/qtquickglobal_p.h> +#include <private/qlazilyallocated_p.h> + +QT_BEGIN_NAMESPACE + +class QQuickAbstractPaletteProvider; + +class Q_QUICK_PRIVATE_EXPORT QQuickPaletteColorProvider + : public std::enable_shared_from_this<QQuickPaletteColorProvider> +{ +public: + QQuickPaletteColorProvider(); + + const QColor &color(QPalette::ColorGroup group, QPalette::ColorRole role) const; + bool setColor(QPalette::ColorGroup group, QPalette::ColorRole role, QColor color); + bool resetColor(QPalette::ColorGroup group, QPalette::ColorRole role); + + bool fromQPalette(QPalette p); + QPalette palette() const; + + const QQuickAbstractPaletteProvider *paletteProvider() const; + void setPaletteProvider(const QQuickAbstractPaletteProvider *paletteProvider); + + bool copyColorGroup(QPalette::ColorGroup cg, const QQuickPaletteColorProvider &p); + + bool reset(); + + bool inheritPalette(const QPalette &p); + +private: + QPalette m_resolvedPalette; + QLazilyAllocated<QPalette> m_requestedPalette; + + using Deleter = std::function<void(const QQuickAbstractPaletteProvider*)>; + using ProviderPtr = std::unique_ptr<const QQuickAbstractPaletteProvider, Deleter>; + ProviderPtr m_paletteProvider; +}; + +QT_END_NAMESPACE + +#endif // QQUICKPALETTECOLORPROVIDER_P_H diff --git a/src/quick/items/qquickpaletteproviderprivatebase_p.h b/src/quick/items/qquickpaletteproviderprivatebase_p.h new file mode 100644 index 0000000000..2461b2d1a9 --- /dev/null +++ b/src/quick/items/qquickpaletteproviderprivatebase_p.h @@ -0,0 +1,398 @@ +/**************************************************************************** +** +** Copyright (C) 2020 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the QtQuick 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 QQUICKPALETTEPROVIDERPRIVATEBASE_H +#define QQUICKPALETTEPROVIDERPRIVATEBASE_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/qquickpalette_p.h> +#include <QtQuick/private/qquickabstractpaletteprovider_p.h> + +#include <QtQml/private/qlazilyallocated_p.h> + +QT_BEGIN_NAMESPACE + +class QWindow; +class QQuickWindow; +class QQuickWindowPrivate; +class QQuickItem; +class QQuickItemPrivate; +class QQuickPopup; +class QQuickPopupPrivate; + +/*! + \internal + + Implements all required operations with palette. + + I -- is interface class (e.g. QQuickItem). + Impl -- is implementation class (e.g. QQuickItemPrivate). + + To use this class you need to inherit implementation class from it. + */ +template <class I, class Impl> +class QQuickPaletteProviderPrivateBase : public QQuickAbstractPaletteProvider +{ + static_assert(std::is_base_of<QObject, I>{}, "The interface class must inherit QObject"); + +public: + virtual ~QQuickPaletteProviderPrivateBase() = default; + + /*! + \internal + + Get current palette. + + \note Palette might be lazily allocated. Signal \p paletteCreated() + will be emitted by an object of interface class in this case. + + \note This function doesn't ask an object of interface class to emit + paletteChanged() signal in order to avoid problems with + property bindigns. + */ + virtual QQuickPalette *palette() const; + + /*! + \internal + + Set new palette. Doesn't transfer ownership. + */ + virtual void setPalette(QQuickPalette *p); + + /*! + \internal + + Reset palette to the default one. + */ + virtual void resetPalette(); + + /*! + \internal + + Check if everything is internally allocated and palette exists. + + Use before call \p palette() to avoid unnecessary allocations. + */ + virtual bool providesPalette() const; + + /*! + \internal + + A default palette for this component. + */ + virtual QPalette defaultPalette() const; + + /*! + \internal + + A parent palette for this component. Can be null. + */ + virtual QPalette parentPalette() const; + + /*! + \internal + + Inherit from \p parentPalette. This function is also called when + either parent or window of this item is changed. + */ + void inheritPalette(const QPalette &parentPalette); + + /*! + \internal + + Updates children palettes. The default implementation invokes + inheritPalette for all visual children. + + This function is also called when palette is changed + (signal changed() is emitted). + */ + virtual void updateChildrenPalettes(const QPalette &parentPalette); + +private: + using PalettePtr = std::unique_ptr<QQuickPalette>; + using Self = QQuickPaletteProviderPrivateBase<I, Impl>; + + void registerPalette(PalettePtr palette); + + bool isValidPalette(const QQuickPalette *palette) const; + + QQuickPalette *windowPalette() const; + + void setCurrentColorGroup(); + + void connectItem(); + + const I *itemWithPalette() const; + I *itemWithPalette(); + + QQuickPalette *paletteData() const; + + QPalette toQPalette() const; + +private: + PalettePtr m_palette; +}; + +template<class I, class Impl> +QQuickPalette *QQuickPaletteProviderPrivateBase<I, Impl>::palette() const +{ + if (!providesPalette()) { + // It's required to create a new palette without parent, + // because this method can be called from the rendering thread + const_cast<Self*>(this)->registerPalette(std::make_unique<QQuickPalette>()); + Q_EMIT const_cast<Self*>(this)->itemWithPalette()->paletteCreated(); + } + + return paletteData(); +} + +template<class I, class Impl> +bool QQuickPaletteProviderPrivateBase<I, Impl>::isValidPalette(const QQuickPalette *palette) const +{ + if (!palette) { + qWarning("Palette cannot be null."); + return false; + } + + if (providesPalette() && paletteData() == palette) { + qWarning("Self assignment makes no sense."); + return false; + } + + return true; +} + +template<class I, class Impl> +void QQuickPaletteProviderPrivateBase<I, Impl>::setPalette(QQuickPalette *p) +{ + if (isValidPalette(p)) { + palette()->fromQPalette(p->toQPalette()); + } +} + +template<class I, class Impl> +void QQuickPaletteProviderPrivateBase<I, Impl>::resetPalette() +{ + paletteData()->reset(); +} + +template<class I, class Impl> +bool QQuickPaletteProviderPrivateBase<I, Impl>::providesPalette() const +{ + return !!m_palette; +} + +template<class I, class Impl> +QPalette QQuickPaletteProviderPrivateBase<I, Impl>::defaultPalette() const +{ + return QPalette(); +} + +template <class Window> +inline constexpr bool isRootWindow() { return std::is_base_of_v<QWindow, Window>; } + +template<class I, class Impl> +void QQuickPaletteProviderPrivateBase<I, Impl>::registerPalette(PalettePtr palette) +{ + if constexpr (!isRootWindow<I>()) { + // Connect item only once, before initial data allocation + if (!providesPalette()) { + connectItem(); + } + } + + m_palette = std::move(palette); + m_palette->setPaletteProvider(this); + m_palette->inheritPalette(parentPalette()); + + setCurrentColorGroup(); + + // In order to avoid extra noise, we should connect + // the following signals only after everything is already setup + I::connect(paletteData(), &QQuickPalette::changed, itemWithPalette(), &I::paletteChanged); + I::connect(paletteData(), &QQuickPalette::changed, [this]{ updateChildrenPalettes(toQPalette()); }); +} + +template<class T> struct dependent_false : std::false_type {}; +template<class Impl, class I> decltype(auto) getPrivateImpl(I &t) { return Impl::get(&t); } + +template <class T> +decltype(auto) getPrivate(T &item) +{ + if constexpr (std::is_same_v<T, QQuickWindow>) { + return getPrivateImpl<QQuickWindowPrivate>(item); + } else if constexpr (std::is_same_v<T, QQuickItem>) { + return getPrivateImpl<QQuickItemPrivate>(item); + } else { + static_assert (dependent_false<T>::value, "Extend please."); + } +} + +template<class I, class Impl> +QQuickPalette *QQuickPaletteProviderPrivateBase<I, Impl>::windowPalette() const +{ + if constexpr (!isRootWindow<I>()) { + if (auto window = itemWithPalette()->window()) { + if (getPrivate(*window)->providesPalette()) { + return getPrivate(*window)->palette(); + } + } + } + + return nullptr; +} + +template<class I, class Impl> +QPalette QQuickPaletteProviderPrivateBase<I, Impl>::parentPalette() const +{ + if constexpr (!isRootWindow<I>()) { + for (auto parentItem = itemWithPalette()->parentItem(); parentItem; + parentItem = parentItem->parentItem()) { + + // Don't allocate a new palette here. Use only if it's already pre allocated + if (parentItem && getPrivate(*parentItem)->providesPalette()) { + return getPrivate(*parentItem)->palette()->toQPalette(); + } + } + + if (auto wp = windowPalette()) { + return wp->toQPalette(); + } + } + + return defaultPalette(); +} + +template<class I> +const QQuickItem* rootItem(const I &item) +{ + if constexpr (isRootWindow<I>()) { + return item.contentItem(); + } else if constexpr (std::is_same_v<QQuickPopup, I>) { + return nullptr; + } else { + return &item; + } +} + +template<class I, class Impl> +void QQuickPaletteProviderPrivateBase<I, Impl>::inheritPalette(const QPalette &parentPalette) +{ + if (providesPalette()) { + // If palette is changed, then this function will be invoked + // for all children because of connection with signal changed() + m_palette->inheritPalette(parentPalette); + } else { + // Otherwise, just propagate parent palette to all children + updateChildrenPalettes(parentPalette); + } +} + +template<class I, class Impl> +void QQuickPaletteProviderPrivateBase<I, Impl>::setCurrentColorGroup() +{ + if constexpr (!isRootWindow<I>()) { + if (paletteData()) { + const bool enabled = itemWithPalette()->isEnabled(); + paletteData()->setCurrentGroup(enabled ? QPalette::Active : QPalette::Disabled); + } + } +} + +template<class I, class Impl> +void QQuickPaletteProviderPrivateBase<I, Impl>::updateChildrenPalettes(const QPalette &parentPalette) +{ + if (auto root = rootItem(*itemWithPalette())) { + for (auto &&child : root->childItems()) { + if (Q_LIKELY(child)) { + getPrivate(*child)->inheritPalette(parentPalette); + } + } + } +} + +template<class I, class Impl> +void QQuickPaletteProviderPrivateBase<I, Impl>::connectItem() +{ + Q_ASSERT(itemWithPalette()); + + if constexpr (!isRootWindow<I>()) { + // Item with palette has the same lifetime as its implementation that inherits this class + I::connect(itemWithPalette(), &I::parentChanged , [this]() { inheritPalette(parentPalette()); }); + I::connect(itemWithPalette(), &I::windowChanged , [this]() { inheritPalette(parentPalette()); }); + I::connect(itemWithPalette(), &I::enabledChanged, [this]() { setCurrentColorGroup(); }); + } +} + +template<class I, class Impl> +const I *QQuickPaletteProviderPrivateBase<I, Impl>::itemWithPalette() const +{ + static_assert(std::is_base_of<QObjectData, Impl>{}, + "The Impl class must inherit QObjectData"); + + return static_cast<const I*>(static_cast<const Impl*>(this)->q_ptr); +} + +template<class I, class Impl> +I *QQuickPaletteProviderPrivateBase<I, Impl>::itemWithPalette() +{ + return const_cast<I*>(const_cast<const Self*>(this)->itemWithPalette()); +} + +template<class I, class Impl> +QQuickPalette *QQuickPaletteProviderPrivateBase<I, Impl>::paletteData() const +{ + Q_ASSERT(m_palette); return m_palette.get(); +} + +template<class I, class Impl> +QPalette QQuickPaletteProviderPrivateBase<I, Impl>::toQPalette() const +{ + return palette()->toQPalette(); +} + +QT_END_NAMESPACE + +#endif // QQUICKPALETTEPROVIDERPRIVATEBASE_H diff --git a/src/quick/items/qquickrendercontrol.cpp b/src/quick/items/qquickrendercontrol.cpp index 08d04d3b11..190e0942ab 100644 --- a/src/quick/items/qquickrendercontrol.cpp +++ b/src/quick/items/qquickrendercontrol.cpp @@ -58,6 +58,7 @@ #include <QtQuick/QQuickWindow> #include <QtQuick/private/qquickwindow_p.h> +#include <QtQuick/private/qquickitem_p.h> #include <QtQuick/private/qsgsoftwarerenderer_p.h> #include <QtCore/private/qobject_p.h> diff --git a/src/quick/items/qquicktextnodeengine.cpp b/src/quick/items/qquicktextnodeengine.cpp index 2356ab36ef..4b807c6e94 100644 --- a/src/quick/items/qquicktextnodeengine.cpp +++ b/src/quick/items/qquicktextnodeengine.cpp @@ -54,6 +54,7 @@ #include <private/qtextimagehandler_p.h> #include <private/qrawfont_p.h> #include <private/qglyphrun_p.h> +#include <private/qquickitem_p.h> QT_BEGIN_NAMESPACE diff --git a/src/quick/items/qquickwindow.cpp b/src/quick/items/qquickwindow.cpp index b245b62d96..81eabe0591 100644 --- a/src/quick/items/qquickwindow.cpp +++ b/src/quick/items/qquickwindow.cpp @@ -5693,6 +5693,24 @@ void QQuickWindow::setTextRenderType(QQuickWindow::TextRenderType renderType) QQuickWindowPrivate::textRenderType = renderType; } + +/*! + \since 6.0 + \qmlproperty QQuickPalette Window::palette + + This property holds the palette currently set for the window. + + The default palette depends on the system environment. QGuiApplication maintains a system/theme + palette which serves as a default for all application windows. You can also set the default palette + for windows by passing a custom palette to QGuiApplication::setPalette(), before loading any QML. + + ApplicationWindow propagates explicit palette properties to child controls. If you change a specific + property on the window's palette, that property propagates to all child controls in the window, + overriding any system defaults for that property. + + \sa Item::palette, Popup::palette, QQuickAbstractPaletteProvider, QQuickColorGroup, QQuickPalette +*/ + #ifndef QT_NO_DEBUG_STREAM QDebug operator<<(QDebug debug, const QQuickWindow *win) { diff --git a/src/quick/items/qquickwindow.h b/src/quick/items/qquickwindow.h index bba8c014c8..1331d036e1 100644 --- a/src/quick/items/qquickwindow.h +++ b/src/quick/items/qquickwindow.h @@ -224,6 +224,9 @@ Q_SIGNALS: Q_REVISION(2, 14) void beforeRenderPassRecording(); Q_REVISION(2, 14) void afterRenderPassRecording(); + Q_REVISION(6, 0) void paletteChanged(); + Q_REVISION(6, 0) void paletteCreated(); + public Q_SLOTS: void update(); void releaseResources(); diff --git a/src/quick/items/qquickwindow_p.h b/src/quick/items/qquickwindow_p.h index 8e4ecbc178..a77ce30a89 100644 --- a/src/quick/items/qquickwindow_p.h +++ b/src/quick/items/qquickwindow_p.h @@ -56,6 +56,7 @@ #include "qquickevents_p_p.h" #include <QtQuick/private/qsgcontext_p.h> +#include <QtQuick/private/qquickpaletteproviderprivatebase_p.h> #include <QtCore/qthread.h> #include <QtCore/qmutex.h> @@ -103,7 +104,9 @@ public: virtual bool swap() = 0; }; -class Q_QUICK_PRIVATE_EXPORT QQuickWindowPrivate : public QWindowPrivate +class Q_QUICK_PRIVATE_EXPORT QQuickWindowPrivate + : public QWindowPrivate + , public QQuickPaletteProviderPrivateBase<QQuickWindow, QQuickWindowPrivate> { public: Q_DECLARE_PUBLIC(QQuickWindow) diff --git a/src/quick/items/qquickwindowmodule.cpp b/src/quick/items/qquickwindowmodule.cpp index ee90af4341..593181ee61 100644 --- a/src/quick/items/qquickwindowmodule.cpp +++ b/src/quick/items/qquickwindowmodule.cpp @@ -41,6 +41,8 @@ #include "qquickwindowattached_p.h" #include "qquickscreen_p.h" #include "qquickview_p.h" +#include "qquickwindowmodule_p_p.h" +#include "qquickitem_p.h" #include <QtQuick/QQuickWindow> #include <QtCore/QCoreApplication> #include <QtQml/QQmlEngine> @@ -55,28 +57,11 @@ QT_BEGIN_NAMESPACE Q_DECLARE_LOGGING_CATEGORY(lcTransient) -class QQuickWindowQmlImplPrivate : public QQuickWindowPrivate -{ -public: - QQuickWindowQmlImplPrivate() - : complete(false) - , visible(false) - , visibility(QQuickWindow::AutomaticVisibility) - { - } - - bool complete; - bool visible; - QQuickWindow::Visibility visibility; - QV4::PersistentValue rootItemMarker; -}; +QQuickWindowQmlImplPrivate::QQuickWindowQmlImplPrivate() = default; QQuickWindowQmlImpl::QQuickWindowQmlImpl(QWindow *parent) - : QQuickWindow(*(new QQuickWindowQmlImplPrivate), parent) + : QQuickWindowQmlImpl(*(new QQuickWindowQmlImplPrivate), parent) { - connect(this, &QWindow::visibleChanged, this, &QQuickWindowQmlImpl::visibleChanged); - connect(this, &QWindow::visibilityChanged, this, &QQuickWindowQmlImpl::visibilityChanged); - connect(this, &QWindow::screenChanged, this, &QQuickWindowQmlImpl::screenChanged); } void QQuickWindowQmlImpl::setVisible(bool visible) @@ -139,6 +124,14 @@ void QQuickWindowQmlImpl::componentComplete() } } +QQuickWindowQmlImpl::QQuickWindowQmlImpl(QQuickWindowQmlImplPrivate &dd, QWindow *parent) + : QQuickWindow(dd, parent) +{ + connect(this, &QWindow::visibleChanged, this, &QQuickWindowQmlImpl::visibleChanged); + connect(this, &QWindow::visibilityChanged, this, &QQuickWindowQmlImpl::visibilityChanged); + connect(this, &QWindow::screenChanged, this, &QQuickWindowQmlImpl::screenChanged); +} + void QQuickWindowQmlImpl::setWindowVisibility() { Q_D(QQuickWindowQmlImpl); diff --git a/src/quick/items/qquickwindowmodule_p.h b/src/quick/items/qquickwindowmodule_p.h index 2f05b987d1..dc260dd47a 100644 --- a/src/quick/items/qquickwindowmodule_p.h +++ b/src/quick/items/qquickwindowmodule_p.h @@ -90,6 +90,8 @@ protected: void classBegin() override; void componentComplete() override; + QQuickWindowQmlImpl(QQuickWindowQmlImplPrivate &dd, QWindow *parent); + private Q_SLOTS: void setWindowVisibility(); diff --git a/src/quick/items/qquickwindowmodule_p_p.h b/src/quick/items/qquickwindowmodule_p_p.h new file mode 100644 index 0000000000..4e94a4e43d --- /dev/null +++ b/src/quick/items/qquickwindowmodule_p_p.h @@ -0,0 +1,71 @@ +/**************************************************************************** +** +** Copyright (C) 2020 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtQuick 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 QQUICKWINDOWMODULE_P_P_H +#define QQUICKWINDOWMODULE_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 "qquickwindow_p.h" +#include <QtQml/private/qv4persistent_p.h> + +QT_BEGIN_NAMESPACE + +class Q_QUICK_PRIVATE_EXPORT QQuickWindowQmlImplPrivate : public QQuickWindowPrivate +{ +public: + QQuickWindowQmlImplPrivate(); + + bool complete = false; + bool visible = false; + QQuickWindow::Visibility visibility = QQuickWindow::AutomaticVisibility; + QV4::PersistentValue rootItemMarker; +}; + +QT_END_NAMESPACE + +#endif // QQUICKWINDOWMODULE_P_P_H diff --git a/src/quick/scenegraph/adaptations/software/qsgsoftwarecontext.cpp b/src/quick/scenegraph/adaptations/software/qsgsoftwarecontext.cpp index f1d0e28fc8..91c26780b1 100644 --- a/src/quick/scenegraph/adaptations/software/qsgsoftwarecontext.cpp +++ b/src/quick/scenegraph/adaptations/software/qsgsoftwarecontext.cpp @@ -56,6 +56,7 @@ #include <QtGui/QWindow> #include <QtQuick/private/qquickwindow_p.h> +#include <QtQuick/private/qquickitem_p.h> // Used for very high-level info about the renderering and gl context // Includes GL_VERSION, type of render loop, atlas size, etc. diff --git a/src/quick/scenegraph/adaptations/software/qsgsoftwarerenderloop.cpp b/src/quick/scenegraph/adaptations/software/qsgsoftwarerenderloop.cpp index c010e0cae5..ad1f9cacf4 100644 --- a/src/quick/scenegraph/adaptations/software/qsgsoftwarerenderloop.cpp +++ b/src/quick/scenegraph/adaptations/software/qsgsoftwarerenderloop.cpp @@ -44,6 +44,7 @@ #include <QtCore/QCoreApplication> #include <private/qquickwindow_p.h> +#include <private/qquickitem_p.h> #include <QElapsedTimer> #include <private/qquickanimatorcontroller_p.h> #include <private/qquickprofiler_p.h> diff --git a/src/quick/scenegraph/adaptations/software/qsgsoftwarethreadedrenderloop.cpp b/src/quick/scenegraph/adaptations/software/qsgsoftwarethreadedrenderloop.cpp index 1de9415dd0..7075d3e1cb 100644 --- a/src/quick/scenegraph/adaptations/software/qsgsoftwarethreadedrenderloop.cpp +++ b/src/quick/scenegraph/adaptations/software/qsgsoftwarethreadedrenderloop.cpp @@ -43,6 +43,7 @@ #include <private/qsgrenderer_p.h> #include <private/qquickwindow_p.h> +#include <private/qquickitem_p.h> #include <private/qquickprofiler_p.h> #include <private/qquickanimatorcontroller_p.h> #include <private/qquickprofiler_p.h> diff --git a/src/quick/scenegraph/compressedtexture/qsgcompressedtexture.cpp b/src/quick/scenegraph/compressedtexture/qsgcompressedtexture.cpp index 65abb2a1af..b30960af1c 100644 --- a/src/quick/scenegraph/compressedtexture/qsgcompressedtexture.cpp +++ b/src/quick/scenegraph/compressedtexture/qsgcompressedtexture.cpp @@ -44,6 +44,7 @@ #include <QOpenGLFunctions> #include <QDebug> #include <QtQuick/private/qquickwindow_p.h> +#include <QtQuick/private/qquickitem_p.h> #include <QtGui/private/qrhi_p.h> QT_BEGIN_NAMESPACE diff --git a/src/quick/scenegraph/qsgdefaultcontext.cpp b/src/quick/scenegraph/qsgdefaultcontext.cpp index 14a0e8b7ab..1d70c826de 100644 --- a/src/quick/scenegraph/qsgdefaultcontext.cpp +++ b/src/quick/scenegraph/qsgdefaultcontext.cpp @@ -61,6 +61,7 @@ #include <QOpenGLFramebufferObject> #include <QtQuick/private/qquickwindow_p.h> +#include <QtQuick/private/qquickitem_p.h> #include <private/qqmlglobal_p.h> diff --git a/src/quick/scenegraph/qsgrenderloop.cpp b/src/quick/scenegraph/qsgrenderloop.cpp index c4f6d4457d..424d1b9ea8 100644 --- a/src/quick/scenegraph/qsgrenderloop.cpp +++ b/src/quick/scenegraph/qsgrenderloop.cpp @@ -57,6 +57,7 @@ #include <QtQuick/QQuickWindow> #include <QtQuick/private/qquickwindow_p.h> +#include <QtQuick/private/qquickitem_p.h> #include <QtQuick/private/qsgcontext_p.h> #include <QtQuick/private/qsgrenderer_p.h> #include <private/qquickprofiler_p.h> diff --git a/src/quick/scenegraph/qsgthreadedrenderloop.cpp b/src/quick/scenegraph/qsgthreadedrenderloop.cpp index 9b288029b4..5f6a7597ab 100644 --- a/src/quick/scenegraph/qsgthreadedrenderloop.cpp +++ b/src/quick/scenegraph/qsgthreadedrenderloop.cpp @@ -53,6 +53,7 @@ #include <QtQuick/QQuickWindow> #include <private/qquickwindow_p.h> +#include <private/qquickitem_p.h> #include <QtQuick/private/qsgrenderer_p.h> diff --git a/src/quick/scenegraph/qsgwindowsrenderloop.cpp b/src/quick/scenegraph/qsgwindowsrenderloop.cpp index 20d7c4557f..03c9183126 100644 --- a/src/quick/scenegraph/qsgwindowsrenderloop.cpp +++ b/src/quick/scenegraph/qsgwindowsrenderloop.cpp @@ -48,6 +48,7 @@ #include <QtQuick/private/qsgcontext_p.h> #include <QtQuick/private/qquickwindow_p.h> +#include <QtQuick/private/qquickitem_p.h> #include <QtQuick/private/qsgrenderer_p.h> #include <QtQuick/private/qsgdefaultrendercontext_p.h> diff --git a/src/quick/util/qquickanimatorcontroller.cpp b/src/quick/util/qquickanimatorcontroller.cpp index 5cf8051922..ad9d4b08cd 100644 --- a/src/quick/util/qquickanimatorcontroller.cpp +++ b/src/quick/util/qquickanimatorcontroller.cpp @@ -41,6 +41,7 @@ #include "qquickanimatorcontroller_p.h" #include <private/qquickwindow_p.h> +#include <private/qquickitem_p.h> #include <private/qsgrenderloop_p.h> #include <private/qanimationgroupjob_p.h> diff --git a/tests/auto/quick/CMakeLists.txt b/tests/auto/quick/CMakeLists.txt index 187600dbf9..6cb3c23334 100644 --- a/tests/auto/quick/CMakeLists.txt +++ b/tests/auto/quick/CMakeLists.txt @@ -65,4 +65,6 @@ if(QT_FEATURE_private_tests) # add_subdirectory(touchmouse) # skip building until fixed in dev # special case add_subdirectory(scenegraph) add_subdirectory(sharedimage) + add_subdirectory(qquickcolorgroup) + add_subdirectory(qquickpalette) endif() diff --git a/tests/auto/quick/qquickcolorgroup/CMakeLists.txt b/tests/auto/quick/qquickcolorgroup/CMakeLists.txt new file mode 100644 index 0000000000..99506fc24d --- /dev/null +++ b/tests/auto/quick/qquickcolorgroup/CMakeLists.txt @@ -0,0 +1,8 @@ +qt_add_test(tst_qquickcolorgroup + SOURCES + tst_qquickcolorgroup.cpp + PUBLIC_LIBRARIES + Qt::CorePrivate + Qt::QmlPrivate + Qt::QuickPrivate +) diff --git a/tests/auto/quick/qquickcolorgroup/qquickcolorgroup.pro b/tests/auto/quick/qquickcolorgroup/qquickcolorgroup.pro new file mode 100644 index 0000000000..99c330199c --- /dev/null +++ b/tests/auto/quick/qquickcolorgroup/qquickcolorgroup.pro @@ -0,0 +1,7 @@ +CONFIG += testcase +TARGET = tst_qquickcolorgroup +SOURCES += tst_qquickcolorgroup.cpp + +macos:CONFIG -= app_bundle + +QT += core-private qml-private quick-private testlib diff --git a/tests/auto/quick/qquickcolorgroup/tst_qquickcolorgroup.cpp b/tests/auto/quick/qquickcolorgroup/tst_qquickcolorgroup.cpp new file mode 100644 index 0000000000..04cc81683c --- /dev/null +++ b/tests/auto/quick/qquickcolorgroup/tst_qquickcolorgroup.cpp @@ -0,0 +1,117 @@ +/**************************************************************************** +** +** Copyright (C) 2020 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the test suite 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 <QtTest/qtest.h> +#include <QtTest/QSignalSpy> + +#include <QtGui/QPalette> + +#include <QtQuick/private/qquickcolorgroup_p.h> + +class tst_QQuickColorGroup : public QObject +{ + Q_OBJECT + +private Q_SLOTS: + void checkColorProperty(); + void checkColorProperty_data(); + + void colorGroupChangedWhenColorChanged(); +}; + +void tst_QQuickColorGroup::checkColorProperty() +{ + QFETCH(int, propertyIndex); + + auto property = QQuickColorGroup::staticMetaObject.property(propertyIndex); + + QVERIFY(property.isReadable()); + QVERIFY(property.isWritable()); + QVERIFY(property.isResettable()); + QVERIFY(property.hasNotifySignal()); + + const QQuickColorGroup defaultGroup; + QQuickColorGroup group; + + auto notifierSignature = QString::number(QSIGNAL_CODE) + property.notifySignal().methodSignature(); + QSignalSpy sp(&group, notifierSignature.toUtf8()); + + QVERIFY(property.write(&group, QColor(Qt::red))); + + QCOMPARE(qvariant_cast<QColor>(property.read(&group)), QColor(Qt::red)); + + QVERIFY(property.reset(&group)); + + QCOMPARE(qvariant_cast<QColor>(property.read(&group)), + qvariant_cast<QColor>(property.read(&defaultGroup))); + + constexpr int expectedNotificationsCount = 2; // One from write + one from reset + QCOMPARE(sp.count(), expectedNotificationsCount); +} + +void tst_QQuickColorGroup::checkColorProperty_data() +{ + QTest::addColumn<int>("propertyIndex"); + + auto mo = QQuickColorGroup::staticMetaObject; + for (int i = mo.propertyOffset(); i < mo.propertyCount(); ++i) { + auto property = mo.property(i); + if (property.type() == QVariant::Color) { + QTest::addRow("%s", property.name()) << i; + } + } +} + +void tst_QQuickColorGroup::colorGroupChangedWhenColorChanged() +{ + QQuickColorGroup group; + group.setGroupTag(QPalette::Active); + + QSignalSpy sp(&group, &QQuickColorGroup::changed); + + QVERIFY(group.mid() != Qt::blue); + + group.setMid(Qt::blue); + + QCOMPARE(sp.count(), 1); +} + +QTEST_MAIN(tst_QQuickColorGroup) + +#include "tst_qquickcolorgroup.moc" diff --git a/tests/auto/quick/qquickdesignersupport/tst_qquickdesignersupport.cpp b/tests/auto/quick/qquickdesignersupport/tst_qquickdesignersupport.cpp index 062a8b5c9a..a4ef25be92 100644 --- a/tests/auto/quick/qquickdesignersupport/tst_qquickdesignersupport.cpp +++ b/tests/auto/quick/qquickdesignersupport/tst_qquickdesignersupport.cpp @@ -461,9 +461,14 @@ void tst_qquickdesignersupport::testNotifyPropertyChangeCallBack() QCOMPARE(s_propertyName, QQuickDesignerSupport::PropertyName("gradient")); } +// We have to use this ugly approach, because the signature of +// registerFixResourcePathsForObjectCallBack doesn't accept +// a proper lambda with a capture list +static QVector<QObject*> s_allSubObjects; + static void fixResourcePathsForObjectCallBackFunction(QObject *object) { - s_object = object; + s_allSubObjects << object; } static void (*fixResourcePathsForObjectCallBackPointer)(QObject *) = &fixResourcePathsForObjectCallBackFunction; @@ -480,7 +485,7 @@ void tst_qquickdesignersupport::testFixResourcePathsForObjectCallBack() QVERIFY(rootItem); - s_object = nullptr; + s_allSubObjects.clear(); QQuickDesignerSupportItems::registerFixResourcePathsForObjectCallBack(fixResourcePathsForObjectCallBackPointer); @@ -490,8 +495,12 @@ void tst_qquickdesignersupport::testFixResourcePathsForObjectCallBack() QQuickDesignerSupportItems::tweakObjects(simpleItem); - //Check that the fixResourcePathsForObjectCallBack was called on simpleItem - QCOMPARE(simpleItem , s_object); + // Check that the fixResourcePathsForObjectCallBack was called on simpleItem + // NOTE: more objects are collected now. There is also at least a palette + // that created on demand. + QVERIFY(s_allSubObjects.contains(simpleItem)); + + s_allSubObjects.clear(); } void doComponentCompleteRecursive(QObject *object) diff --git a/tests/auto/quick/qquickpalette/CMakeLists.txt b/tests/auto/quick/qquickpalette/CMakeLists.txt new file mode 100644 index 0000000000..20a8081c48 --- /dev/null +++ b/tests/auto/quick/qquickpalette/CMakeLists.txt @@ -0,0 +1,8 @@ +qt_add_test(tst_qquickpalette + SOURCES + tst_qquickpalette.cpp + PUBLIC_LIBRARIES + Qt::CorePrivate + Qt::QmlPrivate + Qt::QuickPrivate +) diff --git a/tests/auto/quick/qquickpalette/qquickpalette.pro b/tests/auto/quick/qquickpalette/qquickpalette.pro new file mode 100644 index 0000000000..96c508d82a --- /dev/null +++ b/tests/auto/quick/qquickpalette/qquickpalette.pro @@ -0,0 +1,7 @@ +CONFIG += testcase +TARGET = tst_qquickpalette +SOURCES += tst_qquickpalette.cpp + +macos:CONFIG -= app_bundle + +QT += core-private qml-private quick-private testlib diff --git a/tests/auto/quick/qquickpalette/tst_qquickpalette.cpp b/tests/auto/quick/qquickpalette/tst_qquickpalette.cpp new file mode 100644 index 0000000000..e211a034ee --- /dev/null +++ b/tests/auto/quick/qquickpalette/tst_qquickpalette.cpp @@ -0,0 +1,304 @@ +/**************************************************************************** +** +** Copyright (C) 2020 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the test suite 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 <QtTest/qtest.h> +#include <QtTest/QSignalSpy> + +#include <QtQuick/private/qquickpalette_p.h> +#include <QtQuick/private/qquickabstractpaletteprovider_p.h> +#include <QtQuick/private/qquickpalettecolorprovider_p.h> + +class tst_QQuickPalette : public QObject +{ + Q_OBJECT + +private Q_SLOTS: + void resolvingColor(); + void resolvingColor_data(); + + void newColorSubgroup(); + void newColorSubgroup_data(); + + void onlyRespectiveColorSubgroupChangedAfterAssigment(); + + void paletteChangedWhenColorGroupChanged(); + + void createDefault(); + + void changeCurrentColorGroup(); + + void inheritColor(); + + void inheritCurrentColor(); + + void overrideColor(); + + void resolveColor(); + + void createFromQtPalette(); + void convertToQtPalette(); +}; + +using GroupGetter = QQuickColorGroup* (QQuickPalette::* )() const; +Q_DECLARE_METATYPE(GroupGetter); + +void tst_QQuickPalette::resolvingColor() +{ + QFETCH(QPalette::ColorGroup, colorGroup); + QFETCH(GroupGetter, getter); + + QQuickPalette p; + p.setWindowText(Qt::red); + + auto g = (p.*getter)(); + + QVERIFY(g); + + g->setWindowText(Qt::green); + p.setCurrentGroup(colorGroup); + + QCOMPARE(p.windowText(), Qt::green); +} + +void tst_QQuickPalette::resolvingColor_data() +{ + QTest::addColumn<QPalette::ColorGroup>("colorGroup"); + QTest::addColumn<GroupGetter>("getter"); + + QTest::addRow("Inactive") << QPalette::Inactive << &QQuickPalette::inactive; + QTest::addRow("Disabled") << QPalette::Disabled << &QQuickPalette::disabled; +} + +using GroupSetter = void (QQuickPalette::* )(QQuickColorGroup *); +Q_DECLARE_METATYPE(GroupSetter); + +using GroupNotifier = void (QQuickPalette::* )(); +Q_DECLARE_METATYPE(GroupNotifier); + +void tst_QQuickPalette::newColorSubgroup() +{ + QFETCH(GroupGetter, getter); + QFETCH(GroupSetter, setter); + QFETCH(GroupNotifier, notifier); + + { + QQuickPalette p; + p.fromQPalette(Qt::blue); + + auto defaultGroup = (p.*getter)(); + QVERIFY(defaultGroup); + + QSignalSpy subgroupChanged(&p, notifier); + QSignalSpy paletteChanged(&p, &QQuickPalette::changed); + + QQuickPalette anotherPalette; + anotherPalette.fromQPalette(Qt::red); + (p.*setter)((anotherPalette.*getter)()); + + QCOMPARE(subgroupChanged.count(), 1); + QCOMPARE(paletteChanged.count(), 1); + } +} + +void tst_QQuickPalette::newColorSubgroup_data() +{ + QTest::addColumn<GroupGetter>("getter"); + QTest::addColumn<GroupSetter>("setter"); + QTest::addColumn<GroupNotifier>("notifier"); + + QTest::addRow("Active") << &QQuickPalette::active << &QQuickPalette::setActive + << &QQuickPalette::activeChanged; + QTest::addRow("Inactive") << &QQuickPalette::inactive << &QQuickPalette::setInactive + << &QQuickPalette::inactiveChanged; + QTest::addRow("Disabled") << &QQuickPalette::disabled << &QQuickPalette::setDisabled + << &QQuickPalette::disabledChanged; +} + +void tst_QQuickPalette::onlyRespectiveColorSubgroupChangedAfterAssigment() +{ + QQuickPalette palette; + palette.setWindow(Qt::red); + + QQuickPalette anotherPalette; + anotherPalette.active()->setWindow(Qt::green); + + // Only active subgroup should be copied + palette.setActive(anotherPalette.active()); + + QCOMPARE(palette.active()->window(), Qt::green); + QCOMPARE(palette.disabled()->window(), Qt::red); + QCOMPARE(palette.inactive()->window(), Qt::red); +} + +void tst_QQuickPalette::paletteChangedWhenColorGroupChanged() +{ + QQuickPalette p; + QSignalSpy sp(&p, &QQuickPalette::changed); + + p.active()->setMid(Qt::red); + p.inactive()->setMid(Qt::green); + p.disabled()->setMid(Qt::blue); + + QCOMPARE(sp.count(), 3); +} + +void tst_QQuickPalette::createDefault() +{ + QQuickPalette palette; + + QCOMPARE(palette.currentColorGroup(), QPalette::Active); + QCOMPARE(palette.active()->groupTag(), QPalette::Active); + QCOMPARE(palette.inactive()->groupTag(), QPalette::Inactive); + QCOMPARE(palette.disabled()->groupTag(), QPalette::Disabled); +} + +void tst_QQuickPalette::changeCurrentColorGroup() +{ + QQuickPalette palette; + + QSignalSpy ss(&palette, &QQuickPalette::changed); + palette.setCurrentGroup(QPalette::Disabled); + + QCOMPARE(palette.currentColorGroup(), QPalette::Disabled); + QCOMPARE(ss.count(), 1); +} + +void tst_QQuickPalette::inheritColor() +{ + QQuickPalette parentPalette; + parentPalette.setWindowText(Qt::red); + + QQuickPalette quickPalette; + quickPalette.inheritPalette(parentPalette.toQPalette()); + + QCOMPARE(quickPalette.windowText(), Qt::red); + + QQuickPalette childQuickPalette; + childQuickPalette.inheritPalette(quickPalette.toQPalette()); + + QCOMPARE(childQuickPalette.windowText(), Qt::red); +} + +void tst_QQuickPalette::inheritCurrentColor() +{ + QQuickPalette parentPalette; + parentPalette.setWindowText(Qt::green); + parentPalette.disabled()->setWindowText(Qt::red); + + + QQuickPalette quickPalette; + quickPalette.inheritPalette(parentPalette.toQPalette()); + quickPalette.setCurrentGroup(QPalette::Disabled); + + QCOMPARE(quickPalette.windowText(), Qt::red); +} + +void tst_QQuickPalette::overrideColor() +{ + QQuickPalette rootPalette; + rootPalette.setWindowText(Qt::red); + + QQuickPalette palette; + palette.inheritPalette(rootPalette.toQPalette()); + palette.setWindowText(Qt::yellow); + + QCOMPARE(palette.windowText(), Qt::yellow); + + QQuickPalette childPalette; + childPalette.inheritPalette(palette.toQPalette()); + childPalette.disabled()->setWindowText(Qt::green); + + // Color is not set for the current group. Use parent color + QCOMPARE(childPalette.windowText(), Qt::yellow); + + // Change current group to use color, specified for this particular group + childPalette.setCurrentGroup(QPalette::Disabled); + + QCOMPARE(childPalette.windowText(), Qt::green); +} + +void tst_QQuickPalette::resolveColor() +{ + QQuickPalette palette; + palette.setWindowText(Qt::red); + + // Disabled color should be red, because disabled palette is not specified + palette.setCurrentGroup(QPalette::Disabled); + QCOMPARE(palette.windowText(), Qt::red); + + // Color is changed for disabled palette, because current color group is QPalette::Disabled + palette.disabled()->setWindowText(Qt::yellow); + QCOMPARE(palette.windowText(), Qt::yellow); + QCOMPARE(palette.disabled()->windowText(), Qt::yellow); + + // Change color group back to active + palette.setCurrentGroup(QPalette::Active); + QCOMPARE(palette.windowText(), Qt::red); +} + +void tst_QQuickPalette::createFromQtPalette() +{ + QQuickPalette palette; + QPalette somePalette(Qt::red); + + QSignalSpy sp(&palette, &QQuickColorGroup::changed); + + palette.fromQPalette(QPalette()); + QCOMPARE(sp.count(), 0); + + palette.fromQPalette(somePalette); + QCOMPARE(sp.count(), 1); +} + +void tst_QQuickPalette::convertToQtPalette() +{ + QQuickPalette palette; + + QPalette somePalette(Qt::red); + palette.fromQPalette(somePalette); + + auto pp = palette.paletteProvider(); + QVERIFY(pp); + + QCOMPARE(palette.toQPalette(), somePalette.resolve(pp->defaultPalette())); +} + +QTEST_MAIN(tst_QQuickPalette) + +#include "tst_qquickpalette.moc" diff --git a/tests/auto/quick/quick.pro b/tests/auto/quick/quick.pro index 9ab7119903..71b5794e81 100644 --- a/tests/auto/quick/quick.pro +++ b/tests/auto/quick/quick.pro @@ -42,6 +42,8 @@ PRIVATETESTS += \ qquickstyledtext \ qquickstates \ qquicksystempalette \ + qquickcolorgroup \ + qquickpalette \ qquicktimeline QUICKTESTS += \ diff --git a/tests/benchmarks/quick/colorresolving/colorresolving.pro b/tests/benchmarks/quick/colorresolving/colorresolving.pro new file mode 100644 index 0000000000..dc238caf44 --- /dev/null +++ b/tests/benchmarks/quick/colorresolving/colorresolving.pro @@ -0,0 +1,14 @@ +TEMPLATE = app +TARGET = tst_colorresolving +CONFIG += qmltestcase + +macos:CONFIG -= app_bundle + +SOURCES += \ + $$PWD/tst_colorresolving.cpp + +OTHER_FILES += \ + $$PWD/data/*.qml + +TESTDATA += \ + $$PWD/data/tst_* diff --git a/tests/benchmarks/quick/colorresolving/data/tst_colorresolving.qml b/tests/benchmarks/quick/colorresolving/data/tst_colorresolving.qml new file mode 100644 index 0000000000..37aecaa3a4 --- /dev/null +++ b/tests/benchmarks/quick/colorresolving/data/tst_colorresolving.qml @@ -0,0 +1,149 @@ +/**************************************************************************** +** +** Copyright (C) 2020 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the test suite 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$ +** +****************************************************************************/ +import QtTest 1.2 +import QtQuick 6.0 + +TestCase { + id: testCase + width: 800 + height: 600 + visible: true + when: windowShown + + property var items: [] + property int items_count: 1000 + property int itemWidth : 50 + property int itemHeight: 50 + + // A reference point (added upon request) + function benchmark_do_nothing_with_palettes() {} + + // This test passes through all items in tree to resolve a color. No extra palettes created. + // Should be blazingly fast (approx. 0.01 msecs for 999 items). + function benchmark_color_lookup() { + // Make last item "visible" and create its palette + items[items_count - 1].color = items[items_count - 1].palette.button + + compare(items[0].palette.button, items[items_count - 1].palette.button, + "Color is not propagated to the last element.") + } + + // This test creates palettes for all elements in the tree. + function benchmark_create_all_palettes(data) { + populate_palettes() + check_palettes() + } + + // This test creates and resolves palettes for all elements in the tree. + function benchmark_create_and_resolve_all_palettes() { + populate_palettes() + resolve_palettes() + check_palettes() + } + + function init() { + // Re-create all items on each iteration of the benchmark. + + var componentStr = "import QtQuick 6.0; + + Rectangle { + x: mapFromItem(testCase, testCase.randomX(), testCase.randomY()).x + y: mapFromItem(testCase, testCase.randomX(), testCase.randomY()).y + + color: \"#7F696969\" + + width: testCase.itemWidth + height: testCase.itemHeight + }"; + items.push(createTemporaryQmlObject(componentStr, testCase)) + for (var i = 1; i < items_count; ++i) { + items.push(createTemporaryQmlObject(componentStr, items[i - 1])) + } + + // Create a pallet for item 0 + items[0].palette.button = randomRgba() + + // Make item "visible" (can be overlapped by children) + items[0].color = items[0].palette.button + } + + function cleanup() { + // Explicitly remove all "temporary" items to make sure that a memory + // will be released after each iteration of the benchmark. + for (var i = 0; i < items_count; ++i) { + items[i].destroy(); + } + + items = []; + } + + function randomColorComponent() { + return Math.floor(Math.random() * 256) / 255.0; + } + + function randomRgba() { + return Qt.rgba(randomColorComponent(), + randomColorComponent(), + randomColorComponent(), + randomColorComponent()); + } + + function randomCoordinate(len, itemLen) { return Math.floor(Math.random() * (len - itemLen + 1)); } + function randomX() { return randomCoordinate(width, itemWidth); } + function randomY() { return randomCoordinate(height, itemHeight); } + + function populate_palettes() { + for (var i = 1; i < items_count; ++i) { + items[i].color = items[i].palette.button + } + } + + function check_palettes() { + for (var j = 1; j < items_count; ++j) { + compare(items[j - 1].palette.button, items[j].palette.button, + "Color is not propagated to the next child element.") + } + } + + function resolve_palettes() { + // The loop is just in case. Doesn't affect the benchmark + do { + var randomColor = randomRgba() + } while (items[0].palette.button === randomColor) + + items[0].palette.button = randomColor + } +} diff --git a/tests/benchmarks/quick/colorresolving/tst_colorresolving.cpp b/tests/benchmarks/quick/colorresolving/tst_colorresolving.cpp new file mode 100644 index 0000000000..1ec4781d6c --- /dev/null +++ b/tests/benchmarks/quick/colorresolving/tst_colorresolving.cpp @@ -0,0 +1,38 @@ +/**************************************************************************** +** +** Copyright (C) 2020 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the test suite 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 <QtQuickTest/quicktest.h> +QUICK_TEST_MAIN(tst_colorresolving) diff --git a/tests/benchmarks/quick/quick.pro b/tests/benchmarks/quick/quick.pro index 87df78bd2f..f6de5ec287 100644 --- a/tests/benchmarks/quick/quick.pro +++ b/tests/benchmarks/quick/quick.pro @@ -1,4 +1,5 @@ TEMPLATE = subdirs SUBDIRS += \ - events + events \ + colorresolving |