Kirigami2

icon.cpp
1/*
2 * SPDX-FileCopyrightText: 2011 Marco Martin <mart@kde.org>
3 * SPDX-FileCopyrightText: 2014 Aleix Pol Gonzalez <aleixpol@blue-systems.com>
4 *
5 * SPDX-License-Identifier: LGPL-2.0-or-later
6 */
7
8#include "icon.h"
9#include "scenegraph/managedtexturenode.h"
10
11#include "platform/platformtheme.h"
12#include "platform/units.h"
13
14#include <QBitmap>
15#include <QDebug>
16#include <QGuiApplication>
17#include <QIcon>
18#include <QNetworkReply>
19#include <QPainter>
20#include <QPropertyAnimation>
21#include <QQuickImageProvider>
22#include <QQuickWindow>
23#include <QSGSimpleTextureNode>
24#include <QSGTexture>
25#include <QScreen>
26#include <cstdlib>
27
28Q_GLOBAL_STATIC(ImageTexturesCache, s_iconImageCache)
29
30Icon::Icon(QQuickItem *parent)
31 : QQuickItem(parent)
32 , m_active(false)
33 , m_selected(false)
34 , m_isMask(false)
35{
36 setFlag(ItemHasContents, true);
37 // Using 32 because Icon used to redefine implicitWidth and implicitHeight and hardcode them to 32
38 setImplicitSize(32, 32);
39
41 connect(this, &QQuickItem::enabledChanged, this, [this]() {
42 m_allowNextAnimation = true;
43 polish();
44 });
45}
46
47Icon::~Icon()
48{
49}
50
51void Icon::componentComplete()
52{
54
55 QQmlEngine *engine = qmlEngine(this);
56 Q_ASSERT(engine);
57 m_units = engine->singletonInstance<Kirigami::Platform::Units *>("org.kde.kirigami.platform", "Units");
58 Q_ASSERT(m_units);
59 m_animation = new QPropertyAnimation(this);
60 connect(m_animation, &QPropertyAnimation::valueChanged, this, &Icon::valueChanged);
61 connect(m_animation, &QPropertyAnimation::finished, this, [this]() {
62 m_oldIcon = QImage();
63 m_textureChanged = true;
64 update();
65 });
66 m_animation->setTargetObject(this);
68 m_animation->setDuration(m_units->longDuration());
69 connect(m_units, &Kirigami::Platform::Units::longDurationChanged, m_animation, [this]() {
70 m_animation->setDuration(m_units->longDuration());
71 });
72 updatePaintedGeometry();
73}
74
75void Icon::setSource(const QVariant &icon)
76{
77 if (m_source == icon) {
78 return;
79 }
80 m_source = icon;
81
82 if (!m_theme) {
84 Q_ASSERT(m_theme);
85
86 connect(m_theme, &Kirigami::Platform::PlatformTheme::colorsChanged, this, &QQuickItem::polish);
87 }
88
89 if (m_networkReply) {
90 // if there was a network query going on, interrupt it
91 m_networkReply->close();
92 }
93 m_loadedImage = QImage();
94 setStatus(Loading);
95
96 polish();
97 Q_EMIT sourceChanged();
98 Q_EMIT validChanged();
99}
100
102{
103 return m_source;
104}
105
106void Icon::setActive(const bool active)
107{
108 if (active == m_active) {
109 return;
110 }
111 m_active = active;
112 if (isComponentComplete()) {
113 m_allowNextAnimation = true;
114 }
115 polish();
116 Q_EMIT activeChanged();
117}
118
119bool Icon::active() const
120{
121 return m_active;
122}
123
124bool Icon::valid() const
125{
126 // TODO: should this be return m_status == Ready?
127 // Consider an empty URL invalid, even though isNull() will say false
128 if (m_source.canConvert<QUrl>() && m_source.toUrl().isEmpty()) {
129 return false;
130 }
131
132 return !m_source.isNull();
133}
134
135void Icon::setSelected(const bool selected)
136{
137 if (selected == m_selected) {
138 return;
139 }
140 m_selected = selected;
141 polish();
142 Q_EMIT selectedChanged();
143}
144
145bool Icon::selected() const
146{
147 return m_selected;
148}
149
150void Icon::setIsMask(bool mask)
151{
152 if (m_isMask == mask) {
153 return;
154 }
155
156 m_isMask = mask;
157 polish();
158 Q_EMIT isMaskChanged();
159}
160
161bool Icon::isMask() const
162{
163 return m_isMask;
164}
165
166void Icon::setColor(const QColor &color)
167{
168 if (m_color == color) {
169 return;
170 }
171
172 m_color = color;
173 polish();
174 Q_EMIT colorChanged();
175}
176
177QColor Icon::color() const
178{
179 return m_color;
180}
181
182QSGNode *Icon::createSubtree(qreal initialOpacity)
183{
184 auto opacityNode = new QSGOpacityNode{};
185 opacityNode->setFlag(QSGNode::OwnedByParent, true);
186 opacityNode->setOpacity(initialOpacity);
187
188 auto *mNode = new ManagedTextureNode;
189
190 mNode->setTexture(s_iconImageCache->loadTexture(window(), m_icon, QQuickWindow::TextureCanUseAtlas));
191
192 opacityNode->appendChildNode(mNode);
193
194 return opacityNode;
195}
196
197void Icon::updateSubtree(QSGNode *node, qreal opacity)
198{
199 auto opacityNode = static_cast<QSGOpacityNode *>(node);
200 opacityNode->setOpacity(opacity);
201
202 auto textureNode = static_cast<ManagedTextureNode *>(opacityNode->firstChild());
204}
205
206QSGNode *Icon::updatePaintNode(QSGNode *node, QQuickItem::UpdatePaintNodeData * /*data*/)
207{
208 if (m_source.isNull() || qFuzzyIsNull(width()) || qFuzzyIsNull(height())) {
209 delete node;
210 return Q_NULLPTR;
211 }
212
213 if (!node) {
214 node = new QSGNode{};
215 }
216
217 if (m_animation && m_animation->state() == QAbstractAnimation::Running) {
218 if (node->childCount() < 2) {
219 node->appendChildNode(createSubtree(0.0));
220 m_textureChanged = true;
221 }
222
223 // Rather than doing a perfect crossfade, first fade in the new texture
224 // then fade out the old texture. This is done to avoid the underlying
225 // color bleeding through when both textures are at ~0.5 opacity, which
226 // causes flickering if the two textures are very similar.
227 updateSubtree(node->firstChild(), 2.0 - m_animValue * 2.0);
228 updateSubtree(node->lastChild(), m_animValue * 2.0);
229 } else {
230 if (node->childCount() == 0) {
231 node->appendChildNode(createSubtree(1.0));
232 m_textureChanged = true;
233 }
234
235 if (node->childCount() > 1) {
236 auto toRemove = node->firstChild();
238 delete toRemove;
239 }
240
241 updateSubtree(node->firstChild(), 1.0);
242 }
243
244 if (m_textureChanged) {
245 auto mNode = static_cast<ManagedTextureNode *>(node->lastChild()->firstChild());
246 mNode->setTexture(s_iconImageCache->loadTexture(window(), m_icon, QQuickWindow::TextureCanUseAtlas));
247 m_textureChanged = false;
248 m_sizeChanged = true;
249 }
250
251 if (m_sizeChanged) {
252 const QSizeF iconPixSize(m_icon.width() / m_devicePixelRatio, m_icon.height() / m_devicePixelRatio);
253 const QSizeF itemPixSize = QSizeF((size() * m_devicePixelRatio).toSize()) / m_devicePixelRatio;
255
256 if (itemPixSize.width() != 0 && itemPixSize.height() != 0) {
257 if (iconPixSize != itemPixSize) {
258 // At this point, the image will already be scaled, but we need to output it in
259 // the correct aspect ratio, painted centered in the viewport. So:
260 QRectF destination(QPointF(0, 0), QSizeF(m_icon.size()).scaled(m_paintedSize, Qt::KeepAspectRatio));
261 destination.moveCenter(nodeRect.center());
262 destination.moveTopLeft(QPointF(destination.topLeft().toPoint() * m_devicePixelRatio) / m_devicePixelRatio);
263 nodeRect = destination;
264 }
265 }
266
267 // Adjust the final node on the pixel grid
268 QPointF globalPixelPos = mapToScene(nodeRect.topLeft()) * m_devicePixelRatio;
269 QPointF posAdjust = QPointF(globalPixelPos.x() - std::round(globalPixelPos.x()), globalPixelPos.y() - std::round(globalPixelPos.y()));
270 nodeRect.moveTopLeft(nodeRect.topLeft() - posAdjust);
271
272 for (int i = 0; i < node->childCount(); ++i) {
273 auto mNode = static_cast<ManagedTextureNode *>(node->childAtIndex(i)->firstChild());
274 mNode->setRect(nodeRect);
275 }
276
277 m_sizeChanged = false;
278 }
279
280 return node;
281}
282
283void Icon::geometryChange(const QRectF &newGeometry, const QRectF &oldGeometry)
284{
286 if (newGeometry.size() != oldGeometry.size()) {
287 m_sizeChanged = true;
288 updatePaintedGeometry();
289 polish();
290 }
291}
292
293void Icon::handleRedirect(QNetworkReply *reply)
294{
296 if (reply->error() != QNetworkReply::NoError) {
297 return;
298 }
300 if (!possibleRedirectUrl.isEmpty()) {
301 const QUrl redirectUrl = reply->url().resolved(possibleRedirectUrl);
302 if (redirectUrl == reply->url()) {
303 // no infinite redirections thank you very much
304 reply->deleteLater();
305 return;
306 }
307 reply->deleteLater();
310 m_networkReply = qnam->get(request);
311 connect(m_networkReply.data(), &QNetworkReply::finished, this, [this]() {
312 handleFinished(m_networkReply);
313 });
314 }
315}
316
317void Icon::handleFinished(QNetworkReply *reply)
318{
319 if (!reply) {
320 return;
321 }
322
323 reply->deleteLater();
325 handleRedirect(reply);
326 return;
327 }
328
329 m_loadedImage = QImage();
330
331 const QString filename = reply->url().fileName();
332 if (!m_loadedImage.load(reply, filename.mid(filename.indexOf(QLatin1Char('.'))).toLatin1().constData())) {
333 // broken image from data, inform the user of this with some useful broken-image thing...
334 m_loadedImage = iconPixmap(QIcon::fromTheme(m_fallback));
335 }
336
337 polish();
338}
339
340void Icon::updatePolish()
341{
343
344 if (window()) {
345 m_devicePixelRatio = window()->effectiveDevicePixelRatio();
346 }
347
348 if (m_source.isNull()) {
349 setStatus(Ready);
350 updatePaintedGeometry();
351 update();
352 return;
353 }
354
355 const QSize itemSize(width(), height());
356 if (itemSize.width() != 0 && itemSize.height() != 0) {
357 const QSize size = itemSize;
358
359 if (m_animation) {
360 m_animation->stop();
361 m_oldIcon = m_icon;
362 }
363
364 switch (m_source.userType()) {
366 m_icon = m_source.value<QPixmap>().toImage();
367 break;
369 m_icon = m_source.value<QImage>();
370 break;
372 m_icon = m_source.value<QBitmap>().toImage();
373 break;
374 case QMetaType::QIcon: {
375 m_icon = iconPixmap(m_source.value<QIcon>());
376 break;
377 }
378 case QMetaType::QUrl:
380 m_icon = findIcon(size);
381 break;
383 // todo: fill here too?
386 m_icon.fill(m_source.value<QColor>());
387 break;
388 default:
389 break;
390 }
391
392 if (m_icon.isNull()) {
394 m_icon.fill(Qt::transparent);
395 }
396
397 const QColor tintColor = //
398 !m_color.isValid() || m_color == Qt::transparent //
399 ? (m_selected ? m_theme->highlightedTextColor() : m_theme->textColor())
400 : m_color;
401
402 // TODO: initialize m_isMask with icon.isMask()
403 if (tintColor.alpha() > 0 && isMask()) {
404 QPainter p(&m_icon);
405 p.setCompositionMode(QPainter::CompositionMode_SourceIn);
406 p.fillRect(m_icon.rect(), tintColor);
407 p.end();
408 }
409 }
410
411 // don't animate initial setting
412 bool animated = (m_animated || m_allowNextAnimation) && !m_oldIcon.isNull() && !m_sizeChanged && !m_blockNextAnimation;
413
414 if (animated && m_animation) {
415 m_animValue = 0.0;
416 m_animation->setStartValue((qreal)0);
417 m_animation->setEndValue((qreal)1);
418 m_animation->start();
419 m_allowNextAnimation = false;
420 } else {
421 if (m_animation) {
422 m_animation->stop();
423 }
424 m_animValue = 1.0;
425 m_blockNextAnimation = false;
426 }
427 m_textureChanged = true;
428 updatePaintedGeometry();
429 update();
430}
431
432QImage Icon::findIcon(const QSize &size)
433{
434 QImage img;
435 QString iconSource = m_source.toString();
436
437 if (iconSource.startsWith(QLatin1String("image://"))) {
438 QUrl iconUrl(iconSource);
440 // QUrl path has the "/" prefix while iconId does not
441 QString iconId = iconUrl.path().remove(0, 1);
442
444 auto engine = qmlEngine(this);
445 if (!engine) {
446 return img;
447 }
448 QQuickImageProvider *imageProvider = dynamic_cast<QQuickImageProvider *>(engine->imageProvider(iconProviderId));
449 if (!imageProvider) {
450 return img;
451 }
452 switch (imageProvider->imageType()) {
454 img = imageProvider->requestImage(iconId, &actualSize, size);
455 if (!img.isNull()) {
456 setStatus(Ready);
457 }
458 break;
460 img = imageProvider->requestPixmap(iconId, &actualSize, size).toImage();
461 if (!img.isNull()) {
462 setStatus(Ready);
463 }
464 break;
466 if (!m_loadedImage.isNull()) {
467 setStatus(Ready);
469 }
470 QQuickAsyncImageProvider *provider = dynamic_cast<QQuickAsyncImageProvider *>(imageProvider);
471 auto response = provider->requestImageResponse(iconId, size);
473 if (response->errorString().isEmpty()) {
474 QQuickTextureFactory *textureFactory = response->textureFactory();
475 if (textureFactory) {
476 m_loadedImage = textureFactory->image();
477 delete textureFactory;
478 }
479 if (m_loadedImage.isNull()) {
480 // broken image from data, inform the user of this with some useful broken-image thing...
481 m_loadedImage = iconPixmap(QIcon::fromTheme(m_fallback));
482 setStatus(Error);
483 } else {
484 setStatus(Ready);
485 }
486 polish();
487 }
488 response->deleteLater();
489 });
490 // Temporary icon while we wait for the real image to load...
491 img = iconPixmap(QIcon::fromTheme(m_placeholder));
492 break;
493 }
495 QQuickTextureFactory *textureFactory = imageProvider->requestTexture(iconId, &actualSize, size);
496 if (textureFactory) {
497 img = textureFactory->image();
498 }
499 if (img.isNull()) {
500 // broken image from data, or the texture factory wasn't healthy, inform the user of this with some useful broken-image thing...
501 img = iconPixmap(QIcon::fromTheme(m_fallback));
502 setStatus(Error);
503 } else {
504 setStatus(Ready);
505 }
506 break;
507 }
509 // will have to investigate this more
510 setStatus(Error);
511 break;
512 }
513 } else if (iconSource.startsWith(QLatin1String("http://")) || iconSource.startsWith(QLatin1String("https://"))) {
514 if (!m_loadedImage.isNull()) {
515 setStatus(Ready);
516 return m_loadedImage.scaled(size, Qt::KeepAspectRatio, smooth() ? Qt::SmoothTransformation : Qt::FastTransformation);
517 }
518 const auto url = m_source.toUrl();
519 QQmlEngine *engine = qmlEngine(this);
521 if (engine && (qnam = engine->networkAccessManager()) && (!m_networkReply || m_networkReply->url() != url)) {
522 QNetworkRequest request(url);
524 m_networkReply = qnam->get(request);
525 connect(m_networkReply.data(), &QNetworkReply::finished, this, [this]() {
526 handleFinished(m_networkReply);
527 });
528 }
529 // Temporary icon while we wait for the real image to load...
530 img = iconPixmap(QIcon::fromTheme(m_placeholder));
531 } else {
532 if (iconSource.startsWith(QLatin1String("qrc:/"))) {
533 iconSource = iconSource.mid(3);
534 } else if (iconSource.startsWith(QLatin1String("file:/"))) {
535 iconSource = QUrl(iconSource).path();
536 }
537
538 QIcon icon;
539
540 const QColor tintColor =
541 !m_color.isValid() || m_color == Qt::transparent ? (m_selected ? m_theme->highlightedTextColor() : m_theme->textColor()) : m_color;
542 icon = m_theme->iconFromTheme(iconSource, tintColor);
543
544 if (!icon.isNull()) {
545 img = iconPixmap(icon);
546 setStatus(Ready);
547 }
548 }
549
550 if (!iconSource.isEmpty() && img.isNull()) {
551 setStatus(Error);
552 img = iconPixmap(QIcon::fromTheme(m_fallback));
553 }
554 return img;
555}
556
557QIcon::Mode Icon::iconMode() const
558{
559 if (!isEnabled()) {
560 return QIcon::Disabled;
561 } else if (m_selected) {
562 return QIcon::Selected;
563 } else if (m_active) {
564 return QIcon::Active;
565 }
566 return QIcon::Normal;
567}
568
570{
571 return m_fallback;
572}
573
574void Icon::setFallback(const QString &fallback)
575{
576 if (m_fallback != fallback) {
577 m_fallback = fallback;
578 Q_EMIT fallbackChanged(fallback);
579 }
580}
581
583{
584 return m_placeholder;
585}
586
587void Icon::setPlaceholder(const QString &placeholder)
588{
589 if (m_placeholder != placeholder) {
590 m_placeholder = placeholder;
591 Q_EMIT placeholderChanged(placeholder);
592 }
593}
594
595void Icon::setStatus(Status status)
596{
597 if (status == m_status) {
598 return;
599 }
600
601 m_status = status;
602 Q_EMIT statusChanged();
603}
604
606{
607 return m_status;
608}
609
610qreal Icon::paintedWidth() const
611{
612 return std::round(m_paintedSize.width());
613}
614
615qreal Icon::paintedHeight() const
616{
617 return std::round(m_paintedSize.height());
618}
619
620QSize Icon::iconSizeHint() const
621{
622 if (!m_roundToIconSize) {
623 return QSize(width(), height());
624 } else if (m_units) {
625 return QSize(m_units->iconSizes()->roundedIconSize(std::min(width(), height())), m_units->iconSizes()->roundedIconSize(std::min(width(), height())));
626 } else {
627 return QSize(std::min(width(), height()), std::min(width(), height()));
628 }
629}
630
631QImage Icon::iconPixmap(const QIcon &icon) const
632{
633 const QSize actualSize = icon.actualSize(iconSizeHint());
634 return icon.pixmap(actualSize, m_devicePixelRatio, iconMode(), QIcon::On).toImage();
635}
636
637void Icon::updatePaintedGeometry()
638{
639 QSizeF newSize;
640 if (!m_icon.width() || !m_icon.height()) {
641 newSize = {0, 0};
642 } else {
643 qreal roundedWidth = m_units ? m_units->iconSizes()->roundedIconSize(std::min(width(), height())) : 32;
644 roundedWidth = std::round(roundedWidth * m_devicePixelRatio) / m_devicePixelRatio;
645
647 m_paintedSize = roundedSize;
648 m_textureChanged = true;
649 update();
650 Q_EMIT paintedAreaChanged();
651 return;
652 }
653 if (m_roundToIconSize && m_units) {
654 if (m_icon.width() > m_icon.height()) {
655 newSize = QSizeF(roundedWidth, m_icon.height() * (roundedWidth / static_cast<qreal>(m_icon.width())));
656 } else {
657 newSize = QSizeF(roundedWidth, roundedWidth);
658 }
659 } else {
660 const QSizeF iconPixSize(m_icon.width() / m_devicePixelRatio, m_icon.height() / m_devicePixelRatio);
661
662 const qreal w = widthValid() ? width() : iconPixSize.width();
663 const qreal widthScale = w / iconPixSize.width();
664 const qreal h = heightValid() ? height() : iconPixSize.height();
665 const qreal heightScale = h / iconPixSize.height();
666
667 if (widthScale <= heightScale) {
668 newSize = QSizeF(w, widthScale * iconPixSize.height());
669 } else if (heightScale < widthScale) {
670 newSize = QSizeF(heightScale * iconPixSize.width(), h);
671 }
672 }
673 }
674 if (newSize != m_paintedSize) {
675 m_paintedSize = newSize;
676 m_textureChanged = true;
677 update();
678 Q_EMIT paintedAreaChanged();
679 }
680}
681
682bool Icon::isAnimated() const
683{
684 return m_animated;
685}
686
687void Icon::setAnimated(bool animated)
688{
689 if (m_animated == animated) {
690 return;
691 }
692
693 m_animated = animated;
694 Q_EMIT animatedChanged();
695}
696
697bool Icon::roundToIconSize() const
698{
699 return m_roundToIconSize;
700}
701
702void Icon::setRoundToIconSize(bool roundToIconSize)
703{
704 if (m_roundToIconSize == roundToIconSize) {
705 return;
706 }
707
708 const QSizeF oldPaintedSize = m_paintedSize;
709
710 m_roundToIconSize = roundToIconSize;
711 Q_EMIT roundToIconSizeChanged();
712
713 updatePaintedGeometry();
714 if (oldPaintedSize != m_paintedSize) {
715 Q_EMIT paintedAreaChanged();
716 m_textureChanged = true;
717 update();
718 }
719}
720
721void Icon::itemChange(QQuickItem::ItemChange change, const QQuickItem::ItemChangeData &value)
722{
724 m_blockNextAnimation = true;
725 if (window()) {
726 m_devicePixelRatio = window()->effectiveDevicePixelRatio();
727 }
728 polish();
729 } else if (change == QQuickItem::ItemSceneChange) {
730 if (m_window) {
731 disconnect(m_window.data(), &QWindow::visibleChanged, this, &Icon::windowVisibleChanged);
732 }
733 m_window = value.window;
734 if (m_window) {
735 connect(m_window.data(), &QWindow::visibleChanged, this, &Icon::windowVisibleChanged);
736 m_devicePixelRatio = m_window->effectiveDevicePixelRatio();
737 }
738 } else if (change == ItemVisibleHasChanged && value.boolValue) {
739 m_blockNextAnimation = true;
740 }
741 QQuickItem::itemChange(change, value);
742}
743
744void Icon::valueChanged(const QVariant &value)
745{
746 m_animValue = value.toReal();
747 update();
748}
749
750void Icon::windowVisibleChanged(bool visible)
751{
752 if (visible) {
753 m_blockNextAnimation = true;
754 }
755}
756
757#include "moc_icon.cpp"
qreal paintedHeight
The height of the painted area measured in pixels.
Definition icon.h:163
QString placeholder
The name of an icon from the icon theme to show while the icon set in source is being loaded.
Definition icon.h:88
qreal paintedWidth
The width of the painted area measured in pixels.
Definition icon.h:155
bool selected
Whether this icon will use the QIcon::Selected mode when drawing the icon, resulting in a graphical e...
Definition icon.h:122
bool valid
Whether this icon's source is valid and it is being used.
Definition icon.h:108
bool animated
If set, icon will blend when the source is changed.
Definition icon.h:168
QColor color
The color to use when drawing this icon when isMask is enabled.
Definition icon.h:139
Icon::Status status
Whether the icon is correctly loaded, is asynchronously loading or there was an error.
Definition icon.h:147
bool roundToIconSize
If set, icon will round the painted size to defined icon sizes.
Definition icon.h:173
Status
Definition icon.h:176
@ Ready
No icon has been set.
Definition icon.h:178
@ Loading
The icon loaded correctly.
Definition icon.h:179
QString fallback
The name of a fallback icon to load from the icon theme when the source cannot be found.
Definition icon.h:75
QML_ELEMENTQVariant source
The source of this icon.
Definition icon.h:65
bool isMask
Whether this icon will be treated as a mask.
Definition icon.h:131
bool active
Whether this icon will use the QIcon::Active mode when drawing the icon, resulting in a graphical eff...
Definition icon.h:103
This class is the base for color management in Kirigami, different platforms can reimplement this cla...
QColor textColor
Color for normal foregrounds, usually text, but not limited to it, anything that should be painted wi...
QColor highlightedTextColor
Color for text that has been highlighted, often is a light color while normal text is dark.
A set of values to define semantically sizes and durations.
Definition units.h:80
int longDuration
units.longDuration should be used for longer, screen-covering animations, for opening and closing of ...
Definition units.h:138
Kirigami::Platform::IconSizes * iconSizes
units.iconSizes provides access to platform-dependent icon sizing
Definition units.h:108
Q_SCRIPTABLE CaptureState status()
QAction * actualSize(const QObject *recvr, const char *slot, QObject *parent)
void start(QAbstractAnimation::DeletionPolicy policy)
bool isValid() const const
QSize actualSize(QWindow *window, const QSize &size, Mode mode, State state) const const
QPixmap pixmap(QWindow *window, const QSize &size, Mode mode, State state) const const
QIcon fromTheme(const QString &name)
bool isNull() const const
void fill(Qt::GlobalColor color)
int height() const const
bool isNull() const const
bool load(QIODevice *device, const char *format)
QRect rect() const const
QImage scaled(const QSize &size, Qt::AspectRatioMode aspectRatioMode, Qt::TransformationMode transformMode) const const
QSize size() const const
int width() const const
QNetworkReply * get(const QNetworkRequest &request)
QVariant attribute(QNetworkRequest::Attribute code) const const
NetworkError error() const const
QNetworkAccessManager * manager() const const
QUrl url() const const
Q_EMITQ_EMIT
QMetaObject::Connection connect(const QObject *sender, PointerToMemberFunction signal, Functor functor)
void deleteLater()
bool disconnect(const QMetaObject::Connection &connection)
T qobject_cast(QObject *object)
CompositionMode_SourceIn
QImage toImage() const const
T * data() const const
void setTargetObject(QObject *target)
QQmlImageProviderBase * imageProvider(const QString &providerId) const const
QNetworkAccessManager * networkAccessManager() const const
T singletonInstance(QAnyStringView uri, QAnyStringView typeName)
virtual QQuickImageResponse * requestImageResponse(const QString &id, const QSize &requestedSize)=0
virtual ImageType imageType() const const override
virtual QImage requestImage(const QString &id, QSize *size, const QSize &requestedSize)
virtual QPixmap requestPixmap(const QString &id, QSize *size, const QSize &requestedSize)
virtual QQuickTextureFactory * requestTexture(const QString &id, QSize *size, const QSize &requestedSize)
virtual void componentComplete() override
void enabledChanged()
virtual void geometryChange(const QRectF &newGeometry, const QRectF &oldGeometry)
bool heightValid() const const
bool isComponentComplete() const const
virtual void itemChange(ItemChange change, const ItemChangeData &value)
QPointF mapToScene(const QPointF &point) const const
void polish()
QSizeF size() const const
void smoothChanged(bool)
void update()
virtual void updatePolish()
bool widthValid() const const
QQuickWindow * window() const const
virtual QImage image() const const
qreal effectiveDevicePixelRatio() const const
void appendChildNode(QSGNode *node)
QSGNode * childAtIndex(int i) const const
int childCount() const const
QSGNode * firstChild() const const
QSGNode * lastChild() const const
void removeChildNode(QSGNode *node)
qreal height() const const
QSizeF scaled(const QSizeF &s, Qt::AspectRatioMode mode) const const
qreal width() const const
qsizetype indexOf(QChar ch, qsizetype from, Qt::CaseSensitivity cs) const const
bool isEmpty() const const
QString mid(qsizetype position, qsizetype n) const const
bool startsWith(QChar c, Qt::CaseSensitivity cs) const const
KeepAspectRatio
transparent
SmoothTransformation
QFuture< ArgsType< Signal > > connect(Sender *sender, Signal signal)
QString fileName(ComponentFormattingOptions options) const const
bool isEmpty() const const
QString path(ComponentFormattingOptions options) const const
QUrl resolved(const QUrl &relative) const const
bool canConvert() const const
bool isNull() const const
qreal toReal(bool *ok) const const
QString toString() const const
QUrl toUrl() const const
int userType() const const
T value() const const
void setDuration(int msecs)
void setEasingCurve(const QEasingCurve &easing)
void setEndValue(const QVariant &value)
void setStartValue(const QVariant &value)
void valueChanged(const QVariant &value)
void visibleChanged(bool arg)
This file is part of the KDE documentation.
Documentation copyright © 1996-2024 The KDE developers.
Generated on Fri May 17 2024 11:49:07 by doxygen 1.10.0 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.