aboutsummaryrefslogtreecommitdiffstats
path: root/src/quickcontrols/material/qquickmaterialstyle.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/quickcontrols/material/qquickmaterialstyle.cpp')
-rw-r--r--src/quickcontrols/material/qquickmaterialstyle.cpp1545
1 files changed, 1545 insertions, 0 deletions
diff --git a/src/quickcontrols/material/qquickmaterialstyle.cpp b/src/quickcontrols/material/qquickmaterialstyle.cpp
new file mode 100644
index 0000000000..f8ced5821b
--- /dev/null
+++ b/src/quickcontrols/material/qquickmaterialstyle.cpp
@@ -0,0 +1,1545 @@
+// Copyright (C) 2017 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+#include "qquickmaterialstyle_p.h"
+
+#include <QtCore/qdebug.h>
+#if QT_CONFIG(settings)
+#include <QtCore/qsettings.h>
+#endif
+#include <QtQml/qqmlinfo.h>
+#include <QtQuickControls2/private/qquickstyle_p.h>
+
+QT_BEGIN_NAMESPACE
+
+static const QRgb colors[][14] = {
+ // Red
+ {
+ 0xFFFFEBEE, // Shade50
+ 0xFFFFCDD2, // Shade100
+ 0xFFEF9A9A, // Shade200
+ 0xFFE57373, // Shade300
+ 0xFFEF5350, // Shade400
+ 0xFFF44336, // Shade500
+ 0xFFE53935, // Shade600
+ 0xFFD32F2F, // Shade700
+ 0xFFC62828, // Shade800
+ 0xFFB71C1C, // Shade900
+ 0xFFFF8A80, // ShadeA100
+ 0xFFFF5252, // ShadeA200
+ 0xFFFF1744, // ShadeA400
+ 0xFFD50000 // ShadeA700
+ },
+ // Pink
+ {
+ 0xFFFCE4EC, // Shade50
+ 0xFFF8BBD0, // Shade100
+ 0xFFF48FB1, // Shade200
+ 0xFFF06292, // Shade300
+ 0xFFEC407A, // Shade400
+ 0xFFE91E63, // Shade500
+ 0xFFD81B60, // Shade600
+ 0xFFC2185B, // Shade700
+ 0xFFAD1457, // Shade800
+ 0xFF880E4F, // Shade900
+ 0xFFFF80AB, // ShadeA100
+ 0xFFFF4081, // ShadeA200
+ 0xFFF50057, // ShadeA400
+ 0xFFC51162 // ShadeA700
+ },
+ // Purple
+ {
+ 0xFFF3E5F5, // Shade50
+ 0xFFE1BEE7, // Shade100
+ 0xFFCE93D8, // Shade200
+ 0xFFBA68C8, // Shade300
+ 0xFFAB47BC, // Shade400
+ 0xFF9C27B0, // Shade500
+ 0xFF8E24AA, // Shade600
+ 0xFF7B1FA2, // Shade700
+ 0xFF6A1B9A, // Shade800
+ 0xFF4A148C, // Shade900
+ 0xFFEA80FC, // ShadeA100
+ 0xFFE040FB, // ShadeA200
+ 0xFFD500F9, // ShadeA400
+ 0xFFAA00FF // ShadeA700
+ },
+ // DeepPurple
+ {
+ 0xFFEDE7F6, // Shade50
+ 0xFFD1C4E9, // Shade100
+ 0xFFB39DDB, // Shade200
+ 0xFF9575CD, // Shade300
+ 0xFF7E57C2, // Shade400
+ 0xFF673AB7, // Shade500
+ 0xFF5E35B1, // Shade600
+ 0xFF512DA8, // Shade700
+ 0xFF4527A0, // Shade800
+ 0xFF311B92, // Shade900
+ 0xFFB388FF, // ShadeA100
+ 0xFF7C4DFF, // ShadeA200
+ 0xFF651FFF, // ShadeA400
+ 0xFF6200EA // ShadeA700
+ },
+ // Indigo
+ {
+ 0xFFE8EAF6, // Shade50
+ 0xFFC5CAE9, // Shade100
+ 0xFF9FA8DA, // Shade200
+ 0xFF7986CB, // Shade300
+ 0xFF5C6BC0, // Shade400
+ 0xFF3F51B5, // Shade500
+ 0xFF3949AB, // Shade600
+ 0xFF303F9F, // Shade700
+ 0xFF283593, // Shade800
+ 0xFF1A237E, // Shade900
+ 0xFF8C9EFF, // ShadeA100
+ 0xFF536DFE, // ShadeA200
+ 0xFF3D5AFE, // ShadeA400
+ 0xFF304FFE // ShadeA700
+ },
+ // Blue
+ {
+ 0xFFE3F2FD, // Shade50
+ 0xFFBBDEFB, // Shade100
+ 0xFF90CAF9, // Shade200
+ 0xFF64B5F6, // Shade300
+ 0xFF42A5F5, // Shade400
+ 0xFF2196F3, // Shade500
+ 0xFF1E88E5, // Shade600
+ 0xFF1976D2, // Shade700
+ 0xFF1565C0, // Shade800
+ 0xFF0D47A1, // Shade900
+ 0xFF82B1FF, // ShadeA100
+ 0xFF448AFF, // ShadeA200
+ 0xFF2979FF, // ShadeA400
+ 0xFF2962FF // ShadeA700
+ },
+ // LightBlue
+ {
+ 0xFFE1F5FE, // Shade50
+ 0xFFB3E5FC, // Shade100
+ 0xFF81D4FA, // Shade200
+ 0xFF4FC3F7, // Shade300
+ 0xFF29B6F6, // Shade400
+ 0xFF03A9F4, // Shade500
+ 0xFF039BE5, // Shade600
+ 0xFF0288D1, // Shade700
+ 0xFF0277BD, // Shade800
+ 0xFF01579B, // Shade900
+ 0xFF80D8FF, // ShadeA100
+ 0xFF40C4FF, // ShadeA200
+ 0xFF00B0FF, // ShadeA400
+ 0xFF0091EA // ShadeA700
+ },
+ // Cyan
+ {
+ 0xFFE0F7FA, // Shade50
+ 0xFFB2EBF2, // Shade100
+ 0xFF80DEEA, // Shade200
+ 0xFF4DD0E1, // Shade300
+ 0xFF26C6DA, // Shade400
+ 0xFF00BCD4, // Shade500
+ 0xFF00ACC1, // Shade600
+ 0xFF0097A7, // Shade700
+ 0xFF00838F, // Shade800
+ 0xFF006064, // Shade900
+ 0xFF84FFFF, // ShadeA100
+ 0xFF18FFFF, // ShadeA200
+ 0xFF00E5FF, // ShadeA400
+ 0xFF00B8D4 // ShadeA700
+ },
+ // Teal
+ {
+ 0xFFE0F2F1, // Shade50
+ 0xFFB2DFDB, // Shade100
+ 0xFF80CBC4, // Shade200
+ 0xFF4DB6AC, // Shade300
+ 0xFF26A69A, // Shade400
+ 0xFF009688, // Shade500
+ 0xFF00897B, // Shade600
+ 0xFF00796B, // Shade700
+ 0xFF00695C, // Shade800
+ 0xFF004D40, // Shade900
+ 0xFFA7FFEB, // ShadeA100
+ 0xFF64FFDA, // ShadeA200
+ 0xFF1DE9B6, // ShadeA400
+ 0xFF00BFA5 // ShadeA700
+ },
+ // Green
+ {
+ 0xFFE8F5E9, // Shade50
+ 0xFFC8E6C9, // Shade100
+ 0xFFA5D6A7, // Shade200
+ 0xFF81C784, // Shade300
+ 0xFF66BB6A, // Shade400
+ 0xFF4CAF50, // Shade500
+ 0xFF43A047, // Shade600
+ 0xFF388E3C, // Shade700
+ 0xFF2E7D32, // Shade800
+ 0xFF1B5E20, // Shade900
+ 0xFFB9F6CA, // ShadeA100
+ 0xFF69F0AE, // ShadeA200
+ 0xFF00E676, // ShadeA400
+ 0xFF00C853 // ShadeA700
+ },
+ // LightGreen
+ {
+ 0xFFF1F8E9, // Shade50
+ 0xFFDCEDC8, // Shade100
+ 0xFFC5E1A5, // Shade200
+ 0xFFAED581, // Shade300
+ 0xFF9CCC65, // Shade400
+ 0xFF8BC34A, // Shade500
+ 0xFF7CB342, // Shade600
+ 0xFF689F38, // Shade700
+ 0xFF558B2F, // Shade800
+ 0xFF33691E, // Shade900
+ 0xFFCCFF90, // ShadeA100
+ 0xFFB2FF59, // ShadeA200
+ 0xFF76FF03, // ShadeA400
+ 0xFF64DD17 // ShadeA700
+ },
+ // Lime
+ {
+ 0xFFF9FBE7, // Shade50
+ 0xFFF0F4C3, // Shade100
+ 0xFFE6EE9C, // Shade200
+ 0xFFDCE775, // Shade300
+ 0xFFD4E157, // Shade400
+ 0xFFCDDC39, // Shade500
+ 0xFFC0CA33, // Shade600
+ 0xFFAFB42B, // Shade700
+ 0xFF9E9D24, // Shade800
+ 0xFF827717, // Shade900
+ 0xFFF4FF81, // ShadeA100
+ 0xFFEEFF41, // ShadeA200
+ 0xFFC6FF00, // ShadeA400
+ 0xFFAEEA00 // ShadeA700
+ },
+ // Yellow
+ {
+ 0xFFFFFDE7, // Shade50
+ 0xFFFFF9C4, // Shade100
+ 0xFFFFF59D, // Shade200
+ 0xFFFFF176, // Shade300
+ 0xFFFFEE58, // Shade400
+ 0xFFFFEB3B, // Shade500
+ 0xFFFDD835, // Shade600
+ 0xFFFBC02D, // Shade700
+ 0xFFF9A825, // Shade800
+ 0xFFF57F17, // Shade900
+ 0xFFFFFF8D, // ShadeA100
+ 0xFFFFFF00, // ShadeA200
+ 0xFFFFEA00, // ShadeA400
+ 0xFFFFD600 // ShadeA700
+ },
+ // Amber
+ {
+ 0xFFFFF8E1, // Shade50
+ 0xFFFFECB3, // Shade100
+ 0xFFFFE082, // Shade200
+ 0xFFFFD54F, // Shade300
+ 0xFFFFCA28, // Shade400
+ 0xFFFFC107, // Shade500
+ 0xFFFFB300, // Shade600
+ 0xFFFFA000, // Shade700
+ 0xFFFF8F00, // Shade800
+ 0xFFFF6F00, // Shade900
+ 0xFFFFE57F, // ShadeA100
+ 0xFFFFD740, // ShadeA200
+ 0xFFFFC400, // ShadeA400
+ 0xFFFFAB00 // ShadeA700
+ },
+ // Orange
+ {
+ 0xFFFFF3E0, // Shade50
+ 0xFFFFE0B2, // Shade100
+ 0xFFFFCC80, // Shade200
+ 0xFFFFB74D, // Shade300
+ 0xFFFFA726, // Shade400
+ 0xFFFF9800, // Shade500
+ 0xFFFB8C00, // Shade600
+ 0xFFF57C00, // Shade700
+ 0xFFEF6C00, // Shade800
+ 0xFFE65100, // Shade900
+ 0xFFFFD180, // ShadeA100
+ 0xFFFFAB40, // ShadeA200
+ 0xFFFF9100, // ShadeA400
+ 0xFFFF6D00 // ShadeA700
+ },
+ // DeepOrange
+ {
+ 0xFFFBE9E7, // Shade50
+ 0xFFFFCCBC, // Shade100
+ 0xFFFFAB91, // Shade200
+ 0xFFFF8A65, // Shade300
+ 0xFFFF7043, // Shade400
+ 0xFFFF5722, // Shade500
+ 0xFFF4511E, // Shade600
+ 0xFFE64A19, // Shade700
+ 0xFFD84315, // Shade800
+ 0xFFBF360C, // Shade900
+ 0xFFFF9E80, // ShadeA100
+ 0xFFFF6E40, // ShadeA200
+ 0xFFFF3D00, // ShadeA400
+ 0xFFDD2C00 // ShadeA700
+ },
+ // Brown
+ {
+ 0xFFEFEBE9, // Shade50
+ 0xFFD7CCC8, // Shade100
+ 0xFFBCAAA4, // Shade200
+ 0xFFA1887F, // Shade300
+ 0xFF8D6E63, // Shade400
+ 0xFF795548, // Shade500
+ 0xFF6D4C41, // Shade600
+ 0xFF5D4037, // Shade700
+ 0xFF4E342E, // Shade800
+ 0xFF3E2723, // Shade900
+ 0xFF000000, // ShadeA100
+ 0xFF000000, // ShadeA200
+ 0xFF000000, // ShadeA400
+ 0xFF000000 // ShadeA700
+ },
+ // Grey
+ {
+ 0xFFFAFAFA, // Shade50
+ 0xFFF5F5F5, // Shade100
+ 0xFFEEEEEE, // Shade200
+ 0xFFE0E0E0, // Shade300
+ 0xFFBDBDBD, // Shade400
+ 0xFF9E9E9E, // Shade500
+ 0xFF757575, // Shade600
+ 0xFF616161, // Shade700
+ 0xFF424242, // Shade800
+ 0xFF212121, // Shade900
+ 0xFF000000, // ShadeA100
+ 0xFF000000, // ShadeA200
+ 0xFF000000, // ShadeA400
+ 0xFF000000 // ShadeA700
+ },
+ // BlueGrey
+ {
+ 0xFFECEFF1, // Shade50
+ 0xFFCFD8DC, // Shade100
+ 0xFFB0BEC5, // Shade200
+ 0xFF90A4AE, // Shade300
+ 0xFF78909C, // Shade400
+ 0xFF607D8B, // Shade500
+ 0xFF546E7A, // Shade600
+ 0xFF455A64, // Shade700
+ 0xFF37474F, // Shade800
+ 0xFF263238, // Shade900
+ 0xFF000000, // ShadeA100
+ 0xFF000000, // ShadeA200
+ 0xFF000000, // ShadeA400
+ 0xFF000000 // ShadeA700
+ }
+};
+
+// If no value was inherited from a parent or explicitly set, the "global" values are used.
+// The initial, default values of the globals are hard-coded here, but the environment
+// variables and .conf file override them if specified.
+static QQuickMaterialStyle::Theme globalTheme = QQuickMaterialStyle::Light;
+static uint globalPrimary = QQuickMaterialStyle::Indigo;
+static uint globalAccent = QQuickMaterialStyle::Pink;
+static uint globalForeground = 0xDD000000; // primaryTextColorLight
+static uint globalBackground = 0xFFFAFAFA; // backgroundColorLight
+// These represent whether a global foreground/background was set.
+// Each style's m_hasForeground/m_hasBackground are initialized to these values.
+static bool hasGlobalForeground = false;
+static bool hasGlobalBackground = false;
+// These represent whether or not the global color value was specified as one of the
+// values that QColor accepts, as opposed to one of the pre-defined colors like Red.
+static bool globalPrimaryCustom = false;
+static bool globalAccentCustom = false;
+static bool globalForegroundCustom = true;
+static bool globalBackgroundCustom = true;
+// This is global because:
+// 1) The theme needs access to it to determine font sizes.
+// 2) There can only be one variant used for the whole application.
+static QQuickMaterialStyle::Variant globalVariant = QQuickMaterialStyle::Normal;
+static const QRgb backgroundColorLight = 0xFFFFFBFE;
+static const QRgb backgroundColorDark = 0xFF1C1B1F;
+static const QRgb dialogColorLight = 0xFFFFFFFF;
+static const QRgb dialogColorDark = 0xFF424242;
+static const QRgb primaryTextColorLight = 0xDD000000;
+static const QRgb primaryTextColorDark = 0xFFFFFFFF;
+static const QRgb secondaryTextColorLight = 0x89000000;
+static const QRgb secondaryTextColorDark = 0xB2FFFFFF;
+static const QRgb hintTextColorLight = 0x60000000;
+static const QRgb hintTextColorDark = 0x4CFFFFFF;
+static const QRgb dividerColorLight = 0x1E000000;
+static const QRgb dividerColorDark = 0x1EFFFFFF;
+static const QRgb iconColorLight = 0x89000000;
+static const QRgb iconColorDark = 0xFFFFFFFF;
+static const QRgb iconDisabledColorLight = 0x42000000;
+static const QRgb iconDisabledColorDark = 0x4CFFFFFF;
+static const QRgb raisedButtonColorLight = 0xFFD6D7D7;
+static const QRgb raisedButtonColorDark = 0x3FCCCCCC;
+static const QRgb raisedButtonDisabledColorLight = dividerColorLight;
+static const QRgb raisedButtonDisabledColorDark = dividerColorDark;
+static const QRgb frameColorLight = hintTextColorLight;
+static const QRgb frameColorDark = hintTextColorDark;
+static const QRgb rippleColorLight = 0x10000000;
+static const QRgb rippleColorDark = 0x20FFFFFF;
+static const QRgb spinBoxDisabledIconColorLight = 0xFFCCCCCC;
+static const QRgb spinBoxDisabledIconColorDark = 0xFF666666;
+static const QRgb sliderDisabledColorLight = 0xFF9E9E9E;
+static const QRgb sliderDisabledColorDark = 0xFF616161;
+/*
+ https://m3.material.io/components/switch/specs#57a434cd-5fcc-4d79-9bff-12b2a9768789
+
+ light / dark
+ surface: #FFFBFE/#1C1B1F
+ on-surface: #1C1B1F/#E6E1E5
+ surface-variant: #E7E0EC/#49454F
+
+ 12% = 1E
+ 38% = 61
+
+ handle
+
+ unchecked checked
+ disabled #1C1B1F/#E6E1E5 @ 38% (#611C1B1F/#61E6E1E5) #FFFBFE/#1C1B1F @ 100%
+
+ track
+
+ unchecked checked
+ disabled #E7E0EC/#49454F @ 12% (#1EE7E0EC/#1E49454F) #1C1B1F/#E6E1E5 @ 12% (#1E1C1B1F/#1EE6E1E5)
+
+ track outline
+
+ unchecked checked
+ disabled #1C1B1F/#E6E1E5 @ 12% (#1E1C1B1F/#1EE6E1E5) same as track
+*/
+static const QRgb switchUncheckedTrackColorLight = 0xFFE7E0EC;
+static const QRgb switchUncheckedTrackColorDark = 0x49454F;
+static const QRgb switchDisabledUncheckedTrackColorLight = 0x1EE7E0EC;
+static const QRgb switchDisabledUncheckedTrackColorDark = 0x1E49454F;
+static const QRgb switchDisabledUncheckedTrackBorderColorLight = 0x1E1C1B1F;
+static const QRgb switchDisabledUncheckedTrackBorderColorDark = 0x1EE6E1E5;
+static const QRgb switchDisabledCheckedTrackColorLight = 0x1E1C1B1F;
+static const QRgb switchDisabledCheckedTrackColorDark = 0x1EE6E1E5;
+static const QRgb switchDisabledUncheckedIconColorLight = 0x611C1B1F;
+static const QRgb switchDisabledUncheckedIconColorDark = 0x61E6E1E5;
+static const QRgb textFieldFilledContainerColorLight = 0xFFE7E0EC;
+static const QRgb textFieldFilledContainerColorDark = 0xFF49454F;
+
+static QQuickMaterialStyle::Theme effectiveTheme(QQuickMaterialStyle::Theme theme)
+{
+ if (theme == QQuickMaterialStyle::System)
+ theme = QQuickStylePrivate::isDarkSystemTheme() ? QQuickMaterialStyle::Dark : QQuickMaterialStyle::Light;
+ return theme;
+}
+
+QQuickMaterialStyle::QQuickMaterialStyle(QObject *parent) : QQuickAttachedPropertyPropagator(parent),
+ m_customPrimary(globalPrimaryCustom),
+ m_customAccent(globalAccentCustom),
+ m_customForeground(globalForegroundCustom),
+ m_customBackground(globalBackgroundCustom),
+ m_hasForeground(hasGlobalForeground),
+ m_hasBackground(hasGlobalBackground),
+ m_theme(globalTheme),
+ m_primary(globalPrimary),
+ m_accent(globalAccent),
+ m_foreground(globalForeground),
+ m_background(globalBackground)
+{
+ QQuickAttachedPropertyPropagator::initialize();
+}
+
+QQuickMaterialStyle *QQuickMaterialStyle::qmlAttachedProperties(QObject *object)
+{
+ return new QQuickMaterialStyle(object);
+}
+
+QQuickMaterialStyle::Theme QQuickMaterialStyle::theme() const
+{
+ return m_theme;
+}
+
+void QQuickMaterialStyle::setTheme(Theme theme)
+{
+ if (theme == System)
+ theme = QQuickStylePrivate::isDarkSystemTheme() ? Dark : Light;
+
+ m_explicitTheme = true;
+ if (m_theme == theme)
+ return;
+
+ m_theme = theme;
+ propagateTheme();
+ themeChange();
+ if (!m_customAccent)
+ accentChange();
+ if (!m_hasBackground)
+ backgroundChange();
+ if (!m_hasForeground)
+ foregroundChange();
+}
+
+void QQuickMaterialStyle::inheritTheme(Theme theme)
+{
+ if (m_explicitTheme || m_theme == theme)
+ return;
+
+ m_theme = theme;
+ propagateTheme();
+ themeChange();
+ if (!m_customAccent)
+ accentChange();
+ if (!m_hasBackground)
+ backgroundChange();
+ if (!m_hasForeground)
+ foregroundChange();
+}
+
+void QQuickMaterialStyle::propagateTheme()
+{
+ const auto styles = attachedChildren();
+ for (QQuickAttachedPropertyPropagator *child : styles) {
+ QQuickMaterialStyle *material = qobject_cast<QQuickMaterialStyle *>(child);
+ if (material)
+ material->inheritTheme(m_theme);
+ }
+}
+
+void QQuickMaterialStyle::resetTheme()
+{
+ if (!m_explicitTheme)
+ return;
+
+ m_explicitTheme = false;
+ QQuickMaterialStyle *material = qobject_cast<QQuickMaterialStyle *>(attachedParent());
+ inheritTheme(material ? material->theme() : globalTheme);
+}
+
+void QQuickMaterialStyle::themeChange()
+{
+ emit themeChanged();
+ emit themeOrAccentChanged();
+ emit primaryHighlightedTextColor();
+ emit dialogColorChanged();
+ emit tooltipColorChanged();
+ emit toolBarColorChanged();
+ emit toolTextColorChanged();
+}
+
+QVariant QQuickMaterialStyle::primary() const
+{
+ return primaryColor();
+}
+
+void QQuickMaterialStyle::setPrimary(const QVariant &var)
+{
+ QRgb primary = 0;
+ bool custom = false;
+ if (!variantToRgba(var, "primary", &primary, &custom))
+ return;
+
+ m_explicitPrimary = true;
+ if (m_primary == primary)
+ return;
+
+ m_customPrimary = custom;
+ m_primary = primary;
+ propagatePrimary();
+ primaryChange();
+}
+
+void QQuickMaterialStyle::inheritPrimary(uint primary, bool custom)
+{
+ if (m_explicitPrimary || m_primary == primary)
+ return;
+
+ m_customPrimary = custom;
+ m_primary = primary;
+ propagatePrimary();
+ primaryChange();
+}
+
+void QQuickMaterialStyle::propagatePrimary()
+{
+ const auto styles = attachedChildren();
+ for (QQuickAttachedPropertyPropagator *child : styles) {
+ QQuickMaterialStyle *material = qobject_cast<QQuickMaterialStyle *>(child);
+ if (material)
+ material->inheritPrimary(m_primary, m_customPrimary);
+ }
+}
+
+void QQuickMaterialStyle::resetPrimary()
+{
+ if (!m_explicitPrimary)
+ return;
+
+ m_customPrimary = false;
+ m_explicitPrimary = false;
+ QQuickMaterialStyle *material = qobject_cast<QQuickMaterialStyle *>(attachedParent());
+ if (material)
+ inheritPrimary(material->m_primary, material->m_customPrimary);
+ else
+ inheritPrimary(globalPrimary, false);
+}
+
+void QQuickMaterialStyle::primaryChange()
+{
+ emit primaryChanged();
+ emit toolBarColorChanged();
+ emit toolTextColorChanged();
+}
+
+QVariant QQuickMaterialStyle::accent() const
+{
+ return accentColor();
+}
+
+void QQuickMaterialStyle::setAccent(const QVariant &var)
+{
+ QRgb accent = 0;
+ bool custom = false;
+ if (!variantToRgba(var, "accent", &accent, &custom))
+ return;
+
+ m_explicitAccent = true;
+ if (m_accent == accent)
+ return;
+
+ m_customAccent = custom;
+ m_accent = accent;
+ propagateAccent();
+ accentChange();
+}
+
+void QQuickMaterialStyle::inheritAccent(uint accent, bool custom)
+{
+ if (m_explicitAccent || m_accent == accent)
+ return;
+
+ m_customAccent = custom;
+ m_accent = accent;
+ propagateAccent();
+ accentChange();
+}
+
+void QQuickMaterialStyle::propagateAccent()
+{
+ const auto styles = attachedChildren();
+ for (QQuickAttachedPropertyPropagator *child : styles) {
+ QQuickMaterialStyle *material = qobject_cast<QQuickMaterialStyle *>(child);
+ if (material)
+ material->inheritAccent(m_accent, m_customAccent);
+ }
+}
+
+void QQuickMaterialStyle::resetAccent()
+{
+ if (!m_explicitAccent)
+ return;
+
+ m_customAccent = false;
+ m_explicitAccent = false;
+ QQuickMaterialStyle *material = qobject_cast<QQuickMaterialStyle *>(attachedParent());
+ if (material)
+ inheritAccent(material->m_accent, material->m_customAccent);
+ else
+ inheritAccent(globalAccent, false);
+}
+
+void QQuickMaterialStyle::accentChange()
+{
+ emit accentChanged();
+ emit themeOrAccentChanged();
+}
+
+QVariant QQuickMaterialStyle::foreground() const
+{
+ if (!m_hasForeground)
+ return QColor::fromRgba(m_theme == Light ? primaryTextColorLight : primaryTextColorDark);
+ if (m_customForeground)
+ return QColor::fromRgba(m_foreground);
+ if (m_foreground > BlueGrey)
+ return QColor();
+ return QColor::fromRgba(colors[m_foreground][Shade500]);
+}
+
+void QQuickMaterialStyle::setForeground(const QVariant &var)
+{
+ QRgb foreground = 0;
+ bool custom = false;
+ if (!variantToRgba(var, "foreground", &foreground, &custom))
+ return;
+
+ m_hasForeground = true;
+ m_explicitForeground = true;
+ if (m_foreground == foreground)
+ return;
+
+ m_customForeground = custom;
+ m_foreground = foreground;
+ propagateForeground();
+ foregroundChange();
+}
+
+void QQuickMaterialStyle::inheritForeground(uint foreground, bool custom, bool has)
+{
+ if (m_explicitForeground || m_foreground == foreground)
+ return;
+
+ m_hasForeground = has;
+ m_customForeground = custom;
+ m_foreground = foreground;
+ propagateForeground();
+ foregroundChange();
+}
+
+void QQuickMaterialStyle::propagateForeground()
+{
+ const auto styles = attachedChildren();
+ for (QQuickAttachedPropertyPropagator *child : styles) {
+ QQuickMaterialStyle *material = qobject_cast<QQuickMaterialStyle *>(child);
+ if (material)
+ material->inheritForeground(m_foreground, m_customForeground, m_hasForeground);
+ }
+}
+
+void QQuickMaterialStyle::resetForeground()
+{
+ if (!m_explicitForeground)
+ return;
+
+ m_hasForeground = false;
+ m_customForeground = false;
+ m_explicitForeground = false;
+ QQuickMaterialStyle *material = qobject_cast<QQuickMaterialStyle *>(attachedParent());
+ inheritForeground(material ? material->m_foreground : globalForeground, true, material ? material->m_hasForeground : false);
+}
+
+void QQuickMaterialStyle::foregroundChange()
+{
+ emit foregroundChanged();
+ emit primaryHighlightedTextColorChanged();
+ // TODO: This causes a binding loop: see QTBUG-85699 and the comments on its fix
+// emit toolTextColorChanged();
+}
+
+QVariant QQuickMaterialStyle::background() const
+{
+ return backgroundColor();
+}
+
+void QQuickMaterialStyle::setBackground(const QVariant &var)
+{
+ QRgb background = 0;
+ bool custom = false;
+ if (!variantToRgba(var, "background", &background, &custom))
+ return;
+
+ m_hasBackground = true;
+ m_explicitBackground = true;
+ if (m_background == background)
+ return;
+
+ m_customBackground = custom;
+ m_background = background;
+ propagateBackground();
+ backgroundChange();
+}
+
+void QQuickMaterialStyle::inheritBackground(uint background, bool custom, bool has)
+{
+ if (m_explicitBackground || m_background == background)
+ return;
+
+ m_hasBackground = has;
+ m_customBackground = custom;
+ m_background = background;
+ propagateBackground();
+ backgroundChange();
+}
+
+void QQuickMaterialStyle::propagateBackground()
+{
+ const auto styles = attachedChildren();
+ for (QQuickAttachedPropertyPropagator *child : styles) {
+ QQuickMaterialStyle *material = qobject_cast<QQuickMaterialStyle *>(child);
+ if (material)
+ material->inheritBackground(m_background, m_customBackground, m_hasBackground);
+ }
+}
+
+void QQuickMaterialStyle::resetBackground()
+{
+ if (!m_explicitBackground)
+ return;
+
+ m_hasBackground = false;
+ m_customBackground = false;
+ m_explicitBackground = false;
+ QQuickMaterialStyle *material = qobject_cast<QQuickMaterialStyle *>(attachedParent());
+ inheritBackground(material ? material->m_background : globalBackground, true, material ? material->m_hasBackground : false);
+}
+
+void QQuickMaterialStyle::backgroundChange()
+{
+ emit backgroundChanged();
+ emit dialogColorChanged();
+ emit tooltipColorChanged();
+ emit toolBarColorChanged();
+}
+
+int QQuickMaterialStyle::elevation() const
+{
+ return m_elevation;
+}
+
+void QQuickMaterialStyle::setElevation(int elevation)
+{
+ if (m_elevation == elevation)
+ return;
+
+ m_elevation = elevation;
+ elevationChange();
+}
+
+void QQuickMaterialStyle::resetElevation()
+{
+ setElevation(0);
+}
+
+void QQuickMaterialStyle::elevationChange()
+{
+ emit elevationChanged();
+}
+
+QQuickMaterialStyle::RoundedScale QQuickMaterialStyle::roundedScale() const
+{
+ return m_roundedScale;
+}
+
+void QQuickMaterialStyle::setRoundedScale(RoundedScale roundedScale)
+{
+ if (m_roundedScale == roundedScale)
+ return;
+
+ m_roundedScale = roundedScale;
+ emit roundedScaleChanged();
+}
+
+void QQuickMaterialStyle::resetRoundedScale()
+{
+ setRoundedScale(RoundedScale::NotRounded);
+}
+
+QQuickMaterialStyle::ContainerStyle QQuickMaterialStyle::containerStyle() const
+{
+ return m_containerStyle;
+}
+
+void QQuickMaterialStyle::setContainerStyle(ContainerStyle containerStyle)
+{
+ if (m_containerStyle == containerStyle)
+ return;
+
+ m_containerStyle = containerStyle;
+ emit containerStyleChanged();
+}
+
+void QQuickMaterialStyle::resetContainerStyle()
+{
+ setContainerStyle(ContainerStyle::Filled);
+}
+
+QColor QQuickMaterialStyle::primaryColor() const
+{
+ if (m_customPrimary)
+ return QColor::fromRgba(m_primary);
+ if (m_primary > BlueGrey)
+ return QColor();
+ return colors[m_primary][Shade500];
+}
+
+QColor QQuickMaterialStyle::accentColor(Shade shade) const
+{
+ if (m_customAccent)
+ return shade == themeShade() ? QColor::fromRgba(m_accent)
+ : this->shade(QColor::fromRgba(m_accent), shade);
+ if (m_accent > BlueGrey)
+ return QColor();
+ return colors[m_accent][shade];
+}
+
+QColor QQuickMaterialStyle::accentColor() const
+{
+ return accentColor(themeShade());
+}
+
+QColor QQuickMaterialStyle::backgroundColor(Shade shade) const
+{
+ if (!m_hasBackground)
+ return QColor::fromRgba(m_theme == Light ? backgroundColorLight : backgroundColorDark);
+ if (m_customBackground)
+ return shade == themeShade() ? QColor::fromRgba(m_background)
+ : this->shade(QColor::fromRgba(m_background), shade);
+ if (m_background > BlueGrey)
+ return QColor();
+ return colors[m_background][shade];
+}
+
+QColor QQuickMaterialStyle::backgroundColor() const
+{
+ return backgroundColor(themeShade());
+}
+
+QColor QQuickMaterialStyle::primaryTextColor() const
+{
+ return QColor::fromRgba(m_theme == Light ? primaryTextColorLight : primaryTextColorDark);
+}
+
+QColor QQuickMaterialStyle::primaryHighlightedTextColor() const
+{
+ if (m_explicitForeground)
+ return primaryTextColor();
+ return QColor::fromRgba(primaryTextColorDark);
+}
+
+QColor QQuickMaterialStyle::secondaryTextColor() const
+{
+ return QColor::fromRgba(m_theme == Light ? secondaryTextColorLight : secondaryTextColorDark);
+}
+
+QColor QQuickMaterialStyle::hintTextColor() const
+{
+ return QColor::fromRgba(m_theme == Light ? hintTextColorLight : hintTextColorDark);
+}
+
+QColor QQuickMaterialStyle::textSelectionColor() const
+{
+ QColor color = accentColor();
+ color.setAlphaF(0.4f);
+ return color;
+}
+
+QColor QQuickMaterialStyle::dropShadowColor() const
+{
+ return QColor::fromRgba(0x40000000);
+}
+
+QColor QQuickMaterialStyle::dividerColor() const
+{
+ return QColor::fromRgba(m_theme == Light ? dividerColorLight : dividerColorDark);
+}
+
+QColor QQuickMaterialStyle::iconColor() const
+{
+ return QColor::fromRgba(m_theme == Light ? iconColorLight : iconColorDark);
+}
+
+QColor QQuickMaterialStyle::iconDisabledColor() const
+{
+ return QColor::fromRgba(m_theme == Light ? iconDisabledColorLight : iconDisabledColorDark);
+}
+
+QColor QQuickMaterialStyle::buttonColor(Theme theme, const QVariant &background, const QVariant &accent,
+ bool enabled, bool flat, bool highlighted, bool checked) const
+{
+ if (!enabled && !flat) {
+ return QColor::fromRgba(m_theme == Light
+ ? raisedButtonDisabledColorLight : raisedButtonDisabledColorDark);
+ }
+
+ // We don't use theme (and other arguments) here even though we pass it in, as it's
+ // simpler to just re-use themeShade. We still need the arguments because they allow
+ // us to be re-called whenever they change.
+ Shade shade = themeShade();
+ Q_UNUSED(theme);
+ Q_UNUSED(background);
+ Q_UNUSED(accent);
+
+ QColor color = Qt::transparent;
+
+ if (m_explicitBackground) {
+ color = backgroundColor(shade);
+ } else if (highlighted) {
+ if (m_theme == Light) {
+ color = accentColor(shade);
+ if (checked)
+ color = color.lighter();
+ } else {
+ // A highlighted + checked button should become darker.
+ color = accentColor(checked ? Shade100 : shade);
+ }
+ // Flat, highlighted buttons need to have a semi-transparent background,
+ // otherwise the text won't be visible.
+ if (flat)
+ color.setAlphaF(0.25);
+ } else if (!flat) {
+ // Even if the elevation is zero, it should still have a background if it's not flat.
+ color = QColor::fromRgba(m_theme == Light ? raisedButtonColorLight
+ : raisedButtonColorDark);
+ }
+
+ return color;
+}
+
+QColor QQuickMaterialStyle::frameColor() const
+{
+ return QColor::fromRgba(m_theme == Light ? frameColorLight : frameColorDark);
+}
+
+QColor QQuickMaterialStyle::rippleColor() const
+{
+ return QColor::fromRgba(m_theme == Light ? rippleColorLight : rippleColorDark);
+}
+
+QColor QQuickMaterialStyle::highlightedRippleColor() const
+{
+ QColor pressColor = accentColor();
+ pressColor.setAlpha(m_theme == Light ? 30 : 50);
+ return pressColor;
+}
+
+QColor QQuickMaterialStyle::switchUncheckedTrackColor() const
+{
+ return QColor::fromRgba(m_theme == Light ? switchUncheckedTrackColorLight : switchUncheckedTrackColorDark);
+}
+
+QColor QQuickMaterialStyle::switchCheckedTrackColor() const
+{
+ return accentColor(m_theme == Light ? themeShade() : Shade100);
+}
+
+QColor QQuickMaterialStyle::switchDisabledUncheckedTrackColor() const
+{
+ return QColor::fromRgba(m_theme == Light
+ ? switchDisabledUncheckedTrackColorLight : switchDisabledUncheckedTrackColorDark);
+}
+
+QColor QQuickMaterialStyle::switchDisabledCheckedTrackColor() const
+{
+ return QColor::fromRgba(m_theme == Light
+ ? switchDisabledCheckedTrackColorLight : switchDisabledCheckedTrackColorDark);
+}
+
+QColor QQuickMaterialStyle::switchDisabledUncheckedTrackBorderColor() const
+{
+ return QColor::fromRgba(m_theme == Light
+ ? switchDisabledUncheckedTrackBorderColorLight : switchDisabledUncheckedTrackBorderColorDark);
+}
+
+QColor QQuickMaterialStyle::switchUncheckedHandleColor() const
+{
+ return m_theme == Light ? color(Grey, Shade600) : color(Grey, Shade400);
+}
+
+QColor QQuickMaterialStyle::switchUncheckedHoveredHandleColor() const
+{
+ const QColor color = switchUncheckedHandleColor();
+ return m_theme == Light ? color.darker(140) : color.lighter(120);
+}
+
+QColor QQuickMaterialStyle::switchCheckedHandleColor() const
+{
+ return m_theme == Light ? QColor::fromRgb(0xFFFFFF) : accentColor(Shade800);
+}
+
+QColor QQuickMaterialStyle::switchDisabledUncheckedHandleColor() const
+{
+ if (m_theme == Light)
+ return QColor::fromRgba(0x611C1B1F);
+
+ QColor darkHandleColor = color(Grey, Shade800);
+ darkHandleColor.setAlphaF(0.38f);
+ return darkHandleColor;
+}
+
+QColor QQuickMaterialStyle::switchDisabledCheckedHandleColor() const
+{
+ return QColor::fromRgb(m_theme == Light ? 0xFFFBFE : 0x1C1B1F);
+}
+
+QColor QQuickMaterialStyle::switchDisabledCheckedIconColor() const
+{
+ return QColor::fromRgba(m_theme == Light ? 0x611C1B1F : 0x61E6E1E5);
+}
+
+QColor QQuickMaterialStyle::switchDisabledUncheckedIconColor() const
+{
+ return QColor::fromRgba(m_theme == Light
+ ? switchDisabledUncheckedIconColorLight : switchDisabledUncheckedIconColorDark);
+}
+
+QColor QQuickMaterialStyle::scrollBarColor() const
+{
+ return QColor::fromRgba(m_theme == Light ? 0x40000000 : 0x40FFFFFF);
+}
+
+QColor QQuickMaterialStyle::scrollBarHoveredColor() const
+{
+ return QColor::fromRgba(m_theme == Light ? 0x60000000 : 0x60FFFFFF);
+}
+
+QColor QQuickMaterialStyle::scrollBarPressedColor() const
+{
+ return QColor::fromRgba(m_theme == Light ? 0x80000000 : 0x80FFFFFF);
+}
+
+QColor QQuickMaterialStyle::dialogColor() const
+{
+ if (m_hasBackground)
+ return backgroundColor();
+ return QColor::fromRgba(m_theme == Light ? dialogColorLight : dialogColorDark);
+}
+
+QColor QQuickMaterialStyle::backgroundDimColor() const
+{
+ return QColor::fromRgba(m_theme == Light ? 0x99303030 : 0x99fafafa);
+}
+
+QColor QQuickMaterialStyle::listHighlightColor() const
+{
+ return QColor::fromRgba(m_theme == Light ? 0x1e000000 : 0x1effffff);
+}
+
+QColor QQuickMaterialStyle::tooltipColor() const
+{
+ if (m_explicitBackground)
+ return backgroundColor();
+ return color(Grey, Shade700);
+}
+
+QColor QQuickMaterialStyle::toolBarColor() const
+{
+ if (m_explicitBackground)
+ return backgroundColor();
+ return primaryColor();
+}
+
+QColor QQuickMaterialStyle::toolTextColor() const
+{
+ if (m_hasForeground || m_customPrimary)
+ return primaryTextColor();
+
+ switch (m_primary) {
+ case Red:
+ case Pink:
+ case Purple:
+ case DeepPurple:
+ case Indigo:
+ case Blue:
+ case Teal:
+ case DeepOrange:
+ case Brown:
+ case BlueGrey:
+ return QColor::fromRgba(primaryTextColorDark);
+
+ case LightBlue:
+ case Cyan:
+ case Green:
+ case LightGreen:
+ case Lime:
+ case Yellow:
+ case Amber:
+ case Orange:
+ case Grey:
+ return QColor::fromRgba(primaryTextColorLight);
+
+ default:
+ break;
+ }
+
+ return primaryTextColor();
+}
+
+QColor QQuickMaterialStyle::spinBoxDisabledIconColor() const
+{
+ return QColor::fromRgba(m_theme == Light ? spinBoxDisabledIconColorLight : spinBoxDisabledIconColorDark);
+}
+
+QColor QQuickMaterialStyle::sliderDisabledColor() const
+{
+ return QColor::fromRgba(m_theme == Light ? sliderDisabledColorLight : sliderDisabledColorDark);
+}
+
+QColor QQuickMaterialStyle::textFieldFilledContainerColor() const
+{
+ return QColor::fromRgba(m_theme == Light ? textFieldFilledContainerColorLight : textFieldFilledContainerColorDark);
+}
+
+QColor QQuickMaterialStyle::color(QQuickMaterialStyle::Color color, QQuickMaterialStyle::Shade shade) const
+{
+ int count = sizeof(colors) / sizeof(colors[0]);
+ if (color < 0 || color >= count)
+ return QColor();
+
+ count = sizeof(colors[0]) / sizeof(colors[0][0]);
+ if (shade < 0 || shade >= count)
+ return QColor();
+
+ return colors[color][shade];
+}
+
+static QColor lighterShade(const QColor &color, qreal amount)
+{
+ QColor hsl = color.toHsl();
+ hsl.setHslF(hsl.hueF(), hsl.saturationF(), qBound<qreal>(0.0, hsl.lightnessF() + amount, 1.0), color.alphaF());
+ return hsl.convertTo(color.spec());
+}
+
+static QColor darkerShade(const QColor &color, qreal amount)
+{
+ QColor hsl = color.toHsl();
+ hsl.setHslF(hsl.hueF(), hsl.saturationF(), qBound<qreal>(0.0, hsl.lightnessF() - amount, 1.0), color.alphaF());
+ return hsl.convertTo(color.spec());
+}
+
+QQuickMaterialStyle::Shade QQuickMaterialStyle::themeShade() const
+{
+ return m_theme == Light ? Shade500 : Shade200;
+}
+
+/*
+ * The following lightness values originate from the Material Design Color Generator project.
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2015 mbitson
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+// Returns the same color, if shade == themeShade()
+QColor QQuickMaterialStyle::shade(const QColor &color, Shade shade) const
+{
+ switch (shade) {
+ case Shade50:
+ return lighterShade(color, m_theme == Light ? 0.52 : 0.26);
+ case Shade100:
+ return lighterShade(color, m_theme == Light ? 0.37 : 0.11);
+ case Shade200:
+ return m_theme == Light ? lighterShade(color, 0.26) : color;
+ case Shade300:
+ return m_theme == Light ? lighterShade(color, 0.12) : darkerShade(color, 0.14);
+ case Shade400:
+ return m_theme == Light ? lighterShade(color, 0.06) : darkerShade(color, 0.20);
+ case Shade500:
+ return m_theme == Light ? color : darkerShade(color, 0.26);
+ case Shade600:
+ return darkerShade(color, m_theme == Light ? 0.06 : 0.32);
+ case Shade700:
+ return darkerShade(color, m_theme == Light ? 0.12 : 0.38);
+ case Shade800:
+ return darkerShade(color, m_theme == Light ? 0.18 : 0.44);
+ case Shade900:
+ return darkerShade(color, m_theme == Light ? 0.24 : 0.50);
+ case ShadeA100:
+ return lighterShade(color, m_theme == Light ? 0.54 : 0.28);
+ case ShadeA200:
+ return lighterShade(color, m_theme == Light ? 0.37 : 0.11);
+ case ShadeA400:
+ return m_theme == Light ? lighterShade(color, 0.06) : darkerShade(color, 0.20);
+ case ShadeA700:
+ return darkerShade(color, m_theme == Light ? 0.12 : 0.38);
+ default:
+ Q_UNREACHABLE_RETURN(QColor());
+ }
+}
+
+int QQuickMaterialStyle::touchTarget() const
+{
+ // https://material.io/guidelines/components/buttons.html#buttons-style
+ return globalVariant == Dense ? 44 : 48;
+}
+
+int QQuickMaterialStyle::buttonVerticalPadding() const
+{
+ return globalVariant == Dense ? 10 : 14;
+}
+
+// https://m3.material.io/components/buttons/specs#256326ad-f934-40e7-b05f-0bcb41aa4382
+int QQuickMaterialStyle::buttonLeftPadding(bool flat, bool hasIcon) const
+{
+ static const int noIconPadding = globalVariant == Dense ? 12 : 24;
+ static const int iconPadding = globalVariant == Dense ? 8 : 16;
+ static const int flatPadding = globalVariant == Dense ? 6 : 12;
+ return !flat ? (!hasIcon ? noIconPadding : iconPadding) : flatPadding;
+}
+
+int QQuickMaterialStyle::buttonRightPadding(bool flat, bool hasIcon, bool hasText) const
+{
+ static const int noTextPadding = globalVariant == Dense ? 8 : 16;
+ static const int textPadding = globalVariant == Dense ? 12 : 24;
+ static const int flatNoIconPadding = globalVariant == Dense ? 6 : 12;
+ static const int flatNoTextPadding = globalVariant == Dense ? 6 : 12;
+ static const int flatTextPadding = globalVariant == Dense ? 8 : 16;
+ return !flat
+ ? (!hasText ? noTextPadding : textPadding)
+ : (!hasIcon ? flatNoIconPadding : (!hasText ? flatNoTextPadding : flatTextPadding));
+}
+
+int QQuickMaterialStyle::buttonHeight() const
+{
+ // https://m3.material.io/components/buttons/specs#256326ad-f934-40e7-b05f-0bcb41aa4382
+ return globalVariant == Dense ? 32 : 40;
+}
+
+int QQuickMaterialStyle::delegateHeight() const
+{
+ // https://material.io/guidelines/components/lists.html#lists-specs
+ return globalVariant == Dense ? 40 : 48;
+}
+
+int QQuickMaterialStyle::dialogButtonBoxHeight() const
+{
+ return globalVariant == Dense ? 48 : 52;
+}
+
+int QQuickMaterialStyle::dialogTitleFontPixelSize() const
+{
+ return globalVariant == Dense ? 16 : 24;
+}
+
+// https://m3.material.io/components/dialogs/specs#6771d107-624e-47cc-b6d8-2b7b620ba2f1
+QQuickMaterialStyle::RoundedScale QQuickMaterialStyle::dialogRoundedScale() const
+{
+ return globalVariant == Dense
+ ? QQuickMaterialStyle::RoundedScale::LargeScale
+ : QQuickMaterialStyle::RoundedScale::ExtraLargeScale;
+}
+
+int QQuickMaterialStyle::frameVerticalPadding() const
+{
+ return globalVariant == Dense ? 8 : 12;
+}
+
+int QQuickMaterialStyle::menuItemHeight() const
+{
+ // https://material.io/guidelines/components/menus.html#menus-simple-menus
+ return globalVariant == Dense ? 32 : 48;
+}
+
+int QQuickMaterialStyle::menuItemVerticalPadding() const
+{
+ return globalVariant == Dense ? 8 : 12;
+}
+
+int QQuickMaterialStyle::switchIndicatorWidth() const
+{
+ return globalVariant == Dense ? 40 : 52;
+}
+
+int QQuickMaterialStyle::switchIndicatorHeight() const
+{
+ return globalVariant == Dense ? 22 : 32;
+}
+
+int QQuickMaterialStyle::switchNormalHandleHeight() const
+{
+ return globalVariant == Dense ? 10 : 16;
+}
+
+int QQuickMaterialStyle::switchCheckedHandleHeight() const
+{
+ return globalVariant == Dense ? 16 : 24;
+}
+
+int QQuickMaterialStyle::switchLargestHandleHeight() const
+{
+ return globalVariant == Dense ? 18 : 28;
+}
+
+int QQuickMaterialStyle::switchDelegateVerticalPadding() const
+{
+ // SwitchDelegate's indicator is much larger than the others due to the shadow,
+ // so we must reduce its padding to ensure its implicitHeight is 40 when dense.
+ return globalVariant == Dense ? 4 : 8;
+}
+
+int QQuickMaterialStyle::textFieldHeight() const
+{
+ // filled: https://m3.material.io/components/text-fields/specs#8c032848-e442-46df-b25d-28f1315f234b
+ // outlined: https://m3.material.io/components/text-fields/specs#605e24f1-1c1f-4c00-b385-4bf50733a5ef
+ return globalVariant == Dense ? 44 : 56;
+}
+int QQuickMaterialStyle::textFieldHorizontalPadding() const
+{
+ return globalVariant == Dense ? 12 : 16;
+}
+int QQuickMaterialStyle::textFieldVerticalPadding() const
+{
+ return globalVariant == Dense ? 4 : 8;
+}
+
+int QQuickMaterialStyle::tooltipHeight() const
+{
+ // https://material.io/guidelines/components/tooltips.html
+ return globalVariant == Dense ? 22 : 32;
+}
+
+QQuickMaterialStyle::Variant QQuickMaterialStyle::variant()
+{
+ return globalVariant;
+}
+
+template <typename Enum>
+static Enum toEnumValue(const QByteArray &value, bool *ok)
+{
+ QMetaEnum enumeration = QMetaEnum::fromType<Enum>();
+ return static_cast<Enum>(enumeration.keyToValue(value, ok));
+}
+
+static QByteArray resolveSetting(const QByteArray &env, const QSharedPointer<QSettings> &settings, const QString &name)
+{
+ QByteArray value = qgetenv(env);
+#if QT_CONFIG(settings)
+ if (value.isNull() && !settings.isNull())
+ value = settings->value(name).toByteArray();
+#endif
+ return value;
+}
+
+void QQuickMaterialStyle::initGlobals()
+{
+ QSharedPointer<QSettings> settings = QQuickStylePrivate::settings(QStringLiteral("Material"));
+
+ bool ok = false;
+ QByteArray themeValue = resolveSetting("QT_QUICK_CONTROLS_MATERIAL_THEME", settings, QStringLiteral("Theme"));
+ Theme themeEnum = toEnumValue<Theme>(themeValue, &ok);
+ if (ok)
+ globalTheme = effectiveTheme(themeEnum);
+ else if (!themeValue.isEmpty())
+ qWarning().nospace().noquote() << "Material: unknown theme value: " << themeValue;
+
+ QByteArray variantValue = resolveSetting("QT_QUICK_CONTROLS_MATERIAL_VARIANT", settings, QStringLiteral("Variant"));
+ Variant variantEnum = toEnumValue<Variant>(variantValue, &ok);
+ if (ok)
+ globalVariant = variantEnum;
+ else if (!variantValue.isEmpty())
+ qWarning().nospace().noquote() << "Material: unknown variant value: " << variantValue;
+
+ QByteArray primaryValue = resolveSetting("QT_QUICK_CONTROLS_MATERIAL_PRIMARY", settings, QStringLiteral("Primary"));
+ Color primaryEnum = toEnumValue<Color>(primaryValue, &ok);
+ if (ok) {
+ globalPrimaryCustom = false;
+ globalPrimary = primaryEnum;
+ } else {
+ QColor color = QColor::fromString(primaryValue);
+ if (color.isValid()) {
+ globalPrimaryCustom = true;
+ globalPrimary = color.rgba();
+ } else if (!primaryValue.isEmpty()) {
+ qWarning().nospace().noquote() << "Material: unknown primary value: " << primaryValue;
+ }
+ }
+
+ QByteArray accentValue = resolveSetting("QT_QUICK_CONTROLS_MATERIAL_ACCENT", settings, QStringLiteral("Accent"));
+ Color accentEnum = toEnumValue<Color>(accentValue, &ok);
+ if (ok) {
+ globalAccentCustom = false;
+ globalAccent = accentEnum;
+ } else if (!accentValue.isEmpty()) {
+ QColor color = QColor::fromString(accentValue);
+ if (color.isValid()) {
+ globalAccentCustom = true;
+ globalAccent = color.rgba();
+ } else {
+ qWarning().nospace().noquote() << "Material: unknown accent value: " << accentValue;
+ }
+ }
+
+ QByteArray foregroundValue = resolveSetting("QT_QUICK_CONTROLS_MATERIAL_FOREGROUND", settings, QStringLiteral("Foreground"));
+ Color foregroundEnum = toEnumValue<Color>(foregroundValue, &ok);
+ if (ok) {
+ globalForegroundCustom = false;
+ globalForeground = foregroundEnum;
+ hasGlobalForeground = true;
+ } else if (!foregroundValue.isEmpty()) {
+ QColor color = QColor::fromString(foregroundValue);
+ if (color.isValid()) {
+ globalForegroundCustom = true;
+ globalForeground = color.rgba();
+ hasGlobalForeground = true;
+ } else {
+ qWarning().nospace().noquote() << "Material: unknown foreground value: " << foregroundValue;
+ }
+ }
+
+ QByteArray backgroundValue = resolveSetting("QT_QUICK_CONTROLS_MATERIAL_BACKGROUND", settings, QStringLiteral("Background"));
+ Color backgroundEnum = toEnumValue<Color>(backgroundValue, &ok);
+ if (ok) {
+ globalBackgroundCustom = false;
+ globalBackground = backgroundEnum;
+ hasGlobalBackground = true;
+ } else if (!backgroundValue.isEmpty()) {
+ QColor color = QColor::fromString(backgroundValue);
+ if (color.isValid()) {
+ globalBackgroundCustom = true;
+ globalBackground = color.rgba();
+ hasGlobalBackground = true;
+ } else {
+ qWarning().nospace().noquote() << "Material: unknown background value: " << backgroundValue;
+ }
+ }
+}
+
+void QQuickMaterialStyle::attachedParentChange(QQuickAttachedPropertyPropagator *newParent, QQuickAttachedPropertyPropagator *oldParent)
+{
+ Q_UNUSED(oldParent);
+ QQuickMaterialStyle *material = qobject_cast<QQuickMaterialStyle *>(newParent);
+ if (material) {
+ inheritPrimary(material->m_primary, material->m_customPrimary);
+ inheritAccent(material->m_accent, material->m_customAccent);
+ inheritForeground(material->m_foreground, material->m_customForeground, material->m_hasForeground);
+ inheritBackground(material->m_background, material->m_customBackground, material->m_hasBackground);
+ inheritTheme(material->theme());
+ }
+}
+
+bool QQuickMaterialStyle::variantToRgba(const QVariant &var, const char *name, QRgb *rgba, bool *custom) const
+{
+ *custom = false;
+ if (var.metaType().id() == QMetaType::Int) {
+ int val = var.toInt();
+ if (val > BlueGrey) {
+ qmlWarning(parent()) << "unknown Material." << name << " value: " << val;
+ return false;
+ }
+ *rgba = val;
+ } else {
+ int val = QMetaEnum::fromType<Color>().keyToValue(var.toByteArray());
+ if (val != -1) {
+ *rgba = val;
+ } else {
+ QColor color = QColor::fromString(var.toString());
+ if (!color.isValid()) {
+ qmlWarning(parent()) << "unknown Material." << name << " value: " << var.toString();
+ return false;
+ }
+ *custom = true;
+ *rgba = color.rgba();
+ }
+ }
+ return true;
+}
+
+QT_END_NAMESPACE
+
+#include "moc_qquickmaterialstyle_p.cpp"