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

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