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