File indexing completed on 2024-05-12 15:42:38

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