Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Toggle main menu visibility
Loading...
Searching...
No Matches
qquickiconimage.cpp
Go to the documentation of this file.
1
// Copyright (C) 2017 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
// Qt-Security score:significant reason:default
4
5
#
include
"qquickiconimage_p.h"
6
#
include
"qquickiconimage_p_p.h"
7
8
#
include
<
QtCore
/
qmath
.
h
>
9
#
include
<
QtQuick
/
private
/
qquickimagebase_p_p
.
h
>
10
11
QT_BEGIN_NAMESPACE
12
13
QQuickIconImagePrivate::~QQuickIconImagePrivate()
14
{
15
icon.entries.clear();
16
}
17
18
bool
QQuickIconImagePrivate::updateDevicePixelRatio(qreal targetDevicePixelRatio,
bool
scalable)
19
{
20
if
(isThemeIcon) {
21
devicePixelRatio = effectiveDevicePixelRatio();
22
return
true
;
23
}
24
25
return
QQuickImagePrivate::updateDevicePixelRatio(targetDevicePixelRatio, scalable);
26
}
27
28
void
QQuickIconImage::load()
29
{
30
Q_D(QQuickIconImage);
31
// Both geometryChange() and QQuickImageBase::sourceSizeChanged()
32
// (which we connect to load() in the constructor) can be called as a result
33
// of load() changing the various sizes, so we must check that we're not recursing.
34
if
(d->updatingIcon)
35
return
;
36
37
d->updatingIcon =
true
;
38
39
QSize size = d->sourcesize;
40
// If no size is specified for theme icons, it will use the smallest available size.
41
if
(size.width() <= 0)
42
size.setWidth(width());
43
if
(size.height() <= 0)
44
size.setHeight(height());
45
46
const
qreal dpr = d->devicePixelRatioForLoading();
47
48
if
(
const
auto
*entry = QIconLoaderEngine::entryForSize(d->icon, size * dpr, qCeil(dpr))) {
49
// First, try to load an icon from the theme (index.theme).
50
QQmlContext *context = qmlContext(
this
);
51
const
QUrl entryUrl = QUrl::fromLocalFile(entry->filename);
52
d->url = context ? context->resolvedUrl(entryUrl) : entryUrl;
53
d->isThemeIcon =
true
;
54
}
else
if
(d->source.isEmpty()) {
55
// Then, try loading it through a platform icon engine.
56
std::unique_ptr<QIconEngine> iconEngine(QIconLoader::instance()->iconEngine(d->icon.iconName));
57
if
(iconEngine && !iconEngine->isNull()) {
58
// ### TODO that's the best we can do for now to select different pixmaps based on the
59
// QuickItem's state. QQuickIconImage cannot know about the state of the control that
60
// uses it without adding more properties that are then synced up with the control.
61
const
QIcon::Mode mode = isEnabled() ? QIcon::Normal : QIcon::Disabled;
62
const
QImage image = iconEngine->scaledPixmap(size, mode, QIcon::Off, dpr).toImage();
63
d->devicePixelRatio = image.devicePixelRatio();
64
d->setImage(image);
65
}
66
}
else
{
67
// Either we failed to load a named icon or the source was set instead; use that.
68
d->url = d->source;
69
d->isThemeIcon =
false
;
70
}
71
if
(!d->url.isEmpty())
72
QQuickImage::load();
73
74
d->updatingIcon =
false
;
75
}
76
77
void
QQuickIconImagePrivate::updateFillMode()
78
{
79
Q_Q(QQuickIconImage);
80
// If we start with a sourceSize of 28x28 and then set sourceSize.width to 24, the fillMode
81
// will change to PreserveAspectFit (because pixmapSize.width() > width()), which causes the
82
// pixmap to be reloaded at its original size of 28x28, which causes the fillMode to change
83
// to Pad (because pixmapSize.width() <= width()), and so on.
84
if
(updatingFillMode)
85
return
;
86
87
updatingFillMode =
true
;
88
89
const
QSize pixmapSize = QSize(currentPix->width(), currentPix->height()) / effectiveDevicePixelRatio();
90
if
(pixmapSize.width() > q->width() || pixmapSize.height() > q->height())
91
q->setFillMode(QQuickImage::PreserveAspectFit);
92
else
93
q->setFillMode(QQuickImage::Pad);
94
95
updatingFillMode =
false
;
96
}
97
98
QQuickIconImage::QQuickIconImage(QQuickItem *parent)
99
: QQuickImage(*(
new
QQuickIconImagePrivate), parent)
100
{
101
setFillMode(Pad);
102
}
103
104
QString QQuickIconImage::name()
const
105
{
106
Q_D(
const
QQuickIconImage);
107
return
d->icon.iconName;
108
}
109
110
void
QQuickIconImage::setName(
const
QString &name)
111
{
112
Q_D(QQuickIconImage);
113
if
(d->icon.iconName == name)
114
return
;
115
116
d->icon.entries.clear();
117
d->icon = QIconLoader::instance()->loadIcon(name);
118
if
(d->icon.iconName.isEmpty())
119
d->icon.iconName = name;
120
if
(isComponentComplete())
121
load();
122
emit nameChanged();
123
}
124
125
QColor QQuickIconImage::color()
const
126
{
127
Q_D(
const
QQuickIconImage);
128
return
d->color;
129
}
130
131
void
QQuickIconImage::setColor(
const
QColor &color)
132
{
133
Q_D(QQuickIconImage);
134
if
(d->color == color)
135
return
;
136
137
d->color = color;
138
if
(isComponentComplete())
139
load();
140
emit colorChanged();
141
}
142
143
void
QQuickIconImage::setSource(
const
QUrl &source)
144
{
145
Q_D(QQuickIconImage);
146
if
(d->source == source)
147
return
;
148
149
d->source = source;
150
if
(isComponentComplete())
151
load();
152
emit sourceChanged(source);
153
}
154
155
void
QQuickIconImage::snapPositionTo(QPointF pos)
156
{
157
// Ensure that we are placed on an integer position relative to the owning control. We assume
158
// that there is exactly one intermediate parent item between us and the control (in practice,
159
// the contentItem). The idea is to enable the app, by placing the controls at integer
160
// positions, to avoid the image being smoothed over pixel boundaries in the basic, DPR=1 case.
161
QPointF offset;
162
if
(parentItem())
163
offset = parentItem()->position();
164
QPointF offsetPos(std::round(offset.x() + pos.x()), std::round(offset.y() + pos.y()));
165
setPosition(offsetPos - offset);
166
}
167
168
void
QQuickIconImage::componentComplete()
169
{
170
QQuickImage::componentComplete();
171
load();
172
}
173
174
void
QQuickIconImage::geometryChange(
const
QRectF &newGeometry,
const
QRectF &oldGeometry)
175
{
176
QQuickImage::geometryChange(newGeometry, oldGeometry);
177
if
(isComponentComplete() && newGeometry.size() != oldGeometry.size())
178
load();
179
}
180
181
void
QQuickIconImage::pixmapChange()
182
{
183
Q_D(QQuickIconImage);
184
QQuickImage::pixmapChange();
185
d->updateFillMode();
186
187
// Don't apply the color if we're recursing (updateFillMode() can cause us to recurse).
188
if
(!d->updatingFillMode && d->color.alpha() > 0) {
189
QImage image = d->currentPix->image();
190
if
(!image.isNull()) {
191
QPainter painter(&image);
192
painter.setCompositionMode(QPainter::CompositionMode_SourceIn);
193
painter.fillRect(image.rect(), d->color);
194
d->currentPix->setImage(image);
195
}
196
}
197
}
198
199
QT_END_NAMESPACE
200
201
#
include
"moc_qquickiconimage_p.cpp"
QT_BEGIN_NAMESPACE
Combined button and popup list for selecting options.
Definition
qsequentialanimationgroup.cpp:47
qtdeclarative
src
quickcontrolsimpl
qquickiconimage.cpp
Generated on
for Qt by
1.18.0