1 | /* |
---|---|
2 | |
3 | This file is part of the KDE project, module kdecore. |
4 | SPDX-FileCopyrightText: 2000 Geert Jansen <jansen@kde.org> |
5 | SPDX-FileCopyrightText: 2000 Antonio Larrosa <larrosa@kde.org> |
6 | |
7 | SPDX-License-Identifier: LGPL-2.0-only |
8 | */ |
9 | |
10 | #include "kiconcolors.h" |
11 | #include <KColorScheme> |
12 | |
13 | static QString STYLESHEET_TEMPLATE() |
14 | { |
15 | /* clang-format off */ |
16 | return QStringLiteral(".ColorScheme-Text { color:%1; }\ |
17 | .ColorScheme-Background{ color:%2; }\ |
18 | .ColorScheme-Highlight{ color:%3; }\ |
19 | .ColorScheme-HighlightedText{ color:%4; }\ |
20 | .ColorScheme-PositiveText{ color:%5; }\ |
21 | .ColorScheme-NeutralText{ color:%6; }\ |
22 | .ColorScheme-NegativeText{ color:%7; }\ |
23 | .ColorScheme-ActiveText{ color:%8; }\ |
24 | .ColorScheme-Complement{ color:%9; }\ |
25 | .ColorScheme-Contrast{ color:%10; }\ |
26 | .ColorScheme-Accent{ color:%11; }\ |
27 | "); |
28 | /* clang-format on */ |
29 | } |
30 | |
31 | class KIconColorsPrivate : public QSharedData |
32 | { |
33 | public: |
34 | KIconColorsPrivate() |
35 | { |
36 | } |
37 | |
38 | QColor text; |
39 | QColor background; |
40 | QColor highlight; |
41 | QColor highlightedText; |
42 | QColor accent; |
43 | QColor positiveText; |
44 | QColor neutralText; |
45 | QColor negativeText; |
46 | QColor activeText; |
47 | static std::optional<QPalette> lastPalette; |
48 | static std::optional<KColorScheme> lastColorScheme; |
49 | }; |
50 | |
51 | std::optional<QPalette> KIconColorsPrivate::lastPalette; |
52 | std::optional<KColorScheme> KIconColorsPrivate::lastColorScheme; |
53 | |
54 | KIconColors::KIconColors() |
55 | : KIconColors(QPalette()) |
56 | { |
57 | } |
58 | |
59 | KIconColors::KIconColors(const KIconColors &other) |
60 | : d_ptr(other.d_ptr) |
61 | { |
62 | } |
63 | |
64 | KIconColors KIconColors::operator=(const KIconColors &other) |
65 | { |
66 | if (d_ptr != other.d_ptr) { |
67 | d_ptr = other.d_ptr; |
68 | } |
69 | return *this; |
70 | } |
71 | |
72 | KIconColors::KIconColors(const QColor &color) |
73 | : d_ptr(new KIconColorsPrivate) |
74 | { |
75 | Q_D(KIconColors); |
76 | d->text = color; |
77 | d->background = color; |
78 | d->highlight = color; |
79 | d->highlightedText = color; |
80 | d->positiveText = color; |
81 | d->neutralText = color; |
82 | d->negativeText = color; |
83 | d->accent = color; |
84 | d->activeText = color; |
85 | } |
86 | |
87 | KIconColors::KIconColors(const QPalette &palette) |
88 | : d_ptr(new KIconColorsPrivate) |
89 | { |
90 | Q_D(KIconColors); |
91 | d->text = palette.windowText().color(); |
92 | d->background = palette.window().color(); |
93 | d->highlight = palette.highlight().color(); |
94 | d->highlightedText = palette.highlightedText().color(); |
95 | d->accent = palette.accent().color(); |
96 | |
97 | if (!d->lastColorScheme || !d->lastPalette || palette != d->lastPalette) { |
98 | d->lastPalette = palette; |
99 | d->lastColorScheme = KColorScheme(QPalette::Active, KColorScheme::Window); |
100 | } |
101 | |
102 | d->positiveText = d->lastColorScheme->foreground(KColorScheme::PositiveText).color().name(); |
103 | d->neutralText = d->lastColorScheme->foreground(KColorScheme::NeutralText).color().name(); |
104 | d->negativeText = d->lastColorScheme->foreground(KColorScheme::NegativeText).color().name(); |
105 | d->activeText = d->lastColorScheme->foreground(KColorScheme::ActiveText).color().name(); |
106 | } |
107 | |
108 | KIconColors::~KIconColors() |
109 | { |
110 | } |
111 | |
112 | qreal luma(const QColor &color) { |
113 | return (0.299 * color.red() + 0.587 * color.green() + 0.114 * color.blue()) / 255; |
114 | } |
115 | |
116 | QString KIconColors::stylesheet(KIconLoader::States state) const |
117 | { |
118 | Q_D(const KIconColors); |
119 | |
120 | const QColor complement = |
121 | luma(color: d->background) > 0.5 ? Qt::white : Qt::black; |
122 | |
123 | const QColor contrast = |
124 | luma(color: d->background) > 0.5 ? Qt::black : Qt::white; |
125 | |
126 | QColor accentColor = d->accent; |
127 | // When selected, tint the accent color with a small portion of highlighted text color, |
128 | // because since the accent color used to be the same as the highlight color, it might cause |
129 | // icons, especially folders to "disappear" against the background |
130 | if (state == KIconLoader::SelectedState) { |
131 | const qreal tintRatio = 0.85; |
132 | const qreal r = accentColor.redF() * tintRatio + d->highlightedText.redF() * (1.0 - tintRatio); |
133 | const qreal g = accentColor.greenF() * tintRatio + d->highlightedText.greenF() * (1.0 - tintRatio); |
134 | const qreal b = accentColor.blueF() * tintRatio + d->highlightedText.blueF() * (1.0 - tintRatio); |
135 | accentColor.setRgbF(r, g, b, a: accentColor.alphaF()); |
136 | } |
137 | |
138 | return STYLESHEET_TEMPLATE() |
139 | .arg(a: state == KIconLoader::SelectedState ? d->highlightedText.name() : d->text.name()) |
140 | .arg(a: state == KIconLoader::SelectedState ? d->highlight.name() : d->background.name()) |
141 | .arg(a: state == KIconLoader::SelectedState ? d->highlightedText.name() : d->highlight.name()) |
142 | .arg(a: state == KIconLoader::SelectedState ? d->highlight.name() : d->highlightedText.name()) |
143 | .arg(a: state == KIconLoader::SelectedState ? d->highlightedText.name() : d->positiveText.name()) |
144 | .arg(a: state == KIconLoader::SelectedState ? d->highlightedText.name() : d->neutralText.name()) |
145 | .arg(a: state == KIconLoader::SelectedState ? d->highlightedText.name() : d->negativeText.name()) |
146 | .arg(a: state == KIconLoader::SelectedState ? d->highlightedText.name() : d->activeText.name()) |
147 | .arg(a: complement.name()) |
148 | .arg(a: contrast.name()) |
149 | .arg(a: accentColor.name()); |
150 | } |
151 | |
152 | QColor KIconColors::highlight() const |
153 | { |
154 | Q_D(const KIconColors); |
155 | return d->highlight; |
156 | } |
157 | |
158 | QColor KIconColors::highlightedText() const |
159 | { |
160 | Q_D(const KIconColors); |
161 | return d->highlightedText; |
162 | } |
163 | |
164 | QColor KIconColors::accent() const |
165 | { |
166 | Q_D(const KIconColors); |
167 | return d->accent; |
168 | } |
169 | |
170 | QColor KIconColors::background() const |
171 | { |
172 | Q_D(const KIconColors); |
173 | return d->background; |
174 | } |
175 | |
176 | QColor KIconColors::text() const |
177 | { |
178 | Q_D(const KIconColors); |
179 | return d->text; |
180 | } |
181 | |
182 | QColor KIconColors::negativeText() const |
183 | { |
184 | Q_D(const KIconColors); |
185 | return d->negativeText; |
186 | } |
187 | |
188 | QColor KIconColors::positiveText() const |
189 | { |
190 | Q_D(const KIconColors); |
191 | return d->positiveText; |
192 | } |
193 | |
194 | QColor KIconColors::neutralText() const |
195 | { |
196 | Q_D(const KIconColors); |
197 | return d->neutralText; |
198 | } |
199 | |
200 | QColor KIconColors::activeText() const |
201 | { |
202 | Q_D(const KIconColors); |
203 | return d->activeText; |
204 | } |
205 | |
206 | void KIconColors::setText(const QColor &color) |
207 | { |
208 | Q_D(KIconColors); |
209 | d->text = color; |
210 | } |
211 | |
212 | void KIconColors::setBackground(const QColor &color) |
213 | { |
214 | Q_D(KIconColors); |
215 | d->background = color; |
216 | } |
217 | |
218 | void KIconColors::setHighlight(const QColor &color) |
219 | { |
220 | Q_D(KIconColors); |
221 | d->highlight = color; |
222 | } |
223 | |
224 | void KIconColors::setHighlightedText(const QColor &color) |
225 | { |
226 | Q_D(KIconColors); |
227 | d->highlightedText = color; |
228 | } |
229 | |
230 | void KIconColors::setAccent(const QColor &color) |
231 | { |
232 | Q_D(KIconColors); |
233 | d->accent = color; |
234 | } |
235 | |
236 | void KIconColors::setNegativeText(const QColor &color) |
237 | { |
238 | Q_D(KIconColors); |
239 | d->negativeText = color; |
240 | } |
241 | |
242 | void KIconColors::setNeutralText(const QColor &color) |
243 | { |
244 | Q_D(KIconColors); |
245 | d->neutralText = color; |
246 | } |
247 | |
248 | void KIconColors::setPositiveText(const QColor &color) |
249 | { |
250 | Q_D(KIconColors); |
251 | d->positiveText = color; |
252 | } |
253 | |
254 | void KIconColors::setActiveText(const QColor &color) |
255 | { |
256 | Q_D(KIconColors); |
257 | d->activeText = color; |
258 | } |
259 |