event compression in icons generation

saves generation of useless qimages and speed improvement ruring manual resize: ludicrous
This commit is contained in:
Marco Martin 2014-02-17 15:39:01 +01:00
parent 1b21c1a5d9
commit 317f19d658
2 changed files with 40 additions and 18 deletions

View File

@ -161,6 +161,12 @@ IconItem::IconItem(QQuickItem *parent)
m_active(false), m_active(false),
m_animValue(0) m_animValue(0)
{ {
m_loadPixmapTimer.setSingleShot(true);
m_loadPixmapTimer.setInterval(150);
connect(&m_loadPixmapTimer, &QTimer::timeout, [=] () {
loadPixmap();
});
m_animation = new QPropertyAnimation(this); m_animation = new QPropertyAnimation(this);
connect(m_animation, SIGNAL(valueChanged(QVariant)), connect(m_animation, SIGNAL(valueChanged(QVariant)),
this, SLOT(valueChanged(QVariant))); this, SLOT(valueChanged(QVariant)));
@ -179,7 +185,7 @@ IconItem::IconItem(QQuickItem *parent)
connect(this, SIGNAL(enabledChanged()), connect(this, SIGNAL(enabledChanged()),
this, SLOT(loadPixmap())); &m_loadPixmapTimer, SLOT(start()));
//initialize implicit size to the Dialog size //initialize implicit size to the Dialog size
setImplicitWidth(KIconLoader::global()->currentSize(KIconLoader::Dialog)); setImplicitWidth(KIconLoader::global()->currentSize(KIconLoader::Dialog));
@ -252,7 +258,7 @@ void IconItem::setSource(const QVariant &source)
} }
if (width() > 0 && height() > 0) { if (width() > 0 && height() > 0) {
loadPixmap(); m_loadPixmapTimer.start();
} }
emit sourceChanged(); emit sourceChanged();
@ -276,7 +282,7 @@ void IconItem::setActive(bool active)
} }
m_active = active; m_active = active;
loadPixmap(); m_loadPixmapTimer.start();
emit activeChanged(); emit activeChanged();
} }
@ -309,8 +315,10 @@ void IconItem::paint(QPainter *painter)
painter->setRenderHint(QPainter::Antialiasing, m_smooth); painter->setRenderHint(QPainter::Antialiasing, m_smooth);
painter->setRenderHint(QPainter::SmoothPixmapTransform, m_smooth); painter->setRenderHint(QPainter::SmoothPixmapTransform, m_smooth);
const QRect destRect(QPointF(boundingRect().center() - QPointF(m_iconPixmaps.first().width()/2, m_iconPixmaps.first().height()/2)).toPoint(), const int iconSize = adjustedSize(qMin(boundingRect().size().width(), boundingRect().size().height()));
m_iconPixmaps.first().size());
const QRect destRect(QPointF(boundingRect().center() - QPointF(iconSize/2, iconSize/2)).toPoint(),
QSize(iconSize, iconSize));
if (m_animation->state() == QAbstractAnimation::Running) { if (m_animation->state() == QAbstractAnimation::Running) {
QPixmap result = m_iconPixmaps.first(); QPixmap result = m_iconPixmaps.first();
@ -338,30 +346,35 @@ void IconItem::valueChanged(const QVariant &value)
update(); update();
} }
void IconItem::loadPixmap() int IconItem::adjustedSize(int size)
{ {
int size = qMin(width(), height());
//FIXME: Heuristic: allow 24x24 for icons/ that are in the systray(ugly) //FIXME: Heuristic: allow 24x24 for icons/ that are in the systray(ugly)
if (m_svgIcon && m_svgIcon->imagePath().contains("icons/") && if (m_svgIcon && m_svgIcon->imagePath().contains("icons/") &&
size > KIconLoader::SizeSmallMedium && size > KIconLoader::SizeSmallMedium &&
size < KIconLoader::SizeMedium) { size < KIconLoader::SizeMedium) {
size = 24; return 24;
//if size is less than 16, leave as is //if size is less than 16, leave as is
} else if (size < KIconLoader::SizeSmall) { } else if (size < KIconLoader::SizeSmall) {
//do nothing //do nothing
} else if (size < KIconLoader::SizeSmallMedium) { } else if (size < KIconLoader::SizeSmallMedium) {
size = KIconLoader::SizeSmall; return KIconLoader::SizeSmall;
} else if (size < KIconLoader::SizeMedium) { } else if (size < KIconLoader::SizeMedium) {
size = KIconLoader::SizeSmallMedium; return KIconLoader::SizeSmallMedium;
} else if (size < KIconLoader::SizeLarge) { } else if (size < KIconLoader::SizeLarge) {
size = KIconLoader::SizeMedium; return KIconLoader::SizeMedium;
} else if (size < KIconLoader::SizeHuge) { } else if (size < KIconLoader::SizeHuge) {
size = KIconLoader::SizeLarge; return KIconLoader::SizeLarge;
//if size is more than 64, leave as is //if size is more than 64, leave as is
} }
return size;
}
void IconItem::loadPixmap()
{
const int size = adjustedSize(qMin(width(), height()));
//final pixmap to paint //final pixmap to paint
QPixmap result; QPixmap result;
if (size<=0) { if (size<=0) {
@ -399,9 +412,16 @@ void IconItem::loadPixmap()
m_iconPixmaps << result; m_iconPixmaps << result;
//if there is only one image, don't animate //if there is only one image, don't animate
//if an animation was already running, immediate transition, to not overload //if an animation was already running, immediate transition, to not overload
if (m_animation->state() == QAbstractAnimation::Running) { if (m_iconPixmaps.first().size() != result.size()) {
m_animation->stop();
if (m_iconPixmaps.count() > 1) {
m_iconPixmaps.pop_front();
}
} else if (m_animation->state() == QAbstractAnimation::Running) {
m_animation->stop(); m_animation->stop();
m_iconPixmaps.pop_front(); m_iconPixmaps.pop_front();
} else if (m_iconPixmaps.count() > 1) { } else if (m_iconPixmaps.count() > 1) {
m_animation->setStartValue((qreal)0); m_animation->setStartValue((qreal)0);
m_animation->setEndValue((qreal)1); m_animation->setEndValue((qreal)1);
@ -414,11 +434,10 @@ void IconItem::geometryChanged(const QRectF &newGeometry,
const QRectF &oldGeometry) const QRectF &oldGeometry)
{ {
if (newGeometry.size() != oldGeometry.size()) { if (newGeometry.size() != oldGeometry.size()) {
m_iconPixmaps.clear();
if (newGeometry.width() > 0 && newGeometry.height() > 0) { if (newGeometry.width() > 0 && newGeometry.height() > 0) {
loadPixmap(); m_loadPixmapTimer.start();
update();
} }
} }
QQuickItem::geometryChanged(newGeometry, oldGeometry); QQuickItem::geometryChanged(newGeometry, oldGeometry);

View File

@ -24,6 +24,7 @@
#include <QQuickPaintedItem> #include <QQuickPaintedItem>
#include <QPixmap> #include <QPixmap>
#include <QVariant> #include <QVariant>
#include <QTimer>
class QPropertyAnimation; class QPropertyAnimation;
@ -73,6 +74,7 @@ private Q_SLOTS:
void valueChanged(const QVariant &value); void valueChanged(const QVariant &value);
private: private:
int adjustedSize(int size);
//all the ways we can set an source. Only one of them will be valid //all the ways we can set an source. Only one of them will be valid
QIcon m_icon; QIcon m_icon;
Plasma::Svg *m_svgIcon; Plasma::Svg *m_svgIcon;
@ -80,6 +82,7 @@ private:
QImage m_imageIcon; QImage m_imageIcon;
//this contains the raw variant it was passed //this contains the raw variant it was passed
QVariant m_source; QVariant m_source;
QTimer m_loadPixmapTimer;
QSizeF m_implicitSize; QSizeF m_implicitSize;