Krita Source Code Documentation
Loading...
Searching...
No Matches
kis_iconwidget.cc
Go to the documentation of this file.
1/*
2 * SPDX-FileCopyrightText: 2000 Matthias Elter <elter@kde.org>
3 * SPDX-FileCopyrightText: 2003 Patrick Julien <freak@codepimps.org>
4 *
5 * SPDX-License-Identifier: GPL-2.0-or-later
6 */
7
9
10#include <QPainter>
11#include <QIcon>
12#include <QStylePainter>
13#include <QStyleOptionToolButton>
14#include <KoResource.h>
15
24
25KisIconWidget::KisIconWidget(QWidget *parent, const QString &name)
26 : KisPopupButton(parent)
27 , m_d(new Private)
28{
29 m_d->backgroundColor = QColor(Qt::transparent);
30 setObjectName(name);
31 m_d->resource = nullptr;
32}
33
38
39void KisIconWidget::setThumbnail(const QImage &thumbnail)
40{
41 m_d->thumbnail = thumbnail;
42 m_d->cachedIconPixmap = QPixmap();
43 update();
44}
45
47{
48 m_d->resource = resource;
49 m_d->cachedIconPixmap = QPixmap();
50 update();
51}
52
53void KisIconWidget::setBackgroundColor(const QColor &color)
54{
55 m_d->backgroundColor = color;
56}
57
59{
60 const qint32 cw = width();
61 const qint32 ch = height();
62 const qint32 border = 3;
63 const qint32 iconWidth = cw - (border*2);
64 const qint32 iconHeight = ch - (border*2);
65
66 return QSize(iconWidth, iconHeight)*devicePixelRatioF();
67}
68
69void KisIconWidget::paintEvent(QPaintEvent *event)
70{
71 Q_UNUSED(event);
72
73 const qint32 border = 3;
74 const qint32 iconWidth = width() - (border*2);
75 const qint32 iconHeight = height() - (border*2);
76
77 auto makeIcon = [&](std::function<void (QPainter &)> paintFn) {
78 QPixmap pixmap(iconWidth * devicePixelRatioF(), iconHeight * devicePixelRatioF());
79 pixmap.setDevicePixelRatio(devicePixelRatioF());
80 pixmap.fill(m_d->backgroundColor);
81 QPainter p(&pixmap);
82
83 // Round off the corners of the preview
84 QRegion clipRegion(0, 0, iconWidth, iconHeight);
85 clipRegion -= QRegion(0, 0, 1, 1);
86 clipRegion -= QRegion(iconWidth - 1, 0, 1, 1);
87 clipRegion -= QRegion(iconWidth - 1, iconHeight - 1, 1, 1);
88 clipRegion -= QRegion(0, iconHeight - 1, 1, 1);
89
90 p.setClipRegion(clipRegion);
91 p.setClipping(true);
92 paintFn(p);
93 return pixmap;
94 };
95
96 auto paintThumbnailIcon = [&](QPainter &p) {
97 QImage img = QImage(iconWidth*devicePixelRatioF(), iconHeight*devicePixelRatioF(), QImage::Format_ARGB32);
98 img.setDevicePixelRatio(devicePixelRatioF());
99 img.fill(m_d->backgroundColor);
100 if (m_d->thumbnail.width() < iconWidth || m_d->thumbnail.height() < iconHeight) {
101 QPainter paint2;
102 paint2.begin(&img);
103 for (int x = 0; x < iconWidth; x += m_d->thumbnail.width()) {
104 for (int y = 0; y < iconHeight; y+= m_d->thumbnail.height()) {
105 paint2.drawImage(x, y, m_d->thumbnail);
106 }
107 }
108 } else {
109 img = m_d->thumbnail.scaled(iconWidth*devicePixelRatioF(), iconHeight*devicePixelRatioF(), Qt::KeepAspectRatio, Qt::SmoothTransformation);
110 }
111 p.drawImage(QRect(0, 0, iconWidth, iconHeight), img);
112 };
113
114 auto paintResourceIcon = [&](QPainter &p) {
115 QImage img = QImage(iconWidth*devicePixelRatioF(), iconHeight*devicePixelRatioF(), QImage::Format_ARGB32);
116 img.setDevicePixelRatio(devicePixelRatioF());
117 img.fill(m_d->backgroundColor);
118 if (m_d->resource->image().width() < iconWidth || m_d->resource->image().height() < iconHeight) {
119 QPainter paint2;
120 paint2.begin(&img);
121 for (int x = 0; x < iconWidth; x += m_d->resource->image().width()) {
122 for (int y = 0; y < iconHeight; y += m_d->resource->image().height()) {
123 paint2.drawImage(x, y, m_d->resource->image());
124 }
125 }
126 } else {
127 img = m_d->resource->image().scaled(iconWidth*devicePixelRatioF(), iconHeight*devicePixelRatioF(), Qt::KeepAspectRatio, Qt::SmoothTransformation);
128 }
129 p.drawImage(QRect(0, 0, iconWidth, iconHeight), img);
130 };
131
132 bool useCustomIcon = false;
133
134 const bool isCachedPixmapOutdated = m_d->cachedIconPixmap.isNull()
135 || m_d->cachedIconPixmap.width() != iconWidth
136 || m_d->cachedIconPixmap.height() != iconHeight
137 || m_d->cachedIconPixmap.devicePixelRatio() != devicePixelRatioF();
138
139 if (!m_d->thumbnail.isNull()) {
140 if (isCachedPixmapOutdated) {
141 m_d->cachedIconPixmap = makeIcon(paintThumbnailIcon);
142 }
143 useCustomIcon = true;
144 } else if (m_d->resource) {
145 if (isCachedPixmapOutdated || m_d->cachedResourceImageKey != m_d->resource->image().cacheKey()) {
146 m_d->cachedIconPixmap = makeIcon(paintResourceIcon);
147 }
148 useCustomIcon = true;
149 }
150
151 QStylePainter ps(this);
152 QStyleOptionToolButton opt;
153 initStyleOption(&opt);
154 if (useCustomIcon) {
155 opt.iconSize = QSize(iconWidth, iconHeight);
156 opt.icon = QIcon(m_d->cachedIconPixmap);
157 opt.toolButtonStyle = Qt::ToolButtonIconOnly;
158 }
159 ps.drawComplexControl(QStyle::CC_ToolButton, opt);
160}
161
const Params2D p
void setBackgroundColor(const QColor &color)
QSize preferredIconSize() const
~KisIconWidget() override
Private *const m_d
void setThumbnail(const QImage &thumbnail)
void setResource(KoResourceSP resource)
KisIconWidget(QWidget *parent=0, const QString &name=QString())
void paintEvent(QPaintEvent *) override
typedef void(QOPENGLF_APIENTRYP PFNGLINVALIDATEBUFFERDATAPROC)(GLuint buffer)