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 "iconitem.h"
9 
10 #include "imagetexturescache.h"
11 #include "managedtexturenode.h"
12 #include <QIcon>
13 #include <QQuickWindow>
14 #include <QSGSimpleTextureNode>
15 
Q_GLOBAL_STATIC(ImageTexturesCache,s_iconImageCache)16 Q_GLOBAL_STATIC(ImageTexturesCache, s_iconImageCache)
17 
18 IconItem::IconItem(QQuickItem *parent)
19     : QQuickItem(parent)
20     , m_smooth(false)
21     , m_state(DefaultState)
22     , m_changed(false)
23 {
24     setFlag(ItemHasContents, true);
25 }
26 
~IconItem()27 IconItem::~IconItem()
28 {
29 }
30 
setIcon(const QVariant & icon)31 void IconItem::setIcon(const QVariant &icon)
32 {
33     if (icon.canConvert<QIcon>()) {
34         m_icon = icon.value<QIcon>();
35     } else if (icon.canConvert<QString>()) {
36         m_icon = QIcon::fromTheme(icon.toString());
37     } else {
38         m_icon = QIcon();
39     }
40     m_changed = true;
41     update();
42 }
43 
icon() const44 QIcon IconItem::icon() const
45 {
46     return m_icon;
47 }
48 
state() const49 IconItem::State IconItem::state() const
50 {
51     return m_state;
52 }
53 
setState(IconItem::State state)54 void IconItem::setState(IconItem::State state)
55 {
56     if (m_state == state) {
57         return;
58     }
59 
60     m_state = state;
61     m_changed = true;
62     emit stateChanged(state);
63     update();
64 }
65 
enabled() const66 bool IconItem::enabled() const
67 {
68     return (m_state == DefaultState);
69 }
70 
setEnabled(bool enabled)71 void IconItem::setEnabled(bool enabled)
72 {
73     if (enabled) {
74         setState(DefaultState);
75     } else {
76         setState(DisabledState);
77     }
78 }
79 
implicitWidth() const80 int IconItem::implicitWidth() const
81 {
82     return 32;
83 }
84 
implicitHeight() const85 int IconItem::implicitHeight() const
86 {
87     return 32;
88 }
89 
setSmooth(const bool smooth)90 void IconItem::setSmooth(const bool smooth)
91 {
92     if (smooth == m_smooth) {
93         return;
94     }
95     m_smooth = smooth;
96     m_changed = true;
97     update();
98 }
99 
smooth() const100 bool IconItem::smooth() const
101 {
102     return m_smooth;
103 }
104 
updatePaintNode(QSGNode * node,QQuickItem::UpdatePaintNodeData *)105 QSGNode *IconItem::updatePaintNode(QSGNode *node, QQuickItem::UpdatePaintNodeData * /*data*/)
106 {
107     if (m_icon.isNull()) {
108         delete node;
109         return nullptr;
110     }
111 
112     if (m_changed || node == nullptr) {
113         m_changed = false;
114 
115         ManagedTextureNode *mNode = dynamic_cast<ManagedTextureNode *>(node);
116         if (!mNode) {
117             delete node;
118             mNode = new ManagedTextureNode;
119         }
120 
121         QIcon::Mode mode;
122         switch (m_state) {
123             case DefaultState:
124                 mode = QIcon::Normal;
125                 break;
126             case ActiveState:
127                 mode = QIcon::Active;
128                 break;
129             case DisabledState:
130                 mode = QIcon::Disabled;
131                 break;
132         }
133 
134         QImage img;
135         const QSize size(static_cast<int>(width()), static_cast<int>(height()));
136         if (!size.isEmpty()) {
137             img = m_icon.pixmap(size, mode, QIcon::On).toImage();
138         }
139         mNode->setTexture(s_iconImageCache->loadTexture(window(), img));
140         mNode->setRect(QRect(QPoint(0, 0), size));
141         node = mNode;
142     }
143 
144     return node;
145 }
146 
geometryChanged(const QRectF & newGeometry,const QRectF & oldGeometry)147 void IconItem::geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry)
148 {
149     if (newGeometry.size() != oldGeometry.size()) {
150         m_changed = true;
151         update();
152     }
153     QQuickItem::geometryChanged(newGeometry, oldGeometry);
154 }
155