1 | // Copyright (C) 2022 The Qt Company Ltd. |
2 | // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only |
3 | |
4 | // |
5 | // W A R N I N G |
6 | // ------------- |
7 | // |
8 | // This file is not part of the Qt API. It exists purely as an |
9 | // implementation detail. This header file may change from version to |
10 | // version without notice, or even be removed. |
11 | // |
12 | // We mean it. |
13 | // |
14 | |
15 | #include "qgtk3json_p.h" |
16 | #include "qgtk3storage_p.h" |
17 | #include <qpa/qwindowsysteminterface.h> |
18 | |
19 | QT_BEGIN_NAMESPACE |
20 | |
21 | QGtk3Storage::QGtk3Storage() |
22 | { |
23 | m_interface.reset(p: new QGtk3Interface(this)); |
24 | populateMap(); |
25 | } |
26 | |
27 | /*! |
28 | \internal |
29 | \enum QGtk3Storage::SourceType |
30 | \brief This enum represents the type of a color source. |
31 | |
32 | \value Gtk Color is read from a GTK widget |
33 | \value Fixed A fixed brush is specified |
34 | \value Modified The color is a modification of another color (fixed or read from GTK) |
35 | \omitvalue Invalid |
36 | */ |
37 | |
38 | /*! |
39 | \internal |
40 | \brief Find a brush from a source. |
41 | |
42 | Returns a QBrush from a given \param source and a \param map of available brushes |
43 | to search from. |
44 | |
45 | A null QBrush is returned, if no brush corresponding to the source has been found. |
46 | */ |
47 | QBrush QGtk3Storage::brush(const Source &source, const BrushMap &map) const |
48 | { |
49 | switch (source.sourceType) { |
50 | case SourceType::Gtk: |
51 | return m_interface ? QBrush(m_interface->brush(wtype: source.gtk3.gtkWidgetType, |
52 | source: source.gtk3.source, state: source.gtk3.state)) |
53 | : QBrush(); |
54 | |
55 | case SourceType::Modified: { |
56 | // don't loop through modified sources, break if modified source not found |
57 | Source recSource = brush(brush: TargetBrush(source.rec.colorGroup, source.rec.colorRole, |
58 | source.rec.colorScheme), map); |
59 | |
60 | if (!recSource.isValid() || (recSource.sourceType == SourceType::Modified)) |
61 | return QBrush(); |
62 | |
63 | // Set brush and alter color |
64 | QBrush b = brush(source: recSource, map); |
65 | if (source.rec.width > 0 && source.rec.height > 0) |
66 | b.setTexture(QPixmap(source.rec.width, source.rec.height)); |
67 | QColor c = b.color().lighter(f: source.rec.lighter); |
68 | c = QColor((c.red() + source.rec.deltaRed), |
69 | (c.green() + source.rec.deltaGreen), |
70 | (c.blue() + source.rec.deltaBlue)); |
71 | b.setColor(c); |
72 | return b; |
73 | } |
74 | |
75 | case SourceType::Fixed: |
76 | return source.fix.fixedBrush; |
77 | |
78 | case SourceType::Invalid: |
79 | return QBrush(); |
80 | } |
81 | |
82 | // needed because of the scope after recursive |
83 | Q_UNREACHABLE(); |
84 | } |
85 | |
86 | /*! |
87 | \internal |
88 | \brief Recurse to find a source brush for modification. |
89 | |
90 | Returns the source specified by the target brush \param b in the \param map of brushes. |
91 | Takes dark/light/unknown into consideration. |
92 | Returns an empty brush if no suitable one can be found. |
93 | */ |
94 | QGtk3Storage::Source QGtk3Storage::brush(const TargetBrush &b, const BrushMap &map) const |
95 | { |
96 | #define FIND(brush) if (map.contains(brush))\ |
97 | return map.value(brush) |
98 | |
99 | // Return exact match |
100 | FIND(b); |
101 | |
102 | // unknown color scheme can find anything |
103 | if (b.colorScheme == Qt::ColorScheme::Unknown) { |
104 | FIND(TargetBrush(b, Qt::ColorScheme::Dark)); |
105 | FIND(TargetBrush(b, Qt::ColorScheme::Light)); |
106 | } |
107 | |
108 | // Color group All can always be found |
109 | if (b.colorGroup != QPalette::All) |
110 | return brush(b: TargetBrush(QPalette::All, b.colorRole, b.colorScheme), map); |
111 | |
112 | // Brush not found |
113 | return Source(); |
114 | #undef FIND |
115 | } |
116 | |
117 | /*! |
118 | \internal |
119 | \brief Returns a simple, hard coded base palette. |
120 | |
121 | Create a hard coded palette with default colors as a fallback for any color that can't be |
122 | obtained from GTK. |
123 | |
124 | \note This palette will be used as a default baseline for the system palette, which then |
125 | will be used as a default baseline for any other palette type. |
126 | */ |
127 | QPalette QGtk3Storage::standardPalette() |
128 | { |
129 | QColor backgroundColor(0xd4, 0xd0, 0xc8); |
130 | QColor lightColor(backgroundColor.lighter()); |
131 | QColor darkColor(backgroundColor.darker()); |
132 | const QBrush darkBrush(darkColor); |
133 | QColor midColor(Qt::gray); |
134 | QPalette palette(Qt::black, backgroundColor, lightColor, darkColor, |
135 | midColor, Qt::black, Qt::white); |
136 | palette.setBrush(cg: QPalette::Disabled, cr: QPalette::WindowText, brush: darkBrush); |
137 | palette.setBrush(cg: QPalette::Disabled, cr: QPalette::Text, brush: darkBrush); |
138 | palette.setBrush(cg: QPalette::Disabled, cr: QPalette::ButtonText, brush: darkBrush); |
139 | palette.setBrush(cg: QPalette::Disabled, cr: QPalette::Base, brush: QBrush(backgroundColor)); |
140 | return palette; |
141 | } |
142 | |
143 | /*! |
144 | \internal |
145 | \brief Return a GTK styled QPalette. |
146 | |
147 | Returns the pointer to a (cached) QPalette for \param type, with its brushes |
148 | populated according to the current GTK theme. |
149 | */ |
150 | const QPalette *QGtk3Storage::palette(QPlatformTheme::Palette type) const |
151 | { |
152 | if (type >= QPlatformTheme::NPalettes) |
153 | return nullptr; |
154 | |
155 | if (m_paletteCache[type].has_value()) { |
156 | qCDebug(lcQGtk3Interface) << "Returning palette from cache:" |
157 | << QGtk3Json::fromPalette(palette: type); |
158 | |
159 | return &m_paletteCache[type].value(); |
160 | } |
161 | |
162 | // Read system palette as a baseline first |
163 | if (!m_paletteCache[QPlatformTheme::SystemPalette].has_value() && type != QPlatformTheme::SystemPalette) |
164 | palette(); |
165 | |
166 | // Fall back to system palette for unknown types |
167 | if (!m_palettes.contains(key: type) && type != QPlatformTheme::SystemPalette) { |
168 | qCDebug(lcQGtk3Interface) << "Returning system palette for unknown type" |
169 | << QGtk3Json::fromPalette(palette: type); |
170 | return palette(); |
171 | } |
172 | |
173 | BrushMap brushes = m_palettes.value(key: type); |
174 | |
175 | // Standard palette is base for system palette. System palette is base for all others. |
176 | QPalette p = QPalette( type == QPlatformTheme::SystemPalette ? standardPalette() |
177 | : m_paletteCache[QPlatformTheme::SystemPalette].value()); |
178 | |
179 | qCDebug(lcQGtk3Interface) << "Creating palette:" << QGtk3Json::fromPalette(palette: type); |
180 | for (auto i = brushes.begin(); i != brushes.end(); ++i) { |
181 | Source source = i.value(); |
182 | |
183 | // Brush is set if |
184 | // - theme and source color scheme match |
185 | // - or either of them is unknown |
186 | const auto appSource = i.key().colorScheme; |
187 | const auto appTheme = colorScheme(); |
188 | const bool setBrush = (appSource == appTheme) || |
189 | (appSource == Qt::ColorScheme::Unknown) || |
190 | (appTheme == Qt::ColorScheme::Unknown); |
191 | |
192 | if (setBrush) { |
193 | p.setBrush(cg: i.key().colorGroup, cr: i.key().colorRole, brush: brush(source, map: brushes)); |
194 | } |
195 | } |
196 | |
197 | m_paletteCache[type].emplace(args&: p); |
198 | if (type == QPlatformTheme::SystemPalette) |
199 | qCDebug(lcQGtk3Interface) << "System Palette defined" << themeName() << colorScheme() << p; |
200 | |
201 | return &m_paletteCache[type].value(); |
202 | } |
203 | |
204 | /*! |
205 | \internal |
206 | \brief Return a GTK styled font. |
207 | |
208 | Returns a QFont of \param type, styled according to the current GTK theme. |
209 | */ |
210 | const QFont *QGtk3Storage::font(QPlatformTheme::Font type) const |
211 | { |
212 | if (m_fontCache[type].has_value()) |
213 | return &m_fontCache[type].value(); |
214 | |
215 | m_fontCache[type].emplace(args: m_interface->font(type)); |
216 | return &m_fontCache[type].value(); |
217 | } |
218 | |
219 | /*! |
220 | \internal |
221 | \brief Return a GTK styled standard pixmap if available. |
222 | |
223 | Returns a pixmap specified by \param standardPixmap and \param size. |
224 | Returns an empty pixmap if GTK doesn't support the requested one. |
225 | */ |
226 | QPixmap QGtk3Storage::standardPixmap(QPlatformTheme::StandardPixmap standardPixmap, |
227 | const QSizeF &size) const |
228 | { |
229 | if (m_pixmapCache.contains(key: standardPixmap)) |
230 | return QPixmap::fromImage(image: m_pixmapCache.object(key: standardPixmap)->scaled(s: size.toSize())); |
231 | |
232 | if (!m_interface) |
233 | return QPixmap(); |
234 | |
235 | QImage image = m_interface->standardPixmap(standardPixmap); |
236 | if (image.isNull()) |
237 | return QPixmap(); |
238 | |
239 | m_pixmapCache.insert(key: standardPixmap, object: new QImage(image)); |
240 | return QPixmap::fromImage(image: image.scaled(s: size.toSize())); |
241 | } |
242 | |
243 | /*! |
244 | \internal |
245 | \brief Returns a GTK styled file icon corresponding to \param fileInfo. |
246 | */ |
247 | QIcon QGtk3Storage::fileIcon(const QFileInfo &fileInfo) const |
248 | { |
249 | return m_interface ? m_interface->fileIcon(fileInfo) : QIcon(); |
250 | } |
251 | |
252 | /*! |
253 | \internal |
254 | \brief Clears all caches. |
255 | */ |
256 | void QGtk3Storage::clear() |
257 | { |
258 | m_colorScheme = Qt::ColorScheme::Unknown; |
259 | m_palettes.clear(); |
260 | for (auto &cache : m_paletteCache) |
261 | cache.reset(); |
262 | |
263 | for (auto &cache : m_fontCache) |
264 | cache.reset(); |
265 | } |
266 | |
267 | /*! |
268 | \internal |
269 | \brief Handles a theme change at runtime. |
270 | |
271 | Clear all caches, re-populate with current GTK theme and notify the window system interface. |
272 | This method is a callback for the theme change signal sent from GTK. |
273 | */ |
274 | void QGtk3Storage::handleThemeChange() |
275 | { |
276 | clear(); |
277 | populateMap(); |
278 | QWindowSystemInterface::handleThemeChange(); |
279 | } |
280 | |
281 | /*! |
282 | \internal |
283 | \brief Populates a map with information about how to locate colors in GTK. |
284 | |
285 | This method creates a data structure to locate color information for each brush of a QPalette |
286 | within GTK. The structure can hold mapping information for each QPlatformTheme::Palette |
287 | enum value. If no specific mapping is stored for an enum value, the system palette is returned |
288 | instead of a specific one. If no mapping is stored for the system palette, it will fall back to |
289 | QGtk3Storage::standardPalette. |
290 | |
291 | The method will populate the data structure with a standard mapping, covering the following |
292 | palette types: |
293 | \list |
294 | \li QPlatformTheme::SystemPalette |
295 | \li QPlatformTheme::CheckBoxPalette |
296 | \li QPlatformTheme::RadioButtonPalette |
297 | \li QPlatformTheme::ComboBoxPalette |
298 | \li QPlatformTheme::GroupBoxPalette |
299 | \li QPlatformTheme::MenuPalette |
300 | \li QPlatformTheme::TextLineEditPalette |
301 | \endlist |
302 | |
303 | The method will check the environment variable {{QT_GUI_GTK_JSON_SAVE}}. If it points to a |
304 | valid path with write access, it will write the standard mapping into a Json file. |
305 | That Json file can be modified and/or extended. |
306 | The Json syntax is |
307 | - "QGtk3Palettes" (top level value) |
308 | - QPlatformTheme::Palette |
309 | - QPalette::ColorRole |
310 | - Qt::ColorScheme |
311 | - Qt::ColorGroup |
312 | - Source data |
313 | - Source Type |
314 | - [source data] |
315 | |
316 | If the environment variable {{QT_GUI_GTK_JSON_HARDCODED}} contains the keyword \c true, |
317 | all sources are converted to fixed sources. In that case, they contain the hard coded HexRGBA |
318 | values read from GTK. |
319 | |
320 | The method will also check the environment variable {{QT_GUI_GTK_JSON}}. If it points to a valid |
321 | Json file with read access, it will be parsed instead of creating a standard mapping. |
322 | Parsing errors will be printed out with qCInfo if the logging category {{qt.qpa.gtk}} is activated. |
323 | In case of a parsing error, the method will fall back to creating a standard mapping. |
324 | |
325 | \note |
326 | If a Json file contains only fixed brushes (e.g. exported with {{QT_GUI_GTK_JSON_HARDCODED=true}}), |
327 | no colors will be imported from GTK. |
328 | */ |
329 | void QGtk3Storage::populateMap() |
330 | { |
331 | static QString m_themeName; |
332 | |
333 | // Distiguish initialization, theme change or call without theme change |
334 | const QString newThemeName = themeName(); |
335 | if (m_themeName == newThemeName) |
336 | return; |
337 | |
338 | clear(); |
339 | |
340 | // Derive color scheme from theme name |
341 | m_colorScheme = newThemeName.contains(s: "dark"_L1 , cs: Qt::CaseInsensitive) |
342 | ? Qt::ColorScheme::Dark : m_interface->colorSchemeByColors(); |
343 | |
344 | if (m_themeName.isEmpty()) { |
345 | qCDebug(lcQGtk3Interface) << "GTK theme initialized:" << newThemeName << m_colorScheme; |
346 | } else { |
347 | qCDebug(lcQGtk3Interface) << "GTK theme changed to:" << newThemeName << m_colorScheme; |
348 | } |
349 | m_themeName = newThemeName; |
350 | |
351 | // create standard mapping or load from Json file? |
352 | const QString jsonInput = qEnvironmentVariable(varName: "QT_GUI_GTK_JSON" ); |
353 | if (!jsonInput.isEmpty()) { |
354 | if (load(filename: jsonInput)) { |
355 | return; |
356 | } else { |
357 | qWarning() << "Falling back to standard GTK mapping." ; |
358 | } |
359 | } |
360 | |
361 | createMapping(); |
362 | |
363 | const QString jsonOutput = qEnvironmentVariable(varName: "QT_GUI_GTK_JSON_SAVE" ); |
364 | if (!jsonOutput.isEmpty() && !save(filename: jsonOutput)) |
365 | qWarning() << "File" << jsonOutput << "could not be saved.\n" ; |
366 | } |
367 | |
368 | /*! |
369 | \internal |
370 | \brief Return a palette map for saving. |
371 | |
372 | This method returns the existing palette map, if the environment variable |
373 | {{QT_GUI_GTK_JSON_HARDCODED}} is not set or does not contain the keyword \c true. |
374 | If it contains the keyword \c true, it returns a palette map with all brush |
375 | sources converted to fixed sources. |
376 | */ |
377 | const QGtk3Storage::PaletteMap QGtk3Storage::savePalettes() const |
378 | { |
379 | const QString hard = qEnvironmentVariable(varName: "QT_GUI_GTK_JSON_HARDCODED" ); |
380 | if (!hard.contains(s: "true"_L1 , cs: Qt::CaseInsensitive)) |
381 | return m_palettes; |
382 | |
383 | // Json output is supposed to be readable without GTK connection |
384 | // convert palette map into hard coded brushes |
385 | PaletteMap map = m_palettes; |
386 | for (auto paletteIterator = map.begin(); paletteIterator != map.end(); |
387 | ++paletteIterator) { |
388 | QGtk3Storage::BrushMap &bm = paletteIterator.value(); |
389 | for (auto brushIterator = bm.begin(); brushIterator != bm.end(); |
390 | ++brushIterator) { |
391 | QGtk3Storage::Source &s = brushIterator.value(); |
392 | switch (s.sourceType) { |
393 | |
394 | // Read the brush and convert it into a fixed brush |
395 | case SourceType::Gtk: { |
396 | const QBrush fixedBrush = brush(source: s, map: bm); |
397 | s.fix.fixedBrush = fixedBrush; |
398 | s.sourceType = SourceType::Fixed; |
399 | } |
400 | break; |
401 | case SourceType::Fixed: |
402 | case SourceType::Modified: |
403 | case SourceType::Invalid: |
404 | break; |
405 | } |
406 | } |
407 | } |
408 | return map; |
409 | } |
410 | |
411 | /*! |
412 | \internal |
413 | \brief Saves current palette mapping to a \param filename with Json format \param f. |
414 | |
415 | Saves the current palette mapping into a QJson file, |
416 | taking {{QT_GUI_GTK_JSON_HARDCODED}} into consideration. |
417 | Returns \c true if saving was successful and \c false otherwise. |
418 | */ |
419 | bool QGtk3Storage::save(const QString &filename, QJsonDocument::JsonFormat f) const |
420 | { |
421 | return QGtk3Json::save(map: savePalettes(), fileName: filename, format: f); |
422 | } |
423 | |
424 | /*! |
425 | \internal |
426 | \brief Returns a QJsonDocument with current palette mapping. |
427 | |
428 | Saves the current palette mapping into a QJsonDocument, |
429 | taking {{QT_GUI_GTK_JSON_HARDCODED}} into consideration. |
430 | Returns \c true if saving was successful and \c false otherwise. |
431 | */ |
432 | QJsonDocument QGtk3Storage::save() const |
433 | { |
434 | return QGtk3Json::save(map: savePalettes()); |
435 | } |
436 | |
437 | /*! |
438 | \internal |
439 | \brief Loads palette mapping from Json file \param filename. |
440 | |
441 | Returns \c true if the file was successfully parsed and \c false otherwise. |
442 | */ |
443 | bool QGtk3Storage::load(const QString &filename) |
444 | { |
445 | return QGtk3Json::load(map&: m_palettes, fileName: filename); |
446 | } |
447 | |
448 | /*! |
449 | \internal |
450 | \brief Creates a standard palette mapping. |
451 | |
452 | The method creates a hard coded standard mapping, used if no external Json file |
453 | containing a valid mapping has been specified in the environment variable {{QT_GUI_GTK_JSON}}. |
454 | */ |
455 | void QGtk3Storage::createMapping() |
456 | { |
457 | // Hard code standard mapping |
458 | BrushMap map; |
459 | Source source; |
460 | |
461 | // Define a GTK source |
462 | #define GTK(wtype, colorSource, state)\ |
463 | source = Source(QGtk3Interface::QGtkWidget::gtk_ ##wtype,\ |
464 | QGtk3Interface::QGtkColorSource::colorSource, GTK_STATE_FLAG_ ##state) |
465 | |
466 | // Define a modified source |
467 | #define LIGHTER(group, role, lighter)\ |
468 | source = Source(QPalette::group, QPalette::role,\ |
469 | Qt::ColorScheme::Unknown, lighter) |
470 | #define MODIFY(group, role, red, green, blue)\ |
471 | source = Source(QPalette::group, QPalette::role,\ |
472 | Qt::ColorScheme::Unknown, red, green, blue) |
473 | |
474 | // Define fixed source |
475 | #define FIX(color) source = FixedSource(color); |
476 | |
477 | // Add the source to a target brush |
478 | // Use default Qt::ColorScheme::Unknown, if no color scheme was specified |
479 | #define ADD_2(group, role) map.insert(TargetBrush(QPalette::group, QPalette::role), source); |
480 | #define ADD_3(group, role, app) map.insert(TargetBrush(QPalette::group, QPalette::role,\ |
481 | Qt::ColorScheme::app), source); |
482 | #define ADD_X(x, group, role, app, FUNC, ...) FUNC |
483 | #define ADD(...) ADD_X(,##__VA_ARGS__, ADD_3(__VA_ARGS__), ADD_2(__VA_ARGS__)) |
484 | // Save target brushes to a palette type |
485 | #define SAVE(palette) m_palettes.insert(QPlatformTheme::palette, map) |
486 | // Clear brushes to start next palette |
487 | #define CLEAR map.clear() |
488 | |
489 | /* |
490 | Macro usage: |
491 | |
492 | 1. Define a source |
493 | GTK(QGtkWidget, QGtkColorSource, GTK_STATE_FLAG) |
494 | Fetch the color from a GtkWidget, related to a source and a state. |
495 | |
496 | LIGHTER(ColorGroup, ColorROle, lighter) |
497 | Use a color of the same QPalette related to ColorGroup and ColorRole. |
498 | Make the color lighter (if lighter >100) or darker (if lighter < 100) |
499 | |
500 | MODIFY(ColorGroup, ColorRole, red, green, blue) |
501 | Use a color of the same QPalette related to ColorGroup and ColorRole. |
502 | Modify it by adding red, green, blue. |
503 | |
504 | FIX(const QBrush &) |
505 | Use a fixed brush without querying GTK |
506 | |
507 | 2. Define the target |
508 | Use ADD(ColorGroup, ColorRole) to use the defined source for the |
509 | color group / role in the current palette. |
510 | |
511 | Use ADD(ColorGroup, ColorRole, ColorScheme) to use the defined source |
512 | only for a specific color scheme |
513 | |
514 | 3. Save mapping |
515 | Save the defined mappings for a specific palette. |
516 | If a mapping entry does not cover all color groups and roles of a palette, |
517 | the system palette will be used for the remaining values. |
518 | If the system palette does not have all combination of color groups and roles, |
519 | the remaining ones will be populated by a hard coded fusion-style like palette. |
520 | |
521 | 4. Clear mapping |
522 | Use CLEAR to clear the mapping and begin a new one. |
523 | */ |
524 | |
525 | |
526 | // System palette |
527 | // background color and calculate derivates |
528 | GTK(Default, Background, INSENSITIVE); |
529 | ADD(Normal, Window); |
530 | ADD(Normal, Button); |
531 | ADD(Normal, Base); |
532 | ADD(Inactive, Base); |
533 | ADD(Inactive, Window); |
534 | LIGHTER(Normal, Window, 125); |
535 | ADD(Normal, Light); |
536 | LIGHTER(Normal, Window, 70); |
537 | ADD(Normal, Shadow); |
538 | LIGHTER(Normal, Window, 80); |
539 | ADD(Normal, Dark); |
540 | GTK(button, Foreground, ACTIVE); |
541 | ADD(Inactive, WindowText); |
542 | LIGHTER(Normal, WindowText, 50); |
543 | ADD(Disabled, Text); |
544 | ADD(Disabled, WindowText); |
545 | ADD(Inactive, ButtonText); |
546 | GTK(button, Text, NORMAL); |
547 | ADD(Disabled, ButtonText); |
548 | // special background colors |
549 | GTK(Default, Background, SELECTED); |
550 | ADD(Disabled, Highlight); |
551 | ADD(Normal, Highlight); |
552 | GTK(entry, Foreground, SELECTED); |
553 | ADD(Normal, HighlightedText); |
554 | GTK(entry, Background, ACTIVE); |
555 | ADD(Inactive, HighlightedText); |
556 | // text color and friends |
557 | GTK(entry, Text, NORMAL); |
558 | ADD(Normal, ButtonText); |
559 | ADD(Normal, WindowText); |
560 | ADD(Disabled, WindowText); |
561 | ADD(Disabled, HighlightedText); |
562 | GTK(Default, Text, NORMAL); |
563 | ADD(Normal, Text); |
564 | ADD(Normal, WindowText); |
565 | ADD(Inactive, Text); |
566 | ADD(Normal, HighlightedText); |
567 | LIGHTER(Normal, Base, 93); |
568 | ADD(All, AlternateBase); |
569 | GTK(Default, Foreground, NORMAL); |
570 | ADD(All, ToolTipText); |
571 | MODIFY(Normal, Text, 100, 100, 100); |
572 | ADD(All, PlaceholderText, Light); |
573 | MODIFY(Normal, Text, -100, -100, -100); |
574 | ADD(All, PlaceholderText, Dark); |
575 | SAVE(SystemPalette); |
576 | CLEAR; |
577 | |
578 | // Checkbox and Radio Button |
579 | GTK(button, Text, ACTIVE); |
580 | ADD(Normal, Base, Dark); |
581 | GTK(Default, Background, NORMAL); |
582 | ADD(All, Base); |
583 | GTK(button, Text, NORMAL); |
584 | ADD(Normal, Base, Light); |
585 | SAVE(CheckBoxPalette); |
586 | SAVE(RadioButtonPalette); |
587 | CLEAR; |
588 | |
589 | // ComboBox, GroupBox, Frame |
590 | GTK(combo_box, Text, NORMAL); |
591 | ADD(Normal, ButtonText, Dark); |
592 | ADD(Normal, Text, Dark); |
593 | GTK(combo_box, Text, ACTIVE); |
594 | ADD(Normal, ButtonText, Light); |
595 | ADD(Normal, Text, Light); |
596 | SAVE(ComboBoxPalette); |
597 | SAVE(GroupBoxPalette); |
598 | CLEAR; |
599 | |
600 | // Menu bar |
601 | GTK(Default, Text, ACTIVE); |
602 | ADD(Normal, ButtonText); |
603 | SAVE(MenuPalette); |
604 | CLEAR; |
605 | |
606 | // LineEdit |
607 | GTK(Default, Background, NORMAL); |
608 | ADD(All, Base); |
609 | SAVE(TextLineEditPalette); |
610 | CLEAR; |
611 | |
612 | #undef GTK |
613 | #undef REC |
614 | #undef FIX |
615 | #undef ADD |
616 | #undef ADD_2 |
617 | #undef ADD_3 |
618 | #undef ADD_X |
619 | #undef SAVE |
620 | #undef LOAD |
621 | } |
622 | |
623 | QT_END_NAMESPACE |
624 | |