1/* This file is part of the KDE project
2 * Copyright (C) 2007 Matthew Woehlke <mw_triad@users.sourceforge.net>
3 *
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Library General Public
6 * License as published by the Free Software Foundation; either
7 * version 2 of the License, or (at your option) any later version.
8 *
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Library General Public License for more details.
13 *
14 * You should have received a copy of the GNU Library General Public License
15 * along with this library; see the file COPYING.LIB. If not, write to
16 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
17 * Boston, MA 02110-1301, USA.
18 */
19
20#ifndef KCOLORSCHEME_H
21#define KCOLORSCHEME_H
22
23#include <kdeui_export.h>
24#include <ksharedconfig.h>
25
26#include <QtCore/QExplicitlySharedDataPointer>
27
28#include <QtGui/QPalette>
29
30class QColor;
31class QBrush;
32
33class KColorSchemePrivate;
34
35/**
36 * A set of methods used to work with colors.
37 *
38 * KColorScheme currently provides access to the system color palette that the
39 * user has selected (in the future, it is expected to do more). As of KDE4,
40 * this class is the correct way to look up colors from the system palette,
41 * as opposed to KGlobalSettings (such usage is deprecated). It greatly expands
42 * on KGlobalSettings and QPalette by providing five distinct "sets" with
43 * several color choices each, covering background, foreground, and decoration
44 * colors.
45 *
46 * A KColorScheme instance represents colors corresponding to a "set", where a
47 * set consists of those colors used to draw a particular type of element, such
48 * as a menu, button, view, selected text, or tooltip. Each set has a distinct
49 * set of colors, so you should always use the correct set for drawing and
50 * never assume that a particular foreground for one set is the same as the
51 * foreground for any other set. Individual colors may be quickly referenced by
52 * creating an anonymous instance and invoking a lookup member.
53 *
54 * @note
55 * Historically, it was not needed for applications to give much concern to the
56 * state of a widget (active, inactive, disabled) since only the disabled state
57 * was different, and only slightly. As a result, the old KGlobalSettings color
58 * getters did not care about the widget state. However, starting with KDE4,
59 * the color palettes for the various states may be wildly different.
60 * Therefore, it is important to take the state into account. This is why the
61 * KColorScheme constructor requires a QPalette::ColorGroup as an argument.
62 *
63 * To facilitate working with potentially-varying states, two convenience API's
64 * are provided. These are KColorScheme::adjustBackground and its sister
65 * KColorScheme::adjustForeground, and the helper class ::KStatefulBrush.
66 *
67 * @see KColorScheme::ColorSet, KColorScheme::ForegroundRole,
68 * KColorScheme::BackgroundRole, KColorScheme::DecorationRole,
69 * KColorScheme::ShadeRole
70 */
71class KDEUI_EXPORT KColorScheme {
72public:
73
74 /**
75 * This enumeration describes the color set for which a color is being
76 * selected.
77 *
78 * Color sets define a color "environment", suitable for drawing all parts
79 * of a given region. Colors from different sets should not be combined.
80 */
81 enum ColorSet {
82 /**
83 * Views; for example, frames, input fields, etc.
84 *
85 * If it contains things that can be selected, it is probably a View.
86 */
87 View,
88 /**
89 * Non-editable window elements; for example, menus.
90 *
91 * If it isn't a Button, View, or Tooltip, it is probably a Window.
92 */
93 Window,
94 /**
95 * Buttons and button-like controls.
96 *
97 * In addition to buttons, "button-like" controls such as non-editable
98 * dropdowns, scrollbar sliders, slider handles, etc. should also use
99 * this role.
100 */
101 Button,
102 /**
103 * Selected items in views.
104 *
105 * Note that unfocused or disabled selections should use the Window
106 * role. This makes it more obvious to the user that the view
107 * containing the selection does not have input focus.
108 */
109 Selection,
110 /**
111 * Tooltips.
112 *
113 * The tooltip set can often be substituted for the view
114 * set when editing is not possible, but the Window set is deemed
115 * inappropriate. "What's This" help is an excellent example, another
116 * might be pop-up notifications (depending on taste).
117 */
118 Tooltip
119 };
120
121 /**
122 * This enumeration describes the background color being selected from the
123 * given set.
124 *
125 * Background colors are suitable for drawing under text, and should never
126 * be used to draw text. In combination with one of the overloads of
127 * KColorScheme::shade, they may be used to generate colors for drawing
128 * frames, bevels, and similar decorations.
129 */
130 enum BackgroundRole {
131 /**
132 * Normal background.
133 */
134 NormalBackground = 0,
135 /**
136 * Alternate background; for example, for use in lists.
137 *
138 * This color may be the same as BackgroundNormal, especially in sets
139 * other than View and Window.
140 */
141 AlternateBackground = 1,
142 /**
143 * Third color; for example, items which are new, active, requesting
144 * attention, etc.
145 *
146 * Alerting the user that a certain field must be filled out would be a
147 * good usage (although NegativeBackground could be used to the same
148 * effect, depending on what you are trying to achieve). Unlike
149 * ActiveText, this should not be used for mouseover effects.
150 */
151 ActiveBackground = 2,
152 /**
153 * Fourth color; corresponds to (unvisited) links.
154 *
155 * Exactly what this might be used for is somewhat harder to qualify;
156 * it might be used for bookmarks, as a 'you can click here' indicator,
157 * or to highlight recent content (i.e. in a most-recently-accessed
158 * list).
159 */
160 LinkBackground = 3,
161 /**
162 * Fifth color; corresponds to visited links.
163 *
164 * This can also be used to indicate "not recent" content, especially
165 * when a color is needed to denote content which is "old" or
166 * "archival".
167 */
168 VisitedBackground = 4,
169 /**
170 * Sixth color; for example, errors, untrusted content, etc.
171 */
172 NegativeBackground = 5,
173 /**
174 * Seventh color; for example, warnings, secure/encrypted content.
175 */
176 NeutralBackground = 6,
177 /**
178 * Eigth color; for example, success messages, trusted content.
179 */
180 PositiveBackground = 7
181 };
182
183 /**
184 * This enumeration describes the foreground color being selected from the
185 * given set.
186 *
187 * Foreground colors are suitable for drawing text or glyphs (such as the
188 * symbols on window decoration buttons, assuming a suitable background
189 * brush is used), and should never be used to draw backgrounds.
190 *
191 * For window decorations, the following is suggested, but not set in
192 * stone:
193 * @li Maximize - PositiveText
194 * @li Minimize - NeutralText
195 * @li Close - NegativeText
196 * @li WhatsThis - LinkText
197 * @li Sticky - ActiveText
198 */
199 enum ForegroundRole {
200 /**
201 * Normal foreground.
202 */
203 NormalText = 0,
204 /**
205 * Second color; for example, comments, items which are old, inactive
206 * or disabled. Generally used for things that are meant to be "less
207 * important". InactiveText is not the same role as NormalText in the
208 * inactive state.
209 */
210 InactiveText = 1,
211 /**
212 * Third color; for example items which are new, active, requesting
213 * attention, etc. May be used as a hover color for clickable items.
214 */
215 ActiveText = 2,
216 /**
217 * Fourth color; use for (unvisited) links. May also be used for other
218 * clickable items or content that indicates relationships, items that
219 * indicate somewhere the user can visit, etc.
220 */
221 LinkText = 3,
222 /**
223 * Fifth color; used for (visited) links. As with LinkText, may be used
224 * for items that have already been "visited" or accessed. May also be
225 * used to indicate "historical" (i.e. "old") items or information,
226 * especially if InactiveText is being used in the same context to
227 * express something different.
228 */
229 VisitedText = 4,
230 /**
231 * Sixth color; for example, errors, untrusted content, deletions,
232 * etc.
233 */
234 NegativeText = 5,
235 /**
236 * Seventh color; for example, warnings, secure/encrypted content.
237 */
238 NeutralText = 6,
239 /**
240 * Eigth color; for example, additions, success messages, trusted
241 * content.
242 */
243 PositiveText = 7
244 };
245
246 /**
247 * This enumeration describes the decoration color being selected from the
248 * given set.
249 *
250 * Decoration colors are used to draw decorations (such as frames) for
251 * special purposes. Like color shades, they are neither foreground nor
252 * background colors. Text should not be painted over a decoration color,
253 * and decoration colors should not be used to draw text.
254 */
255 enum DecorationRole {
256 /**
257 * Color used to draw decorations for items which have input focus.
258 */
259 FocusColor,
260 /**
261 * Color used to draw decorations for items which will be activated by
262 * clicking.
263 */
264 HoverColor
265 };
266
267 /**
268 * This enumeration describes the color shade being selected from the given
269 * set.
270 *
271 * Color shades are used to draw "3d" elements, such as frames and bevels.
272 * They are neither foreground nor background colors. Text should not be
273 * painted over a shade, and shades should not be used to draw text.
274 */
275 enum ShadeRole {
276 /**
277 * The light color is lighter than dark() or shadow() and contrasts
278 * with the base color.
279 */
280 LightShade,
281 /**
282 * The midlight color is in between base() and light().
283 */
284 MidlightShade,
285 /**
286 * The mid color is in between base() and dark().
287 */
288 MidShade,
289 /**
290 * The dark color is in between mid() and shadow().
291 */
292 DarkShade,
293 /**
294 * The shadow color is darker than light() or midlight() and contrasts
295 * the base color.
296 */
297 ShadowShade
298 };
299
300 /** Construct a copy of another KColorScheme. */
301 KColorScheme(const KColorScheme&);
302
303 /** Destructor */
304 virtual ~KColorScheme();
305
306 /** Standard assignment operator */
307 KColorScheme& operator=(const KColorScheme&);
308
309 /**
310 * Construct a palette from given color set and state, using the colors
311 * from the given KConfig (if null, the system colors are used).
312 *
313 * @note KColorScheme provides direct access to the color scheme for users
314 * that deal directly with widget states. Unless you are a low-level user
315 * or have a legitimate reason to only care about a fixed, limited number
316 * of states (e.g. windows that cannot be inactive), consider using a
317 * ::KStatefulBrush instead.
318 */
319 explicit KColorScheme(QPalette::ColorGroup, ColorSet = View, KSharedConfigPtr = KSharedConfigPtr());
320
321 /**
322 * Retrieve the requested background brush.
323 */
324 QBrush background(BackgroundRole = NormalBackground) const;
325
326 /**
327 * Retrieve the requested foreground brush.
328 */
329 QBrush foreground(ForegroundRole = NormalText) const;
330
331 /**
332 * Retrieve the requested decoration brush.
333 */
334 QBrush decoration(DecorationRole) const;
335
336 /**
337 * Retrieve the requested shade color, using
338 * KColorScheme::background(KColorScheme::NormalBackground)
339 * as the base color and the contrast setting from the KConfig used to
340 * create this KColorScheme instance (the system contrast setting, if no
341 * KConfig was specified).
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 midlight() == shadow().
346 * Conversely, if the base color is very light, the 'light' shades will be
347 * darker than the base color, with light() == mid().
348 */
349 QColor shade(ShadeRole) const;
350
351 /**
352 * Retrieve the requested shade color, using the specified color as the
353 * base color and the system contrast setting.
354 *
355 * @note Shades are chosen such that all shades would contrast with the
356 * base color. This means that if base is very dark, the 'dark' shades will
357 * be lighter than the base color, with midlight() == shadow().
358 * Conversely, if the base color is very light, the 'light' shades will be
359 * darker than the base color, with light() == mid().
360 */
361 static QColor shade(const QColor&, ShadeRole);
362
363 /**
364 * Retrieve the requested shade color, using the specified color as the
365 * base color and the specified contrast.
366 *
367 * @param contrast Amount roughly specifying the contrast by which to
368 * adjust the base color, between -1.0 and 1.0 (values between 0.0 and 1.0
369 * correspond to the value from KGlobalSettings::contrastF)
370 * @param chromaAdjust (optional) Amount by which to adjust the chroma of
371 * the shade (1.0 means no adjustment)
372 *
373 * @note Shades are chosen such that all shades would contrast with the
374 * base color. This means that if base is very dark, the 'dark' shades will
375 * be lighter than the base color, with midlight() == shadow().
376 * Conversely, if the base color is very light, the 'light' shades will be
377 * darker than the base color, with light() == mid().
378 *
379 * @see KColorUtils::shade
380 */
381 static QColor shade(const QColor&, ShadeRole,
382 qreal contrast, qreal chromaAdjust = 0.0);
383
384 /**
385 * Adjust a QPalette by replacing the specified QPalette::ColorRole with
386 * the requested background color for all states. Using this method is
387 * safer than replacing individual states, as it insulates you against
388 * changes in QPalette::ColorGroup.
389 *
390 * @note Although it is possible to replace a foreground color using this
391 * method, it's bad usability to do so. Just say "no".
392 */
393 static void adjustBackground(QPalette &,
394 BackgroundRole newRole = NormalBackground,
395 QPalette::ColorRole color = QPalette::Base,
396 ColorSet set = View,
397 KSharedConfigPtr = KSharedConfigPtr());
398
399 /**
400 * Adjust a QPalette by replacing the specified QPalette::ColorRole with
401 * the requested foreground color for all states. Using this method is
402 * safer than replacing individual states, as it insulates you against
403 * changes in QPalette::ColorGroup.
404 *
405 * @note Although it is possible to replace a background color using this
406 * method, it's bad usability to do so. Just say "no".
407 */
408 static void adjustForeground(QPalette &,
409 ForegroundRole newRole = NormalText,
410 QPalette::ColorRole color = QPalette::Text,
411 ColorSet set = View,
412 KSharedConfigPtr = KSharedConfigPtr());
413
414private:
415 QExplicitlySharedDataPointer<KColorSchemePrivate> d;
416};
417
418/**
419 * A container for a "state-aware" brush.
420 *
421 * KStatefulBrush provides an easy and safe way to store a color for use in a
422 * user interface. It is "safe" both in that it will make it easy to deal with
423 * widget states in a correct manner, and that it insulates you against changes
424 * in QPalette::ColorGroup.
425 *
426 * Basically, a stateful brush is used to cache a particular "color" from the
427 * KDE system palette (usually, one which does not live in QPalette) in the way
428 * you would have used a QColor in KDE3. When you are ready to draw using the
429 * brush, you use the current state to retrieve the appropriate brush.
430 *
431 * Stateful brushes can also be used to apply state effects to arbitrary
432 * brushes, for example when working with a application specific user-defined
433 * color palette.
434 *
435 * @note As of Qt 4.3, QPalette::ColorGroup is missing a state for disabled
436 * widgets in an inactive window. Hopefully Trolltech will fix this bug, at
437 * which point KColorScheme and KStatefulBrush will be updated to recognize the
438 * new state. Using KStatefulBrush will allow your application to inherit these
439 * changes "for free", without even recompiling.
440 */
441class KDEUI_EXPORT KStatefulBrush
442{
443public:
444 /**
445 * Construct a "default" stateful brush. For such an instance, all
446 * overloads of KStatefulBrush::brush will return a default brush (i.e.
447 * <tt>QBrush()</tt>).
448 */
449 explicit KStatefulBrush();
450
451 /**
452 * Construct a stateful brush from given color set and foreground role,
453 * using the colors from the given KConfig (if null, the system colors are
454 * used).
455 */
456 explicit KStatefulBrush(KColorScheme::ColorSet,
457 KColorScheme::ForegroundRole,
458 KSharedConfigPtr = KSharedConfigPtr());
459
460 /**
461 * Construct a stateful brush from given color set and background role,
462 * using the colors from the given KConfig (if null, the system colors are
463 * used).
464 */
465 explicit KStatefulBrush(KColorScheme::ColorSet,
466 KColorScheme::BackgroundRole,
467 KSharedConfigPtr = KSharedConfigPtr());
468
469 /**
470 * Construct a stateful brush from given color set and decoration role,
471 * using the colors from the given KConfig (if null, the system colors are
472 * used).
473 */
474 explicit KStatefulBrush(KColorScheme::ColorSet,
475 KColorScheme::DecorationRole,
476 KSharedConfigPtr = KSharedConfigPtr());
477
478 /**
479 * Construct a stateful background brush from a specified QBrush (or
480 * QColor, via QBrush's implicit constructor). The various states are
481 * determined from the base QBrush (which fills in the Active state)
482 * according to the same rules used to build stateful color schemes from
483 * the system color scheme. The state effects from the given KConfig are
484 * used (if null, the system state effects are used).
485 */
486 explicit KStatefulBrush(const QBrush&, KSharedConfigPtr = KSharedConfigPtr());
487
488 /**
489 * Construct a stateful foreground/decoration brush from a specified
490 * QBrush (or QColor, via QBrush's implicit constructor). The various
491 * states are determined from the base QBrush (which fills in the Active
492 * state) according to the same rules used to build stateful color schemes
493 * from the system color scheme. The state effects from the given KConfig
494 * are used (if null, the system state effects are used).
495 *
496 * @param background The background brush (or color) corresponding to the
497 * KColorScheme::NormalBackground role and QPalette::Active state for this
498 * foreground/decoration color.
499 */
500 explicit KStatefulBrush(const QBrush&, const QBrush &background,
501 KSharedConfigPtr = KSharedConfigPtr());
502
503 /** Construct a copy of another KStatefulBrush. */
504 KStatefulBrush(const KStatefulBrush&);
505
506 /** Destructor */
507 ~KStatefulBrush();
508
509 /** Standard assignment operator */
510 KStatefulBrush& operator=(const KStatefulBrush&);
511
512 /**
513 * Retrieve the brush for the specified widget state. This is used when you
514 * know explicitly what state is wanted. Otherwise one of overloads is
515 * often more convenient.
516 */
517 QBrush brush(QPalette::ColorGroup) const;
518
519 /**
520 * Retrieve the brush, using a QPalette reference to determine the correct
521 * state. Use when your painting code has easy access to the QPalette that
522 * it is supposed to be using. The state used in this instance is the
523 * currentColorGroup of the palette.
524 */
525 QBrush brush(const QPalette&) const;
526
527 /**
528 * Retrieve the brush, using a QWidget pointer to determine the correct
529 * state. Use when you have a pointer to the widget that you are painting.
530 * The state used is the current state of the widget.
531 *
532 * @note If you pass an invalid widget, you will get a default brush (i.e.
533 * <tt>QBrush()</tt>).
534 */
535 QBrush brush(const QWidget*) const;
536
537private:
538 class KStatefulBrushPrivate *d;
539};
540
541Q_DECLARE_METATYPE(KStatefulBrush) /* so we can pass it in QVariant's */
542
543#endif // KCOLORSCHEME_H
544// kate: space-indent on; indent-width 4; replace-tabs on; auto-insert-doxygen on;
545