File indexing completed on 2024-05-05 04:47:00

0001 /*
0002  *  SPDX-FileCopyrightText: 2017 by Marco Martin <mart@kde.org>
0003  *
0004  *  SPDX-License-Identifier: LGPL-2.0-or-later
0005  */
0006 
0007 #ifndef PLATFORMTHEME_H
0008 #define PLATFORMTHEME_H
0009 
0010 #include <QColor>
0011 #include <QIcon>
0012 #include <QObject>
0013 #include <QPalette>
0014 #include <QQuickItem>
0015 
0016 //#include "kirigami2_export.h"
0017 
0018 namespace Maui
0019 {
0020 class PlatformThemeData;
0021 class PlatformThemePrivate;
0022 
0023 /**
0024  * @class PlatformTheme platformtheme.h <Maui/PlatformTheme>
0025  *
0026  * This class is the base for color management in Maui,
0027  * different platforms can reimplement this class to integrate with
0028  * system platform colors of a given platform
0029  */
0030 class PlatformTheme : public QObject
0031 {
0032     Q_OBJECT
0033     QML_NAMED_ELEMENT(Theme)
0034     QML_ATTACHED(Maui::PlatformTheme)
0035     QML_UNCREATABLE("Attached Property")
0036     /**
0037      * This enumeration describes the color set for which a color is being selected.
0038      *
0039      * Color sets define a color "environment", suitable for drawing all parts of a
0040      * given region. Colors from different sets should not be combined.
0041      */
0042     Q_PROPERTY(ColorSet colorSet READ colorSet WRITE setColorSet NOTIFY colorSetChanged)
0043 
0044     /**
0045      * This enumeration describes the color group used to generate the colors.
0046      * The enum value is based upon QPalette::CpolorGroup and has the same values.
0047      * It's redefined here in order to make it work with QML
0048      * @since 4.43
0049      */
0050     Q_PROPERTY(ColorGroup colorGroup READ colorGroup WRITE setColorGroup NOTIFY colorGroupChanged)
0051 
0052     /**
0053      * If true, the colorSet will be inherited from the colorset of a theme of one
0054      * of the ancestor items
0055      * default: true
0056      */
0057     Q_PROPERTY(bool inherit READ inherit WRITE setInherit NOTIFY inheritChanged)
0058 
0059     // foreground colors
0060     /**
0061      * Color for normal foregrounds, usually text, but not limited to it,
0062      * anything that should be painted with a clear contrast should use this color
0063      */
0064     Q_PROPERTY(QColor textColor READ textColor WRITE setCustomTextColor RESET setCustomTextColor NOTIFY colorsChanged)
0065 
0066     /**
0067      * Foreground color for disabled areas, usually a mid-gray
0068      */
0069     Q_PROPERTY(QColor disabledTextColor READ disabledTextColor WRITE setCustomDisabledTextColor RESET setCustomDisabledTextColor NOTIFY colorsChanged)
0070 
0071     /**
0072      * Color for text that has been highlighted, often is a light color while normal text is dark
0073      */
0074     Q_PROPERTY(
0075         QColor highlightedTextColor READ highlightedTextColor WRITE setCustomHighlightedTextColor RESET setCustomHighlightedTextColor NOTIFY colorsChanged)
0076 
0077     /**
0078      * Foreground for areas that are active or requesting attention
0079      */
0080     Q_PROPERTY(QColor activeTextColor READ activeTextColor WRITE setCustomActiveTextColor RESET setCustomActiveTextColor NOTIFY colorsChanged)
0081 
0082     /**
0083      * Color for links
0084      */
0085     Q_PROPERTY(QColor linkColor READ linkColor WRITE setCustomLinkColor RESET setCustomLinkColor NOTIFY colorsChanged)
0086 
0087     /**
0088      * Color for visited links, usually a bit darker than linkColor
0089      */
0090     Q_PROPERTY(QColor visitedLinkColor READ visitedLinkColor WRITE setCustomVisitedLinkColor RESET setCustomVisitedLinkColor NOTIFY colorsChanged)
0091 
0092     /**
0093      * Foreground color for negative areas, such as critical error text
0094      */
0095     Q_PROPERTY(QColor negativeTextColor READ negativeTextColor WRITE setCustomNegativeTextColor RESET setCustomNegativeTextColor NOTIFY colorsChanged)
0096 
0097     /**
0098      * Foreground color for neutral areas, such as warning texts (but not critical)
0099      */
0100     Q_PROPERTY(QColor neutralTextColor READ neutralTextColor WRITE setCustomNeutralTextColor RESET setCustomNeutralTextColor NOTIFY colorsChanged)
0101 
0102     /**
0103      * Success messages, trusted content
0104      */
0105     Q_PROPERTY(QColor positiveTextColor READ positiveTextColor WRITE setCustomPositiveTextColor RESET setCustomPositiveTextColor NOTIFY colorsChanged)
0106 
0107     // background colors
0108     /**
0109      * The generic background color
0110      */
0111     Q_PROPERTY(QColor backgroundColor READ backgroundColor WRITE setCustomBackgroundColor RESET setCustomBackgroundColor NOTIFY colorsChanged)
0112 
0113     /**
0114      * The generic background color
0115      * Alternate background; for example, for use in lists.
0116      * This color may be the same as BackgroundNormal,
0117      * especially in sets other than View and Window.
0118      */
0119     Q_PROPERTY(QColor alternateBackgroundColor READ alternateBackgroundColor WRITE setCustomAlternateBackgroundColor RESET setCustomAlternateBackgroundColor
0120                    NOTIFY colorsChanged)
0121 
0122     /**
0123      * The background color for selected areas
0124      */
0125     Q_PROPERTY(QColor highlightColor READ highlightColor WRITE setCustomHighlightColor RESET setCustomHighlightColor NOTIFY colorsChanged)
0126 
0127     /**
0128      * Background for areas that are active or requesting attention
0129      */
0130     Q_PROPERTY(
0131         QColor activeBackgroundColor READ activeBackgroundColor WRITE setCustomActiveBackgroundColor RESET setCustomActiveBackgroundColor NOTIFY colorsChanged)
0132 
0133     /**
0134      * Background color for links
0135      */
0136     Q_PROPERTY(QColor linkBackgroundColor READ linkBackgroundColor WRITE setCustomLinkBackgroundColor RESET setCustomLinkBackgroundColor NOTIFY colorsChanged)
0137 
0138     /**
0139      * Background color for visited links, usually a bit darker than linkBackgroundColor
0140      */
0141     Q_PROPERTY(QColor visitedLinkBackgroundColor READ visitedLinkBackgroundColor WRITE setCustomVisitedLinkBackgroundColor RESET
0142                    setCustomVisitedLinkBackgroundColor NOTIFY colorsChanged)
0143 
0144     /**
0145      * Background color for negative areas, such as critical errors and destructive actions
0146      */
0147     Q_PROPERTY(QColor negativeBackgroundColor READ negativeBackgroundColor WRITE setCustomNegativeBackgroundColor RESET setCustomNegativeBackgroundColor NOTIFY
0148                    colorsChanged)
0149 
0150     /**
0151      * Background color for neutral areas, such as warnings (but not critical)
0152      */
0153     Q_PROPERTY(QColor neutralBackgroundColor READ neutralBackgroundColor WRITE setCustomNeutralBackgroundColor RESET setCustomNeutralBackgroundColor NOTIFY
0154                    colorsChanged)
0155 
0156     /**
0157      * Background color for positive areas, such as success messages and trusted content
0158      */
0159     Q_PROPERTY(QColor positiveBackgroundColor READ positiveBackgroundColor WRITE setCustomPositiveBackgroundColor RESET setCustomPositiveBackgroundColor NOTIFY
0160                    colorsChanged)
0161 
0162     // decoration colors
0163     /**
0164      * A decoration color that indicates active focus
0165      */
0166     Q_PROPERTY(QColor focusColor READ focusColor WRITE setCustomFocusColor RESET setCustomFocusColor NOTIFY colorsChanged)
0167 
0168     /**
0169      * A decoration color that indicates mouse hovering
0170      */
0171     Q_PROPERTY(QColor hoverColor READ hoverColor WRITE setCustomHoverColor RESET setCustomHoverColor NOTIFY colorsChanged)
0172 
0173     // Active palette
0174     Q_PROPERTY(QPalette palette READ palette NOTIFY paletteChanged)
0175 
0176 public:
0177     enum ColorSet {
0178         View = 0, /** Color set for item views, usually the lightest of all */
0179         Window, /** Default Color set for windows and "chrome" areas */
0180         Button, /** Color set used by buttons */
0181         Selection, /** Color set used by selectged areas */
0182         Tooltip, /** Color set used by tooltips */
0183         Complementary, /** Color set meant to be complementary to Window: usually is a dark theme for light themes */
0184         Header, /** Color set to be used by heading areas of applications, such as toolbars */
0185 
0186         ColorSetCount, // Number of items in this enum, this should always be the last item.
0187     };
0188     Q_ENUM(ColorSet)
0189 
0190     enum ColorGroup {
0191         Disabled = QPalette::Disabled,
0192         Active = QPalette::Active,
0193         Inactive = QPalette::Inactive,
0194         Normal = QPalette::Normal,
0195 
0196         ColorGroupCount, // Number of items in this enum, this should always be the last item.
0197     };
0198     Q_ENUM(ColorGroup)
0199 
0200     explicit PlatformTheme(QObject *parent = nullptr);
0201     ~PlatformTheme() override;
0202 
0203     void setColorSet(PlatformTheme::ColorSet);
0204     PlatformTheme::ColorSet colorSet() const;
0205 
0206     void setColorGroup(PlatformTheme::ColorGroup);
0207     PlatformTheme::ColorGroup colorGroup() const;
0208 
0209     bool inherit() const;
0210     void setInherit(bool inherit);
0211 
0212     // foreground colors
0213     QColor textColor() const;
0214     QColor disabledTextColor() const;
0215     QColor highlightedTextColor() const;
0216     QColor activeTextColor() const;
0217     QColor linkColor() const;
0218     QColor visitedLinkColor() const;
0219     QColor negativeTextColor() const;
0220     QColor neutralTextColor() const;
0221     QColor positiveTextColor() const;
0222 
0223     // background colors
0224     QColor backgroundColor() const;
0225     QColor alternateBackgroundColor() const;
0226     QColor highlightColor() const;
0227     QColor activeBackgroundColor() const;
0228     QColor linkBackgroundColor() const;
0229     QColor visitedLinkBackgroundColor() const;
0230     QColor negativeBackgroundColor() const;
0231     QColor neutralBackgroundColor() const;
0232     QColor positiveBackgroundColor() const;
0233 
0234     // decoration colors
0235     QColor focusColor() const;
0236     QColor hoverColor() const;
0237 
0238     // this may is used by the desktop QQC2 to set the styleoption palettes
0239     QPalette palette() const;
0240 
0241     // this will be used by desktopicon to fetch icons with KIconLoader
0242     virtual Q_INVOKABLE QIcon iconFromTheme(const QString &name, const QColor &customColor = Qt::transparent);
0243 
0244     bool supportsIconColoring() const;
0245 
0246     // foreground colors
0247     void setCustomTextColor(const QColor &color = QColor());
0248     void setCustomDisabledTextColor(const QColor &color = QColor());
0249     void setCustomHighlightedTextColor(const QColor &color = QColor());
0250     void setCustomActiveTextColor(const QColor &color = QColor());
0251     void setCustomLinkColor(const QColor &color = QColor());
0252     void setCustomVisitedLinkColor(const QColor &color = QColor());
0253     void setCustomNegativeTextColor(const QColor &color = QColor());
0254     void setCustomNeutralTextColor(const QColor &color = QColor());
0255     void setCustomPositiveTextColor(const QColor &color = QColor());
0256     // background colors
0257     void setCustomBackgroundColor(const QColor &color = QColor());
0258     void setCustomAlternateBackgroundColor(const QColor &color = QColor());
0259     void setCustomHighlightColor(const QColor &color = QColor());
0260     void setCustomActiveBackgroundColor(const QColor &color = QColor());
0261     void setCustomLinkBackgroundColor(const QColor &color = QColor());
0262     void setCustomVisitedLinkBackgroundColor(const QColor &color = QColor());
0263     void setCustomNegativeBackgroundColor(const QColor &color = QColor());
0264     void setCustomNeutralBackgroundColor(const QColor &color = QColor());
0265     void setCustomPositiveBackgroundColor(const QColor &color = QColor());
0266     // decoration colors
0267     void setCustomFocusColor(const QColor &color = QColor());
0268     void setCustomHoverColor(const QColor &color = QColor());
0269 
0270     // QML attached property
0271     static PlatformTheme *qmlAttachedProperties(QObject *object);
0272 
0273 Q_SIGNALS:
0274     // TODO: parameters to signals as this is also a c++ api
0275     void colorsChanged();
0276     void colorSetChanged(Maui::PlatformTheme::ColorSet colorSet);
0277     void colorGroupChanged(Maui::PlatformTheme::ColorGroup colorGroup);
0278     void paletteChanged(const QPalette &pal);
0279     void inheritChanged(bool inherit);
0280 
0281 protected:
0282     // Setters, not accessible from QML but from implementations
0283     void setSupportsIconColoring(bool support);
0284 
0285     // foreground colors
0286     void setTextColor(const QColor &color);
0287     void setDisabledTextColor(const QColor &color);
0288     void setHighlightedTextColor(const QColor &color);
0289     void setActiveTextColor(const QColor &color);
0290     void setLinkColor(const QColor &color);
0291     void setVisitedLinkColor(const QColor &color);
0292     void setNegativeTextColor(const QColor &color);
0293     void setNeutralTextColor(const QColor &color);
0294     void setPositiveTextColor(const QColor &color);
0295 
0296     // background colors
0297     void setBackgroundColor(const QColor &color);
0298     void setAlternateBackgroundColor(const QColor &color);
0299     void setHighlightColor(const QColor &color);
0300     void setActiveBackgroundColor(const QColor &color);
0301     void setLinkBackgroundColor(const QColor &color);
0302     void setVisitedLinkBackgroundColor(const QColor &color);
0303     void setNegativeBackgroundColor(const QColor &color);
0304     void setNeutralBackgroundColor(const QColor &color);
0305     void setPositiveBackgroundColor(const QColor &color);
0306 
0307     // decoration colors
0308     void setFocusColor(const QColor &color);
0309     void setHoverColor(const QColor &color);
0310 
0311     bool event(QEvent *event) override;
0312 
0313 private:
0314     void update();
0315     void updateChildren(QObject *item);
0316     void emitSignals();
0317     void emitColorChanged();
0318     QObject *determineParent(QObject *object);
0319 
0320     PlatformThemePrivate *d;
0321     friend class PlatformThemePrivate;
0322     friend class PlatformThemeData;
0323 };
0324 
0325 namespace PlatformThemeEvents
0326 {
0327 // To avoid the overhead of Qt's signal/slot connections, we use custom events
0328 // to communicate with subclasses. This way, we can indicate what actually
0329 // changed without needing to add new virtual functions to PlatformTheme which
0330 // would break binary compatibility.
0331 //
0332 // To handle these events in your subclass, override QObject::event() and check
0333 // if you receive one of these events, then do what is needed. Finally, make
0334 // sure to call PlatformTheme::event() since that will also do some processing
0335 // of these events.
0336 
0337 template<typename T>
0338 class PropertyChangedEvent : public QEvent
0339 {
0340 public:
0341     PropertyChangedEvent(PlatformTheme *theme, const T &previous, const T &current)
0342         : QEvent(PropertyChangedEvent<T>::type)
0343         , sender(theme)
0344         , oldValue(previous)
0345         , newValue(current)
0346     {
0347     }
0348 
0349     PlatformTheme *sender;
0350     T oldValue;
0351     T newValue;
0352 
0353     static QEvent::Type type;
0354 };
0355 
0356 using DataChangedEvent = PropertyChangedEvent<std::shared_ptr<PlatformThemeData>>;
0357 using ColorSetChangedEvent = PropertyChangedEvent<PlatformTheme::ColorSet>;
0358 using ColorGroupChangedEvent = PropertyChangedEvent<PlatformTheme::ColorGroup>;
0359 using ColorChangedEvent = PropertyChangedEvent<QColor>;
0360 using FontChangedEvent = PropertyChangedEvent<QFont>;
0361 
0362 }
0363 
0364 } // namespace Maui
0365 
0366 // QML_DECLARE_TYPEINFO(Maui::PlatformTheme, QML_HAS_ATTACHED_PROPERTIES)
0367 
0368 #endif // PLATFORMTHEME_H