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#ifndef QGTK3STORAGE_P_H
5#define QGTK3STORAGE_P_H
6
7//
8// W A R N I N G
9// -------------
10//
11// This file is not part of the Qt API. It exists purely as an
12// implementation detail. This header file may change from version to
13// version without notice, or even be removed.
14//
15// We mean it.
16//
17
18#include "qgtk3interface_p.h"
19
20#include <QtCore/QJsonDocument>
21#include <QtCore/QCache>
22#include <QtCore/QString>
23#include <QtGui/QGuiApplication>
24#include <QtGui/QPalette>
25
26#include <qpa/qplatformtheme.h>
27#include <private/qflatmap_p.h>
28
29QT_BEGIN_NAMESPACE
30class QGtk3Storage
31{
32 Q_GADGET
33public:
34 QGtk3Storage();
35
36 // Enum documented in cpp file. Please keep it in line with updates made here.
37 enum class SourceType {
38 Gtk,
39 Fixed,
40 Modified,
41 Invalid
42 };
43 Q_ENUM(SourceType)
44
45 // Standard GTK source: Populate a brush from GTK
46 struct Gtk3Source {
47 QGtk3Interface::QGtkWidget gtkWidgetType;
48 QGtk3Interface::QGtkColorSource source;
49 GtkStateFlags state;
50 int width = -1;
51 int height = -1;
52 QDebug operator<<(QDebug dbg)
53 {
54 return dbg << "QGtkStorage::Gtk3Source(gtkwidgetType=" << gtkWidgetType << ", source="
55 << source << ", state=" << state << ", width=" << width << ", height="
56 << height << ")";
57 }
58 };
59
60 // Recursive source: Populate a brush by altering another source
61 struct RecursiveSource {
62 QPalette::ColorGroup colorGroup;
63 QPalette::ColorRole colorRole;
64 Qt::ColorScheme colorScheme;
65 int lighter = 100;
66 int deltaRed = 0;
67 int deltaGreen = 0;
68 int deltaBlue = 0;
69 int width = -1;
70 int height = -1;
71 QDebug operator<<(QDebug dbg)
72 {
73 return dbg << "QGtkStorage::RecursiceSource(colorGroup=" << colorGroup << ", colorRole="
74 << colorRole << ", colorScheme=" << colorScheme << ", lighter=" << lighter
75 << ", deltaRed="<< deltaRed << "deltaBlue =" << deltaBlue << "deltaGreen="
76 << deltaGreen << ", width=" << width << ", height=" << height << ")";
77 }
78 };
79
80 // Fixed source: Populate a brush with fixed values rather than reading GTK
81 struct FixedSource {
82 QBrush fixedBrush;
83 QDebug operator<<(QDebug dbg)
84 {
85 return dbg << "QGtkStorage::FixedSource(" << fixedBrush << ")";
86 }
87 };
88
89 // Data source for brushes
90 struct Source {
91 SourceType sourceType = SourceType::Invalid;
92 Gtk3Source gtk3;
93 RecursiveSource rec;
94 FixedSource fix;
95
96 // GTK constructor
97 Source(QGtk3Interface::QGtkWidget wtype, QGtk3Interface::QGtkColorSource csource,
98 GtkStateFlags cstate, int bwidth = -1, int bheight = -1) : sourceType(SourceType::Gtk)
99 {
100 gtk3.gtkWidgetType = wtype;
101 gtk3.source = csource;
102 gtk3.state = cstate;
103 gtk3.width = bwidth;
104 gtk3.height = bheight;
105 }
106
107 // Recursive constructor for darker/lighter colors
108 Source(QPalette::ColorGroup group, QPalette::ColorRole role,
109 Qt::ColorScheme scheme, int p_lighter = 100)
110 : sourceType(SourceType::Modified)
111 {
112 rec.colorGroup = group;
113 rec.colorRole = role;
114 rec.colorScheme = scheme;
115 rec.lighter = p_lighter;
116 }
117
118 // Recursive ocnstructor for color modification
119 Source(QPalette::ColorGroup group, QPalette::ColorRole role,
120 Qt::ColorScheme scheme, int p_red, int p_green, int p_blue)
121 : sourceType(SourceType::Modified)
122 {
123 rec.colorGroup = group;
124 rec.colorRole = role;
125 rec.colorScheme = scheme;
126 rec.deltaRed = p_red;
127 rec.deltaGreen = p_green;
128 rec.deltaBlue = p_blue;
129 }
130
131 // Recursive constructor for all: color modification and darker/lighter
132 Source(QPalette::ColorGroup group, QPalette::ColorRole role,
133 Qt::ColorScheme scheme, int p_lighter,
134 int p_red, int p_green, int p_blue) : sourceType(SourceType::Modified)
135 {
136 rec.colorGroup = group;
137 rec.colorRole = role;
138 rec.colorScheme = scheme;
139 rec.lighter = p_lighter;
140 rec.deltaRed = p_red;
141 rec.deltaGreen = p_green;
142 rec.deltaBlue = p_blue;
143 }
144
145 // Fixed Source constructor
146 Source(const QBrush &brush) : sourceType(SourceType::Fixed)
147 {
148 fix.fixedBrush = brush;
149 };
150
151 // Invalid constructor and getter
152 Source() : sourceType(SourceType::Invalid) {};
153 bool isValid() const { return sourceType != SourceType::Invalid; }
154
155 // Debug
156 QDebug operator<<(QDebug dbg)
157 {
158 return dbg << "QGtk3Storage::Source(sourceType=" << sourceType << ")";
159 }
160 };
161
162 // Struct with key attributes to identify a brush: color group, color role and color scheme
163 struct TargetBrush {
164 QPalette::ColorGroup colorGroup;
165 QPalette::ColorRole colorRole;
166 Qt::ColorScheme colorScheme;
167
168 // Generic constructor
169 TargetBrush(QPalette::ColorGroup group, QPalette::ColorRole role,
170 Qt::ColorScheme scheme = Qt::ColorScheme::Unknown) :
171 colorGroup(group), colorRole(role), colorScheme(scheme) {};
172
173 // Copy constructor with color scheme modifier for dark/light aware search
174 TargetBrush(const TargetBrush &other, Qt::ColorScheme scheme) :
175 colorGroup(other.colorGroup), colorRole(other.colorRole), colorScheme(scheme) {};
176
177 // struct becomes key of a map, so operator< is needed
178 bool operator<(const TargetBrush& other) const {
179 return std::tie(args: colorGroup, args: colorRole, args: colorScheme) <
180 std::tie(args: other.colorGroup, args: other.colorRole, args: other.colorScheme);
181 }
182 };
183
184 // Mapping a palette's brushes to their GTK sources
185 typedef QFlatMap<TargetBrush, Source> BrushMap;
186
187 // Storage of palettes and their GTK sources
188 typedef QFlatMap<QPlatformTheme::Palette, BrushMap> PaletteMap;
189
190 // Public getters
191 const QPalette *palette(QPlatformTheme::Palette = QPlatformTheme::SystemPalette) const;
192 QPixmap standardPixmap(QPlatformTheme::StandardPixmap standardPixmap, const QSizeF &size) const;
193 Qt::ColorScheme colorScheme() const { return m_colorScheme; };
194 static QPalette standardPalette();
195 const QString themeName() const { return m_interface ? m_interface->themeName() : QString(); };
196 const QFont *font(QPlatformTheme::Font type) const;
197 QIcon fileIcon(const QFileInfo &fileInfo) const;
198
199 // Initialization
200 void populateMap();
201 void handleThemeChange();
202
203private:
204 // Storage for palettes and their brushes
205 PaletteMap m_palettes;
206
207 std::unique_ptr<QGtk3Interface> m_interface;
208
209
210 Qt::ColorScheme m_colorScheme = Qt::ColorScheme::Unknown;
211
212 // Caches for Pixmaps, fonts and palettes
213 mutable QCache<QPlatformTheme::StandardPixmap, QImage> m_pixmapCache;
214 mutable std::array<std::optional<QPalette>, QPlatformTheme::Palette::NPalettes> m_paletteCache;
215 mutable std::array<std::optional<QFont>, QPlatformTheme::NFonts> m_fontCache;
216
217 // Search brush with a given GTK3 source
218 QBrush brush(const Source &source, const BrushMap &map) const;
219
220 // Get GTK3 source for a target brush
221 Source brush (const TargetBrush &brush, const BrushMap &map) const;
222
223 // clear cache, palettes and color scheme
224 void clear();
225
226 // Data creation, import & export
227 void createMapping ();
228 const PaletteMap savePalettes() const;
229 bool save(const QString &filename, const QJsonDocument::JsonFormat f = QJsonDocument::Indented) const;
230 QJsonDocument save() const;
231 bool load(const QString &filename);
232};
233
234QT_END_NAMESPACE
235#endif // QGTK3STORAGE_H
236

source code of qtbase/src/plugins/platformthemes/gtk3/qgtk3storage_p.h