diff options
Diffstat (limited to 'src/imports/controls/material/qquickmaterialstyle.cpp')
-rw-r--r-- | src/imports/controls/material/qquickmaterialstyle.cpp | 772 |
1 files changed, 573 insertions, 199 deletions
diff --git a/src/imports/controls/material/qquickmaterialstyle.cpp b/src/imports/controls/material/qquickmaterialstyle.cpp index d7a25914..1c19bbd3 100644 --- a/src/imports/controls/material/qquickmaterialstyle.cpp +++ b/src/imports/controls/material/qquickmaterialstyle.cpp @@ -1,9 +1,9 @@ /**************************************************************************** ** -** Copyright (C) 2015 The Qt Company Ltd. +** Copyright (C) 2016 The Qt Company Ltd. ** Contact: http://www.qt.io/licensing/ ** -** This file is part of the Qt Quick Controls module of the Qt Toolkit. +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. ** ** $QT_BEGIN_LICENSE:LGPL3$ ** Commercial License Usage @@ -39,7 +39,7 @@ #include <QtCore/qdebug.h> #include <QtCore/qsettings.h> #include <QtQml/qqmlinfo.h> -#include <QtLabsControls/private/qquickstyle_p.h> +#include <QtQuickControls2/private/qquickstyleattached_p.h> QT_BEGIN_NAMESPACE @@ -369,41 +369,67 @@ static const QRgb colors[][14] = { } }; -static QQuickMaterialStyle::Theme defaultTheme = QQuickMaterialStyle::Light; -static uint defaultPrimary = QQuickMaterialStyle::Indigo; -static uint defaultAccent = QQuickMaterialStyle::Pink; -static bool defaultPrimaryCustom = false; -static bool defaultAccentCustom = false; +// 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; + static const QRgb backgroundColorLight = 0xFFFAFAFA; static const QRgb backgroundColorDark = 0xFF303030; static const QRgb dialogColorLight = 0xFFFFFFFF; -static const QRgb dialogColorDark = 0xFF303030; +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 dividerTextColorLight = 0x1E000000; -static const QRgb dividerTextColorDark = 0x1EFFFFFF; +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; -// TODO: find out actual value -static const QRgb raisedButtonPressColorLight = 0xFFCCCDCD; -static const QRgb raisedButtonDisabledColorLight = dividerTextColorLight; -static const QRgb raisedButtonDisabledColorDark = dividerTextColorDark; +static const QRgb raisedButtonColorDark = 0x3FCCCCCC; +static const QRgb raisedButtonDisabledColorLight = dividerColorLight; +static const QRgb raisedButtonDisabledColorDark = dividerColorDark; static const QRgb flatButtonPressColorLight = 0x66999999; static const QRgb flatButtonPressColorDark = 0x3FCCCCCC; static const QRgb flatButtonFocusColorLight = 0x33CCCCCC; static const QRgb flatButtonFocusColorDark = 0x26CCCCCC; +static const QRgb swipeDelegateColorLight = 0xFFD6D7D7; +static const QRgb swipeDelegateColorDark = 0xFF525252; +static const QRgb swipeDelegateHoverColorLight = 0xFFDFDFDF; +static const QRgb swipeDelegateHoverColorDark = 0xFF5D5D5D; +static const QRgb swipeDelegatePressColorLight = 0xFFCFCFCF; +static const QRgb swipeDelegatePressColorDark = 0xFF484848; +static const QRgb swipeDelegateDisabledColorLight = 0xFFEFEFEF; +static const QRgb swipeDelegateDisabledColorDark = 0xFF7C7C7C; static const QRgb frameColorLight = hintTextColorLight; static const QRgb frameColorDark = hintTextColorDark; static const QRgb switchUncheckedTrackColorLight = 0x42000000; static const QRgb switchUncheckedTrackColorDark = 0x4CFFFFFF; static const QRgb switchDisabledTrackColorLight = 0x1E000000; static const QRgb switchDisabledTrackColorDark = 0x19FFFFFF; -// TODO: find out actual values static const QRgb checkBoxUncheckedRippleColorLight = 0x10000000; static const QRgb checkBoxUncheckedRippleColorDark = 0x20FFFFFF; +static const QRgb spinBoxDisabledIconColorLight = 0xFFCCCCCC; +static const QRgb spinBoxDisabledIconColorDark = 0xFF666666; static QColor alphaBlend(const QColor &bg, const QColor &fg) { @@ -415,15 +441,24 @@ static QColor alphaBlend(const QColor &bg, const QColor &fg) return result; } -QQuickMaterialStyle::QQuickMaterialStyle(QObject *parent) : QQuickStyle(parent), +QQuickMaterialStyle::QQuickMaterialStyle(QObject *parent) : QQuickStyleAttached(parent), m_explicitTheme(false), m_explicitPrimary(false), m_explicitAccent(false), - m_customPrimary(defaultPrimaryCustom), - m_customAccent(defaultAccentCustom), - m_theme(defaultTheme), - m_primary(defaultPrimary), - m_accent(defaultAccent) + m_explicitForeground(false), + m_explicitBackground(false), + 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), + m_elevation(0) { init(); } @@ -441,27 +476,42 @@ QQuickMaterialStyle::Theme QQuickMaterialStyle::theme() const void QQuickMaterialStyle::setTheme(Theme theme) { m_explicitTheme = true; - if (m_theme != theme) { - m_theme = theme; - propagateTheme(); - emit themeChanged(); - emit paletteChanged(); - } + if (m_theme == theme) + return; + + m_theme = theme; + propagateTheme(); + emit themeChanged(); + emit paletteChanged(); + if (!m_customAccent) + emit accentChanged(); + if (!m_hasBackground) + emit backgroundChanged(); + if (!m_hasForeground) + emit foregroundChanged(); } void QQuickMaterialStyle::inheritTheme(Theme theme) { - if (!m_explicitTheme && m_theme != theme) { - m_theme = theme; - propagateTheme(); - emit themeChanged(); - emit paletteChanged(); - } + if (m_explicitTheme || m_theme == theme) + return; + + m_theme = theme; + propagateTheme(); + emit themeChanged(); + emit paletteChanged(); + if (!m_customAccent) + emit accentChanged(); + if (!m_hasBackground) + emit backgroundChanged(); + if (!m_hasForeground) + emit foregroundChanged(); } void QQuickMaterialStyle::propagateTheme() { - foreach (QQuickStyle *child, childStyles()) { + const auto styles = childStyles(); + for (QQuickStyleAttached *child : styles) { QQuickMaterialStyle *material = qobject_cast<QQuickMaterialStyle *>(child); if (material) material->inheritTheme(m_theme); @@ -470,11 +520,12 @@ void QQuickMaterialStyle::propagateTheme() void QQuickMaterialStyle::resetTheme() { - if (m_explicitTheme) { - m_explicitTheme = false; - QQuickMaterialStyle *material = qobject_cast<QQuickMaterialStyle *>(parentStyle()); - inheritTheme(material ? material->theme() : defaultTheme); - } + if (!m_explicitTheme) + return; + + m_explicitTheme = false; + QQuickMaterialStyle *material = qobject_cast<QQuickMaterialStyle *>(parentStyle()); + inheritTheme(material ? material->theme() : globalTheme); } QVariant QQuickMaterialStyle::primary() const @@ -486,52 +537,36 @@ void QQuickMaterialStyle::setPrimary(const QVariant &var) { QRgb primary = 0; bool custom = false; - if (var.type() == QVariant::Int) { - int val = var.toInt(); - if (val > BlueGrey) { - qmlInfo(parent()) << "unknown Material.primary value: " << val; - return; - } - primary = val; - } else { - int val = QMetaEnum::fromType<Color>().keyToValue(var.toByteArray()); - if (val != -1) { - primary = val; - } else { - QColor color(var.toString()); - if (!color.isValid()) { - qmlInfo(parent()) << "unknown Material.primary value: " << var.toString(); - return; - } - custom = true; - primary = color.rgba(); - } - } + if (!variantToRgba(var, "primary", &primary, &custom)) + return; m_explicitPrimary = true; - if (m_primary != primary) { - m_customPrimary = custom; - m_primary = primary; - propagatePrimary(); - emit primaryChanged(); - emit paletteChanged(); - } + if (m_primary == primary) + return; + + m_customPrimary = custom; + m_primary = primary; + propagatePrimary(); + emit primaryChanged(); + emit paletteChanged(); } void QQuickMaterialStyle::inheritPrimary(uint primary, bool custom) { - if (!m_explicitPrimary && m_primary != primary) { - m_customPrimary = custom; - m_primary = primary; - propagatePrimary(); - emit primaryChanged(); - emit paletteChanged(); - } + if (m_explicitPrimary || m_primary == primary) + return; + + m_customPrimary = custom; + m_primary = primary; + propagatePrimary(); + emit primaryChanged(); + emit paletteChanged(); } void QQuickMaterialStyle::propagatePrimary() { - foreach (QQuickStyle *child, childStyles()) { + const auto styles = childStyles(); + for (QQuickStyleAttached *child : styles) { QQuickMaterialStyle *material = qobject_cast<QQuickMaterialStyle *>(child); if (material) material->inheritPrimary(m_primary, m_customPrimary); @@ -540,12 +575,16 @@ void QQuickMaterialStyle::propagatePrimary() void QQuickMaterialStyle::resetPrimary() { - if (m_explicitPrimary) { - m_customPrimary = false; - m_explicitPrimary = false; - QQuickMaterialStyle *material = qobject_cast<QQuickMaterialStyle *>(parentStyle()); - inheritPrimary(material ? material->m_primary : defaultPrimary, true); - } + if (!m_explicitPrimary) + return; + + m_customPrimary = false; + m_explicitPrimary = false; + QQuickMaterialStyle *material = qobject_cast<QQuickMaterialStyle *>(parentStyle()); + if (material) + inheritPrimary(material->m_primary, material->m_customPrimary); + else + inheritPrimary(globalPrimary, false); } QVariant QQuickMaterialStyle::accent() const @@ -557,52 +596,36 @@ void QQuickMaterialStyle::setAccent(const QVariant &var) { QRgb accent = 0; bool custom = false; - if (var.type() == QVariant::Int) { - int val = var.toInt(); - if (val > BlueGrey) { - qmlInfo(parent()) << "unknown Material.accent value: " << val; - return; - } - accent = val; - } else { - int val = QMetaEnum::fromType<Color>().keyToValue(var.toByteArray()); - if (val != -1) { - accent = val; - } else { - QColor color(var.toString()); - if (!color.isValid()) { - qmlInfo(parent()) << "unknown Material.accent value: " << var.toString(); - return; - } - custom = true; - accent = color.rgba(); - } - } + if (!variantToRgba(var, "accent", &accent, &custom)) + return; m_explicitAccent = true; - if (m_accent != accent) { - m_customAccent = custom; - m_accent = accent; - propagateAccent(); - emit accentChanged(); - emit paletteChanged(); - } + if (m_accent == accent) + return; + + m_customAccent = custom; + m_accent = accent; + propagateAccent(); + emit accentChanged(); + emit paletteChanged(); } void QQuickMaterialStyle::inheritAccent(uint accent, bool custom) { - if (!m_explicitAccent && m_accent != accent) { - m_customAccent = custom; - m_accent = accent; - propagateAccent(); - emit accentChanged(); - emit paletteChanged(); - } + if (m_explicitAccent || m_accent == accent) + return; + + m_customAccent = custom; + m_accent = accent; + propagateAccent(); + emit accentChanged(); + emit paletteChanged(); } void QQuickMaterialStyle::propagateAccent() { - foreach (QQuickStyle *child, childStyles()) { + const auto styles = childStyles(); + for (QQuickStyleAttached *child : styles) { QQuickMaterialStyle *material = qobject_cast<QQuickMaterialStyle *>(child); if (material) material->inheritAccent(m_accent, m_customAccent); @@ -611,14 +634,153 @@ void QQuickMaterialStyle::propagateAccent() void QQuickMaterialStyle::resetAccent() { - if (m_explicitAccent) { - m_customAccent = false; - m_explicitAccent = false; - QQuickMaterialStyle *material = qobject_cast<QQuickMaterialStyle *>(parentStyle()); - inheritAccent(material ? material->m_accent : defaultAccent, true); + if (!m_explicitAccent) + return; + + m_customAccent = false; + m_explicitAccent = false; + QQuickMaterialStyle *material = qobject_cast<QQuickMaterialStyle *>(parentStyle()); + if (material) + inheritAccent(material->m_accent, material->m_customAccent); + else + inheritAccent(globalAccent, false); +} + +QVariant QQuickMaterialStyle::foreground() const +{ + return primaryTextColor(); +} + +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(); + emit foregroundChanged(); +} + +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(); + emit foregroundChanged(); +} + +void QQuickMaterialStyle::propagateForeground() +{ + const auto styles = childStyles(); + for (QQuickStyleAttached *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 *>(parentStyle()); + inheritForeground(material ? material->m_foreground : globalForeground, true, material ? material->m_hasForeground : false); +} + +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(); + emit backgroundChanged(); + emit paletteChanged(); +} + +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(); + emit backgroundChanged(); + emit paletteChanged(); +} + +void QQuickMaterialStyle::propagateBackground() +{ + const auto styles = childStyles(); + for (QQuickStyleAttached *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 *>(parentStyle()); + inheritBackground(material ? material->m_background : globalBackground, true, material ? material->m_hasBackground : false); +} + +int QQuickMaterialStyle::elevation() const +{ + return m_elevation; +} + +void QQuickMaterialStyle::setElevation(int elevation) +{ + if (m_elevation == elevation) + return; + + m_elevation = elevation; + emit elevationChanged(); +} + +void QQuickMaterialStyle::resetElevation() +{ + setElevation(0); +} + QColor QQuickMaterialStyle::primaryColor() const { if (m_customPrimary) @@ -628,27 +790,53 @@ QColor QQuickMaterialStyle::primaryColor() const return colors[m_primary][Shade500]; } -QColor QQuickMaterialStyle::accentColor() const +QColor QQuickMaterialStyle::accentColor(Shade shade) const { if (m_customAccent) - return QColor::fromRgba(m_accent); + return shade == themeShade() ? QColor::fromRgba(m_accent) + : this->shade(QColor::fromRgba(m_accent), shade); if (m_accent > BlueGrey) return QColor(); - return colors[m_accent][m_theme == Light ? Shade500 : Shade200]; + 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 QColor::fromRgba(m_theme == Light ? backgroundColorLight : backgroundColorDark); + return backgroundColor(themeShade()); } QColor QQuickMaterialStyle::primaryTextColor() const { - return QColor::fromRgba(m_theme == Light ? primaryTextColorLight : primaryTextColorDark); + 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 colors[m_foreground][Shade500]; } QColor QQuickMaterialStyle::primaryHighlightedTextColor() const { + if (m_explicitForeground) + return primaryTextColor(); return QColor::fromRgba(primaryTextColorDark); } @@ -676,60 +864,117 @@ QColor QQuickMaterialStyle::dropShadowColor() const QColor QQuickMaterialStyle::dividerColor() const { - return QColor::fromRgba(m_theme == Light ? dividerTextColorLight : dividerTextColorDark); + return QColor::fromRgba(m_theme == Light ? dividerColorLight : dividerColorDark); } -QColor QQuickMaterialStyle::raisedButtonColor() const +QColor QQuickMaterialStyle::iconColor() const { - return QColor::fromRgba(m_theme == Light ? raisedButtonColorLight : flatButtonFocusColorDark); + return QColor::fromRgba(m_theme == Light ? iconColorLight : iconColorDark); } -QColor QQuickMaterialStyle::raisedButtonHoverColor() const +QColor QQuickMaterialStyle::iconDisabledColor() const { - // The specs don't specify different colors here for the light theme. - return QColor::fromRgba(m_theme == Light ? raisedButtonColorLight : flatButtonPressColorDark); + return QColor::fromRgba(m_theme == Light ? iconDisabledColorLight : iconDisabledColorDark); } -QColor QQuickMaterialStyle::raisedButtonPressColor() const +QColor QQuickMaterialStyle::buttonColor(bool highlighted, bool pressed, bool hover) const { - return QColor::fromRgba(m_theme == Light ? raisedButtonPressColorLight : flatButtonPressColorDark); + Shade shade = pressed ? (m_theme == Light ? Shade700 : Shade100) + : themeShade(); + + QColor color = Qt::transparent; + + if (m_explicitBackground) { + color = backgroundColor(shade); + } else if (highlighted) { + color = accentColor(shade); + } else if (elevation() > 0) { + color = QColor::fromRgba(m_theme == Light ? raisedButtonColorLight + : raisedButtonColorDark); + + if (pressed) { + color = this->shade(color, shade); + } + } + + if (color == Qt::transparent) { + if (pressed) { + return QColor::fromRgba(m_theme == Light ? flatButtonPressColorLight + : flatButtonPressColorDark); + } else if (hover) { + return QColor::fromRgba(m_theme == Light ? flatButtonFocusColorLight + : flatButtonFocusColorDark); + } else { + return color; + } + } + + if (pressed || hover) { + // Add overlaying black shadow 12% opacity + return alphaBlend(color, QColor::fromRgba(0x1F000000)); + } else { + return color; + } } -QColor QQuickMaterialStyle::raisedButtonDisabledColor() const +QColor QQuickMaterialStyle::buttonColor() const { - return QColor::fromRgba(m_theme == Light ? raisedButtonDisabledColorLight : raisedButtonDisabledColorDark); + return buttonColor(false, false, false); } -QColor QQuickMaterialStyle::raisedHighlightedButtonColor() const +QColor QQuickMaterialStyle::buttonHoverColor() const { - return accentColor(); + return buttonColor(false, false, true); } -QColor QQuickMaterialStyle::raisedHighlightedButtonHoverColor() const +QColor QQuickMaterialStyle::buttonPressColor() const { - // Add overlaying black shadow 12% opacity - return alphaBlend(accentColor(), QColor::fromRgba(0x1F000000)); + return buttonColor(false, true, false); } -QColor QQuickMaterialStyle::raisedHighlightedButtonPressColor() const +QColor QQuickMaterialStyle::buttonDisabledColor() const { - // Add overlaying black shadow 12% opacity - return alphaBlend(shade(accentColor(), m_theme == Light ? Shade700 : Shade100), QColor::fromRgba(0x1F000000)); + if (elevation() > 0) { + return QColor::fromRgba(m_theme == Light ? raisedButtonDisabledColorLight + : raisedButtonDisabledColorDark); + } else { + return Qt::transparent; + } +} + +QColor QQuickMaterialStyle::highlightedButtonColor() const +{ + return buttonColor(true, false, false); +} + +QColor QQuickMaterialStyle::highlightedButtonHoverColor() const +{ + return buttonColor(true, false, true); +} + +QColor QQuickMaterialStyle::highlightedButtonPressColor() const +{ + return buttonColor(true, true, false); } -QColor QQuickMaterialStyle::raisedHighlightedButtonDisabledColor() const +QColor QQuickMaterialStyle::swipeDelegateColor() const { - return QColor::fromRgba(m_theme == Light ? raisedButtonDisabledColorLight : raisedButtonDisabledColorDark); + return QColor::fromRgba(m_theme == Light ? swipeDelegateColorLight : swipeDelegateColorDark); } -QColor QQuickMaterialStyle::flatButtonPressColor() const +QColor QQuickMaterialStyle::swipeDelegateHoverColor() const { - return QColor::fromRgba(m_theme == Light ? flatButtonPressColorLight : flatButtonPressColorDark); + return QColor::fromRgba(m_theme == Light ? swipeDelegateHoverColorLight : swipeDelegateHoverColorDark); } -QColor QQuickMaterialStyle::flatButtonFocusColor() const +QColor QQuickMaterialStyle::swipeDelegatePressColor() const { - return QColor::fromRgba(m_theme == Light ? flatButtonFocusColorLight : flatButtonFocusColorDark); + return QColor::fromRgba(m_theme == Light ? swipeDelegatePressColorLight : swipeDelegatePressColorDark); +} + +QColor QQuickMaterialStyle::swipeDelegateDisabledColor() const +{ + return QColor::fromRgba(m_theme == Light ? swipeDelegateDisabledColorLight : swipeDelegateDisabledColorDark); } QColor QQuickMaterialStyle::frameColor() const @@ -745,7 +990,6 @@ QColor QQuickMaterialStyle::checkBoxUncheckedRippleColor() const QColor QQuickMaterialStyle::checkBoxCheckedRippleColor() const { QColor pressColor = accentColor(); - // TODO: find out actual value pressColor.setAlpha(m_theme == Light ? 30 : 50); return pressColor; } @@ -757,7 +1001,7 @@ QColor QQuickMaterialStyle::switchUncheckedTrackColor() const QColor QQuickMaterialStyle::switchCheckedTrackColor() const { - QColor trackColor = m_theme == Light ? accentColor() : shade(accentColor(), Shade200); + QColor trackColor(accentColor()); trackColor.setAlphaF(0.5); return trackColor; } @@ -792,13 +1036,10 @@ QColor QQuickMaterialStyle::scrollBarPressedColor() const return QColor::fromRgba(m_theme == Light ? 0x80000000 : 0x80FFFFFF); } -QColor QQuickMaterialStyle::drawerBackgroundColor() const -{ - return QColor::fromRgba(dividerTextColorLight); -} - QColor QQuickMaterialStyle::dialogColor() const { + if (m_hasBackground) + return backgroundColor(); return QColor::fromRgba(m_theme == Light ? dialogColorLight : dialogColorDark); } @@ -812,6 +1053,61 @@ 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::color(QQuickMaterialStyle::Color color, QQuickMaterialStyle::Shade shade) const { int count = sizeof(colors) / sizeof(colors[0]); @@ -832,13 +1128,18 @@ static QColor lighterShade(const QColor &color, qreal amount) return hsl.convertTo(color.spec()); } -QColor darkerShade(const QColor &color, qreal amount) +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. * @@ -864,6 +1165,8 @@ QColor darkerShade(const QColor &color, qreal amount) * 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) { @@ -901,13 +1204,15 @@ QColor QQuickMaterialStyle::shade(const QColor &color, Shade shade) const } } -void QQuickMaterialStyle::parentStyleChange(QQuickStyle *newParent, QQuickStyle *oldParent) +void QQuickMaterialStyle::parentStyleChange(QQuickStyleAttached *newParent, QQuickStyleAttached *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()); } } @@ -919,54 +1224,123 @@ static Enum toEnumValue(const QByteArray &value, bool *ok) 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 (value.isNull() && !settings.isNull()) + value = settings->value(name).toByteArray(); + return value; +} + void QQuickMaterialStyle::init() { - static bool defaultsInitialized = false; - if (!defaultsInitialized) { - QSharedPointer<QSettings> settings = QQuickStyle::settings(QStringLiteral("Material")); - if (!settings.isNull()) { - bool ok = false; - QByteArray value = settings->value(QStringLiteral("Theme")).toByteArray(); - Theme theme = toEnumValue<Theme>(value, &ok); - if (ok) - defaultTheme = m_theme = theme; - else if (!value.isEmpty()) - qWarning().nospace().noquote() << settings->fileName() << ": unknown Material theme value: " << value; - - value = settings->value(QStringLiteral("Primary")).toByteArray(); - Color primary = toEnumValue<Color>(value, &ok); - if (ok) { - defaultPrimaryCustom = m_customPrimary = false; - defaultPrimary = m_primary = primary; + static bool globalsInitialized = false; + if (!globalsInitialized) { + QSharedPointer<QSettings> settings = QQuickStyleAttached::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 = m_theme = themeEnum; + else if (!themeValue.isEmpty()) + qWarning().nospace().noquote() << "Material: unknown theme value: " << themeValue; + + QByteArray primaryValue = resolveSetting("QT_QUICK_CONTROLS_MATERIAL_PRIMARY", settings, QStringLiteral("Primary")); + Color primaryEnum = toEnumValue<Color>(primaryValue, &ok); + if (ok) { + globalPrimaryCustom = m_customPrimary = false; + globalPrimary = m_primary = primaryEnum; + } else { + QColor color(primaryValue.constData()); + if (color.isValid()) { + globalPrimaryCustom = m_customPrimary = true; + globalPrimary = m_primary = 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 = m_customAccent = false; + globalAccent = m_accent = accentEnum; + } else if (!accentValue.isEmpty()) { + QColor color(accentValue.constData()); + if (color.isValid()) { + globalAccentCustom = m_customAccent = true; + globalAccent = m_accent = color.rgba(); } else { - QColor color(value.constData()); - if (color.isValid()) { - defaultPrimaryCustom = m_customPrimary = true; - defaultPrimary = m_primary = color.rgba(); - } else if (!value.isEmpty()) { - qWarning().nospace().noquote() << settings->fileName() << ": unknown Material primary value: " << value; - } + 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 = m_customForeground = false; + globalForeground = m_foreground = foregroundEnum; + hasGlobalForeground = m_hasForeground = true; + } else if (!foregroundValue.isEmpty()) { + QColor color(foregroundValue.constData()); + if (color.isValid()) { + globalForegroundCustom = m_customForeground = true; + globalForeground = m_foreground = color.rgba(); + hasGlobalForeground = m_hasForeground = true; + } else { + qWarning().nospace().noquote() << "Material: unknown foreground value: " << foregroundValue; + } + } - value = settings->value(QStringLiteral("Accent")).toByteArray(); - Color accent = toEnumValue<Color>(value, &ok); - if (ok) { - defaultAccentCustom = m_customAccent = false; - defaultAccent = m_accent = accent; + QByteArray backgroundValue = resolveSetting("QT_QUICK_CONTROLS_MATERIAL_BACKGROUND", settings, QStringLiteral("Background")); + Color backgroundEnum = toEnumValue<Color>(backgroundValue, &ok); + if (ok) { + globalBackgroundCustom = m_customBackground = false; + globalBackground = m_background = backgroundEnum; + hasGlobalBackground = m_hasBackground = true; + } else if (!backgroundValue.isEmpty()) { + QColor color(backgroundValue.constData()); + if (color.isValid()) { + globalBackgroundCustom = m_customBackground = true; + globalBackground = m_background = color.rgba(); + hasGlobalBackground = m_hasBackground = true; } else { - QColor color(value.constData()); - if (color.isValid()) { - defaultAccentCustom = m_customAccent = true; - defaultAccent = m_accent = color.rgba(); - } else if (!value.isEmpty()) { - qWarning().nospace().noquote() << settings->fileName() << ": unknown Material accent value: " << value; - } + qWarning().nospace().noquote() << "Material: unknown background value: " << backgroundValue; } } - defaultsInitialized = true; + + globalsInitialized = true; } - QQuickStyle::init(); // TODO: lazy init? + QQuickStyleAttached::init(); // TODO: lazy init? +} + +bool QQuickMaterialStyle::variantToRgba(const QVariant &var, const char *name, QRgb *rgba, bool *custom) const +{ + *custom = false; + if (var.type() == QVariant::Int) { + int val = var.toInt(); + if (val > BlueGrey) { + qmlInfo(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(var.toString()); + if (!color.isValid()) { + qmlInfo(parent()) << "unknown Material." << name << " value: " << var.toString(); + return false; + } + *custom = true; + *rgba = color.rgba(); + } + } + return true; } QT_END_NAMESPACE |