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#if QT_CONFIG(dbus)
20#include "qgtk3portalinterface_p.h"
21#endif
22
23#include <QtCore/QJsonDocument>
24#include <QtCore/QCache>
25#include <QtCore/QString>
26#include <QtGui/QGuiApplication>
27#include <QtGui/QPalette>
28
29#include <qpa/qplatformtheme.h>
30#include <private/qflatmap_p.h>
31
32QT_BEGIN_NAMESPACE
33class QGtk3Storage
34{
35 Q_GADGET
36public:
37 QGtk3Storage();
38
39 // Enum documented in cpp file. Please keep it in line with updates made here.
40 enum class SourceType {
41 Gtk,
42 Fixed,
43 Modified,
44 Mixed,
45 Invalid
46 };
47 Q_ENUM(SourceType)
48
49 // Standard GTK source: Populate a brush from GTK
50 struct Gtk3Source {
51 QGtk3Interface::QGtkWidget gtkWidgetType;
52 QGtk3Interface::QGtkColorSource source;
53 GtkStateFlags state;
54 int width = -1;
55 int height = -1;
56 QDebug operator<<(QDebug dbg)
57 {
58 return dbg << "QGtkStorage::Gtk3Source(gtkwidgetType=" << gtkWidgetType << ", source="
59 << source << ", state=" << state << ", width=" << width << ", height="
60 << height << ")";
61 }
62 };
63
64 // Recursive source: Populate a brush by altering another source
65 struct RecursiveSource {
66 QPalette::ColorGroup colorGroup;
67 QPalette::ColorRole colorRole;
68 Qt::ColorScheme colorScheme;
69 int lighter = 100;
70 int deltaRed = 0;
71 int deltaGreen = 0;
72 int deltaBlue = 0;
73 int width = -1;
74 int height = -1;
75 QDebug operator<<(QDebug dbg)
76 {
77 return dbg << "QGtkStorage::RecursiceSource(colorGroup=" << colorGroup << ", colorRole="
78 << colorRole << ", colorScheme=" << colorScheme << ", lighter=" << lighter
79 << ", deltaRed="<< deltaRed << "deltaBlue =" << deltaBlue << "deltaGreen="
80 << deltaGreen << ", width=" << width << ", height=" << height << ")";
81 }
82 };
83
84 // Mixed source: Populate a brush by mixing two brushes.
85 // Useful for creating disabled color by mixing,
86 // for example the background and foreground colors.
87 struct MixSources {
88 QPalette::ColorGroup sourceGroup; // source group of the mixing color roles
89 QPalette::ColorRole colorRole1;
90 QPalette::ColorRole colorRole2;
91 QDebug operator<<(QDebug dbg)
92 {
93 return dbg << "QGtkStorage::MixSources(sourceGroup=" << sourceGroup
94 << ", colorRole1=" << colorRole1
95 << ", colorRole2=" << colorRole2 << ")";
96 }
97 static inline QColor mixColors(const QColor &color1, const QColor &color2)
98 {
99 return QColor{ (color1.red() + color2.red()) / 2,
100 (color1.green() + color2.green()) / 2,
101 (color1.blue() + color2.blue()) / 2 };
102 }
103 };
104
105 // Fixed source: Populate a brush with fixed values rather than reading GTK
106 struct FixedSource {
107 QBrush fixedBrush;
108 QDebug operator<<(QDebug dbg)
109 {
110 return dbg << "QGtkStorage::FixedSource(" << fixedBrush << ")";
111 }
112 };
113
114 // Data source for brushes
115 struct Source {
116 SourceType sourceType = SourceType::Invalid;
117 Gtk3Source gtk3;
118 RecursiveSource rec;
119 FixedSource fix;
120 MixSources mix;
121
122 // GTK constructor
123 Source(QGtk3Interface::QGtkWidget wtype, QGtk3Interface::QGtkColorSource csource,
124 GtkStateFlags cstate, int bwidth = -1, int bheight = -1) : sourceType(SourceType::Gtk)
125 {
126 gtk3.gtkWidgetType = wtype;
127 gtk3.source = csource;
128 gtk3.state = cstate;
129 gtk3.width = bwidth;
130 gtk3.height = bheight;
131 }
132
133 // Recursive constructor for darker/lighter colors
134 Source(QPalette::ColorGroup group, QPalette::ColorRole role,
135 Qt::ColorScheme scheme, int p_lighter = 100)
136 : sourceType(SourceType::Modified)
137 {
138 rec.colorGroup = group;
139 rec.colorRole = role;
140 rec.colorScheme = scheme;
141 rec.lighter = p_lighter;
142 }
143
144 // Recursive constructor for color modification
145 Source(QPalette::ColorGroup group, QPalette::ColorRole role,
146 Qt::ColorScheme scheme, int p_red, int p_green, int p_blue)
147 : sourceType(SourceType::Modified)
148 {
149 rec.colorGroup = group;
150 rec.colorRole = role;
151 rec.colorScheme = scheme;
152 rec.deltaRed = p_red;
153 rec.deltaGreen = p_green;
154 rec.deltaBlue = p_blue;
155 }
156
157 // Recursive constructor for all: color modification and darker/lighter
158 Source(QPalette::ColorGroup group, QPalette::ColorRole role,
159 Qt::ColorScheme scheme, int p_lighter,
160 int p_red, int p_green, int p_blue) : sourceType(SourceType::Modified)
161 {
162 rec.colorGroup = group;
163 rec.colorRole = role;
164 rec.colorScheme = scheme;
165 rec.lighter = p_lighter;
166 rec.deltaRed = p_red;
167 rec.deltaGreen = p_green;
168 rec.deltaBlue = p_blue;
169 }
170
171 // Mixed constructor for color modification
172 Source(QPalette::ColorGroup sourceGroup,
173 QPalette::ColorRole role1, QPalette::ColorRole role2)
174 : sourceType(SourceType::Mixed)
175 {
176 mix.sourceGroup = sourceGroup;
177 mix.colorRole1 = role1;
178 mix.colorRole2 = role2;
179 }
180
181 // Fixed Source constructor
182 Source(const QBrush &brush) : sourceType(SourceType::Fixed)
183 {
184 fix.fixedBrush = brush;
185 };
186
187 // Invalid constructor and getter
188 Source() : sourceType(SourceType::Invalid) {};
189 bool isValid() const { return sourceType != SourceType::Invalid; }
190
191 // Debug
192 QDebug operator<<(QDebug dbg)
193 {
194 return dbg << "QGtk3Storage::Source(sourceType=" << sourceType << ")";
195 }
196 };
197
198 // Struct with key attributes to identify a brush: color group, color role and color scheme
199 struct TargetBrush {
200 QPalette::ColorGroup colorGroup;
201 QPalette::ColorRole colorRole;
202 Qt::ColorScheme colorScheme;
203
204 // Generic constructor
205 TargetBrush(QPalette::ColorGroup group, QPalette::ColorRole role,
206 Qt::ColorScheme scheme = Qt::ColorScheme::Unknown) :
207 colorGroup(group), colorRole(role), colorScheme(scheme) {};
208
209 // Copy constructor with color scheme modifier for dark/light aware search
210 TargetBrush(const TargetBrush &other, Qt::ColorScheme scheme) :
211 colorGroup(other.colorGroup), colorRole(other.colorRole), colorScheme(scheme) {};
212
213 // struct becomes key of a map, so operator< is needed
214 bool operator<(const TargetBrush& other) const {
215 return std::tie(args: colorGroup, args: colorRole, args: colorScheme) <
216 std::tie(args: other.colorGroup, args: other.colorRole, args: other.colorScheme);
217 }
218 };
219
220 // Mapping a palette's brushes to their GTK sources
221 typedef QFlatMap<TargetBrush, Source> BrushMap;
222
223 // Storage of palettes and their GTK sources
224 typedef QFlatMap<QPlatformTheme::Palette, BrushMap> PaletteMap;
225
226 // Public getters
227 const QPalette *palette(QPlatformTheme::Palette = QPlatformTheme::SystemPalette) const;
228 QPixmap standardPixmap(QPlatformTheme::StandardPixmap standardPixmap, const QSizeF &size) const;
229 Qt::ColorScheme colorScheme() const { return m_colorScheme; };
230 static QPalette standardPalette();
231 const QString themeName() const { return m_interface ? m_interface->themeName() : QString(); };
232 const QFont *font(QPlatformTheme::Font type) const;
233 QIcon fileIcon(const QFileInfo &fileInfo) const;
234
235 // Initialization
236 void populateMap();
237 void handleThemeChange();
238
239private:
240 // Storage for palettes and their brushes
241 PaletteMap m_palettes;
242
243 std::unique_ptr<QGtk3Interface> m_interface;
244#if QT_CONFIG(dbus)
245 std::unique_ptr<QGtk3PortalInterface> m_portalInterface;
246#endif
247
248 Qt::ColorScheme m_colorScheme = Qt::ColorScheme::Unknown;
249
250 // Caches for Pixmaps, fonts and palettes
251 mutable QCache<QPlatformTheme::StandardPixmap, QImage> m_pixmapCache;
252 mutable std::array<std::optional<QPalette>, QPlatformTheme::Palette::NPalettes> m_paletteCache;
253 mutable std::array<std::optional<QFont>, QPlatformTheme::NFonts> m_fontCache;
254
255 // Search brush with a given GTK3 source
256 QBrush brush(const Source &source, const BrushMap &map) const;
257
258 // Get GTK3 source for a target brush
259 Source brush (const TargetBrush &brush, const BrushMap &map) const;
260
261 // clear cache, palettes and color scheme
262 void clear();
263
264 // Data creation, import & export
265 void createMapping ();
266 const PaletteMap savePalettes() const;
267 bool save(const QString &filename, const QJsonDocument::JsonFormat f = QJsonDocument::Indented) const;
268 QJsonDocument save() const;
269 bool load(const QString &filename);
270};
271
272QT_END_NAMESPACE
273#endif // QGTK3STORAGE_H
274

Provided by KDAB

Privacy Policy
Start learning QML with our Intro Training
Find out more

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