File indexing completed on 2024-05-05 04:46:57

0001 /*
0002  * SPDX-FileCopyrightText: 2017 by Marco Martin <mart@kde.org>
0003  * SPDX-FileCopyrightText: 2021 Arjen Hiemstra <ahiemstra@heimr.nl>
0004  *
0005  * SPDX-License-Identifier: LGPL-2.0-or-later
0006  */
0007 
0008 #include "basictheme_p.h"
0009 
0010 #include <QFile>
0011 #include <QGuiApplication>
0012 #include <QPalette>
0013 
0014 #include "libs/style.h"
0015 #include "imagecolors.h"
0016 
0017 namespace Maui
0018 {
0019     BasicThemeDefinition::BasicThemeDefinition(QObject *parent)
0020     : QObject(parent)
0021     ,m_imgColors(new ImageColors(this))
0022     {
0023 
0024         auto style = Style::instance();
0025         connect(style, &Style::styleTypeChanged, [this, style](Style::StyleType type)
0026         {
0027             switch(type)
0028             {
0029                 case Style::StyleType::Light:
0030                 {
0031                     setLightColors();
0032                     break;
0033                 }
0034                 case Style::StyleType::Dark:
0035                 {
0036                     setDarkColors();
0037                     break;
0038                 }
0039                 case Style::StyleType::TrueBlack:
0040                 {
0041                     setTrueBlackColors();
0042                     break;
0043                 }
0044                 case Style::StyleType::Inverted:
0045                 {
0046                     setTrueBlackColors(true);
0047                     break;
0048                 }
0049                 case Style::StyleType::Adaptive:
0050                 {
0051                     m_imgColors->setSource(style->adaptiveColorSchemeSource());
0052                     break;
0053                 }
0054                 case Style::StyleType::Auto:
0055                 default:
0056                 {
0057                     setSystemPaletteColors();
0058                     break;
0059                 }
0060             }
0061 
0062             Q_EMIT this->changed();
0063         });
0064 
0065         connect(style, &Style::accentColorChanged, [this, style](QColor)
0066         {
0067             switch(style->styleType())
0068             {
0069                 case Style::StyleType::Light:
0070                 {
0071                     setLightColors();
0072                     break;
0073                 }
0074                 case Style::StyleType::Dark:
0075                 {
0076                     setDarkColors();
0077                     break;
0078                 }
0079                 case Style::StyleType::TrueBlack:
0080                 case Style::StyleType::Inverted:
0081                 case Style::StyleType::Auto:
0082                 case Style::StyleType::Adaptive:
0083                 default:
0084                 {
0085                     break;
0086                 }
0087             }
0088 
0089             Q_EMIT this->changed();
0090         });
0091 
0092         connect(style, &Style::adaptiveColorSchemeSourceChanged, [this, style](QVariant source)
0093         {
0094             if(style->styleType() == Style::StyleType::Adaptive)
0095             {
0096                 m_imgColors->setSource(source);
0097             }
0098         });
0099 
0100         connect(m_imgColors, &ImageColors::paletteChanged, [this, style]()
0101         {
0102             if(style->styleType() == Style::StyleType::Adaptive)
0103             {
0104                 setAdaptiveColors();
0105                 Q_EMIT this->changed();
0106             }
0107         });
0108 #if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
0109         connect(qGuiApp, &QGuiApplication::paletteChanged, [this, style](QPalette)
0110         {
0111             if(style->styleType() == Style::StyleType::Auto)
0112             {
0113                 setSystemPaletteColors();
0114                 Q_EMIT this->changed();
0115             }
0116         });
0117 #else
0118         connect(qGuiApp, &QGuiApplication::paletteChanged, [this, style](QPalette)
0119         {
0120             if(style->styleType() == Style::StyleType::Auto)
0121             {
0122                 setSystemPaletteColors();
0123                 Q_EMIT this->changed();
0124             }
0125         });
0126 #endif
0127         switch(style->styleType())
0128         {
0129             case Style::StyleType::Light:
0130             {
0131                 setLightColors();
0132                 break;
0133             }
0134             case Style::StyleType::Dark:
0135             {
0136                     setDarkColors();
0137                 break;
0138             }
0139             case Style::StyleType::Adaptive:
0140             {
0141                 m_imgColors->setSource(style->adaptiveColorSchemeSource());
0142                 break;
0143             }
0144             case Style::StyleType::TrueBlack:
0145             {
0146                 setTrueBlackColors();
0147                 break;
0148             }
0149             case Style::StyleType::Inverted:
0150             {
0151                 setTrueBlackColors(true);
0152                 break;
0153             }
0154             case Style::StyleType::Auto:
0155             default:
0156             {
0157                 setSystemPaletteColors();
0158                 break;
0159             }
0160         }
0161     }
0162 
0163     // const char *colorProperty = "KDE_COLOR_SCHEME_PATH";
0164     void BasicThemeDefinition::setSystemPaletteColors()
0165     {
0166         auto palette = QGuiApplication::palette();
0167 
0168         textColor = palette.color(QPalette::ColorRole::WindowText);
0169         disabledTextColor = palette.color(QPalette::ColorRole::PlaceholderText);
0170 
0171         highlightColor = palette.color(QPalette::ColorRole::Highlight);
0172         highlightedTextColor = palette.color(QPalette::ColorRole::HighlightedText);
0173 
0174         backgroundColor = palette.color(QPalette::ColorRole::Window);
0175 
0176         ColorUtils cu;
0177         const auto isDark = cu.brightnessForColor(backgroundColor) == ColorUtils::Dark;
0178 
0179         activeBackgroundColor = highlightColor;
0180         alternateBackgroundColor = isDark ? palette.color(QPalette::ColorRole::AlternateBase).lighter(104) : palette.color(QPalette::ColorRole::AlternateBase).darker(104);
0181 
0182         hoverColor = palette.color(isDark ? QPalette::ColorRole::Midlight : QPalette::ColorRole::Mid);
0183         focusColor = highlightColor;
0184 
0185         activeTextColor = highlightColor;
0186 
0187         buttonTextColor = palette.color(QPalette::ColorRole::ButtonText);
0188         buttonBackgroundColor = palette.color(QPalette::ColorRole::Button);
0189         buttonAlternateBackgroundColor = isDark ? buttonBackgroundColor.lighter(104) : buttonBackgroundColor.darker(104);
0190         buttonHoverColor = palette.color(isDark ? QPalette::ColorRole::Midlight : QPalette::ColorRole::Mid);
0191         buttonFocusColor = highlightColor;
0192 
0193         viewTextColor = palette.color(QPalette::ColorRole::Text);
0194         viewBackgroundColor = palette.color(QPalette::ColorRole::Base);
0195         viewAlternateBackgroundColor = isDark ? viewBackgroundColor.lighter(104) : viewBackgroundColor.darker(104);
0196         viewHoverColor = palette.color(isDark ? QPalette::ColorRole::Midlight : QPalette::ColorRole::Mid);
0197         viewFocusColor = highlightColor;
0198 
0199         selectionTextColor = palette.color(QPalette::ColorRole::HighlightedText);
0200         selectionBackgroundColor = highlightColor;
0201         selectionAlternateBackgroundColor = isDark ? highlightColor.lighter() : highlightColor.darker();
0202         selectionHoverColor = isDark ? highlightColor.darker() : highlightColor.lighter();
0203         selectionFocusColor = highlightColor;
0204 
0205        bool useDefaultColors = true;
0206 //         #ifndef Q_OS_ANDROID
0207 //         if (qApp && qApp->property(colorProperty).isValid())
0208 //         {
0209 //             auto path = qApp->property(colorProperty).toString();
0210 //             auto config = KSharedConfig::openConfig(path);
0211 //
0212 //             auto active = KColorScheme(QPalette::Active, KColorScheme::Header, config);
0213 //
0214 //             headerTextColor = active.foreground().color();
0215 //             headerBackgroundColor = active.background().color();
0216 //             headerAlternateBackgroundColor = active.background(KColorScheme::AlternateBackground).color();
0217 //             headerHoverColor = active.decoration(KColorScheme::HoverColor).color();
0218 //             headerFocusColor = active.decoration(KColorScheme::HoverColor).color();
0219 //             useDefaultColors = false;
0220 //         }
0221 //         #endif
0222 
0223         if(useDefaultColors)
0224         {
0225             headerTextColor = textColor;
0226             headerBackgroundColor = palette.color(QPalette::ColorRole::Window);
0227             headerAlternateBackgroundColor =palette.color(QPalette::ColorRole::AlternateBase);
0228             headerHoverColor =palette.color(QPalette::ColorRole::Light);
0229             headerFocusColor = highlightColor;
0230         }
0231 
0232 
0233         complementaryTextColor = palette.color(QPalette::ColorRole::BrightText);
0234         complementaryBackgroundColor = palette.color(QPalette::ColorRole::Shadow);
0235         complementaryAlternateBackgroundColor = palette.color(QPalette::ColorRole::Dark);
0236         complementaryHoverColor = palette.color(QPalette::ColorRole::Mid);
0237         complementaryFocusColor = highlightColor;
0238 
0239         linkColor = palette.color(QPalette::ColorRole::Link);
0240         linkBackgroundColor =  palette.color(QPalette::ColorRole::Light);
0241         visitedLinkColor =  palette.color(QPalette::ColorRole::LinkVisited);
0242         visitedLinkBackgroundColor =  palette.color(QPalette::ColorRole::Light);
0243 
0244         negativeTextColor = QColor{"#dac7cb"};
0245         negativeBackgroundColor = QColor{"#DA4453"};
0246         neutralTextColor = QColor{"#333"};
0247         neutralBackgroundColor = QColor{"#F67400"};
0248         positiveTextColor = QColor{"#333"};
0249         positiveBackgroundColor = QColor{"#27AE60"};
0250 
0251         tooltipTextColor = QColor{"#fafafa"};
0252         tooltipBackgroundColor = QColor{"#333"};
0253         tooltipAlternateBackgroundColor = tooltipBackgroundColor.darker();
0254         tooltipHoverColor = QColor{"#000"};
0255         tooltipFocusColor = QColor{"#000"};
0256     }
0257 
0258     void BasicThemeDefinition::setTrueBlackColors( bool inverted )
0259     {
0260         QColor color1{"#ffffff"};
0261         QColor color2{"#000000"};
0262 
0263         textColor = inverted ? color2 : color1;
0264         disabledTextColor = textColor;
0265 
0266         highlightColor = inverted ? color2 : color1;
0267         highlightedTextColor = inverted ? color1 : color2;
0268 
0269         backgroundColor = inverted ? color1 : color2;
0270         activeBackgroundColor = highlightColor;
0271         alternateBackgroundColor = backgroundColor;
0272         hoverColor = backgroundColor;
0273         focusColor = highlightColor;
0274 
0275         activeTextColor = highlightColor;
0276 
0277         buttonTextColor = textColor;
0278         buttonBackgroundColor = backgroundColor;
0279         buttonAlternateBackgroundColor = buttonBackgroundColor;
0280         buttonHoverColor = buttonBackgroundColor;
0281         buttonFocusColor = buttonBackgroundColor;
0282 
0283         viewTextColor = textColor;
0284         viewBackgroundColor = backgroundColor;
0285         viewAlternateBackgroundColor = viewBackgroundColor;
0286         viewHoverColor = viewBackgroundColor;
0287         viewFocusColor = highlightColor;
0288 
0289         selectionTextColor = highlightedTextColor;
0290         selectionBackgroundColor = highlightColor;
0291         selectionAlternateBackgroundColor = selectionBackgroundColor;
0292         selectionHoverColor = selectionBackgroundColor;
0293         selectionFocusColor = highlightColor;
0294 
0295         complementaryTextColor = highlightedTextColor;
0296         complementaryBackgroundColor = highlightColor;
0297         complementaryAlternateBackgroundColor = complementaryBackgroundColor;
0298         complementaryHoverColor = complementaryBackgroundColor;
0299         complementaryFocusColor = highlightColor;
0300 
0301         headerTextColor = textColor;
0302         headerBackgroundColor = backgroundColor;
0303         headerAlternateBackgroundColor = headerBackgroundColor;
0304         headerHoverColor = headerBackgroundColor;
0305         headerFocusColor = highlightColor;
0306 
0307         linkColor = QColor{"#21b9ff"};
0308         linkBackgroundColor = QColor{"#21b9ff"};
0309         visitedLinkColor = QColor{"#ff17d4"};
0310         visitedLinkBackgroundColor = QColor{"#ff17d4"};
0311 
0312         negativeTextColor = QColor{"#DA4453"};
0313         negativeBackgroundColor = backgroundColor;
0314         neutralTextColor = QColor{"#F67400"};
0315         neutralBackgroundColor = backgroundColor;
0316         positiveTextColor = QColor{"#27AE60"};
0317         positiveBackgroundColor = backgroundColor;
0318 
0319         tooltipTextColor = textColor;
0320         tooltipBackgroundColor = backgroundColor;
0321         tooltipAlternateBackgroundColor = tooltipBackgroundColor;
0322         tooltipHoverColor = tooltipBackgroundColor;
0323         tooltipFocusColor = tooltipBackgroundColor;
0324     }
0325 
0326     void BasicThemeDefinition::setDarkColors()
0327     {
0328         ColorUtils cu;
0329 
0330         textColor = DarkColor::textColor;
0331         disabledTextColor = DarkColor::disabledTextColor;
0332 
0333         highlightColor = Style::instance()->accentColor();
0334         const auto isDark = cu.brightnessForColor(highlightColor) == ColorUtils::Dark;
0335 
0336         highlightedTextColor = isDark ? QColor{"#eff0f1"} : QColor{"#232323"};
0337 
0338         backgroundColor = cu.tintWithAlpha(DarkColor::backgroundColor, highlightColor, 0.02);
0339         activeBackgroundColor = highlightColor;
0340         alternateBackgroundColor = cu.tintWithAlpha(DarkColor::alternateBackgroundColor, highlightColor, 0.02);
0341         hoverColor = cu.tintWithAlpha(DarkColor::hoverColor, highlightColor, 0.02);
0342         focusColor = highlightColor;
0343 
0344         activeTextColor = highlightColor;
0345 
0346         buttonTextColor = textColor;
0347         buttonBackgroundColor = cu.tintWithAlpha(DarkColor::buttonBackgroundColor, highlightColor, 0.02);
0348         buttonAlternateBackgroundColor = cu.tintWithAlpha(DarkColor::buttonAlternateBackgroundColor, highlightColor, 0.02);
0349         buttonHoverColor =  cu.tintWithAlpha(DarkColor::buttonHoverColor, highlightColor, 0.02);
0350         buttonFocusColor = highlightColor;
0351 
0352         viewTextColor = textColor;
0353         viewBackgroundColor = cu.tintWithAlpha(DarkColor::viewBackgroundColor, highlightColor, 0.02);
0354         viewAlternateBackgroundColor = cu.tintWithAlpha(DarkColor::viewAlternateBackgroundColor, highlightColor, 0.02);
0355         viewHoverColor =  cu.tintWithAlpha(DarkColor::viewHoverColor, highlightColor, 0.02);
0356         viewFocusColor = highlightColor;
0357 
0358         selectionTextColor = QColor{"#fcfcfc"};
0359         selectionBackgroundColor = highlightColor;
0360         selectionAlternateBackgroundColor = selectionBackgroundColor.darker();
0361         selectionHoverColor = selectionBackgroundColor.lighter();
0362         selectionFocusColor = highlightColor;
0363 
0364         complementaryTextColor = QColor{"#eff0f1"};
0365         complementaryBackgroundColor = cu.tintWithAlpha(QColor{"#31363b"}, highlightColor, 0.03);
0366         complementaryAlternateBackgroundColor = complementaryBackgroundColor.darker();
0367         complementaryHoverColor = complementaryBackgroundColor.lighter();
0368         complementaryFocusColor = highlightColor;
0369 
0370         headerTextColor = textColor;
0371         headerBackgroundColor =  cu.tintWithAlpha(DarkColor::headerBackgroundColor, highlightColor, 0.04);
0372         headerAlternateBackgroundColor = cu.tintWithAlpha(DarkColor::headerAlternateBackgroundColor, highlightColor, 0.02);
0373         headerHoverColor = DarkColor::hoverColor;
0374         headerFocusColor = highlightColor;
0375 
0376         linkColor = QColor{"#21b9ff"};
0377         linkBackgroundColor = QColor{"#21b9ff"};
0378         visitedLinkColor = QColor{"#ff17d4"};
0379         visitedLinkBackgroundColor = QColor{"#ff17d4"};
0380 
0381         negativeTextColor = QColor{"#dac7cb"};
0382         negativeBackgroundColor = QColor{"#DA4453"};
0383         neutralTextColor = QColor{"#333"};
0384         neutralBackgroundColor = QColor{"#F67400"};
0385         positiveTextColor = QColor{"#333"};
0386         positiveBackgroundColor = QColor{"#27AE60"};
0387 
0388         tooltipTextColor = QColor{"#fafafa"};
0389         tooltipBackgroundColor = QColor{"#333"};
0390         tooltipAlternateBackgroundColor = tooltipBackgroundColor.darker();
0391         tooltipHoverColor = QColor{"#000"};
0392         tooltipFocusColor = QColor{"#000"};
0393     }
0394 
0395     void BasicThemeDefinition::setLightColors()
0396     {
0397         ColorUtils cu;
0398 
0399         textColor = LightColor::textColor;
0400         disabledTextColor = LightColor::disabledTextColor;
0401 
0402         highlightColor = Style::instance()->accentColor();
0403         //         backgroundColor = QColor{"#efefef"};
0404         const auto isDark = cu.brightnessForColor(highlightColor) == ColorUtils::Dark;
0405         highlightedTextColor = isDark ? QColor{"#eff0f1"} : QColor{"#232323"};
0406 
0407         backgroundColor = cu.tintWithAlpha(LightColor::backgroundColor, highlightColor, 0.02);
0408         activeBackgroundColor = highlightColor;
0409         alternateBackgroundColor = cu.tintWithAlpha(LightColor::alternateBackgroundColor, highlightColor, 0.02);
0410         hoverColor = LightColor::hoverColor;
0411         focusColor = highlightColor;
0412 
0413         activeTextColor = highlightColor;
0414 
0415         buttonTextColor = textColor;
0416         buttonBackgroundColor = cu.tintWithAlpha(LightColor::buttonBackgroundColor, highlightColor, 0.03);
0417         buttonAlternateBackgroundColor = LightColor::buttonAlternateBackgroundColor;
0418         buttonHoverColor = cu.tintWithAlpha(LightColor::buttonHoverColor, highlightColor, 0.02);
0419         buttonFocusColor = highlightColor;
0420 
0421         viewTextColor = QColor{"#333333"};
0422         viewBackgroundColor = cu.tintWithAlpha(LightColor::viewBackgroundColor, highlightColor, 0.02);
0423         viewAlternateBackgroundColor =cu.tintWithAlpha(LightColor::viewAlternateBackgroundColor, highlightColor, 0.02);
0424         viewHoverColor = cu.tintWithAlpha(LightColor::viewHoverColor, highlightColor, 0.02);
0425         viewFocusColor = highlightColor;
0426 
0427         selectionTextColor = QColor{"#eff0f1"};
0428         selectionBackgroundColor = highlightColor;
0429         selectionAlternateBackgroundColor = selectionBackgroundColor.darker(120);
0430         selectionHoverColor = selectionBackgroundColor.lighter(120);
0431         selectionFocusColor = highlightColor;
0432 
0433         complementaryTextColor = QColor{"#eff0f1"};
0434         complementaryBackgroundColor = cu.tintWithAlpha(QColor{"#31363b"}, highlightColor, 0.03);
0435         complementaryAlternateBackgroundColor = complementaryBackgroundColor.darker(120);
0436         complementaryHoverColor = complementaryBackgroundColor.lighter(120);
0437         complementaryFocusColor = highlightColor;
0438 
0439         headerTextColor = textColor;
0440         headerBackgroundColor = cu.tintWithAlpha(LightColor::headerBackgroundColor, highlightColor, 0.04);
0441         headerAlternateBackgroundColor = cu.tintWithAlpha(LightColor::headerAlternateBackgroundColor, highlightColor, 0.02);
0442         headerHoverColor = LightColor::hoverColor;
0443         headerFocusColor = highlightColor;
0444 
0445         linkColor = QColor{"#21b9ff"};
0446         linkBackgroundColor = QColor{"#21b9ff"};
0447         visitedLinkColor = QColor{"#ff17d4"};
0448         visitedLinkBackgroundColor = QColor{"#ff17d4"};
0449 
0450         negativeTextColor = QColor{"#dac7cb"};
0451         negativeBackgroundColor = QColor{"#DA4453"};
0452         neutralTextColor = QColor{"#333"};
0453         neutralBackgroundColor = QColor{"#F67400"};
0454         positiveTextColor = QColor{"#333"};
0455         positiveBackgroundColor = QColor{"#27AE60"};
0456 
0457         tooltipTextColor = QColor{"#fafafa"};
0458         tooltipBackgroundColor = QColor{"#333"};
0459         tooltipAlternateBackgroundColor = tooltipBackgroundColor.darker();
0460         tooltipHoverColor = QColor{"#000"};
0461         tooltipFocusColor = QColor{"#000"};
0462     }
0463 
0464     void BasicThemeDefinition::setAdaptiveColors()
0465     {
0466         ColorUtils cu;
0467 
0468         textColor = m_imgColors->foreground();
0469         disabledTextColor = textColor.lighter(120);
0470 
0471         highlightColor = m_imgColors->highlight();
0472 
0473         const auto isDark = m_imgColors->paletteBrightness() == ColorUtils::Dark;
0474         const auto bgColor = cu.tintWithAlpha(isDark ? DarkColor::backgroundColor : LightColor::backgroundColor, m_imgColors->background(), 0.1);
0475        const auto btnColor =  cu.tintWithAlpha(isDark ? DarkColor::buttonBackgroundColor : LightColor::buttonBackgroundColor, highlightColor, 0.06);
0476 
0477         highlightedTextColor = cu.brightnessForColor(highlightColor) ==  ColorUtils::Dark ? m_imgColors->closestToWhite() : m_imgColors->closestToBlack();
0478 //         backgroundColor = cu.tintWithAlpha(m_imgColors->background(), bgColor, 0.8);
0479         backgroundColor =  cu.tintWithAlpha(bgColor, highlightColor, 0.03);
0480         activeBackgroundColor = highlightColor;
0481         alternateBackgroundColor = cu.tintWithAlpha(isDark ? DarkColor::alternateBackgroundColor : LightColor::alternateBackgroundColor, highlightColor, 0.03);
0482         hoverColor =  cu.tintWithAlpha(isDark ? DarkColor::hoverColor : LightColor::hoverColor, highlightColor, 0.02);
0483 
0484         focusColor = highlightColor;
0485 
0486         activeTextColor = highlightColor;
0487 
0488         buttonTextColor = textColor;
0489         buttonBackgroundColor = btnColor;
0490         buttonAlternateBackgroundColor = cu.tintWithAlpha(isDark ? DarkColor::buttonBackgroundColor : LightColor::buttonBackgroundColor, highlightColor, 0.03);
0491         buttonHoverColor = cu.tintWithAlpha(isDark ? DarkColor::buttonHoverColor : LightColor::buttonHoverColor, highlightColor, 0.03);
0492         buttonFocusColor = highlightColor;
0493 
0494         viewTextColor = textColor;
0495         viewBackgroundColor = cu.tintWithAlpha(isDark ? DarkColor::viewBackgroundColor : LightColor::viewBackgroundColor, highlightColor, 0.07);
0496         viewAlternateBackgroundColor =  cu.tintWithAlpha(isDark ? DarkColor::viewAlternateBackgroundColor : LightColor::viewAlternateBackgroundColor, highlightColor, 0.03);
0497         viewHoverColor = cu.tintWithAlpha(isDark ? DarkColor::viewHoverColor : LightColor::viewHoverColor, highlightColor, 0.03);
0498         viewFocusColor = highlightColor;
0499 
0500         selectionTextColor = QColor{"#fcfcfc"};
0501         selectionBackgroundColor = highlightColor;
0502         selectionAlternateBackgroundColor = selectionBackgroundColor.darker();
0503         selectionHoverColor = selectionBackgroundColor.lighter();
0504         selectionFocusColor = highlightColor;
0505 
0506         complementaryTextColor = QColor{"#eff0f1"};
0507         complementaryBackgroundColor = cu.tintWithAlpha(QColor{"#31363b"}, highlightColor, 0.03);
0508         complementaryAlternateBackgroundColor = complementaryBackgroundColor.darker();
0509         complementaryHoverColor = complementaryBackgroundColor.lighter();
0510         complementaryFocusColor = highlightColor;
0511 
0512         headerTextColor = textColor;
0513         headerBackgroundColor = cu.tintWithAlpha(bgColor, highlightColor, 0.05);
0514         headerAlternateBackgroundColor = headerBackgroundColor.darker();
0515         headerHoverColor = headerBackgroundColor.lighter();
0516         headerFocusColor = highlightColor;
0517 
0518         linkColor = QColor{"#2980B9"};
0519         linkBackgroundColor = QColor{"#2980B9"};
0520         visitedLinkColor = QColor{"#7F8C8D"};
0521         visitedLinkBackgroundColor = QColor{"#2196F3"};
0522 
0523         negativeTextColor = QColor{"#dac7cb"};
0524         negativeBackgroundColor = QColor{"#DA4453"};
0525         neutralTextColor = QColor{"#333"};
0526         neutralBackgroundColor = QColor{"#F67400"};
0527         positiveTextColor = QColor{"#333"};
0528         positiveBackgroundColor = QColor{"#27AE60"};
0529 
0530         tooltipTextColor = QColor{"#fafafa"};
0531         tooltipBackgroundColor = QColor{"#333"};
0532         tooltipAlternateBackgroundColor = tooltipBackgroundColor.darker();
0533         tooltipHoverColor = QColor{"#000"};
0534         tooltipFocusColor = QColor{"#000"};
0535     }
0536 
0537     void BasicThemeDefinition::syncToQml(PlatformTheme *object)
0538     {
0539         auto item = qobject_cast<QQuickItem *>(object->parent());
0540         if (item && qmlAttachedPropertiesObject<PlatformTheme>(item, false) == object) {
0541             Q_EMIT sync(item);
0542         }
0543     }
0544 
0545     BasicThemeInstance::BasicThemeInstance(QObject *parent)
0546     : QObject(parent)
0547     {
0548     }
0549 
0550     BasicThemeDefinition &BasicThemeInstance::themeDefinition(QQmlEngine *engine)
0551     {
0552         if (m_themeDefinition) {
0553             return *m_themeDefinition;
0554         }
0555 
0556         m_themeDefinition = std::make_unique<BasicThemeDefinition>();
0557 
0558         connect(m_themeDefinition.get(), &BasicThemeDefinition::changed, this, &BasicThemeInstance::onDefinitionChanged);
0559 
0560         return *m_themeDefinition;
0561     }
0562 
0563     void BasicThemeInstance::onDefinitionChanged()
0564     {
0565         for (auto watcher : std::as_const(watchers))
0566         {
0567             watcher->sync();
0568         }
0569     }
0570 
0571     Q_GLOBAL_STATIC(BasicThemeInstance, basicThemeInstance)
0572 
0573     BasicTheme::BasicTheme(QObject *parent)
0574     : PlatformTheme(parent)
0575     {
0576         basicThemeInstance()->watchers.append(this);
0577 
0578         sync();
0579     }
0580 
0581     BasicTheme::~BasicTheme()
0582     {
0583         basicThemeInstance()->watchers.removeOne(this);
0584     }
0585 
0586     void BasicTheme::sync()
0587     {
0588         auto &definition = basicThemeInstance()->themeDefinition(qmlEngine(parent()));
0589 
0590         switch (colorSet()) {
0591             case BasicTheme::Button:
0592                 setTextColor(tint(definition.buttonTextColor));
0593                 setBackgroundColor(tint(definition.buttonBackgroundColor));
0594                 setAlternateBackgroundColor(tint(definition.buttonAlternateBackgroundColor));
0595                 setHoverColor(tint(definition.buttonHoverColor));
0596                 setFocusColor(tint(definition.buttonFocusColor));
0597                 break;
0598             case BasicTheme::View:
0599                 setTextColor(tint(definition.viewTextColor));
0600                 setBackgroundColor(tint(definition.viewBackgroundColor));
0601                 setAlternateBackgroundColor(tint(definition.viewAlternateBackgroundColor));
0602                 setHoverColor(tint(definition.viewHoverColor));
0603                 setFocusColor(tint(definition.viewFocusColor));
0604                 break;
0605             case BasicTheme::Selection:
0606                 setTextColor(tint(definition.selectionTextColor));
0607                 setBackgroundColor(tint(definition.selectionBackgroundColor));
0608                 setAlternateBackgroundColor(tint(definition.selectionAlternateBackgroundColor));
0609                 setHoverColor(tint(definition.selectionHoverColor));
0610                 setFocusColor(tint(definition.selectionFocusColor));
0611                 break;
0612             case BasicTheme::Tooltip:
0613                 setTextColor(tint(definition.tooltipTextColor));
0614                 setBackgroundColor(tint(definition.tooltipBackgroundColor));
0615                 setAlternateBackgroundColor(tint(definition.tooltipAlternateBackgroundColor));
0616                 setHoverColor(tint(definition.tooltipHoverColor));
0617                 setFocusColor(tint(definition.tooltipFocusColor));
0618                 break;
0619             case BasicTheme::Complementary:
0620                 setTextColor(tint(definition.complementaryTextColor));
0621                 setBackgroundColor(tint(definition.complementaryBackgroundColor));
0622                 setAlternateBackgroundColor(tint(definition.complementaryAlternateBackgroundColor));
0623                 setHoverColor(tint(definition.complementaryHoverColor));
0624                 setFocusColor(tint(definition.complementaryFocusColor));
0625                 break;
0626             case BasicTheme::Header:
0627                 setTextColor(tint(definition.headerTextColor));
0628                 setBackgroundColor(tint(definition.headerBackgroundColor));
0629                 setAlternateBackgroundColor(tint(definition.headerAlternateBackgroundColor));
0630                 setHoverColor(tint(definition.headerHoverColor));
0631                 setFocusColor(tint(definition.headerFocusColor));
0632                 break;
0633             case BasicTheme::Window:
0634             default:
0635                 setTextColor(tint(definition.textColor));
0636                 setBackgroundColor(tint(definition.backgroundColor));
0637                 setAlternateBackgroundColor(tint(definition.alternateBackgroundColor));
0638                 setHoverColor(tint(definition.hoverColor));
0639                 setFocusColor(tint(definition.focusColor));
0640                 break;
0641         }
0642 
0643         setDisabledTextColor(tint(definition.disabledTextColor));
0644         setHighlightColor(tint(definition.highlightColor));
0645         setHighlightedTextColor(tint(definition.highlightedTextColor));
0646         setActiveTextColor(tint(definition.activeTextColor));
0647         setActiveBackgroundColor(tint(definition.activeBackgroundColor));
0648         setLinkColor(tint(definition.linkColor));
0649         setLinkBackgroundColor(tint(definition.linkBackgroundColor));
0650         setVisitedLinkColor(tint(definition.visitedLinkColor));
0651         setVisitedLinkBackgroundColor(tint(definition.visitedLinkBackgroundColor));
0652         setNegativeTextColor(tint(definition.negativeTextColor));
0653         setNegativeBackgroundColor(tint(definition.negativeBackgroundColor));
0654         setNeutralTextColor(tint(definition.neutralTextColor));
0655         setNeutralBackgroundColor(tint(definition.neutralBackgroundColor));
0656         setPositiveTextColor(tint(definition.positiveTextColor));
0657         setPositiveBackgroundColor(tint(definition.positiveBackgroundColor));
0658     }
0659 
0660     bool BasicTheme::event(QEvent *event)
0661     {
0662         if (event->type() == PlatformThemeEvents::DataChangedEvent::type) {
0663             sync();
0664         }
0665 
0666         if (event->type() == PlatformThemeEvents::ColorSetChangedEvent::type) {
0667             sync();
0668         }
0669 
0670         if (event->type() == PlatformThemeEvents::ColorGroupChangedEvent::type) {
0671             sync();
0672         }
0673 
0674         if (event->type() == PlatformThemeEvents::ColorChangedEvent::type) {
0675             basicThemeInstance()->themeDefinition(qmlEngine(parent())).syncToQml(this);
0676         }
0677 
0678         if (event->type() == PlatformThemeEvents::FontChangedEvent::type) {
0679             basicThemeInstance()->themeDefinition(qmlEngine(parent())).syncToQml(this);
0680         }
0681 
0682         return PlatformTheme::event(event);
0683     }
0684 
0685     QColor BasicTheme::tint(const QColor &color)
0686     {
0687         switch (colorGroup()) {
0688             case PlatformTheme::Inactive:
0689                 return QColor::fromHsvF(color.hueF(), color.saturationF() * 0.5, color.valueF());
0690             case PlatformTheme::Disabled:
0691                 return QColor::fromHsvF(color.hueF(), color.saturationF() * 0.5, color.valueF() * 0.8);
0692             default:
0693                 return color;
0694         }
0695     }
0696 }