Qt
Internal/Contributor docs for the Qt SDK. <b>Note:</b> These are NOT official API docs; those are found <a href='https://doc.qt.io/'>here</a>.
Loading...
Searching...
No Matches
qwindowsiconengine.cpp
Go to the documentation of this file.
1// Copyright (C) 2023 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
5
6#include <QtCore/qoperatingsystemversion.h>
7#include <QtGui/qguiapplication.h>
8#include <QtGui/qpainter.h>
9#include <QtGui/qpalette.h>
10
12
13using namespace Qt::StringLiterals;
14
15QString QWindowsIconEngine::glyphs() const
16{
17 if (!QFontInfo(m_iconFont).exactMatch())
18 return {};
19
20 static constexpr std::pair<QLatin1StringView, QStringView> glyphMap[] = {
21 {"address-book-new"_L1, u"\ue780"},
22 {"application-exit"_L1, u"\ue8bb"},
23 {"appointment-new"_L1, u"\ue878"},
24 {"call-start"_L1, u"\uf715"},
25 {"call-stop"_L1, u"\uf405"},
26 {"contact-new"_L1, u"\ue8fa"},
27 {"document-new"_L1, u"\ue8a5"},
28 {"document-open"_L1, u"\ue8e5"},
29 {"document-open-recent"_L1, u"\ue823"},
30 {"document-page-setup"_L1, u"\ue7c3"},
31 {"document-print"_L1, u"\ue749"},
32 {"document-print-preview"_L1, u"\ue956"},
33 {"document-properties"_L1, u"\ue90f"},
34 {"document-revert"_L1, u"\ue7a7"}, // ?
35 {"document-save"_L1, u"\ue74e"}, // or e78c?
36 {"document-save-as"_L1, u"\ue792"},
37 {"document-send"_L1, u"\ue724"},
38 {"edit-clear"_L1, u"\ue894"},
39 {"edit-copy"_L1, u"\ue8c8"},
40 {"edit-cut"_L1, u"\ue8c6"},
41 {"edit-delete"_L1, u"\ue74d"},
42 {"edit-find"_L1, u"\ue721"},
43 //{"edit-find-replace"_L1, u"\u"},
44 {"edit-paste"_L1, u"\ue77f"},
45 {"edit-redo"_L1, u"\ue7a6"},
46 {"edit-select-all"_L1, u"\ue8b3"},
47 {"edit-undo"_L1, u"\ue7a7"},
48 {"folder-new"_L1, u"\ue8f4"},
49 //{"format-indent-less"_L1, u"\u"},
50 //{"format-indent-more"_L1, u"\u"},
51 {"format-justify-center"_L1, u"\ue8e3"},
52 //{"format-justify-fill"_L1, u"\ue235"},
53 {"format-justify-left"_L1, u"\ue8e4"},
54 {"format-justify-right"_L1, u"\ue8e2"},
55 //{"format-text-direction-ltr"_L1, u"\ue247"},
56 //{"format-text-direction-rtl"_L1, u"\ue248"},
57 {"format-text-bold"_L1, u"\ue8dd"},
58 {"format-text-italic"_L1, u"\ue8db"},
59 {"format-text-underline"_L1, u"\ue8dc"},
60 {"format-text-strikethrough"_L1, u"\uede0"},
61 //{"go-bottom"_L1,u"\ue258"},
62 {"go-down"_L1,u"\ue74b"},
63 //{"go-first"_L1, u"\ue5dc"},
64 {"go-home"_L1, u"\ue80f"},
65 // {"go-jump"_L1, u"\uf719"},
66 //{"go-last"_L1, u"\ue5dd"},
67 {"go-next"_L1, u"\ue893"},
68 {"go-previous"_L1, u"\ue892"},
69 //{"go-top"_L1, u"\ue25a"},
70 {"go-up"_L1, u"\ue74a"},
71 {"help-about"_L1, u"\ue946"},
72 //{"help-contents"_L1, u"\ue8de"},
73 {"help-faq"_L1, u"\ue897"},
74 {"insert-image"_L1, u"\ue946"},
75 {"insert-link"_L1, u"\ue71b"},
76 //{"insert-object"_L1, u"\u"},
77 //{"insert-text"_L1, u"\uf827"},
78 {"list-add"_L1, u"\ue710"},
79 {"list-remove"_L1, u"\ue738"},
80 {"mail-forward"_L1, u"\ue89c"},
81 //{"mail-mark-important"_L1, u"\ue937"},
82 //{"mail-mark-junk"_L1, u"\u"},
83 //{"mail-mark-notjunk"_L1, u"\u"},
84 {"mail-mark-read"_L1, u"\ue8c3"},
85 //{"mail-mark-unread"_L1, u"\ue9bc"},
86 {"mail-message-new"_L1, u"\ue70f"},
87 {"mail-reply-all"_L1, u"\ue8c2"},
88 {"mail-reply-sender"_L1, u"\ue8ca"},
89 {"mail-send"_L1, u"\ue724"},
90 //{"mail-send-receive"_L1, u"\u"},
91 {"media-eject"_L1, u"\uf847"},
92 {"media-playback-pause"_L1, u"\ue769"},
93 {"media-playback-start"_L1, u"\ue768"},
94 {"media-playback-stop"_L1, u"\ue71a"},
95 {"media-record"_L1, u"\ue7c8"},
96 {"media-seek-backward"_L1, u"\ueb9e"},
97 {"media-seek-forward"_L1, u"\ueb9d"},
98 {"media-skip-backward"_L1, u"\ue892"},
99 {"media-skip-forward"_L1, u"\ue893"},
100 //{"object-flip-horizontal"_L1, u"\u"},
101 //{"object-flip-vertical"_L1, u"\u"},
102 {"object-rotate-left"_L1, u"\ue80c"},
103 {"object-rotate-right"_L1, u"\ue80d"},
104 //{"process-stop"_L1, u"\ue5c9"},
105 {"system-lock-screen"_L1, u"\uee3f"},
106 {"system-log-out"_L1, u"\uf3b1"},
107 //{"system-run"_L1, u"\u"},
108 {"system-search"_L1, u"\ue721"},
109 {"system-reboot"_L1, u"\ue777"}, // unsure?
110 {"system-shutdown"_L1, u"\ue7e8"},
111 {"tools-check-spelling"_L1, u"\uf87b"},
112 {"view-fullscreen"_L1, u"\ue740"},
113 {"view-refresh"_L1, u"\ue72c"},
114 {"view-restore"_L1, u"\ue777"},
115 //{"view-sort-ascending"_L1, u"\ue25a"},
116 //{"view-sort-descending"_L1, u"\ue258"},
117 {"window-close"_L1, u"\ue8bb"},
118 {"window-new"_L1, u"\ue78b"},
119 {"zoom-fit-best"_L1, u"\ue9a6"},
120 {"zoom-in"_L1, u"\ue8a3"},
121 //{"zoom-original"_L1, u"\u"},
122 {"zoom-out"_L1, u"\ue71f"},
123
124 {"process-working"_L1, u"\ue9f3"},
125
126 {"accessories-calculator"_L1, u"\ue8ef"},
127 {"accessories-character-map"_L1, u"\uf2b7"},
128 {"accessories-dictionary"_L1, u"\ue82d"},
129 //{"accessories-text-editor"_L1, u"\ue262"},
130 {"help-browser"_L1, u"\ue897"},
131 {"multimedia-volume-control"_L1, u"\ue767"},
132 {"preferences-desktop-accessibility"_L1, u"\ue776"},
133 {"preferences-desktop-font"_L1, u"\ue8d2"},
134 {"preferences-desktop-keyboard"_L1, u"\ue765"},
135 {"preferences-desktop-locale"_L1, u"\uf2b7"},
136 //{"preferences-desktop-multimedia"_L1, u"\uea75"},
137 {"preferences-desktop-screensaver"_L1, u"\uf182"},
138 //{"preferences-desktop-theme"_L1, u"\uf560"},
139 //{"preferences-desktop-wallpaper"_L1, u"\ue1bc"},
140 {"system-file-manager"_L1, u"\uec50"},
141 //{"system-software-install"_L1, u"\ueb71"},
142 {"system-software-update"_L1, u"\uecc5"},
143 {"utilities-system-monitor"_L1, u"\ue7f4"},
144 //{"utilities-terminal"_L1, u"\ueb8e"},
145
146 //{"applications-accessories"_L1, u"\u"},
147 {"applications-development"_L1, u"\uec7a"},
148 //{"applications-engineering"_L1, u"\uea3d"},
149 {"applications-games"_L1, u"\ue7fc"},
150 //{"applications-graphics"_L1, u"\u"},
151 {"applications-internet"_L1, u"\ue774"},
152 {"applications-multimedia"_L1, u"\uea69"},
153 //{"applications-office"_L1, u"\u"},
154 //{"applications-other"_L1, u"\u"},
155 //{"applications-science"_L1, u"\uea4b"},
156 {"applications-system"_L1, u"\ue770"},
157 //{"applications-utilities"_L1, u"\u"},
158 //{"preferences-desktop"_L1, u"\ueb97"},
159 //{"preferences-desktop-peripherals"_L1, u"\u"},
160 //{"preferences-desktop-personal"_L1, u"\uf835"},
161 //{"preferences-other"_L1, u"\u"},
162 //{"preferences-system"_L1, u"\ue8b8"},
163 //{"preferences-system-network"_L1, u"\ue894"},
164 {"system-help"_L1, u"\ue946"},
165
166 {"audio-card"_L1, u"\ue8d6"},
167 {"audio-input-microphone"_L1, u"\ue720"},
168 {"battery"_L1, u"\ue83f"},
169 {"camera-photo"_L1, u"\ue722"},
170 {"camera-video"_L1, u"\ue714"},
171 {"camera-web"_L1, u"\ue8b8"},
172 {"computer"_L1, u"\ue7f8"}, // or e7fb?
173 {"drive-harddisk"_L1, u"\ueda2"},
174 {"drive-optical"_L1, u"\ue958"},
175 //{"drive-removable-media"_L1, u"\u"},
176 //{"input-gaming"_L1, u"\u"},
177 {"input-keyboard"_L1, u"\ue92e"},
178 {"input-mouse"_L1, u"\ue962"},
179 {"input-tablet"_L1, u"\ue70a"},
180 {"media-flash"_L1, u"\ue88e"},
181 //{"media-floppy"_L1, u"\u"},
182 {"media-optical"_L1, u"\ue958"},
183 {"media-tape"_L1, u"\ue96a"},
184 //{"modem"_L1, u"\u"},
185 //{"multimedia-player"_L1, u"\u"},
186 {"network-wired"_L1, u"\ue968"},
187 {"network-wireless"_L1, u"\ue701"},
188 //{"pda"_L1, u"\u"},
189 {"phone"_L1, u"\ue717"},
190 {"printer"_L1, u"\ue749"},
191 {"scanner"_L1, u"\ue8fe"},
192 //{"video-display"_L1, u"\uf06a"},
193
194 {"emblem-default"_L1, u"\uf56d"},
195 {"emblem-documents"_L1, u"\ue8a5"},
196 {"emblem-downloads"_L1, u"\ue896"},
197 {"emblem-favorite"_L1, u"\ue734"},
198 {"emblem-important"_L1, u"\ue8c9"},
199 {"emblem-mail"_L1, u"\ue715"},
200 {"emblem-photos"_L1, u"\ue91b"},
201 //{"emblem-readonly"_L1, u"\u"},
202 {"emblem-shared"_L1, u"\ue902"},
203 {"emblem-symbolic-link"_L1, u"\ue71b"},
204 {"emblem-synchronized"_L1, u"\uedab"},
205 {"emblem-system"_L1, u"\ue770"},
206 //{"emblem-unreadable"_L1, u"\u"},
207
208 {"folder"_L1, u"\ue8b7"},
209 //{"folder-remote"_L1, u"\u"},
210 //{"network-server"_L1, u"\ue875"},
211 //{"network-workgroup"_L1, u"\ue1a0"},
212 {"start-here"_L1, u"\ue8fc"}, // unsure
213 {"user-bookmarks"_L1, u"\ue8a4"},
214 //{"user-desktop"_L1, u"\ue30a"},
215 {"user-home"_L1, u"\ue80f"},
216 {"user-trash"_L1, u"\ue74d"},
217
218 //{"appointment-missed"_L1, u"\ue615"},
219 //{"appointment-soon"_L1, u"\uf540"},
220 {"audio-volume-high"_L1, u"\ue995"},
221 {"audio-volume-low"_L1, u"\ue993"},
222 {"audio-volume-medium"_L1, u"\ue994"},
223 {"audio-volume-muted"_L1, u"\ue992"},
224 //{"battery-caution"_L1, u"\ue19c"},
225 {"battery-low"_L1, u"\ue851"}, // ?
226 {"dialog-error"_L1, u"\ue783"},
227 {"dialog-information"_L1, u"\ue946"},
228 //{"dialog-password"_L1, u"\uf042"},
229 {"dialog-question"_L1, u"\uf142"}, // unsure
230 {"dialog-warning"_L1, u"\ue7ba"},
231 //{"folder-drag-accept"_L1, @u"\ue9a3"},
232 {"folder-open"_L1, u"\ue838"},
233 //{"folder-visiting"_L1, u"\ue8a7"},
234 //{"image-loading"_L1, u"\ue41a"},
235 //{"image-missing"_L1, u"\ue3ad"},
236 {"mail-attachment"_L1, u"\ue723"},
237 //{"mail-unread"_L1, u"\uf18a"},
238 //{"mail-read"_L1, u"\uf18c"},
239 {"mail-replied"_L1, u"\ue8ca"},
240 //{"mail-signed"_L1, u"\u"},
241 //{"mail-signed-verified"_L1, u"\u"},
242 {"media-playlist-repeat"_L1, u"\ue8ee"},
243 {"media-playlist-shuffle"_L1, u"\ue8b1"},
244 //{"network-error"_L1, u"\uead9"},
245 //{"network-idle"_L1, u"\ue51f"},
246 {"network-offline"_L1, u"\uf384"},
247 //{"network-receive"_L1, u"\ue2c0"},
248 //{"network-transmit"_L1, u"\ue2c3"},
249 //{"network-transmit-receive"_L1, u"\uca18"},
250 //{"printer-error"_L1, u"\uf7a0"},
251 //{"printer-printing"_L1, u"\uf7a1"},
252 //{"security-high"_L1, u"\ue32a"},
253 //{"security-medium"_L1, u"\ue9e0"},
254 //{"security-low"_L1, u"\uf012"},
255 //{"software-update-available"_L1, u"\ue923"},
256 //{"software-update-urgent"_L1, u"\uf05a"},
257 {"sync-error"_L1, u"\uea6a"},
258 {"sync-synchronizing"_L1, u"\ue895"},
259 //{"task-due"_L1, u"\u"},
260 //{"task-past-due"_L1, u"\u"},
261 {"user-available"_L1, u"\ue8cf"},
262 //{"user-away"_L1, u"\ue510"},
263 //{"user-idle"_L1, u"\u"},
264 //{"user-offline"_L1, u"\uf7b3"},
265 //{"user-trash-full"_L1, u"\ue872"}, //delete
266 //{"user-trash-full"_L1, u"\ue92b"}, //delete_forever
267 {"weather-clear"_L1, u"\ue706"},
268 //{"weather-clear-night"_L1, u"\uf159"},
269 //{"weather-few-clouds"_L1, u"\uf172"},
270 //{"weather-few-clouds-night"_L1, u"\uf174"},
271 //{"weather-fog"_L1, u"\ue818"},
272 {"weather-overcast"_L1, u"\ue753"},
273 //{"weather-severe-alert"_L1, u"\ue002"}, //warning
274 //{"weather-showers"_L1, u"\uf176"},
275 //{"weather-showers-scattered"_L1, u"\u"},
276 //{"weather-snow"_L1, u"\ue80f"}, //snowing
277 //{"weather-storm"_L1, u"\uf070"},
278 };
279
280 const auto it = std::find_if(std::begin(glyphMap), std::end(glyphMap), [this](const auto &c){
281 return c.first == m_iconName;
282 });
283
284 return it != std::end(glyphMap) ? it->second.toString()
285 : (m_iconName.length() == 1 ? m_iconName : QString());
286}
287
288namespace {
289auto iconFontFamily()
290{
291 static const bool isWindows11 = QOperatingSystemVersion::current() >= QOperatingSystemVersion::Windows11;
292 return isWindows11 ? u"Segoe Fluent Icons"_s
293 : u"Segoe MDL2 Assets"_s;
294}
295}
296
298 : m_iconName(iconName), m_iconFont(iconFontFamily())
299 , m_glyphs(glyphs())
300{
301}
302
305
307{
308 return new QWindowsIconEngine(m_iconName);
309}
310
312{
313 return u"QWindowsIconEngine"_s;
314}
315
317{
318 return m_iconName;
319}
320
322{
323 if (m_glyphs.isEmpty())
324 return true;
325
326 const QChar c0 = m_glyphs.at(0);
327 const QFontMetrics fontMetrics(m_iconFont);
328 if (c0.category() == QChar::Other_Surrogate && m_glyphs.size() > 1)
329 return !fontMetrics.inFontUcs4(QChar::surrogateToUcs4(c0, m_glyphs.at(1)));
330 return !fontMetrics.inFont(c0);
331}
332
334{
335 return {{16, 16}, {24, 24}, {48, 48}, {128, 128}};
336}
337
342
347
349{
350 const quint64 cacheKey = calculateCacheKey(mode, state);
351 if (cacheKey != m_cacheKey || m_pixmap.size() != size || m_pixmap.devicePixelRatio() != scale) {
352 m_pixmap = QPixmap(size * scale);
353 m_pixmap.fill(Qt::transparent);
354 m_pixmap.setDevicePixelRatio(scale);
355
356 QPainter painter(&m_pixmap);
358
359 m_cacheKey = cacheKey;
360 }
361
362 return m_pixmap;
363}
364
366{
368
369 painter->save();
370 QFont renderFont(m_iconFont);
371 renderFont.setPixelSize(rect.height());
372 painter->setFont(renderFont);
373
375 switch (mode) {
376 case QIcon::Active:
378 break;
379 case QIcon::Normal:
381 break;
382 case QIcon::Disabled:
384 break;
385 case QIcon::Selected:
387 break;
388 }
389
391 painter->restore();
392}
393
\inmodule QtCore
\reentrant
Definition qfontinfo.h:16
\reentrant \inmodule QtGui
\reentrant
Definition qfont.h:22
The QIconEngine class provides an abstract base class for QIcon renderers.
Definition qiconengine.h:15
virtual QSize actualSize(const QSize &size, QIcon::Mode mode, QIcon::State state)
Returns the actual size of the icon the engine provides for the requested size, mode and state.
Mode
This enum type describes the mode for which a pixmap is intended to be used.
Definition qicon.h:22
@ Disabled
Definition qicon.h:22
@ Selected
Definition qicon.h:22
@ Normal
Definition qicon.h:22
@ Active
Definition qicon.h:22
State
This enum describes the state for which a pixmap is intended to be used.
Definition qicon.h:23
static Q_CORE_EXPORT QOperatingSystemVersionBase current()
static constexpr QOperatingSystemVersionBase Windows11
\variable QOperatingSystemVersion::Windows11
The QPainter class performs low-level painting on widgets and other paint devices.
Definition qpainter.h:46
void setPen(const QColor &color)
This is an overloaded member function, provided for convenience. It differs from the above function o...
void restore()
Restores the current painter state (pops a saved state off the stack).
void save()
Saves the current painter state (pushes the state onto a stack).
void setFont(const QFont &f)
Sets the painter's font to the given font.
void drawText(const QPointF &p, const QString &s)
Draws the given text with the currently defined text direction, beginning at the given position.
The QPalette class contains color groups for each widget state.
Definition qpalette.h:19
@ Disabled
Definition qpalette.h:49
@ HighlightedText
Definition qpalette.h:53
Returns a copy of the pixmap that is transformed using the given transformation transform and transfo...
Definition qpixmap.h:27
QSize size() const
Returns the size of the pixmap.
Definition qpixmap.cpp:493
void setDevicePixelRatio(qreal scaleFactor)
Sets the device pixel ratio for the pixmap.
Definition qpixmap.cpp:604
void fill(const QColor &fillColor=Qt::white)
Fills the pixmap with the given color.
Definition qpixmap.cpp:850
qreal devicePixelRatio() const
Returns the device pixel ratio for the pixmap.
Definition qpixmap.cpp:576
\inmodule QtCore\reentrant
Definition qpoint.h:25
\inmodule QtCore\reentrant
Definition qrect.h:30
\inmodule QtCore
Definition qsize.h:25
\macro QT_RESTRICTED_CAST_FROM_ASCII
Definition qstring.h:129
bool isEmpty() const noexcept
Returns true if the string has no characters; otherwise returns false.
Definition qstring.h:192
qsizetype size() const noexcept
Returns the number of characters in this string.
Definition qstring.h:186
const QChar at(qsizetype i) const
Returns the character at the given index position in the string.
Definition qstring.h:1226
qsizetype length() const noexcept
Returns the number of characters in this string.
Definition qstring.h:191
QSize actualSize(const QSize &size, QIcon::Mode mode, QIcon::State state) override
Returns the actual size of the icon the engine provides for the requested size, mode and state.
QIconEngine * clone() const override
Reimplement this method to return a clone of this icon engine.
QPixmap pixmap(const QSize &size, QIcon::Mode mode, QIcon::State state) override
Returns the icon as a pixmap with the required size, mode, and state.
QString iconName() override
QList< QSize > availableSizes(QIcon::Mode, QIcon::State) override
void paint(QPainter *painter, const QRect &rect, QIcon::Mode mode, QIcon::State state) override
Uses the given painter to paint the icon with the required mode and state into the rectangle rect.
QString key() const override
\variable QIconEngine::ScaledPixmapArgument::size
QWindowsIconEngine(const QString &iconName)
QPixmap scaledPixmap(const QSize &size, QIcon::Mode mode, QIcon::State state, qreal scale) override
QPainter paint
QSet< QString >::iterator it
rect
[4]
fontMetrics
else opt state
[0]
Combined button and popup list for selecting options.
@ AlignCenter
Definition qnamespace.h:163
@ transparent
Definition qnamespace.h:47
static QByteArray cacheKey(Args &&...args)
GLenum mode
GLenum GLuint GLintptr GLsizeiptr size
[1]
const GLubyte * c
GLenum GLenum GLenum GLenum GLenum scale
#define Q_UNUSED(x)
unsigned long long quint64
Definition qtypes.h:61
double qreal
Definition qtypes.h:187
QPainter painter(this)
[7]