KIconThemes

kiconengine.cpp
1/*
2 This file is part of the KDE libraries
3 SPDX-FileCopyrightText: 2006 Hamish Rodda <rodda@kde.org>
4
5 SPDX-License-Identifier: LGPL-2.0-only
6*/
7
8#include "kiconengine.h"
9
10#include "kiconloader_p.h"
11#include <kiconloader.h>
12
13#include "kiconcolors.h"
14#include <KIconTheme>
15#include <QFileInfo>
16#include <QLibraryInfo>
17#include <QPainter>
18#include <qscopeguard.h>
19
20class KIconEnginePrivate
21{
22public:
23 QPointer<KIconLoader> mIconLoader;
24 bool mCustomColors = false;
25 KIconColors mColors;
26 QString mActualIconName;
27};
28
29KIconEngine::KIconEngine(const QString &iconName, KIconLoader *iconLoader, const QStringList &overlays)
30 : mIconName(iconName)
31 , mOverlays(overlays)
32 , d(new KIconEnginePrivate{iconLoader, false, {}, {}})
33{
34}
35
36KIconEngine::KIconEngine(const QString &iconName, KIconLoader *iconLoader)
37 : mIconName(iconName)
38 , d(new KIconEnginePrivate{iconLoader, false, {}, {}})
39{
40}
41
42KIconEngine::KIconEngine(const QString &iconName, const KIconColors &colors, KIconLoader *iconLoader)
43 : mIconName(iconName)
44 , d(new KIconEnginePrivate{iconLoader, true, colors, {}})
45{
46}
47
48KIconEngine::KIconEngine(const QString &iconName, const KIconColors &colors, KIconLoader *iconLoader, const QStringList &overlays)
49 : mIconName(iconName)
50 , mOverlays(overlays)
51 , d(new KIconEnginePrivate{iconLoader, true, colors, {}})
52{
53}
54
56{
57 delete d;
58}
59
60static inline int qIconModeToKIconState(QIcon::Mode mode)
61{
62 switch (mode) {
63 case QIcon::Normal:
65 case QIcon::Active:
67 case QIcon::Disabled:
69 case QIcon::Selected:
71 default:
73 }
74}
75
77{
78 return QIconEngine::actualSize(size, mode, state);
79}
80
81void KIconEngine::paint(QPainter *painter, const QRect &rect, QIcon::Mode mode, QIcon::State state)
82{
83 if (!d->mIconLoader) {
84 return;
85 }
86
87 const qreal dpr = painter->device()->devicePixelRatioF();
88 const QPixmap pix = createPixmap(rect.size(), dpr, mode, state);
89 painter->drawPixmap(rect, pix);
90}
91
92QPixmap KIconEngine::createPixmap(const QSize &logicalSize, qreal scale, QIcon::Mode mode, QIcon::State state)
93{
94 Q_UNUSED(state)
95
96 if (scale < 1) {
97 scale = 1;
98 }
99
100 if (logicalSize.isEmpty()) {
101 return QPixmap();
102 }
103
104 if (!d->mIconLoader) {
105 QPixmap pm(logicalSize * scale);
106 pm.setDevicePixelRatio(scale);
107 pm.fill(Qt::transparent);
108 return pm;
109 }
110
111 QString iconPath;
112
113 const int kstate = qIconModeToKIconState(mode);
114 QPixmap pix = d->mIconLoader->loadScaledIcon(mIconName,
116 scale,
117 logicalSize,
118 kstate,
119 mOverlays,
120 &iconPath,
121 false,
122 d->mCustomColors ? std::make_optional(d->mColors) : std::nullopt);
123
124 if (!iconPath.isEmpty() && !d->mActualIconName.isEmpty()) {
125 d->mActualIconName = QFileInfo(iconPath).completeBaseName();
126 }
127
128 if (pix.size() == logicalSize * scale) {
129 return pix;
130 }
131
132 QPixmap pix2(logicalSize * scale);
133 pix2.setDevicePixelRatio(scale);
134 pix2.fill(QColor(0, 0, 0, 0));
135
136 QPainter painter(&pix2);
137 painter.setRenderHint(QPainter::SmoothPixmapTransform);
138 const QSizeF targetSize = pix.size().scaled(logicalSize, Qt::KeepAspectRatio);
139 QRectF targetRect({0, 0}, targetSize);
140 targetRect.moveCenter(QRectF(pix2.rect()).center() / scale);
141 painter.drawPixmap(targetRect, pix, pix.rect());
142
143 return pix2;
144}
145
147{
148 return createPixmap(size, 1 /*scale*/, mode, state);
149}
150
151QPixmap KIconEngine::scaledPixmap(const QSize &size, QIcon::Mode mode, QIcon::State state, qreal scale)
152{
153 // Since https://codereview.qt-project.org/c/qt/qtbase/+/563553 size is in logical pixels
154 if (QLibraryInfo::version() >= QVersionNumber(6, 8, 0)) {
155 return createPixmap(size, scale, mode, state);
156 } else {
157 return createPixmap(size / scale, scale, mode, state);
158 }
159}
160
162{
163 if (!d->mActualIconName.isEmpty()) {
164 return d->mActualIconName;
165 }
166
167 if (!d->mIconLoader) {
168 return QString();
169 }
170
171 const QString iconPath = KIconLoaderPrivate::get(d->mIconLoader)->preferredIconPath(mIconName);
172 if (iconPath.isEmpty()) {
173 return QString();
174 }
175
176 d->mActualIconName = QFileInfo(iconPath).completeBaseName();
177 return d->mActualIconName;
178}
179
180Q_GLOBAL_STATIC_WITH_ARGS(QList<QSize>,
181 sSizes,
182 (QList<QSize>() << QSize(16, 16) << QSize(22, 22) << QSize(32, 32) << QSize(48, 48) << QSize(64, 64) << QSize(128, 128)
183 << QSize(256, 256)))
184
185QList<QSize> KIconEngine::availableSizes(QIcon::Mode mode, QIcon::State state)
186{
187 Q_UNUSED(mode);
188 Q_UNUSED(state);
189
190 if (!d->mIconLoader) {
191 return QList<QSize>();
192 }
193
194 const bool found = d->mIconLoader->hasIcon(mIconName);
195 return found ? *sSizes : QList<QSize>();
196}
197
198QString KIconEngine::key() const
199{
200 return QStringLiteral("KIconEngine");
201}
202
203QIconEngine *KIconEngine::clone() const
204{
205 return new KIconEngine(mIconName, d->mIconLoader, mOverlays);
206}
207
208bool KIconEngine::read(QDataStream &in)
209{
210 in >> mIconName >> mOverlays;
211 return true;
212}
213
214bool KIconEngine::write(QDataStream &out) const
215{
216 out << mIconName << mOverlays;
217 return true;
218}
219
220bool KIconEngine::isNull()
221{
222 return !d->mIconLoader || !d->mIconLoader->hasIcon(mIconName);
223}
Sepecifies which colors will be used when recoloring icons as its stylesheet.
Definition kiconcolors.h:31
A class to provide rendering of KDE icons.
Definition kiconengine.h:29
QSize actualSize(const QSize &size, QIcon::Mode mode, QIcon::State state) override
Reimplementation.
~KIconEngine() override
Destructor.
KIconEngine(const QString &iconName, KIconLoader *iconLoader, const QStringList &overlays)
Constructs an icon engine for a named icon.
QString iconName() override
Reimplementation.
QPixmap pixmap(const QSize &size, QIcon::Mode mode, QIcon::State state) override
Reimplementation.
void paint(QPainter *painter, const QRect &rect, QIcon::Mode mode, QIcon::State state) override
Reimplementation.
Iconloader for KDE.
Definition kiconloader.h:73
@ Desktop
Desktop icons.
@ ActiveState
Icon is active.
@ DisabledState
Icon is disabled.
@ DefaultState
The default state.
@ SelectedState
Icon is selected.
QString completeBaseName() const const
virtual QSize actualSize(const QSize &size, QIcon::Mode mode, QIcon::State state)
QVersionNumber version()
qreal devicePixelRatioF() const const
SmoothPixmapTransform
QPaintDevice * device() const const
void drawPixmap(const QPoint &point, const QPixmap &pixmap)
QRect rect() const const
QSize size() const const
QSize size() const const
QPointF center() const const
void moveCenter(const QPointF &position)
bool isEmpty() const const
QSize scaled(const QSize &s, Qt::AspectRatioMode mode) const const
bool isEmpty() const const
KeepAspectRatio
transparent
This file is part of the KDE documentation.
Documentation copyright © 1996-2024 The KDE developers.
Generated on Fri Dec 6 2024 12:00:05 by doxygen 1.12.0 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.