KColorScheme

kcolorscheme.cpp
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#include "kcolorscheme.h"
9#include "kcolorschemehelpers_p.h"
10
11#include "kcolorscheme_debug.h"
12
13#include <KColorUtils>
14#include <KConfig>
15#include <KConfigGroup>
16
17#include <QBrush>
18#include <QColor>
19#include <QGuiApplication>
20#include <QPalette>
21
22// BEGIN StateEffects
23StateEffects::StateEffects(QPalette::ColorGroup state, const KSharedConfigPtr &config)
24 : _color(0, 0, 0, 0) //, _chain(0) not needed yet
25{
26 QString group;
27 if (state == QPalette::Disabled) {
28 group = QStringLiteral("ColorEffects:Disabled");
29 } else if (state == QPalette::Inactive) {
30 group = QStringLiteral("ColorEffects:Inactive");
31 }
32
33 for (auto &effect : _effects) {
34 effect = 0;
35 }
36
37 // NOTE: keep this in sync with kdebase/workspace/kcontrol/colors/colorscm.cpp
38 if (!group.isEmpty()) {
39 KConfigGroup cfg(config, group);
40 const bool enabledByDefault = (state == QPalette::Disabled);
41 if (cfg.readEntry("Enable", enabledByDefault)) {
42 _effects[Intensity] = cfg.readEntry("IntensityEffect", (int)(state == QPalette::Disabled ? IntensityDarken : IntensityNoEffect));
43 _effects[Color] = cfg.readEntry("ColorEffect", (int)(state == QPalette::Disabled ? ColorNoEffect : ColorDesaturate));
44 _effects[Contrast] = cfg.readEntry("ContrastEffect", (int)(state == QPalette::Disabled ? ContrastFade : ContrastTint));
45 _amount[Intensity] = cfg.readEntry("IntensityAmount", state == QPalette::Disabled ? 0.10 : 0.0);
46 _amount[Color] = cfg.readEntry("ColorAmount", state == QPalette::Disabled ? 0.0 : -0.9);
47 _amount[Contrast] = cfg.readEntry("ContrastAmount", state == QPalette::Disabled ? 0.65 : 0.25);
48 if (_effects[Color] > ColorNoEffect) {
49 _color = cfg.readEntry("Color", state == QPalette::Disabled ? QColor(56, 56, 56) : QColor(112, 111, 110));
50 }
51 }
52 }
53}
54
55QBrush StateEffects::brush(const QBrush &background) const
56{
57 QColor color = background.color(); // TODO - actually work on brushes
58 switch (_effects[Intensity]) {
59 case IntensityShade:
60 color = KColorUtils::shade(color, _amount[Intensity]);
61 break;
62 case IntensityDarken:
63 color = KColorUtils::darken(color, _amount[Intensity]);
64 break;
65 case IntensityLighten:
66 color = KColorUtils::lighten(color, _amount[Intensity]);
67 break;
68 }
69 switch (_effects[Color]) {
70 case ColorDesaturate:
71 color = KColorUtils::darken(color, 0.0, 1.0 - _amount[Color]);
72 break;
73 case ColorFade:
74 color = KColorUtils::mix(color, _color, _amount[Color]);
75 break;
76 case ColorTint:
77 color = KColorUtils::tint(color, _color, _amount[Color]);
78 break;
79 }
80 return QBrush(color);
81}
82
83QBrush StateEffects::brush(const QBrush &foreground, const QBrush &background) const
84{
85 QColor color = foreground.color(); // TODO - actually work on brushes
86 QColor bg = background.color();
87 // Apply the foreground effects
88 switch (_effects[Contrast]) {
89 case ContrastFade:
90 color = KColorUtils::mix(color, bg, _amount[Contrast]);
91 break;
92 case ContrastTint:
93 color = KColorUtils::tint(color, bg, _amount[Contrast]);
94 break;
95 }
96 // Now apply global effects
97 return brush(color);
98}
99// END StateEffects
100
101// BEGIN default colors
102struct SerializedColors {
103 QColor NormalBackground;
104 QColor AlternateBackground;
105 QColor NormalText;
106 QColor InactiveText;
107 QColor ActiveText;
108 QColor LinkText;
109 QColor VisitedText;
110 QColor NegativeText;
111 QColor NeutralText;
112 QColor PositiveText;
113};
114
115struct DecorationColors {
116 QColor Focus;
117 QColor Hover;
118};
119
120// clang-format off
121// These numbers come from the default color scheme which is currently
122// Breeze Light ([breeze repo]/colors/BreezeLight.colors)
123static const SerializedColors defaultViewColors = {
124 { 255, 255, 255 }, // Background
125 { 247, 247, 247 }, // Alternate
126 { 35, 38, 41 }, // Normal
127 { 112, 125, 138 }, // Inactive
128 { 61, 174, 233 }, // Active
129 { 41, 128, 185 }, // Link
130 { 155, 89, 182 }, // Visited
131 { 218, 68, 83 }, // Negative
132 { 246, 116, 0 }, // Neutral
133 { 39, 174, 96 } // Positive
134};
135
136static const SerializedColors defaultWindowColors = {
137 { 239, 240, 241 }, // Background
138 { 227, 229, 231 }, // Alternate
139 { 35, 38, 41 }, // Normal
140 { 112, 125, 138 }, // Inactive
141 { 61, 174, 233 }, // Active
142 { 41, 128, 185 }, // Link
143 { 155, 89, 182 }, // Visited
144 { 218, 68, 83 }, // Negative
145 { 246, 116, 0 }, // Neutral
146 { 39, 174, 96 } // Positive
147};
148
149static const SerializedColors defaultButtonColors = {
150 { 252, 252, 252 }, // Background
151 { 163, 212, 250 }, // Alternate
152 { 35, 38, 41 }, // Normal
153 { 112, 125, 138 }, // Inactive
154 { 61, 174, 233 }, // Active
155 { 41, 128, 185 }, // Link
156 { 155, 89, 182 }, // Visited
157 { 218, 68, 83 }, // Negative
158 { 246, 116, 0 }, // Neutral
159 { 39, 174, 96 } // Positive
160};
161
162static const SerializedColors defaultSelectionColors = {
163 { 61, 174, 233 }, // Background
164 { 163, 212, 250 }, // Alternate
165 { 255, 255, 255 }, // Normal
166 { 112, 125, 138 }, // Inactive
167 { 255, 255, 255 }, // Active
168 { 253, 188, 75 }, // Link
169 { 155, 89, 182 }, // Visited
170 { 176, 55, 69 }, // Negative
171 { 198, 92, 0 }, // Neutral
172 { 23, 104, 57 } // Positive
173};
174
175static const SerializedColors defaultTooltipColors = {
176 { 247, 247, 247 }, // Background
177 { 239, 240, 241 }, // Alternate
178 { 35, 38, 41 }, // Normal
179 { 112, 125, 138 }, // Inactive
180 { 61, 174, 233 }, // Active
181 { 41, 128, 185 }, // Link
182 { 155, 89, 182 }, // Visited
183 { 218, 68, 83 }, // Negative
184 { 246, 116, 0 }, // Neutral
185 { 39, 174, 96 } // Positive
186};
187
188static const SerializedColors defaultComplementaryColors = {
189 { 42, 46, 50 }, // Background
190 { 27, 30, 32 }, // Alternate
191 { 252, 252, 252 }, // Normal
192 { 161, 169, 177 }, // Inactive
193 { 61, 174, 233 }, // Active
194 { 29, 153, 243 }, // Link
195 { 155, 89, 182 }, // Visited
196 { 218, 68, 83 }, // Negative
197 { 246, 116, 0 }, // Neutral
198 { 39, 174, 96 } // Positive
199};
200
201static const SerializedColors defaultHeaderColors = {
202 { 222, 224, 226 }, // Background
203 { 239, 240, 241 }, // Alternate
204 { 35, 38, 41 }, // Normal
205 { 112, 125, 138 }, // Inactive
206 { 61, 174, 233 }, // Active
207 { 41, 128, 185 }, // Link
208 { 155, 89, 182 }, // Visited
209 { 218, 68, 83 }, // Negative
210 { 246, 116, 0 }, // Neutral
211 { 39, 174, 96 } // Positive
212};
213
214static const DecorationColors defaultDecorationColors = {
215 { 61, 174, 233 }, // Focus
216 { 147, 206, 233 }, // Hover
217};
218// END default colors
219// clang-format off
220
221//BEGIN KColorSchemePrivate
222class KColorSchemePrivate : public QSharedData
223{
224public:
225 explicit KColorSchemePrivate(const KSharedConfigPtr &, QPalette::ColorGroup state, KColorScheme::ColorSet set);
226 ~KColorSchemePrivate()
227 {
228 }
229
230 void initFromConfig(const KSharedConfigPtr &config, QPalette::ColorGroup state, KColorScheme::ColorSet set);
231 void initFromSystemPalette(QPalette::ColorGroup state, KColorScheme::ColorSet set);
232
233 QBrush background(KColorScheme::BackgroundRole) const;
234 QBrush foreground(KColorScheme::ForegroundRole) const;
235 QBrush decoration(KColorScheme::DecorationRole) const;
236 qreal contrast() const;
237
238 struct Brushes {
239 std::array<QBrush, KColorScheme::NForegroundRoles> fg;
240 std::array<QBrush, KColorScheme::NBackgroundRoles> bg;
241 std::array<QBrush, KColorScheme::NDecorationRoles> deco;
242
243 bool operator==(const Brushes &b) const
244 {
245 return this == &b || (fg == b.fg && bg == b.bg && deco == b.deco);
246 }
247 } _brushes;
248
249 qreal _contrast;
250};
251
252static SerializedColors loadSerializedColors(const KConfigGroup &group, const SerializedColors &defaults)
253{
254 constexpr std::array configMap = {
255 std::pair{"ForegroundNormal", &SerializedColors::NormalText},
256 std::pair{"ForegroundInactive", &SerializedColors::InactiveText},
257 std::pair{"ForegroundActive", &SerializedColors::ActiveText},
258 std::pair{"ForegroundLink", &SerializedColors::LinkText},
259 std::pair{"ForegroundVisited", &SerializedColors::VisitedText},
260 std::pair{"ForegroundNegative", &SerializedColors::NegativeText},
261 std::pair{"ForegroundNeutral", &SerializedColors::NeutralText},
262 std::pair{"ForegroundPositive", &SerializedColors::PositiveText},
263 std::pair{"BackgroundNormal", &SerializedColors::NormalBackground},
264 std::pair{"BackgroundAlternate", &SerializedColors::AlternateBackground},
265 };
266 SerializedColors loadedColors;
267 for (const auto &entry : configMap) {
268 loadedColors.*(entry.second) = group.readEntry(entry.first, defaults.*(entry.second));
269 }
270 return loadedColors;
271}
272
273static DecorationColors loadDecorationColors(const KConfigGroup &group, const DecorationColors &defaults)
274{
275 DecorationColors colors;
276 colors.Focus = group.readEntry("DecorationFocus", defaults.Focus);
277 colors.Hover = group.readEntry("DecorationHover", defaults.Hover);
278 return colors;
279}
280
281KColorSchemePrivate::KColorSchemePrivate(const KSharedConfigPtr &config, QPalette::ColorGroup state, KColorScheme::ColorSet set)
282{
283 if (config) {
284 initFromConfig(config, state, set);
285 } else {
286 initFromSystemPalette(state, set);
287 }
288}
289
290void KColorSchemePrivate::initFromConfig(const KSharedConfigPtr &config, QPalette::ColorGroup state, KColorScheme::ColorSet set)
291{
292 QString groupName;
293 SerializedColors defaultColors;
294 DecorationColors defaultDecoColors = defaultDecorationColors;
295 QColor tint;
296 switch (set) {
298 groupName = QStringLiteral("Colors:Window");
299 defaultColors = defaultWindowColors;
300 break;
302 groupName = QStringLiteral("Colors:Button");
303 defaultColors = defaultButtonColors;
304 break;
306 const KConfigGroup inactiveEffectGroup(config, QStringLiteral("ColorEffects:Inactive"));
307 // NOTE: keep this in sync with kdebase/workspace/kcontrol/colors/colorscm.cpp
308 const bool inactiveSelectionEffect = inactiveEffectGroup.readEntry("ChangeSelectionColor", inactiveEffectGroup.readEntry("Enable", true));
309 // if enabled, inactive/disabled uses Window colors instead, ala gtk
310 // ...except tinted with the Selection:NormalBackground color so it looks more like selection
311 if (state == QPalette::Active || (state == QPalette::Inactive && !inactiveSelectionEffect)) {
312 groupName = QStringLiteral("Colors:Selection");
313 defaultColors = defaultSelectionColors;
314 } else if (state == QPalette::Inactive) {
315 groupName = QStringLiteral("Colors:Window");
316 defaultColors = defaultWindowColors;
317 tint = config->group(QStringLiteral("Colors:Selection")).readEntry("BackgroundNormal", defaultSelectionColors.NormalBackground);
318 } else { // disabled (...and still want this branch when inactive+disabled exists)
319 groupName = QStringLiteral("Colors:Window");
320 defaultColors = defaultWindowColors;
321 }
322 } break;
324 groupName = QStringLiteral("Colors:Tooltip");
325 defaultColors = defaultTooltipColors;
326 break;
328 groupName = QStringLiteral("Colors:Complementary");
329 defaultColors = defaultComplementaryColors;
330 break;
332 groupName = QStringLiteral("Colors:Header");
333 defaultColors = loadSerializedColors(config->group(QStringLiteral("Colors:Window")), defaultHeaderColors);
334 defaultDecoColors = loadDecorationColors(config->group(QStringLiteral("Colors:Window")), defaultDecorationColors);
335 break;
337 qCWarning(KCOLORSCHEME) << "ColorSet::NColorSets is not a valid color set value to pass to KColorScheme::KColorScheme";
338 [[fallthrough]];
340 groupName = QStringLiteral("Colors:View");
341 defaultColors = defaultViewColors;
342 break;
343 }
344
345 KConfigGroup cfg(config, groupName);
346 bool hasInactivePalette = false;
347 if (state == QPalette::Inactive) {
348 KConfigGroup inactiveGroup = KConfigGroup(&cfg, QStringLiteral("Inactive"));
349 if (inactiveGroup.exists()) {
350 cfg = inactiveGroup;
351 hasInactivePalette = true;
352 }
353 }
354
355 _contrast = KColorScheme::contrastF(config);
356
357 const SerializedColors loadedColors = loadSerializedColors(cfg, defaultColors);
358 const DecorationColors loadedDecoColors = loadDecorationColors(cfg, defaultDecoColors);
359
360 _brushes.fg[KColorScheme::NormalText] = loadedColors.NormalText;
361 _brushes.fg[KColorScheme::InactiveText] = loadedColors.InactiveText;
362 _brushes.fg[KColorScheme::ActiveText] = loadedColors.ActiveText;
363 _brushes.fg[KColorScheme::LinkText] = loadedColors.LinkText;
364 _brushes.fg[KColorScheme::VisitedText] = loadedColors.VisitedText;
365 _brushes.fg[KColorScheme::NegativeText] = loadedColors.NegativeText;
366 _brushes.fg[KColorScheme::NeutralText] = loadedColors.NeutralText;
367 _brushes.fg[KColorScheme::PositiveText] = loadedColors.PositiveText;
368
369 _brushes.bg[KColorScheme::NormalBackground] = loadedColors.NormalBackground;
370 _brushes.bg[KColorScheme::AlternateBackground] = loadedColors.AlternateBackground;
371
372 _brushes.deco[KColorScheme::FocusColor] = loadedDecoColors.Focus;
373 _brushes.deco[KColorScheme::HoverColor] = loadedDecoColors.Hover;
374
375 if (tint.isValid()) {
376 // adjustment
377 _brushes.bg[KColorScheme::NormalBackground] =
378 KColorUtils::tint(_brushes.bg[KColorScheme::NormalBackground].color(), tint, 0.4);
380 KColorUtils::tint(_brushes.bg[KColorScheme::AlternateBackground].color(), tint, 0.4);
381 }
382
383 // apply state adjustments
384 if (state != QPalette::Active || (state == QPalette::Inactive && !hasInactivePalette)) {
385 StateEffects effects(state, config);
386 for (auto &fg : _brushes.fg) {
387 fg = effects.brush(fg, _brushes.bg[KColorScheme::NormalBackground]);
388 }
389 for (auto &deco : _brushes.deco) {
390 deco = effects.brush(deco, _brushes.bg[KColorScheme::NormalBackground]);
391 }
392 _brushes.bg[KColorScheme::NormalBackground] = effects.brush(_brushes.bg[KColorScheme::NormalBackground]);
393 _brushes.bg[KColorScheme::AlternateBackground] = effects.brush(_brushes.bg[KColorScheme::AlternateBackground]);
394 }
395
396 // calculated backgrounds
397 _brushes.bg[KColorScheme::ActiveBackground] =
399 _brushes.fg[KColorScheme::ActiveText].color());
400 _brushes.bg[KColorScheme::LinkBackground] =
402 _brushes.fg[KColorScheme::LinkText].color());
405 _brushes.fg[KColorScheme::VisitedText].color());
408 _brushes.fg[KColorScheme::NegativeText].color());
411 _brushes.fg[KColorScheme::NeutralText].color());
414 _brushes.fg[KColorScheme::PositiveText].color());
415}
416
417void KColorSchemePrivate::initFromSystemPalette(QPalette::ColorGroup state, KColorScheme::ColorSet set)
418{
419 // Initialize the color scheme from the system palette. This is supposed
420 // to be done if high-contrast mode is active (on Windows).
421 const QPalette systemPalette = qApp->palette();
422
423 QColor foreground;
424 QColor background;
425 switch (set) {
427 foreground = systemPalette.color(state, QPalette::ButtonText);
428 background = systemPalette.color(state, QPalette::Button);
429 break;
431 foreground = systemPalette.color(state, QPalette::ToolTipText);
432 background = systemPalette.color(state, QPalette::ToolTipBase);
433 break;
435 foreground = systemPalette.color(state, QPalette::HighlightedText);
436 background = systemPalette.color(state, QPalette::Highlight);
437 break;
439 foreground = systemPalette.color(state, QPalette::Text);
440 background = systemPalette.color(state, QPalette::Base);
441 break;
443 qCWarning(KCOLORSCHEME) << "ColorSet::NColorSets is not a valid color set value to pass to KColorScheme::KColorScheme";
444 [[fallthrough]];
448 foreground = systemPalette.color(state, QPalette::WindowText);
449 background = systemPalette.color(state, QPalette::Window);
450 break;
451 }
452
453 _contrast = KColorScheme::contrastF({});
454
455 _brushes.fg[KColorScheme::NormalText] = foreground;
456 _brushes.fg[KColorScheme::InactiveText] = foreground;
457 _brushes.fg[KColorScheme::ActiveText] = foreground;
458 _brushes.fg[KColorScheme::LinkText] = systemPalette.color(state, QPalette::Link);
459 _brushes.fg[KColorScheme::VisitedText] = systemPalette.color(state, QPalette::LinkVisited);
460 _brushes.fg[KColorScheme::NegativeText] = foreground;
461 _brushes.fg[KColorScheme::NeutralText] = foreground;
462 _brushes.fg[KColorScheme::PositiveText] = foreground;
463
464 _brushes.bg[KColorScheme::NormalBackground] = background;
465 _brushes.bg[KColorScheme::AlternateBackground] = systemPalette.color(state, QPalette::AlternateBase);
466 _brushes.bg[KColorScheme::ActiveBackground] = background;
467 _brushes.bg[KColorScheme::LinkBackground] = background;
468 _brushes.bg[KColorScheme::VisitedBackground] = background;
469 _brushes.bg[KColorScheme::NegativeBackground] = background;
470 _brushes.bg[KColorScheme::NeutralBackground] = background;
471 _brushes.bg[KColorScheme::PositiveBackground] = background;
472
473 _brushes.deco[KColorScheme::FocusColor] = systemPalette.color(state, QPalette::Highlight);
474 _brushes.deco[KColorScheme::HoverColor] = systemPalette.color(state, QPalette::Highlight);
475}
476
477QBrush KColorSchemePrivate::background(KColorScheme::BackgroundRole role) const
478{
480 return _brushes.bg[role];
481 } else {
482 return _brushes.bg[KColorScheme::NormalBackground];
483 }
484}
485
486QBrush KColorSchemePrivate::foreground(KColorScheme::ForegroundRole role) const
487{
489 return _brushes.fg[role];
490 } else {
491 return _brushes.fg[KColorScheme::NormalText];
492 }
493}
494
495QBrush KColorSchemePrivate::decoration(KColorScheme::DecorationRole role) const
496{
498 return _brushes.deco[role];
499 } else {
500 return _brushes.deco[KColorScheme::FocusColor];
501 }
502}
503
504qreal KColorSchemePrivate::contrast() const
505{
506 return _contrast;
507}
508//END KColorSchemePrivate
509
510//BEGIN KColorScheme
511KColorScheme::KColorScheme(const KColorScheme &) = default;
512KColorScheme &KColorScheme::operator=(const KColorScheme &) = default;
513KColorScheme::KColorScheme(KColorScheme &&) = default;
514KColorScheme &KColorScheme::operator=(KColorScheme &&) = default;
516
517KColorScheme::KColorScheme(QPalette::ColorGroup state, ColorSet set, KSharedConfigPtr config)
518 : d(new KColorSchemePrivate(config ? config : defaultConfig(), state, set))
519{
520}
521
522bool KColorScheme::operator==(const KColorScheme &other) const
523{
524 return d == other.d
525 || (d->_contrast == other.d->_contrast
526 && d->_brushes == other.d->_brushes)
527 ;
528}
529
530// static
531qreal KColorScheme::contrastF(const KSharedConfigPtr &config)
532{
533 KSharedConfigPtr conf = config ? config : defaultConfig();
534 if (!conf) {
535 return 0.7;
536 }
537 KConfigGroup g(conf, QStringLiteral("KDE"));
538 return 0.1 * g.readEntry("contrast", 7);
539}
540
542{
543 return d->background(role);
544}
545
547{
548 return d->foreground(role);
549}
550
552{
553 return d->decoration(role);
554}
555
557{
558 return shade(background().color(), role, d->contrast());
559}
560
562{
563 return shade(color, role, KColorScheme::contrastF());
564}
565
566QColor KColorScheme::shade(const QColor &color, ShadeRole role, qreal contrast, qreal chromaAdjust)
567{
568 // nan -> 1.0
569 contrast = (1.0 > contrast ? (-1.0 < contrast ? contrast : -1.0) : 1.0);
570 qreal y = KColorUtils::luma(color);
571 qreal yi = 1.0 - y;
572
573 // handle very dark colors (base, mid, dark, shadow == midlight, light)
574 if (y < 0.006) {
575 switch (role) {
577 return KColorUtils::shade(color, 0.05 + 0.95 * contrast, chromaAdjust);
579 return KColorUtils::shade(color, 0.01 + 0.20 * contrast, chromaAdjust);
581 return KColorUtils::shade(color, 0.02 + 0.40 * contrast, chromaAdjust);
582 default:
583 return KColorUtils::shade(color, 0.03 + 0.60 * contrast, chromaAdjust);
584 }
585 }
586
587 // handle very light colors (base, midlight, light == mid, dark, shadow)
588 if (y > 0.93) {
589 switch (role) {
591 return KColorUtils::shade(color, -0.02 - 0.20 * contrast, chromaAdjust);
593 return KColorUtils::shade(color, -0.06 - 0.60 * contrast, chromaAdjust);
595 return KColorUtils::shade(color, -0.10 - 0.90 * contrast, chromaAdjust);
596 default:
597 return KColorUtils::shade(color, -0.04 - 0.40 * contrast, chromaAdjust);
598 }
599 }
600
601 // handle everything else
602 qreal lightAmount = (0.05 + y * 0.55) * (0.25 + contrast * 0.75);
603 qreal darkAmount = (- y) * (0.55 + contrast * 0.35);
604 switch (role) {
606 return KColorUtils::shade(color, lightAmount, chromaAdjust);
608 return KColorUtils::shade(color, (0.15 + 0.35 * yi) * lightAmount, chromaAdjust);
610 return KColorUtils::shade(color, (0.35 + 0.15 * y) * darkAmount, chromaAdjust);
612 return KColorUtils::shade(color, darkAmount, chromaAdjust);
613 default:
614 return KColorUtils::darken(KColorUtils::shade(color, darkAmount, chromaAdjust), 0.5 + 0.3 * y);
615 }
616}
617
619 ColorSet set, KSharedConfigPtr config)
620{
621 palette.setBrush(QPalette::Active, color, KColorScheme(QPalette::Active, set, config).background(newRole));
622 palette.setBrush(QPalette::Inactive, color, KColorScheme(QPalette::Inactive, set, config).background(newRole));
623 palette.setBrush(QPalette::Disabled, color, KColorScheme(QPalette::Disabled, set, config).background(newRole));
624}
625
627 ColorSet set, KSharedConfigPtr config)
628{
629 palette.setBrush(QPalette::Active, color, KColorScheme(QPalette::Active, set, config).foreground(newRole));
630 palette.setBrush(QPalette::Inactive, color, KColorScheme(QPalette::Inactive, set, config).foreground(newRole));
631 palette.setBrush(QPalette::Disabled, color, KColorScheme(QPalette::Disabled, set, config).foreground(newRole));
632}
633
634bool KColorScheme::isColorSetSupported(const KSharedConfigPtr &config, KColorScheme::ColorSet set)
635{
636 switch (set) {
637 case View:
638 return config->hasGroup(QStringLiteral("Colors:View"));
639 case Window:
640 return config->hasGroup(QStringLiteral("Colors:Window"));
641 case Button:
642 return config->hasGroup(QStringLiteral("Colors:Button"));
643 case Selection:
644 return config->hasGroup(QStringLiteral("Colors:Selection"));
645 case Tooltip:
646 return config->hasGroup(QStringLiteral("Colors:Tooltip"));
647 case Complementary:
648 return config->hasGroup(QStringLiteral("Colors:Complementary"));
649 case Header:
650 return config->hasGroup(QStringLiteral("Colors:Header"));
651 case NColorSets:
652 break;
653 }
654
655 return false;
656}
657
659{
660 static const QPalette::ColorGroup states[QPalette::NColorGroups] = {
662 };
663
664 // TT thinks tooltips shouldn't use active, so we use our active colors for all states
665 KColorScheme schemeTooltip(QPalette::Active, KColorScheme::Tooltip, config);
666
667 QPalette palette;
668 for (auto state : states) {
669 KColorScheme schemeView(state, KColorScheme::View, config);
670 KColorScheme schemeWindow(state, KColorScheme::Window, config);
671 KColorScheme schemeButton(state, KColorScheme::Button, config);
672 KColorScheme schemeSelection(state, KColorScheme::Selection, config);
673
674 palette.setBrush(state, QPalette::WindowText, schemeWindow.foreground());
675 palette.setBrush(state, QPalette::Window, schemeWindow.background());
676 palette.setBrush(state, QPalette::Base, schemeView.background());
677 palette.setBrush(state, QPalette::Text, schemeView.foreground());
678 palette.setBrush(state, QPalette::Button, schemeButton.background());
679 palette.setBrush(state, QPalette::ButtonText, schemeButton.foreground());
680 palette.setBrush(state, QPalette::Highlight, schemeSelection.background());
681 palette.setBrush(state, QPalette::HighlightedText, schemeSelection.foreground());
682 palette.setBrush(state, QPalette::ToolTipBase, schemeTooltip.background());
683 palette.setBrush(state, QPalette::ToolTipText, schemeTooltip.foreground());
685 palette.setBrush(state, QPalette::Accent, schemeSelection.background());
686
687 palette.setColor(state, QPalette::Light, schemeWindow.shade(KColorScheme::LightShade));
688 palette.setColor(state, QPalette::Midlight, schemeWindow.shade(KColorScheme::MidlightShade));
689 palette.setColor(state, QPalette::Mid, schemeWindow.shade(KColorScheme::MidShade));
690 palette.setColor(state, QPalette::Dark, schemeWindow.shade(KColorScheme::DarkShade));
691 palette.setColor(state, QPalette::Shadow, schemeWindow.shade(KColorScheme::ShadowShade));
692
694 palette.setBrush(state, QPalette::Link, schemeView.foreground(KColorScheme::LinkText));
696 }
697
698 return palette;
699}
700
701//END KColorScheme
A set of methods used to work with colors.
static void adjustForeground(QPalette &, ForegroundRole newRole=NormalText, QPalette::ColorRole color=QPalette::Text, ColorSet set=View, KSharedConfigPtr=KSharedConfigPtr())
Adjust a QPalette by replacing the specified QPalette::ColorRole with the requested foreground color ...
ForegroundRole
This enumeration describes the foreground color being selected from the given set.
@ NForegroundRoles
Number of foreground roles.
@ ActiveText
Third color; for example items which are new, active, requesting attention, etc.
@ VisitedText
Fifth color; used for (visited) links.
@ LinkText
Fourth color; use for (unvisited) links.
@ NeutralText
Seventh color; for example, warnings, secure/encrypted content.
@ NormalText
Normal foreground.
@ InactiveText
Second color; for example, comments, items which are old, inactive or disabled.
@ NegativeText
Sixth color; for example, errors, untrusted content, deletions, etc.
@ PositiveText
Eighth color; for example, additions, success messages, trusted content.
static QPalette createApplicationPalette(const KSharedConfigPtr &config)
Used to obtain the QPalette that will be used to set the application palette from KDE Platform theme.
bool operator==(const KColorScheme &other) const
ShadeRole
This enumeration describes the color shade being selected from the given set.
@ MidlightShade
The midlight color is in between base() and light().
@ DarkShade
The dark color is in between mid() and shadow().
@ LightShade
The light color is lighter than dark() or shadow() and contrasts with the base color.
@ ShadowShade
The shadow color is darker than light() or midlight() and contrasts the base color.
@ MidShade
The mid color is in between base() and dark().
BackgroundRole
This enumeration describes the background color being selected from the given set.
@ PositiveBackground
Eighth color; for example, success messages, trusted content.
@ NeutralBackground
Seventh color; for example, warnings, secure/encrypted content.
@ AlternateBackground
Alternate background; for example, for use in lists.
@ NormalBackground
Normal background.
@ VisitedBackground
Fifth color; corresponds to visited links.
@ NBackgroundRoles
Number of background roles.
@ ActiveBackground
Third color; for example, items which are new, active, requesting attention, etc.
@ NegativeBackground
Sixth color; for example, errors, untrusted content, etc.
@ LinkBackground
Fourth color; corresponds to (unvisited) links.
ColorSet
This enumeration describes the color set for which a color is being selected.
@ Header
Colors for header areas that should be used both by the top toolbar and the titlebar.
@ Complementary
Complementary areas.
@ Tooltip
Tooltips.
@ NColorSets
Number of color sets.
@ View
Views; for example, frames, input fields, etc.
@ Window
Non-editable window elements; for example, menus.
@ Selection
Selected items in views.
@ Button
Buttons and button-like controls.
static qreal contrastF(const KSharedConfigPtr &config=KSharedConfigPtr())
Returns the contrast for borders as a floating point value.
static bool isColorSetSupported(const KSharedConfigPtr &config, KColorScheme::ColorSet set)
Used to check if the color scheme has a given set.
QBrush background(BackgroundRole=NormalBackground) const
Retrieve the requested background brush.
DecorationRole
This enumeration describes the decoration color being selected from the given set.
@ HoverColor
Color used to draw decorations for items which will be activated by clicking.
@ NDecorationRoles
Number of decoration roles.
@ FocusColor
Color used to draw decorations for items which have input focus.
static void adjustBackground(QPalette &, BackgroundRole newRole=NormalBackground, QPalette::ColorRole color=QPalette::Base, ColorSet set=View, KSharedConfigPtr=KSharedConfigPtr())
Adjust a QPalette by replacing the specified QPalette::ColorRole with the requested background color ...
QBrush decoration(DecorationRole) const
Retrieve the requested decoration brush.
virtual ~KColorScheme()
Destructor.
QColor shade(ShadeRole) const
Retrieve the requested shade color, using KColorScheme::background(KColorScheme::NormalBackground) as...
QBrush foreground(ForegroundRole=NormalText) const
Retrieve the requested foreground brush.
QString readEntry(const char *key, const char *aDefault=nullptr) const
bool exists() const
KGUIADDONS_EXPORT QColor darken(const QColor &, qreal amount=0.5, qreal chromaGain=1.0)
KGUIADDONS_EXPORT qreal luma(const QColor &)
KGUIADDONS_EXPORT QColor shade(const QColor &, qreal lumaAmount, qreal chromaAmount=0.0)
KGUIADDONS_EXPORT QColor mix(const QColor &c1, const QColor &c2, qreal bias=0.5)
KGUIADDONS_EXPORT QColor tint(const QColor &base, const QColor &color, qreal amount=0.3)
KGUIADDONS_EXPORT QColor lighten(const QColor &, qreal amount=0.5, qreal chromaInverseGain=1.0)
KGuiItem defaults()
const QColor & color() const const
bool isValid() const const
const QColor & color(ColorGroup group, ColorRole role) const const
void setBrush(ColorGroup group, ColorRole role, const QBrush &brush)
void setColor(ColorGroup group, ColorRole role, const QColor &color)
bool isEmpty() const const
This file is part of the KDE documentation.
Documentation copyright © 1996-2025 The KDE developers.
Generated on Fri Apr 25 2025 11:57:11 by doxygen 1.13.2 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.