• Skip to content
  • Skip to link menu
KDE API Reference
  • KDE API Reference
  • kde-runtime API Reference
  • KDE Home
  • Contact Us
 

PlasmaCore

  • sources
  • kde-4.12
  • kde-runtime
  • plasma
  • declarativeimports
  • core
iconitem.cpp
Go to the documentation of this file.
1 /*
2  * Copyright 2012 Marco Martin <mart@kde.org>
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU Library General Public License as
6  * published by the Free Software Foundation; either version 2, or
7  * (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details
13  *
14  * You should have received a copy of the GNU Library General Public
15  * License along with this program; if not, write to the
16  * Free Software Foundation, Inc.,
17  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18  */
19 
20 #include "iconitem.h"
21 
22 #include <KIcon>
23 #include <KIconLoader>
24 #include <KIconEffect>
25 #include <QPainter>
26 #include <QPropertyAnimation>
27 #include <QStyleOptionGraphicsItem>
28 
29 #include <Plasma/PaintUtils>
30 #include <Plasma/Svg>
31 
32 IconItem::IconItem(QDeclarativeItem *parent)
33  : QDeclarativeItem(parent),
34  m_svgIcon(0),
35  m_smooth(false),
36  m_active(false),
37  m_animValue(0)
38 {
39  m_animation = new QPropertyAnimation(this);
40  connect(m_animation, SIGNAL(valueChanged(QVariant)),
41  this, SLOT(valueChanged(QVariant)));
42  connect(m_animation, SIGNAL(finished()),
43  this, SLOT(animationFinished()));
44  m_animation->setTargetObject(this);
45  m_animation->setEasingCurve(QEasingCurve::InOutQuad);
46  m_animation->setDuration(250);
47 
48  setFlag(QGraphicsItem::ItemHasNoContents, false);
49 
50  connect(KIconLoader::global(), SIGNAL(iconLoaderSettingsChanged()),
51  this, SIGNAL(implicitWidthChanged()));
52  connect(KIconLoader::global(), SIGNAL(iconLoaderSettingsChanged()),
53  this, SIGNAL(implicitHeightChanged()));
54 
55 
56  connect(this, SIGNAL(enabledChanged()),
57  this, SLOT(loadPixmap()));
58 
59  //initialize implicit size to the Dialog size
60  setImplicitWidth(KIconLoader::global()->currentSize(KIconLoader::Dialog));
61  setImplicitHeight(KIconLoader::global()->currentSize(KIconLoader::Dialog));
62 }
63 
64 
65 IconItem::~IconItem()
66 {
67 }
68 
69 void IconItem::setSource(const QVariant &source)
70 {
71  if (source == m_source) {
72  return;
73  }
74 
75  m_source = source;
76 
77  if (source.canConvert<QIcon>()) {
78  m_icon = source.value<QIcon>();
79  m_imageIcon = QImage();
80  m_pixmapIcon = QPixmap();
81  delete m_svgIcon;
82  m_svgIcon = 0;
83 
84  } else if (source.canConvert<QString>()) {
85  if (!m_svgIcon) {
86  m_svgIcon = new Plasma::Svg(this);
87  }
88  const QString element = source.toString();
89  const QString filename = element.split('-').first();
90  //try as a svg toolbar icon
91  m_svgIcon->setImagePath("toolbar-icons/" + filename);
92 
93  //try as a svg normal icon (like systray)
94  if (!m_svgIcon->isValid() || !m_svgIcon->hasElement(element)) {
95  m_svgIcon->setImagePath("icons/" + filename);
96  }
97  m_svgIcon->setContainsMultipleImages(true);
98 
99  //success?
100  if (m_svgIcon->isValid() && m_svgIcon->hasElement(element)) {
101  m_icon = QIcon();
102  } else {
103  //ok, svg not available
104  m_icon = KIcon(element);
105  delete m_svgIcon;
106  m_svgIcon = 0;
107  }
108 
109  m_imageIcon = QImage();
110  m_pixmapIcon = QPixmap();
111 
112  } else if (source.canConvert<QPixmap>()) {
113  m_icon = QIcon();
114  m_imageIcon = QImage();
115  m_pixmapIcon = source.value<QPixmap>();
116  delete m_svgIcon;
117  m_svgIcon = 0;
118 
119  } else if (source.canConvert<QImage>()) {
120  m_icon = QIcon();
121  m_imageIcon = source.value<QImage>();
122  m_pixmapIcon = QPixmap();
123  delete m_svgIcon;
124  m_svgIcon = 0;
125 
126  } else {
127  m_icon = QIcon();
128  m_imageIcon = QImage();
129  m_pixmapIcon = QPixmap();
130  delete m_svgIcon;
131  m_svgIcon = 0;
132  }
133 
134  if (width() > 0 && height() > 0) {
135  loadPixmap();
136  }
137 
138  emit sourceChanged();
139  emit validChanged();
140 }
141 
142 QVariant IconItem::source() const
143 {
144  return m_source;
145 }
146 
147 bool IconItem::isActive() const
148 {
149  return m_active;
150 }
151 
152 void IconItem::setActive(bool active)
153 {
154  if (m_active == active) {
155  return;
156  }
157 
158  m_active = active;
159  loadPixmap();
160  emit activeChanged();
161 }
162 
163 void IconItem::setImplicitWidth(qreal width)
164 {
165  if (implicitWidth() == width) {
166  return;
167  }
168 
169  QDeclarativeItem::setImplicitWidth(width);
170 
171  emit implicitWidthChanged();
172 }
173 
174 qreal IconItem::implicitWidth() const
175 {
176  return QDeclarativeItem::implicitWidth();
177 }
178 
179 void IconItem::setImplicitHeight(qreal height)
180 {
181  if (implicitHeight() == height) {
182  return;
183  }
184 
185  QDeclarativeItem::setImplicitHeight(height);
186 
187  emit implicitHeightChanged();
188 }
189 
190 qreal IconItem::implicitHeight() const
191 {
192  return QDeclarativeItem::implicitHeight();
193 }
194 
195 void IconItem::setSmooth(const bool smooth)
196 {
197  if (smooth == m_smooth) {
198  return;
199  }
200  m_smooth = smooth;
201  update();
202 }
203 
204 bool IconItem::smooth() const
205 {
206  return m_smooth;
207 }
208 
209 bool IconItem::isValid() const
210 {
211  return !m_icon.isNull() || m_svgIcon || !m_pixmapIcon.isNull() || !m_imageIcon.isNull();
212 }
213 
214 void IconItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
215 {
216  Q_UNUSED(option);
217  Q_UNUSED(widget);
218 
219  if (m_iconPixmaps.isEmpty()) {
220  return;
221  }
222  painter->save();
223  painter->setRenderHint(QPainter::Antialiasing, m_smooth);
224  painter->setRenderHint(QPainter::SmoothPixmapTransform, m_smooth);
225 
226  const QRect destRect(QPointF(boundingRect().center() - QPointF(m_iconPixmaps.first().width()/2, m_iconPixmaps.first().height()/2)).toPoint(),
227  m_iconPixmaps.first().size());
228 
229  if (m_animation->state() == QAbstractAnimation::Running) {
230  QPixmap result = m_iconPixmaps.first();
231  result = Plasma::PaintUtils::transition(result,
232  m_iconPixmaps.last(), m_animValue);
233  painter->drawPixmap(destRect, result);
234  //simpler logic for just paint
235  } else {
236  painter->drawPixmap(destRect, m_iconPixmaps.first());
237  }
238 
239  painter->restore();
240 }
241 
242 void IconItem::animationFinished()
243 {
244  while (m_iconPixmaps.count() > 1) {
245  m_iconPixmaps.pop_front();
246  }
247 }
248 
249 void IconItem::valueChanged(const QVariant &value)
250 {
251  m_animValue = value.toReal();
252  update();
253 }
254 
255 void IconItem::loadPixmap()
256 {
257  int size = qMin(width(), height());
258 
259  //FIXME: Heuristic: allow 24x24 for icons/ that are in the systray(ugly)
260  if (m_svgIcon && m_svgIcon->imagePath().contains("icons/") &&
261  size > KIconLoader::SizeSmallMedium &&
262  size < KIconLoader::SizeMedium) {
263  size = 24;
264 
265  //if size is less than 16, leave as is
266  } else if (size < KIconLoader::SizeSmall) {
267  //do nothing
268  } else if (size < KIconLoader::SizeSmallMedium) {
269  size = KIconLoader::SizeSmall;
270  } else if (size < KIconLoader::SizeMedium) {
271  size = KIconLoader::SizeSmallMedium;
272  } else if (size < KIconLoader::SizeLarge) {
273  size = KIconLoader::SizeMedium;
274  } else if (size < KIconLoader::SizeHuge) {
275  size = KIconLoader::SizeLarge;
276  //if size is more than 64, leave as is
277  }
278 
279 
280  //final pixmap to paint
281  QPixmap result;
282  if (size <= 0) {
283  m_animation->stop();
284  update();
285  return;
286  } else if (m_svgIcon) {
287  m_svgIcon->resize(size, size);
288  result = m_svgIcon->pixmap(m_source.toString());
289  } else if (!m_icon.isNull() && size>0) {
290  result = m_icon.pixmap(QSize(size, size));
291  } else if (!m_pixmapIcon.isNull()) {
292  result = m_pixmapIcon;
293  } else if (!m_imageIcon.isNull()) {
294  result = QPixmap::fromImage(m_imageIcon);
295  } else {
296  m_iconPixmaps.clear();
297  m_animation->stop();
298  update();
299  return;
300  }
301 
302  if (!isEnabled()) {
303  result = KIconLoader::global()->iconEffect()->apply(result, KIconLoader::Desktop, KIconLoader::DisabledState);
304  } else if (m_active) {
305  result = KIconLoader::global()->iconEffect()->apply(result, KIconLoader::Desktop, KIconLoader::ActiveState);
306  }
307 
308  //this happen only when loadPixmap has been called when an anim is running
309  while (m_iconPixmaps.count() > 1) {
310  m_iconPixmaps.pop_front();
311  }
312 
313  m_iconPixmaps << result;
314  //if there is only one image, don't animate
315  //if an animation was already running, immediate transition, to not overload
316  if (m_animation->state() == QAbstractAnimation::Running) {
317  m_animation->stop();
318  m_iconPixmaps.pop_front();
319  } else if (m_iconPixmaps.count() > 1) {
320  m_animation->setStartValue((qreal)0);
321  m_animation->setEndValue((qreal)1);
322  m_animation->start();
323  }
324  update();
325 }
326 
327 void IconItem::geometryChanged(const QRectF &newGeometry,
328  const QRectF &oldGeometry)
329 {
330  if (newGeometry.size() != oldGeometry.size()) {
331  m_iconPixmaps.clear();
332  if (newGeometry.width() > 0 && newGeometry.height() > 0) {
333  loadPixmap();
334  }
335 
336  QDeclarativeItem::geometryChanged(newGeometry, oldGeometry);
337  }
338 }
339 
340 #include "iconitem.moc"
IconItem::geometryChanged
void geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry)
Definition: iconitem.cpp:327
IconItem::implicitWidthChanged
void implicitWidthChanged()
iconitem.h
IconItem::~IconItem
~IconItem()
Definition: iconitem.cpp:65
IconItem::validChanged
void validChanged()
IconItem::smooth
bool smooth() const
IconItem::active
bool active
Definition: iconitem.h:41
IconItem::setSource
void setSource(const QVariant &source)
Definition: iconitem.cpp:69
IconItem::setImplicitHeight
void setImplicitHeight(qreal height)
Definition: iconitem.cpp:179
IconItem::implicitHeightChanged
void implicitHeightChanged()
QDeclarativeItem
IconItem::isValid
bool isValid() const
Definition: iconitem.cpp:209
IconItem::sourceChanged
void sourceChanged()
IconItem::IconItem
IconItem(QDeclarativeItem *parent=0)
Definition: iconitem.cpp:32
IconItem::implicitHeight
qreal implicitHeight() const
IconItem::activeChanged
void activeChanged()
IconItem::isActive
bool isActive() const
Definition: iconitem.cpp:147
IconItem::implicitWidth
qreal implicitWidth() const
IconItem::source
QVariant source() const
IconItem::setSmooth
void setSmooth(const bool smooth)
Definition: iconitem.cpp:195
IconItem::paint
void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
Definition: iconitem.cpp:214
IconItem::setActive
void setActive(bool active)
Definition: iconitem.cpp:152
IconItem::setImplicitWidth
void setImplicitWidth(qreal width)
Definition: iconitem.cpp:163
This file is part of the KDE documentation.
Documentation copyright © 1996-2014 The KDE developers.
Generated on Tue Oct 14 2014 23:02:42 by doxygen 1.8.7 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.

PlasmaCore

Skip menu "PlasmaCore"
  • Main Page
  • Namespace List
  • Alphabetical List
  • Class List
  • Class Hierarchy
  • Class Members
  • File List
  • File Members

kde-runtime API Reference

Skip menu "kde-runtime API Reference"
  • KCMShell
  • KNotify
  • Plasma Runtime
  •     PlasmaCore
  •     DragAndDrop
  •     PlasmaComponents
  •     PlasmaExtraComponents
  •     QtExtraComponents

Search



Report problems with this website to our bug tracking system.
Contact the specific authors with questions and comments about the page contents.

KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal