1/*
2 This file is part of the KDE project
3 SPDX-FileCopyrightText: 2007 Matthew Woehlke <mw_triad@users.sourceforge.net>
4
5 SPDX-License-Identifier: LGPL-2.0-or-later
6*/
7
8#ifndef KCOLORSCHEME_H
9#define KCOLORSCHEME_H
10
11#include <KSharedConfig>
12#include "kcolorscheme_export.h"
13
14#include <QExplicitlySharedDataPointer>
15
16#include <QPalette>
17
18class QColor;
19class QBrush;
20
21class KColorSchemePrivate;
22
23/*!
24 * \class KColorScheme
25 * \inmodule KColorScheme
26 * \brief A set of methods used to work with colors.
27 *
28 * KColorScheme currently provides access to the system color palette that the
29 * user has selected (in the future, it is expected to do more). It greatly
30 * expands on QPalette by providing five distinct "sets" with several color
31 * choices each, covering background, foreground, and decoration colors.
32 *
33 * A KColorScheme instance represents colors corresponding to a "set", where a
34 * set consists of those colors used to draw a particular type of element, such
35 * as a menu, button, view, selected text, or tooltip. Each set has a distinct
36 * set of colors, so you should always use the correct set for drawing and
37 * never assume that a particular foreground for one set is the same as the
38 * foreground for any other set. Individual colors may be quickly referenced by
39 * creating an anonymous instance and invoking a lookup member.
40 *
41 * \note
42 * The color palettes for the various states of a widget (active, inactive,
43 * disabled) may be wildly different. Therefore, it is important to take the
44 * state into account. This is why the KColorScheme constructor requires a
45 * QPalette::ColorGroup as an argument.
46 *
47 * To facilitate working with potentially-varying states, two convenience API's
48 * are provided. These are KColorScheme::adjustBackground and its sister
49 * KColorScheme::adjustForeground, and the helper class KStatefulBrush.
50 *
51 * \sa KColorScheme::ColorSet, KColorScheme::ForegroundRole,
52 * KColorScheme::BackgroundRole, KColorScheme::DecorationRole,
53 * KColorScheme::ShadeRole
54 */
55class KCOLORSCHEME_EXPORT KColorScheme
56{
57public:
58 /*!
59 * \enum KColorScheme::ColorSet
60 *
61 * This enumeration describes the color set for which a color is being
62 * selected.
63 *
64 * Color sets define a color "environment", suitable for drawing all parts
65 * of a given region. Colors from different sets should not be combined.
66 *
67 * \value View Views; for example, frames, input fields, etc.\br\br
68 * If it contains things that can be selected, it is probably a \c View.
69 * \value Window Non-editable window elements; for example, menus.\br\br
70 * If it isn't a \c Button, \c View, or \c Tooltip, it is probably a \c Window.
71 * \value Button Buttons and button-like controls.\br\br
72 * In addition to buttons, "button-like" controls such as non-editable
73 * dropdowns, scrollbar sliders, slider handles, etc. should also use
74 * this role.
75 * \value Selection Selected items in views.\br\br
76 * Note that unfocused or disabled selections should use the \c Window
77 * role. This makes it more obvious to the user that the view
78 * containing the selection does not have input focus.
79 * \value Tooltip Tooltips.\br\br
80 * The tooltip set can often be substituted for the view
81 * set when editing is not possible, but the Window set is deemed
82 * inappropriate. "What's This" help is an excellent example, another
83 * might be pop-up notifications (depending on taste).
84 * \value [since KColorScheme 5.19] Complementary Complementary areas.\br\br
85 * Some applications want some areas to have a different color scheme.
86 * Usually dark areas over a light theme. For instance the fullscreen UI
87 * of a picture viewer, or the logout/lock screen of the plasma workspace
88 * ask for a dark color scheme even on light themes.
89 * \value Header
90 * \omitvalue NColorSets
91 */
92 enum ColorSet {
93 View,
94 Window,
95 Button,
96 Selection,
97 Tooltip,
98 Complementary,
99 Header,
100 NColorSets,
101 };
102
103 /*!
104 * \enum KColorScheme::BackgroundRole
105 *
106 * This enumeration describes the background color being selected from the
107 * given set.
108 *
109 * Background colors are suitable for drawing under text, and should never
110 * be used to draw text. In combination with one of the overloads of
111 * KColorScheme::shade, they may be used to generate colors for drawing
112 * frames, bevels, and similar decorations.
113 *
114 * \value NormalBackground Normal background.
115 * \value AlternateBackground Alternate background; for example, for use in lists.
116 * This color may be the same as \c BackgroundNormal, especially in sets
117 * other than \c View and \c Window.
118 * \value ActiveBackground Third color; for example, items which are new, active, requesting
119 * attention, etc.\br\br
120 * Alerting the user that a certain field must be filled out would be a
121 * good usage (although NegativeBackground could be used to the same
122 * effect, depending on what you are trying to achieve). Unlike
123 * \c ActiveText, this should not be used for mouseover effects.
124 * \value LinkBackground Fourth color; corresponds to (unvisited) links.\br\br
125 * Exactly what this might be used for is somewhat harder to qualify;
126 * it might be used for bookmarks, as a 'you can click here' indicator,
127 * or to highlight recent content (i.e. in a most-recently-accessed
128 * list).
129 * \value VisitedBackground Fifth color; corresponds to visited links.\br\br
130 * This can also be used to indicate "not recent" content, especially
131 * when a color is needed to denote content which is "old" or
132 * "archival".
133 * \value NegativeBackground Sixth color; for example, errors, untrusted content, etc.
134 * \value NeutralBackground Seventh color; for example, warnings, secure/encrypted content.
135 * \value PositiveBackground Eighth color; for example, success messages, trusted content.
136 * \omitvalue NBackgroundRoles
137 */
138 enum BackgroundRole {
139 NormalBackground,
140 AlternateBackground,
141 ActiveBackground,
142 LinkBackground,
143 VisitedBackground,
144 NegativeBackground,
145 NeutralBackground,
146 PositiveBackground,
147 NBackgroundRoles,
148 };
149
150 /*!
151 * \enum KColorScheme::ForegroundRole
152 *
153 * This enumeration describes the foreground color being selected from the
154 * given set.
155 *
156 * Foreground colors are suitable for drawing text or glyphs (such as the
157 * symbols on window decoration buttons, assuming a suitable background
158 * brush is used), and should never be used to draw backgrounds.
159 *
160 * For window decorations, the following is suggested, but not set in
161 * stone:
162 * \list
163 * \li Maximize - \c PositiveText
164 * \li Minimize - \c NeutralText
165 * \li Close - \c NegativeText
166 * \li WhatsThis - \c LinkText
167 * \li Sticky - \c ActiveText
168 * \endlist
169 *
170 * \value NormalText Normal foreground.
171 * \value InactiveText Second color; for example, comments, items which are old, inactive
172 * or disabled.\br\br
173 * Generally used for things that are meant to be "less
174 * important". \c InactiveText is not the same role as NormalText in the
175 * inactive state.
176 * \value ActiveText Third color; for example items which are new, active, requesting
177 * attention, etc.\br\br
178 * May be used as a hover color for clickable items.
179 * \value LinkText Fourth color; use for (unvisited) links.\br\br
180 * May also be used for other
181 * clickable items or content that indicates relationships, items that
182 * indicate somewhere the user can visit, etc.
183 * \value VisitedText Fifth color; used for (visited) links.\br\br
184 * As with \c LinkText, may be used
185 * for items that have already been "visited" or accessed. May also be
186 * used to indicate "historical" (i.e. "old") items or information,
187 * especially if \c InactiveText is being used in the same context to
188 * express something different.
189 * \value NegativeText Sixth color; for example, errors, untrusted content, deletions,
190 * etc.
191 * \value NeutralText Seventh color; for example, warnings, secure/encrypted content.
192 * \value PositiveText Eighth color; for example, additions, success messages, trusted
193 * content.
194 * \omitvalue NForegroundRoles
195 */
196 enum ForegroundRole {
197 NormalText,
198 InactiveText,
199 ActiveText,
200 LinkText,
201 VisitedText,
202 NegativeText,
203 NeutralText,
204 PositiveText,
205 NForegroundRoles,
206 };
207
208 /*!
209 * \enum KColorScheme::DecorationRole
210 *
211 * This enumeration describes the decoration color being selected from the
212 * given set.
213 *
214 * Decoration colors are used to draw decorations (such as frames) for
215 * special purposes. Like color shades, they are neither foreground nor
216 * background colors. Text should not be painted over a decoration color,
217 * and decoration colors should not be used to draw text.
218 *
219 * \value FocusColor Color used to draw decorations for items which have input focus.
220 * \value HoverColor Color used to draw decorations for items which will be activated by
221 * clicking.
222 * \omitvalue NDecorationRoles
223 */
224 enum DecorationRole {
225 FocusColor,
226 HoverColor,
227 NDecorationRoles,
228 };
229
230 /*!
231 * \enum KColorScheme::ShadeRole
232 *
233 * This enumeration describes the color shade being selected from the given
234 * set.
235 *
236 * Color shades are used to draw "3d" elements, such as frames and bevels.
237 * They are neither foreground nor background colors. Text should not be
238 * painted over a shade, and shades should not be used to draw text.
239 *
240 * \value LightShade The light color is lighter than QPalette::dark() or QPalette::shadow() and contrasts
241 * with the base color.
242 * \value MidlightShade The midlight color is in between base() and QPalette::light().
243 * \value MidShade The mid color is in between QPalette::base() and QPalette::dark().
244 * \value DarkShade The dark color is in between QPalette::mid() and QPalette::shadow().
245 * \value ShadowShade The shadow color is darker than QPalette::light() or QPalette::midlight() and contrasts
246 * the base color.
247 * \omitvalue NShadeRoles
248 */
249 enum ShadeRole {
250 LightShade,
251 MidlightShade,
252 MidShade,
253 DarkShade,
254 ShadowShade,
255 NShadeRoles,
256 };
257
258 /*! Destructor */
259 virtual ~KColorScheme(); // TODO KF6: remove virtual
260
261 KColorScheme(const KColorScheme &);
262 KColorScheme &operator=(const KColorScheme &);
263 KColorScheme(KColorScheme &&);
264 KColorScheme &operator=(KColorScheme &&);
265
266 /*!
267 * Construct a palette from given color set and state. Colors are taken
268 * from the given KConfig. If null, the application's color scheme is used
269 * (either the system default or one set by KColorSchemeManager).
270 *
271 * \note KColorScheme provides direct access to the color scheme for users
272 * that deal directly with widget states. Unless you are a low-level user
273 * or have a legitimate reason to only care about a fixed, limited number
274 * of states (e.g. windows that cannot be inactive), consider using a
275 * KStatefulBrush instead.
276 */
277 explicit KColorScheme(QPalette::ColorGroup = QPalette::Normal, ColorSet = View, KSharedConfigPtr = KSharedConfigPtr());
278
279 /*!
280 * Retrieve the requested background brush.
281 */
282 QBrush background(BackgroundRole = NormalBackground) const;
283
284 /*!
285 * Retrieve the requested foreground brush.
286 */
287 QBrush foreground(ForegroundRole = NormalText) const;
288
289 /*!
290 * Retrieve the requested decoration brush.
291 */
292 QBrush decoration(DecorationRole) const;
293
294 /*!
295 * Retrieve the requested shade color, using
296 * KColorScheme::background(KColorScheme::NormalBackground)
297 * as the base color and the contrast setting from the KConfig used to
298 * create this KColorScheme instance.
299 *
300 * \note Shades are chosen such that all shades would contrast with the
301 * base color. This means that if base is very dark, the 'dark' shades will
302 * be lighter than the base color, with QPalette::midlight() == QPalette::shadow().
303 * Conversely, if the base color is very light, the 'light' shades will be
304 * darker than the base color, with QPalette::light() == QPalette::mid().
305 */
306 QColor shade(ShadeRole) const;
307
308 /*!
309 * Returns the contrast for borders as a floating point value.
310 *
311 * \a config pointer to the config from which to read the contrast
312 * setting. If null, the application's color scheme will be used
313 * (either the system default or one set by KColorSchemeManager).
314 *
315 * Returns the contrast (between 0.0 for minimum and 1.0 for maximum
316 * contrast)
317 */
318 static qreal contrastF(const KSharedConfigPtr &config = KSharedConfigPtr());
319
320 /*!
321 * Retrieve the requested shade color, using the specified color as the
322 * base color and the application's contrast setting.
323 *
324 * \note Shades are chosen such that all shades would contrast with the
325 * base color. This means that if base is very dark, the 'dark' shades will
326 * be lighter than the base color, with QPalette::midlight() == QPalette::shadow().
327 * Conversely, if the base color is very light, the 'light' shades will be
328 * darker than the base color, with QPalette::light() == QPalette::mid().
329 */
330 static QColor shade(const QColor &, ShadeRole);
331
332 /*!
333 * Retrieve the requested shade color, using the specified color as the
334 * base color and the specified contrast.
335 *
336 * \a contrast Amount roughly specifying the contrast by which to
337 * adjust the base color, between -1.0 and 1.0 (values between 0.0 and 1.0
338 * correspond to the value from KColorScheme::contrastF)
339 *
340 * \a chromaAdjust (optional) Amount by which to adjust the chroma of
341 * the shade (1.0 means no adjustment)
342 *
343 * \note Shades are chosen such that all shades would contrast with the
344 * base color. This means that if base is very dark, the 'dark' shades will
345 * be lighter than the base color, with QPalette::midlight() == QPalette::shadow().
346 * Conversely, if the base color is very light, the 'light' shades will be
347 * darker than the base color, with QPalette::light() == QPalette::mid().
348 *
349 * \sa KColorUtils::shade
350 */
351 static QColor shade(const QColor &, ShadeRole, qreal contrast, qreal chromaAdjust = 0.0);
352
353 /*!
354 * Adjust a QPalette by replacing the specified QPalette::ColorRole with
355 * the requested background color for all states. Using this method is
356 * safer than replacing individual states, as it insulates you against
357 * changes in QPalette::ColorGroup.
358 *
359 * \note Although it is possible to replace a foreground color using this
360 * method, it's bad usability to do so. Just say "no".
361 */
362 static void adjustBackground(QPalette &,
363 BackgroundRole newRole = NormalBackground,
364 QPalette::ColorRole color = QPalette::Base,
365 ColorSet set = View,
366 KSharedConfigPtr = KSharedConfigPtr());
367
368 /*!
369 * Adjust a QPalette by replacing the specified QPalette::ColorRole with
370 * the requested foreground color for all states. Using this method is
371 * safer than replacing individual states, as it insulates you against
372 * changes in QPalette::ColorGroup.
373 *
374 * \note Although it is possible to replace a background color using this
375 * method, it's bad usability to do so. Just say "no".
376 */
377 static void adjustForeground(QPalette &,
378 ForegroundRole newRole = NormalText,
379 QPalette::ColorRole color = QPalette::Text,
380 ColorSet set = View,
381 KSharedConfigPtr = KSharedConfigPtr());
382
383 /*!
384 * Used to obtain the QPalette that will be used to set the application
385 * palette from KDE Platform theme.
386 *
387 * \a config KConfig from which to load the colors
388 *
389 * Returns the QPalette
390 *
391 * \since 5.0
392 */
393 static QPalette createApplicationPalette(const KSharedConfigPtr &config);
394
395 /*!
396 * Used to check if the color scheme has a given set.
397 *
398 * \a config KConfig from which to load the colors
399 *
400 * \a set The color set to check for.
401 *
402 * Returns whether the color scheme has a given color set
403 *
404 * \since 5.75
405 */
406 static bool isColorSetSupported(const KSharedConfigPtr &config, KColorScheme::ColorSet set);
407
408 /*!
409 * \since 5.92
410 */
411 bool operator==(const KColorScheme &other) const;
412
413private:
414 QExplicitlySharedDataPointer<KColorSchemePrivate> d;
415};
416
417Q_DECLARE_METATYPE(KColorScheme)
418
419#endif // KCOLORSCHEME_H
420

source code of kcolorscheme/src/kcolorscheme.h