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 QGTK3INTERFACE_H
5#define QGTK3INTERFACE_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 <QtCore/QString>
19#include <QtCore/QCache>
20#include <private/qflatmap_p.h>
21#include <QtCore/QObject>
22#include <QtGui/QIcon>
23#include <QtGui/QPalette>
24#include <QtWidgets/QWidget>
25#include <QtCore/QLoggingCategory>
26#include <QtGui/QPixmap>
27#include <qpa/qplatformtheme.h>
28
29#undef signals // Collides with GTK symbols
30#include <gtk/gtk.h>
31#include <gdk/gdk.h>
32#include <glib.h>
33
34QT_BEGIN_NAMESPACE
35
36Q_DECLARE_LOGGING_CATEGORY(lcQGtk3Interface);
37
38using namespace Qt::StringLiterals;
39
40class QGtk3Storage;
41
42/*!
43 \internal
44 \brief The QGtk3Interface class centralizes communication with the GTK3 library.
45
46 By encapsulating all GTK version specific syntax and conversions, it makes Qt's GTK theme
47 independent from GTK versions.
48
49 \note
50 Including GTK3 headers requires #undef signals, which disables Qt signal/slot handling.
51 */
52
53class QGtk3Interface
54{
55 Q_GADGET
56 Q_DISABLE_COPY_MOVE(QGtk3Interface)
57public:
58 QGtk3Interface(QGtk3Storage *);
59 ~QGtk3Interface();
60
61 /*!
62 * \internal
63 \enum QGtk3Interface::QGtkWidget
64 \brief Represents GTK widget types used to obtain color information.
65
66 \note The enum value gtk_Default refers to the GTK default style, rather than to a specific widget.
67 */
68 enum class QGtkWidget {
69 gtk_menu_bar,
70 gtk_menu,
71 gtk_button,
72 gtk_button_box,
73 gtk_check_button,
74 gtk_radio_button,
75 gtk_frame,
76 gtk_statusbar,
77 gtk_entry,
78 gtk_popup,
79 gtk_notebook,
80 gtk_toolbar,
81 gtk_tree_view,
82 gtk_combo_box,
83 gtk_combo_box_text,
84 gtk_progress_bar,
85 gtk_fixed,
86 gtk_separator_menu_item,
87 gtk_Default,
88 gtk_offscreen_window
89 };
90 Q_ENUM(QGtkWidget)
91
92 /*!
93 \internal
94 \enum QGtk3Interface::QGtkColorSource
95 \brief The QGtkColorSource enum represents the source of a color within a GTK widgets style context.
96
97 If the current GTK theme provides such a color for a given widget, the color can be read
98 from the style context by passing the enum's key as a property name to the GTK method
99 gtk_style_context_lookup_color. The method will return false, if no color has been found.
100 */
101 enum class QGtkColorSource {
102 Foreground,
103 Background,
104 Text,
105 Base,
106 Border
107 };
108 Q_ENUM(QGtkColorSource)
109
110 /*!
111 \internal
112 \enum QGtk3Interface::QGtkColorDefault
113 \brief The QGtkColorDefault enum represents generic GTK colors.
114
115 The GTK3 methods gtk_style_context_get_color, gtk_style_context_get_background_color, and
116 gtk_style_context_get_foreground_color always return the respective colors with a widget's
117 style context. Unless set as a property by the current GTK theme, GTK's default colors will
118 be returned.
119 These generic default colors, represented by the GtkColorDefault enum, are used as a
120 back, if a specific color property is requested but not defined in the current GTK theme.
121 */
122 enum class QGtkColorDefault {
123 Foreground,
124 Background,
125 Border
126 };
127 Q_ENUM(QGtkColorDefault)
128
129 // Create a brush from GTK widget type, color source and color state
130 QBrush brush(QGtkWidget wtype, QGtkColorSource source, GtkStateFlags state) const;
131
132 // Font & icon getters
133 QImage standardPixmap(QPlatformTheme::StandardPixmap standardPixmap) const;
134 QFont font(QPlatformTheme::Font type) const;
135 QIcon fileIcon(const QFileInfo &fileInfo) const;
136
137 // Return current GTK theme name
138 QString themeName() const;
139
140 // Derive color scheme from default colors
141 Qt::ColorScheme colorSchemeByColors() const;
142
143 // Convert GTK state to/from string
144 static int toGtkState(const QString &state);
145 static const QLatin1String fromGtkState(GtkStateFlags state);
146
147private:
148
149 // Map colors to GTK property names and default to generic color getters
150 struct ColorKey {
151 QGtkColorSource colorSource = QGtkColorSource::Background;
152 GtkStateFlags state = GTK_STATE_FLAG_NORMAL;
153
154 // struct becomes key of a map, so operator< is needed
155 bool operator<(const ColorKey& other) const {
156 return std::tie(args: colorSource, args: state) <
157 std::tie(args: other.colorSource, args: other.state);
158 }
159
160 QDebug operator<<(QDebug dbg)
161 {
162 return dbg << "QGtk3Interface::ColorKey(colorSource=" << colorSource << ", GTK state=" << fromGtkState(state) << ")";
163 }
164 };
165
166 struct ColorValue {
167 QString propertyName = QString();
168 QGtkColorDefault genericSource = QGtkColorDefault::Background;
169
170 QDebug operator<<(QDebug dbg)
171 {
172 return dbg << "QGtk3Interface::ColorValue(propertyName=" << propertyName << ", genericSource=" << genericSource << ")";
173 }
174 };
175
176 typedef QFlatMap<ColorKey, ColorValue> ColorMap;
177 ColorMap gtkColorMap;
178 void initColorMap();
179
180 GdkRGBA genericColor(GtkStyleContext *con, GtkStateFlags state, QGtkColorDefault def) const;
181
182 // Cache for GTK widgets
183 mutable QFlatMap<QGtkWidget, GtkWidget *> cache;
184
185 // Converters for GTK icon and GDK pixbuf
186 QImage qt_gtk_get_icon(const char *iconName) const;
187 QImage qt_convert_gdk_pixbuf(GdkPixbuf *buf) const;
188
189 // Create new GTK widget object
190 GtkWidget *qt_new_gtkWidget(QGtkWidget type) const;
191
192 // Deliver GTK Widget from cache or create new
193 GtkWidget *widget(QGtkWidget type) const;
194
195 // Get a GTK widget's style context. Default settings style context if nullptr
196 GtkStyleContext *context(GtkWidget *widget = nullptr) const;
197
198 // Convert GTK color into QColor
199 static inline QColor fromGdkColor (const GdkRGBA &c)
200 { return QColor::fromRgbF(r: c.red, g: c.green, b: c.blue, a: c.alpha); }
201
202 // get a QColor of a GTK widget (default settings style if nullptr)
203 QColor color (GtkWidget *widget, QGtkColorSource source, GtkStateFlags state) const;
204
205 // Mappings for GTK fonts
206 inline static constexpr QGtkWidget toWidgetType(QPlatformTheme::Font);
207 inline static constexpr QFont::Style toFontStyle(PangoStyle style);
208 inline static constexpr int toFontWeight(PangoWeight weight);
209
210};
211QT_END_NAMESPACE
212#endif // QGTK3INTERFACE_H
213

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