File indexing completed on 2024-04-14 14:18:47

0001 /*
0002     This file is part of the KDE project
0003     SPDX-FileCopyrightText: 2007 Matthew Woehlke <mw_triad@users.sourceforge.net>
0004 
0005     SPDX-License-Identifier: LGPL-2.0-or-later
0006 */
0007 
0008 #ifndef KCOLORSCHEME_H
0009 #define KCOLORSCHEME_H
0010 
0011 #include <KSharedConfig>
0012 #include <kconfigwidgets_export.h>
0013 
0014 #include <QExplicitlySharedDataPointer>
0015 
0016 #include <QPalette>
0017 
0018 class QColor;
0019 class QBrush;
0020 
0021 class KColorSchemePrivate;
0022 
0023 /**
0024  * @class KColorScheme kcolorscheme.h KColorScheme
0025  *
0026  * A set of methods used to work with colors.
0027  *
0028  * KColorScheme currently provides access to the system color palette that the
0029  * user has selected (in the future, it is expected to do more).  It greatly
0030  * expands on QPalette by providing five distinct "sets" with several color
0031  * choices each, covering background, foreground, and decoration colors.
0032  *
0033  * A KColorScheme instance represents colors corresponding to a "set", where a
0034  * set consists of those colors used to draw a particular type of element, such
0035  * as a menu, button, view, selected text, or tooltip. Each set has a distinct
0036  * set of colors, so you should always use the correct set for drawing and
0037  * never assume that a particular foreground for one set is the same as the
0038  * foreground for any other set. Individual colors may be quickly referenced by
0039  * creating an anonymous instance and invoking a lookup member.
0040  *
0041  * @note
0042  * The color palettes for the various states of a widget (active, inactive,
0043  * disabled) may be wildly different.  Therefore, it is important to take the
0044  * state into account. This is why the KColorScheme constructor requires a
0045  * QPalette::ColorGroup as an argument.
0046  *
0047  * To facilitate working with potentially-varying states, two convenience API's
0048  * are provided. These are KColorScheme::adjustBackground and its sister
0049  * KColorScheme::adjustForeground, and the helper class ::KStatefulBrush.
0050  *
0051  * @see KColorScheme::ColorSet, KColorScheme::ForegroundRole,
0052  * KColorScheme::BackgroundRole, KColorScheme::DecorationRole,
0053  * KColorScheme::ShadeRole
0054  */
0055 class KCONFIGWIDGETS_EXPORT KColorScheme
0056 {
0057 public:
0058     /**
0059      * This enumeration describes the color set for which a color is being
0060      * selected.
0061      *
0062      * Color sets define a color "environment", suitable for drawing all parts
0063      * of a given region. Colors from different sets should not be combined.
0064      */
0065     enum ColorSet {
0066         /**
0067          * Views; for example, frames, input fields, etc.
0068          *
0069          * If it contains things that can be selected, it is probably a View.
0070          */
0071         View,
0072         /**
0073          * Non-editable window elements; for example, menus.
0074          *
0075          * If it isn't a Button, View, or Tooltip, it is probably a Window.
0076          */
0077         Window,
0078         /**
0079          * Buttons and button-like controls.
0080          *
0081          * In addition to buttons, "button-like" controls such as non-editable
0082          * dropdowns, scrollbar sliders, slider handles, etc. should also use
0083          * this role.
0084          */
0085         Button,
0086         /**
0087          * Selected items in views.
0088          *
0089          * Note that unfocused or disabled selections should use the Window
0090          * role. This makes it more obvious to the user that the view
0091          * containing the selection does not have input focus.
0092          */
0093         Selection,
0094         /**
0095          * Tooltips.
0096          *
0097          * The tooltip set can often be substituted for the view
0098          * set when editing is not possible, but the Window set is deemed
0099          * inappropriate. "What's This" help is an excellent example, another
0100          * might be pop-up notifications (depending on taste).
0101          */
0102         Tooltip,
0103         /**
0104          * Complementary areas.
0105          *
0106          * Some applications want some areas to have a different color scheme.
0107          * Usually dark areas over a light theme. For instance the fullscreen UI
0108          * of a picture viewer, or the logout/lock screen of the plasma workspace
0109          * ask for a dark color scheme even on light themes.
0110          * @since 5.19
0111          */
0112         Complementary,
0113         /**
0114          * Colors for header areas that should be used both by the top toolbar and the titlebar.
0115          * @since 5.69
0116          */
0117         Header,
0118         /**
0119          * Number of color sets.
0120          * Note: don't use this
0121          * @since 5.65
0122          */
0123         NColorSets,
0124     };
0125 
0126     /**
0127      * This enumeration describes the background color being selected from the
0128      * given set.
0129      *
0130      * Background colors are suitable for drawing under text, and should never
0131      * be used to draw text. In combination with one of the overloads of
0132      * KColorScheme::shade, they may be used to generate colors for drawing
0133      * frames, bevels, and similar decorations.
0134      */
0135     enum BackgroundRole {
0136         /**
0137          * Normal background.
0138          */
0139         NormalBackground,
0140         /**
0141          * Alternate background; for example, for use in lists.
0142          *
0143          * This color may be the same as BackgroundNormal, especially in sets
0144          * other than View and Window.
0145          */
0146         AlternateBackground,
0147         /**
0148          * Third color; for example, items which are new, active, requesting
0149          * attention, etc.
0150          *
0151          * Alerting the user that a certain field must be filled out would be a
0152          * good usage (although NegativeBackground could be used to the same
0153          * effect, depending on what you are trying to achieve). Unlike
0154          * ActiveText, this should not be used for mouseover effects.
0155          */
0156         ActiveBackground,
0157         /**
0158          * Fourth color; corresponds to (unvisited) links.
0159          *
0160          * Exactly what this might be used for is somewhat harder to qualify;
0161          * it might be used for bookmarks, as a 'you can click here' indicator,
0162          * or to highlight recent content (i.e. in a most-recently-accessed
0163          * list).
0164          */
0165         LinkBackground,
0166         /**
0167          * Fifth color; corresponds to visited links.
0168          *
0169          * This can also be used to indicate "not recent" content, especially
0170          * when a color is needed to denote content which is "old" or
0171          * "archival".
0172          */
0173         VisitedBackground,
0174         /**
0175          * Sixth color; for example, errors, untrusted content, etc.
0176          */
0177         NegativeBackground,
0178         /**
0179          * Seventh color; for example, warnings, secure/encrypted content.
0180          */
0181         NeutralBackground,
0182         /**
0183          * Eighth color; for example, success messages, trusted content.
0184          */
0185         PositiveBackground,
0186         /**
0187          * Number of background roles.
0188          * @since 5.65
0189          */
0190         NBackgroundRoles,
0191     };
0192 
0193     /**
0194      * This enumeration describes the foreground color being selected from the
0195      * given set.
0196      *
0197      * Foreground colors are suitable for drawing text or glyphs (such as the
0198      * symbols on window decoration buttons, assuming a suitable background
0199      * brush is used), and should never be used to draw backgrounds.
0200      *
0201      * For window decorations, the following is suggested, but not set in
0202      * stone:
0203      * @li Maximize - PositiveText
0204      * @li Minimize - NeutralText
0205      * @li Close - NegativeText
0206      * @li WhatsThis - LinkText
0207      * @li Sticky - ActiveText
0208      */
0209     enum ForegroundRole {
0210         /**
0211          * Normal foreground.
0212          */
0213         NormalText,
0214         /**
0215          * Second color; for example, comments, items which are old, inactive
0216          * or disabled. Generally used for things that are meant to be "less
0217          * important". InactiveText is not the same role as NormalText in the
0218          * inactive state.
0219          */
0220         InactiveText,
0221         /**
0222          * Third color; for example items which are new, active, requesting
0223          * attention, etc. May be used as a hover color for clickable items.
0224          */
0225         ActiveText,
0226         /**
0227          * Fourth color; use for (unvisited) links. May also be used for other
0228          * clickable items or content that indicates relationships, items that
0229          * indicate somewhere the user can visit, etc.
0230          */
0231         LinkText,
0232         /**
0233          * Fifth color; used for (visited) links. As with LinkText, may be used
0234          * for items that have already been "visited" or accessed. May also be
0235          * used to indicate "historical" (i.e. "old") items or information,
0236          * especially if InactiveText is being used in the same context to
0237          * express something different.
0238          */
0239         VisitedText,
0240         /**
0241          * Sixth color; for example, errors, untrusted content, deletions,
0242          * etc.
0243          */
0244         NegativeText,
0245         /**
0246          * Seventh color; for example, warnings, secure/encrypted content.
0247          */
0248         NeutralText,
0249         /**
0250          * Eighth color; for example, additions, success messages, trusted
0251          * content.
0252          */
0253         PositiveText,
0254         /**
0255          * Number of foreground roles.
0256          * @since 5.65
0257          */
0258         NForegroundRoles,
0259     };
0260 
0261     /**
0262      * This enumeration describes the decoration color being selected from the
0263      * given set.
0264      *
0265      * Decoration colors are used to draw decorations (such as frames) for
0266      * special purposes. Like color shades, they are neither foreground nor
0267      * background colors. Text should not be painted over a decoration color,
0268      * and decoration colors should not be used to draw text.
0269      */
0270     enum DecorationRole {
0271         /**
0272          * Color used to draw decorations for items which have input focus.
0273          */
0274         FocusColor,
0275         /**
0276          * Color used to draw decorations for items which will be activated by
0277          * clicking.
0278          */
0279         HoverColor,
0280         /**
0281          * Number of decoration roles.
0282          * @since 5.65
0283          */
0284         NDecorationRoles,
0285     };
0286 
0287     /**
0288      * This enumeration describes the color shade being selected from the given
0289      * set.
0290      *
0291      * Color shades are used to draw "3d" elements, such as frames and bevels.
0292      * They are neither foreground nor background colors. Text should not be
0293      * painted over a shade, and shades should not be used to draw text.
0294      */
0295     enum ShadeRole {
0296         /**
0297          * The light color is lighter than dark() or shadow() and contrasts
0298          * with the base color.
0299          */
0300         LightShade,
0301         /**
0302          * The midlight color is in between base() and light().
0303          */
0304         MidlightShade,
0305         /**
0306          * The mid color is in between base() and dark().
0307          */
0308         MidShade,
0309         /**
0310          * The dark color is in between mid() and shadow().
0311          */
0312         DarkShade,
0313         /**
0314          * The shadow color is darker than light() or midlight() and contrasts
0315          * the base color.
0316          */
0317         ShadowShade,
0318         /**
0319          * Number of shade roles.
0320          * @since 5.65
0321          */
0322         NShadeRoles,
0323     };
0324 
0325     /** Destructor */
0326     virtual ~KColorScheme(); // TODO KF6: remove virtual
0327 
0328     KColorScheme(const KColorScheme &);
0329     KColorScheme &operator=(const KColorScheme &);
0330     KColorScheme(KColorScheme &&);
0331     KColorScheme &operator=(KColorScheme &&);
0332 
0333     /**
0334      * Construct a palette from given color set and state. Colors are taken
0335      * from the given KConfig. If null, the application's color scheme is used
0336      *  (either the system default or one set by KColorSchemeManager).
0337      *
0338      * @note KColorScheme provides direct access to the color scheme for users
0339      * that deal directly with widget states. Unless you are a low-level user
0340      * or have a legitimate reason to only care about a fixed, limited number
0341      * of states (e.g. windows that cannot be inactive), consider using a
0342      * ::KStatefulBrush instead.
0343      */
0344     explicit KColorScheme(QPalette::ColorGroup = QPalette::Normal, ColorSet = View, KSharedConfigPtr = KSharedConfigPtr());
0345 
0346     /**
0347      * Retrieve the requested background brush.
0348      */
0349     QBrush background(BackgroundRole = NormalBackground) const;
0350 
0351     /**
0352      * Retrieve the requested foreground brush.
0353      */
0354     QBrush foreground(ForegroundRole = NormalText) const;
0355 
0356     /**
0357      * Retrieve the requested decoration brush.
0358      */
0359     QBrush decoration(DecorationRole) const;
0360 
0361     /**
0362      * Retrieve the requested shade color, using
0363      * KColorScheme::background(KColorScheme::NormalBackground)
0364      * as the base color and the contrast setting from the KConfig used to
0365      * create this KColorScheme instance.
0366      *
0367      * @note Shades are chosen such that all shades would contrast with the
0368      * base color. This means that if base is very dark, the 'dark' shades will
0369      * be lighter than the base color, with midlight() == shadow().
0370      * Conversely, if the base color is very light, the 'light' shades will be
0371      * darker than the base color, with light() == mid().
0372      */
0373     QColor shade(ShadeRole) const;
0374 
0375 #if KCONFIGWIDGETS_ENABLE_DEPRECATED_SINCE(5, 93)
0376     /**
0377      * Returns the contrast for borders.
0378      * @return the contrast (between 0 for minimum and 10 for maximum
0379      *         contrast)
0380      * @deprecated since 5.93, use <tt>contrastF() * 10</tt>
0381      */
0382     KCONFIGWIDGETS_DEPRECATED_VERSION(5, 93, "Use contrastF() * 10")
0383     static int contrast();
0384 #endif
0385 
0386     /**
0387      * Returns the contrast for borders as a floating point value.
0388      * @param config pointer to the config from which to read the contrast
0389      * setting. If null, the application's color scheme will be used
0390      *   (either the system default or one set by KColorSchemeManager).
0391      * @return the contrast (between 0.0 for minimum and 1.0 for maximum
0392      *         contrast)
0393      */
0394     static qreal contrastF(const KSharedConfigPtr &config = KSharedConfigPtr());
0395 
0396     /**
0397      * Retrieve the requested shade color, using the specified color as the
0398      * base color and the application's contrast setting.
0399      *
0400      * @note Shades are chosen such that all shades would contrast with the
0401      * base color. This means that if base is very dark, the 'dark' shades will
0402      * be lighter than the base color, with midlight() == shadow().
0403      * Conversely, if the base color is very light, the 'light' shades will be
0404      * darker than the base color, with light() == mid().
0405      */
0406     static QColor shade(const QColor &, ShadeRole);
0407 
0408     /**
0409      * Retrieve the requested shade color, using the specified color as the
0410      * base color and the specified contrast.
0411      *
0412      * @param contrast Amount roughly specifying the contrast by which to
0413      * adjust the base color, between -1.0 and 1.0 (values between 0.0 and 1.0
0414      * correspond to the value from KColorScheme::contrastF)
0415      * @param chromaAdjust (optional) Amount by which to adjust the chroma of
0416      * the shade (1.0 means no adjustment)
0417      *
0418      * @note Shades are chosen such that all shades would contrast with the
0419      * base color. This means that if base is very dark, the 'dark' shades will
0420      * be lighter than the base color, with midlight() == shadow().
0421      * Conversely, if the base color is very light, the 'light' shades will be
0422      * darker than the base color, with light() == mid().
0423      *
0424      * @see KColorUtils::shade
0425      */
0426     static QColor shade(const QColor &, ShadeRole, qreal contrast, qreal chromaAdjust = 0.0);
0427 
0428     /**
0429      * Adjust a QPalette by replacing the specified QPalette::ColorRole with
0430      * the requested background color for all states. Using this method is
0431      * safer than replacing individual states, as it insulates you against
0432      * changes in QPalette::ColorGroup.
0433      *
0434      * @note Although it is possible to replace a foreground color using this
0435      * method, it's bad usability to do so. Just say "no".
0436      */
0437     static void adjustBackground(QPalette &,
0438                                  BackgroundRole newRole = NormalBackground,
0439                                  QPalette::ColorRole color = QPalette::Base,
0440                                  ColorSet set = View,
0441                                  KSharedConfigPtr = KSharedConfigPtr());
0442 
0443     /**
0444      * Adjust a QPalette by replacing the specified QPalette::ColorRole with
0445      * the requested foreground color for all states. Using this method is
0446      * safer than replacing individual states, as it insulates you against
0447      * changes in QPalette::ColorGroup.
0448      *
0449      * @note Although it is possible to replace a background color using this
0450      * method, it's bad usability to do so. Just say "no".
0451      */
0452     static void adjustForeground(QPalette &,
0453                                  ForegroundRole newRole = NormalText,
0454                                  QPalette::ColorRole color = QPalette::Text,
0455                                  ColorSet set = View,
0456                                  KSharedConfigPtr = KSharedConfigPtr());
0457 
0458     /**
0459      * Used to obtain the QPalette that will be used to set the application
0460      * palette from KDE Platform theme.
0461      *
0462      * @param config KConfig from which to load the colors
0463      *
0464      * @returns the QPalette
0465      *
0466      * @since 5.0
0467      */
0468     static QPalette createApplicationPalette(const KSharedConfigPtr &config);
0469 
0470     /**
0471      * Used to check if the color scheme has a given set.
0472      *
0473      * @param config KConfig from which to load the colors
0474      *
0475      * @param set The color set to check for.
0476      *
0477      * @returns whether the color scheme has a given color set
0478      *
0479      * @since 5.75
0480      */
0481     static bool isColorSetSupported(const KSharedConfigPtr &config, KColorScheme::ColorSet set);
0482 
0483     /**
0484      * @since 5.92
0485      */
0486     bool operator==(const KColorScheme &other) const;
0487 
0488 private:
0489     QExplicitlySharedDataPointer<KColorSchemePrivate> d;
0490 };
0491 
0492 Q_DECLARE_METATYPE(KColorScheme)
0493 
0494 #if KCONFIGWIDGETS_ENABLE_DEPRECATED_SINCE(5, 93)
0495 // Include for compatibility because class was defined here before
0496 #include "kstatefulbrush.h"
0497 #endif
0498 
0499 #endif // KCOLORSCHEME_H