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

KDE's Doxygen guidelines are available online.