2012-11-26 20:49:16 +01:00
|
|
|
/*
|
2020-08-13 19:08:54 +00:00
|
|
|
SPDX-FileCopyrightText: 2012 Marco Martin <mart@kde.org>
|
|
|
|
SPDX-FileCopyrightText: 2014 David Edmundson <davidedmudnson@kde.org>
|
|
|
|
|
|
|
|
SPDX-License-Identifier: LGPL-2.0-or-later
|
|
|
|
*/
|
2012-11-26 20:49:16 +01:00
|
|
|
|
|
|
|
#include "iconitem.h"
|
2013-03-13 12:05:06 +01:00
|
|
|
#include <QDebug>
|
|
|
|
#include <QPaintEngine>
|
2012-11-26 20:49:16 +01:00
|
|
|
#include <QPainter>
|
Try to apply the colorscheme of the current theme to QIcons
Summary:
Before icons loaded internally with QIcon::fromTheme were being colored with the
colors from the current global color scheme instead of the ones from the current
Plasma Theme. Leading to visual bugs when the two differ. This happened because
KIconLoader uses the global color scheme by default.
A prominent case is the notification send by the network plasmoid when one
successfully connected to a wireless network. It sets the icon
"network-wireless-on" which is not included in Breeze icons (but is included in
Breeze Plasma Theme). If the current icon theme is indeed Breeze, IconItem
resorts to using QIcon::fromTheme and we end up with a wrong colored
"network-wireless" icon.
BUG: 417780
Test Plan:
{F8125752}
{F8125753}
Reviewers: #plasma, cblack, ngraham, mart
Reviewed By: #plasma, cblack, ngraham, mart
Subscribers: mart, wbauer, cblack, kde-frameworks-devel
Tags: #frameworks
Differential Revision: https://phabricator.kde.org/D27589
2020-02-24 14:34:23 +01:00
|
|
|
#include <QPalette>
|
2012-11-26 20:49:16 +01:00
|
|
|
#include <QPropertyAnimation>
|
2014-05-12 18:47:49 +02:00
|
|
|
#include <QSGSimpleTextureNode>
|
|
|
|
#include <QQuickWindow>
|
2012-11-26 20:49:16 +01:00
|
|
|
|
2020-07-08 07:44:43 +02:00
|
|
|
#include <KIconLoader>
|
|
|
|
#include <KIconEffect>
|
2015-10-20 11:44:52 +02:00
|
|
|
#include <KIconTheme>
|
2013-03-13 12:05:06 +01:00
|
|
|
|
2014-05-12 18:47:49 +02:00
|
|
|
#include "fadingnode_p.h"
|
2014-10-15 13:22:27 +02:00
|
|
|
#include <QuickAddons/ManagedTextureNode>
|
Try to apply the colorscheme of the current theme to QIcons
Summary:
Before icons loaded internally with QIcon::fromTheme were being colored with the
colors from the current global color scheme instead of the ones from the current
Plasma Theme. Leading to visual bugs when the two differ. This happened because
KIconLoader uses the global color scheme by default.
A prominent case is the notification send by the network plasmoid when one
successfully connected to a wireless network. It sets the icon
"network-wireless-on" which is not included in Breeze icons (but is included in
Breeze Plasma Theme). If the current icon theme is indeed Breeze, IconItem
resorts to using QIcon::fromTheme and we end up with a wrong colored
"network-wireless" icon.
BUG: 417780
Test Plan:
{F8125752}
{F8125753}
Reviewers: #plasma, cblack, ngraham, mart
Reviewed By: #plasma, cblack, ngraham, mart
Subscribers: mart, wbauer, cblack, kde-frameworks-devel
Tags: #frameworks
Differential Revision: https://phabricator.kde.org/D27589
2020-02-24 14:34:23 +01:00
|
|
|
#include "theme.h"
|
2014-09-25 14:33:39 +02:00
|
|
|
#include "units.h"
|
2013-02-02 04:43:20 +01:00
|
|
|
|
[PlasmaCore.IconItem] Refactor source handling for different types
Summary: There are 3 possible strategies: QIcon, QImage and SVG. This change moves logic of each of these strategies into separate class.
Test Plan: Should behave exactly the same
Reviewers: #plasma, broulik, apol, davidedmundson, #frameworks
Reviewed By: #plasma, davidedmundson
Subscribers: mart, davidre, cblack, kde-frameworks-devel, #plasma
Tags: #frameworks
Differential Revision: https://phabricator.kde.org/D28470
2020-03-31 22:37:34 +02:00
|
|
|
class IconItemSource
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
explicit IconItemSource(IconItem *iconItem) : m_iconItem(iconItem) {}
|
|
|
|
virtual ~IconItemSource() {}
|
|
|
|
|
|
|
|
virtual bool isValid() const = 0;
|
|
|
|
virtual const QSize size() const = 0;
|
|
|
|
virtual QPixmap pixmap(const QSize &size) = 0;
|
|
|
|
|
|
|
|
protected:
|
|
|
|
QQuickWindow *window()
|
|
|
|
{
|
|
|
|
return m_iconItem->window();
|
|
|
|
}
|
|
|
|
|
|
|
|
IconItem *m_iconItem;
|
|
|
|
};
|
|
|
|
|
|
|
|
class NullSource : public IconItemSource
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
explicit NullSource(IconItem *iconItem) : IconItemSource(iconItem) {}
|
|
|
|
|
|
|
|
bool isValid() const override
|
|
|
|
{
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
const QSize size() const override
|
|
|
|
{
|
|
|
|
return QSize();
|
|
|
|
}
|
|
|
|
|
|
|
|
QPixmap pixmap(const QSize &size) override
|
|
|
|
{
|
|
|
|
Q_UNUSED(size)
|
|
|
|
return QPixmap();
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
class QIconSource : public IconItemSource
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
explicit QIconSource(const QIcon &icon, IconItem *iconItem) : IconItemSource(iconItem)
|
|
|
|
{
|
|
|
|
m_icon = icon;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool isValid() const override
|
|
|
|
{
|
|
|
|
return !m_icon.isNull();
|
|
|
|
}
|
|
|
|
|
|
|
|
const QSize size() const override
|
|
|
|
{
|
|
|
|
return QSize();
|
|
|
|
}
|
|
|
|
|
|
|
|
QPixmap pixmap(const QSize &size) override
|
|
|
|
{
|
|
|
|
KIconLoader::global()->setCustomPalette(Plasma::Theme().palette());
|
|
|
|
QPixmap result = m_icon.pixmap(window(), size);
|
|
|
|
KIconLoader::global()->resetPalette();
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
|
|
|
private:
|
|
|
|
QIcon m_icon;
|
|
|
|
};
|
|
|
|
|
|
|
|
class QImageSource : public IconItemSource
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
explicit QImageSource(const QImage &imageIcon, IconItem *iconItem) : IconItemSource(iconItem)
|
|
|
|
{
|
|
|
|
m_imageIcon = imageIcon;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool isValid() const override
|
|
|
|
{
|
|
|
|
return !m_imageIcon.isNull();
|
|
|
|
}
|
|
|
|
|
|
|
|
const QSize size() const override
|
|
|
|
{
|
|
|
|
const QSize s = m_imageIcon.size();
|
|
|
|
if (s.isValid()) {
|
|
|
|
return s;
|
|
|
|
}
|
|
|
|
|
|
|
|
return QSize();
|
|
|
|
}
|
|
|
|
|
|
|
|
QPixmap pixmap(const QSize &size) override
|
|
|
|
{
|
|
|
|
Q_UNUSED(size)
|
|
|
|
return QPixmap::fromImage(m_imageIcon);
|
|
|
|
}
|
|
|
|
|
|
|
|
private:
|
|
|
|
QImage m_imageIcon;
|
|
|
|
};
|
|
|
|
|
|
|
|
class SvgSource : public IconItemSource
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
explicit SvgSource(const QString &sourceString, IconItem* iconItem) : IconItemSource(iconItem)
|
|
|
|
{
|
|
|
|
m_svgIcon = new Plasma::Svg(iconItem);
|
|
|
|
m_svgIcon->setColorGroup(iconItem->colorGroup());
|
|
|
|
m_svgIcon->setStatus(iconItem->status());
|
|
|
|
m_svgIcon->setDevicePixelRatio(devicePixelRatio());
|
|
|
|
QObject::connect(m_svgIcon, &Plasma::Svg::repaintNeeded, iconItem, &IconItem::schedulePixmapUpdate);
|
|
|
|
QObject::connect(iconItem, &IconItem::statusChanged, m_svgIcon, [=] {
|
|
|
|
if (m_svgIcon) {
|
|
|
|
m_svgIcon->setStatus(iconItem->status());
|
|
|
|
}
|
|
|
|
});
|
|
|
|
QObject::connect(iconItem, &IconItem::colorGroupChanged, m_svgIcon, [=] {
|
|
|
|
if (m_svgIcon) {
|
|
|
|
m_svgIcon->setColorGroup(iconItem->colorGroup());
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
|
|
|
if (iconItem->usesPlasmaTheme()) {
|
|
|
|
//try as a svg icon from plasma theme
|
|
|
|
m_svgIcon->setImagePath(QLatin1String("icons/") + sourceString.section(QLatin1Char('-'), 0, 0));
|
|
|
|
m_svgIcon->setContainsMultipleImages(true);
|
|
|
|
}
|
|
|
|
|
|
|
|
//success?
|
|
|
|
if (iconItem->usesPlasmaTheme() && m_svgIcon->isValid() && m_svgIcon->hasElement(sourceString)) {
|
|
|
|
m_svgIconName = sourceString;
|
|
|
|
//ok, svg not available from the plasma theme
|
|
|
|
} else {
|
|
|
|
//try to load from iconloader an svg with Plasma::Svg
|
|
|
|
const auto *iconTheme = KIconLoader::global()->theme();
|
|
|
|
QString iconPath;
|
|
|
|
if (iconTheme) {
|
|
|
|
iconPath = iconTheme->iconPath(sourceString + QLatin1String(".svg"), qMin(iconItem->width(), iconItem->height()), KIconLoader::MatchBest);
|
|
|
|
if (iconPath.isEmpty()) {
|
|
|
|
iconPath = iconTheme->iconPath(sourceString + QLatin1String(".svgz"), qMin(iconItem->width(), iconItem->height()), KIconLoader::MatchBest);
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
qWarning() << "KIconLoader has no theme set";
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!iconPath.isEmpty()) {
|
|
|
|
m_svgIcon->setImagePath(iconPath);
|
|
|
|
m_svgIconName = sourceString;
|
|
|
|
} else {
|
|
|
|
//fail, cleanup
|
|
|
|
delete m_svgIcon;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-04-30 22:06:49 +02:00
|
|
|
~SvgSource() {
|
2020-05-14 12:19:27 +01:00
|
|
|
if (m_svgIcon) {
|
|
|
|
QObject::disconnect(m_iconItem, nullptr, m_svgIcon, nullptr);
|
|
|
|
}
|
2020-04-30 22:06:49 +02:00
|
|
|
}
|
|
|
|
|
[PlasmaCore.IconItem] Refactor source handling for different types
Summary: There are 3 possible strategies: QIcon, QImage and SVG. This change moves logic of each of these strategies into separate class.
Test Plan: Should behave exactly the same
Reviewers: #plasma, broulik, apol, davidedmundson, #frameworks
Reviewed By: #plasma, davidedmundson
Subscribers: mart, davidre, cblack, kde-frameworks-devel, #plasma
Tags: #frameworks
Differential Revision: https://phabricator.kde.org/D28470
2020-03-31 22:37:34 +02:00
|
|
|
bool isValid() const override
|
|
|
|
{
|
|
|
|
return m_svgIcon;
|
|
|
|
}
|
|
|
|
|
|
|
|
const QSize size() const override
|
|
|
|
{
|
|
|
|
QSize s;
|
|
|
|
if (m_svgIcon) { // FIXME: Check Svg::isValid()? Considered expensive by apidox.
|
|
|
|
//resize() resets the icon to its implicit size, specified
|
|
|
|
m_svgIcon->resize();
|
|
|
|
|
|
|
|
//plasma theme icon, where one file contains multiple images
|
|
|
|
if (m_svgIcon->hasElement(m_svgIconName)) {
|
|
|
|
s = m_svgIcon->elementSize(m_svgIconName);
|
|
|
|
//normal icon: one image per file, page size is icon size
|
|
|
|
} else {
|
|
|
|
s = m_svgIcon->size();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return s;
|
|
|
|
}
|
|
|
|
|
|
|
|
QPixmap pixmap(const QSize &size) override
|
|
|
|
{
|
|
|
|
m_svgIcon->setDevicePixelRatio(devicePixelRatio());
|
|
|
|
m_svgIcon->resize(size);
|
|
|
|
if (!m_svgIconName.isEmpty() && m_svgIcon->hasElement(m_svgIconName)) {
|
|
|
|
return m_svgIcon->pixmap(m_svgIconName);
|
|
|
|
} else if (!m_svgIconName.isEmpty()) {
|
|
|
|
const auto *iconTheme = KIconLoader::global()->theme();
|
|
|
|
if (iconTheme) {
|
|
|
|
QString iconPath = iconTheme->iconPath(m_svgIconName + QLatin1String(".svg"), size.width(), KIconLoader::MatchBest);
|
|
|
|
if (iconPath.isEmpty()) {
|
|
|
|
iconPath = iconTheme->iconPath(m_svgIconName + QLatin1String(".svgz"), size.width(), KIconLoader::MatchBest);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!iconPath.isEmpty()) {
|
|
|
|
m_svgIcon->setImagePath(iconPath);
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
qWarning() << "KIconLoader has no theme set";
|
|
|
|
}
|
|
|
|
|
|
|
|
return m_svgIcon->pixmap();
|
|
|
|
}
|
|
|
|
|
|
|
|
return QPixmap();
|
|
|
|
}
|
|
|
|
|
|
|
|
private:
|
|
|
|
qreal devicePixelRatio()
|
|
|
|
{
|
|
|
|
return window() ? window()->devicePixelRatio() : qApp->devicePixelRatio();
|
|
|
|
}
|
|
|
|
|
|
|
|
QPointer<Plasma::Svg> m_svgIcon;
|
|
|
|
QString m_svgIconName;
|
|
|
|
};
|
|
|
|
|
2013-02-01 17:26:26 +01:00
|
|
|
IconItem::IconItem(QQuickItem *parent)
|
2014-05-12 18:47:49 +02:00
|
|
|
: QQuickItem(parent),
|
[PlasmaCore.IconItem] Refactor source handling for different types
Summary: There are 3 possible strategies: QIcon, QImage and SVG. This change moves logic of each of these strategies into separate class.
Test Plan: Should behave exactly the same
Reviewers: #plasma, broulik, apol, davidedmundson, #frameworks
Reviewed By: #plasma, davidedmundson
Subscribers: mart, davidre, cblack, kde-frameworks-devel, #plasma
Tags: #frameworks
Differential Revision: https://phabricator.kde.org/D28470
2020-03-31 22:37:34 +02:00
|
|
|
m_iconItemSource(new NullSource(this)),
|
2016-06-01 14:47:56 +02:00
|
|
|
m_status(Plasma::Svg::Normal),
|
2012-11-26 20:49:16 +01:00
|
|
|
m_active(false),
|
2016-01-06 20:21:15 +01:00
|
|
|
m_animated(true),
|
2016-01-20 11:28:56 +01:00
|
|
|
m_usesPlasmaTheme(true),
|
2017-02-26 11:27:58 +01:00
|
|
|
m_roundToIconSize(true),
|
2015-03-24 11:50:28 +01:00
|
|
|
m_textureChanged(false),
|
|
|
|
m_sizeChanged(false),
|
2016-03-11 14:07:44 +01:00
|
|
|
m_allowNextAnimation(false),
|
2016-07-12 10:02:47 +02:00
|
|
|
m_blockNextAnimation(false),
|
2017-04-03 15:42:29 +02:00
|
|
|
m_implicitHeightSetByUser(false),
|
|
|
|
m_implicitWidthSetByUser(false),
|
2014-06-18 19:22:02 +02:00
|
|
|
m_colorGroup(Plasma::Theme::NormalColorGroup),
|
2012-11-26 20:49:16 +01:00
|
|
|
m_animValue(0)
|
|
|
|
{
|
|
|
|
m_animation = new QPropertyAnimation(this);
|
2017-07-10 22:24:50 +02:00
|
|
|
connect(m_animation, &QPropertyAnimation::valueChanged,
|
|
|
|
this, &IconItem::valueChanged);
|
|
|
|
connect(m_animation, &QPropertyAnimation::finished,
|
|
|
|
this, &IconItem::animationFinished);
|
2012-11-26 20:49:16 +01:00
|
|
|
m_animation->setTargetObject(this);
|
|
|
|
m_animation->setEasingCurve(QEasingCurve::InOutQuad);
|
2014-05-12 18:47:49 +02:00
|
|
|
m_animation->setDuration(250); //FIXME from theme
|
2012-11-26 20:49:16 +01:00
|
|
|
|
2013-02-01 18:18:52 +01:00
|
|
|
setFlag(ItemHasContents, true);
|
2012-11-26 20:49:16 +01:00
|
|
|
|
2017-01-08 16:16:59 +01:00
|
|
|
connect(KIconLoader::global(), &KIconLoader::iconLoaderSettingsChanged,
|
|
|
|
this, &IconItem::updateImplicitSize);
|
2012-11-26 20:49:16 +01:00
|
|
|
|
2017-04-03 15:42:29 +02:00
|
|
|
connect(this, &IconItem::implicitWidthChanged, this, &IconItem::implicitWidthChanged2);
|
|
|
|
connect(this, &IconItem::implicitHeightChanged, this, &IconItem::implicitHeightChanged2);
|
|
|
|
|
2017-01-08 16:16:59 +01:00
|
|
|
updateImplicitSize();
|
2012-11-26 20:49:16 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
IconItem::~IconItem()
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2017-01-08 16:16:59 +01:00
|
|
|
void IconItem::updateImplicitSize()
|
|
|
|
{
|
[PlasmaCore.IconItem] Refactor source handling for different types
Summary: There are 3 possible strategies: QIcon, QImage and SVG. This change moves logic of each of these strategies into separate class.
Test Plan: Should behave exactly the same
Reviewers: #plasma, broulik, apol, davidedmundson, #frameworks
Reviewed By: #plasma, davidedmundson
Subscribers: mart, davidre, cblack, kde-frameworks-devel, #plasma
Tags: #frameworks
Differential Revision: https://phabricator.kde.org/D28470
2020-03-31 22:37:34 +02:00
|
|
|
if (m_iconItemSource->isValid()) {
|
|
|
|
const QSize s = m_iconItemSource->size();
|
2017-03-24 06:19:15 +09:00
|
|
|
|
|
|
|
if (s.isValid()) {
|
2017-04-03 15:42:29 +02:00
|
|
|
if (!m_implicitWidthSetByUser && !m_implicitHeightSetByUser) {
|
|
|
|
setImplicitSize(s.width(), s.height());
|
|
|
|
} else if (!m_implicitWidthSetByUser) {
|
|
|
|
setImplicitWidth(s.width());
|
|
|
|
} else if (!m_implicitHeightSetByUser) {
|
|
|
|
setImplicitHeight(s.height());
|
|
|
|
}
|
2017-03-24 06:19:15 +09:00
|
|
|
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Fall back to initializing implicit size to the Dialog size.
|
2017-01-08 16:16:59 +01:00
|
|
|
const int implicitSize = KIconLoader::global()->currentSize(KIconLoader::Dialog);
|
2017-04-03 15:42:29 +02:00
|
|
|
|
|
|
|
if (!m_implicitWidthSetByUser && !m_implicitHeightSetByUser) {
|
|
|
|
setImplicitSize(implicitSize, implicitSize);
|
|
|
|
} else if (!m_implicitWidthSetByUser) {
|
|
|
|
setImplicitWidth(implicitSize);
|
|
|
|
} else if (!m_implicitHeightSetByUser) {
|
|
|
|
setImplicitHeight(implicitSize);
|
|
|
|
}
|
2017-01-08 16:16:59 +01:00
|
|
|
}
|
|
|
|
|
2012-11-26 20:49:16 +01:00
|
|
|
void IconItem::setSource(const QVariant &source)
|
|
|
|
{
|
|
|
|
if (source == m_source) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2018-08-23 11:31:15 +02:00
|
|
|
disconnect(KIconLoader::global(), &KIconLoader::iconChanged, this, &IconItem::iconLoaderIconChanged);
|
|
|
|
|
2017-12-02 11:39:43 +01:00
|
|
|
const bool oldValid = isValid();
|
|
|
|
|
2012-11-26 20:49:16 +01:00
|
|
|
m_source = source;
|
2016-03-04 23:44:57 +01:00
|
|
|
QString sourceString = source.toString();
|
2012-11-26 20:49:16 +01:00
|
|
|
|
2016-01-19 10:14:49 +01:00
|
|
|
// If the QIcon was created with QIcon::fromTheme(), try to load it as svg
|
2016-03-04 23:44:57 +01:00
|
|
|
if (source.canConvert<QIcon>() && !source.value<QIcon>().name().isEmpty()) {
|
|
|
|
sourceString = source.value<QIcon>().name();
|
2016-01-19 10:14:49 +01:00
|
|
|
}
|
2012-11-26 20:49:16 +01:00
|
|
|
|
2016-03-04 23:44:57 +01:00
|
|
|
if (!sourceString.isEmpty()) {
|
2018-01-15 10:22:18 +01:00
|
|
|
// If a file:// URL or a absolute path is passed, take the image pointed by that from disk
|
|
|
|
QString localFile;
|
2017-05-29 17:18:42 +02:00
|
|
|
if (sourceString.startsWith(QLatin1String("file:"))) {
|
2018-01-15 10:22:18 +01:00
|
|
|
localFile = QUrl(sourceString).toLocalFile();
|
|
|
|
} else if (sourceString.startsWith(QLatin1Char('/'))) {
|
|
|
|
localFile = sourceString;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!localFile.isEmpty()) {
|
2018-09-19 15:48:27 +02:00
|
|
|
if (sourceString.endsWith(QLatin1String(".svg")) ||
|
|
|
|
sourceString.endsWith(QLatin1String(".svgz"))) {
|
[PlasmaCore.IconItem] Refactor source handling for different types
Summary: There are 3 possible strategies: QIcon, QImage and SVG. This change moves logic of each of these strategies into separate class.
Test Plan: Should behave exactly the same
Reviewers: #plasma, broulik, apol, davidedmundson, #frameworks
Reviewed By: #plasma, davidedmundson
Subscribers: mart, davidre, cblack, kde-frameworks-devel, #plasma
Tags: #frameworks
Differential Revision: https://phabricator.kde.org/D28470
2020-03-31 22:37:34 +02:00
|
|
|
QIcon icon = QIcon(localFile);
|
|
|
|
m_iconItemSource.reset(new QIconSource(icon, this));
|
2018-09-19 15:48:27 +02:00
|
|
|
} else {
|
[PlasmaCore.IconItem] Refactor source handling for different types
Summary: There are 3 possible strategies: QIcon, QImage and SVG. This change moves logic of each of these strategies into separate class.
Test Plan: Should behave exactly the same
Reviewers: #plasma, broulik, apol, davidedmundson, #frameworks
Reviewed By: #plasma, davidedmundson
Subscribers: mart, davidre, cblack, kde-frameworks-devel, #plasma
Tags: #frameworks
Differential Revision: https://phabricator.kde.org/D28470
2020-03-31 22:37:34 +02:00
|
|
|
QImage imageIcon = QImage(localFile);
|
|
|
|
m_iconItemSource.reset(new QImageSource(imageIcon, this));
|
2018-09-19 15:48:27 +02:00
|
|
|
}
|
2014-11-26 15:13:33 +01:00
|
|
|
} else {
|
[PlasmaCore.IconItem] Refactor source handling for different types
Summary: There are 3 possible strategies: QIcon, QImage and SVG. This change moves logic of each of these strategies into separate class.
Test Plan: Should behave exactly the same
Reviewers: #plasma, broulik, apol, davidedmundson, #frameworks
Reviewed By: #plasma, davidedmundson
Subscribers: mart, davidre, cblack, kde-frameworks-devel, #plasma
Tags: #frameworks
Differential Revision: https://phabricator.kde.org/D28470
2020-03-31 22:37:34 +02:00
|
|
|
m_iconItemSource.reset(new SvgSource(sourceString, this));
|
2014-11-26 15:13:33 +01:00
|
|
|
|
[PlasmaCore.IconItem] Refactor source handling for different types
Summary: There are 3 possible strategies: QIcon, QImage and SVG. This change moves logic of each of these strategies into separate class.
Test Plan: Should behave exactly the same
Reviewers: #plasma, broulik, apol, davidedmundson, #frameworks
Reviewed By: #plasma, davidedmundson
Subscribers: mart, davidre, cblack, kde-frameworks-devel, #plasma
Tags: #frameworks
Differential Revision: https://phabricator.kde.org/D28470
2020-03-31 22:37:34 +02:00
|
|
|
if (!m_iconItemSource->isValid()) {
|
|
|
|
//if we started with a QIcon use that.
|
|
|
|
QIcon icon = source.value<QIcon>();
|
|
|
|
if (icon.isNull()) {
|
|
|
|
icon = QIcon::fromTheme(sourceString);
|
2015-10-20 11:44:52 +02:00
|
|
|
}
|
[PlasmaCore.IconItem] Refactor source handling for different types
Summary: There are 3 possible strategies: QIcon, QImage and SVG. This change moves logic of each of these strategies into separate class.
Test Plan: Should behave exactly the same
Reviewers: #plasma, broulik, apol, davidedmundson, #frameworks
Reviewed By: #plasma, davidedmundson
Subscribers: mart, davidre, cblack, kde-frameworks-devel, #plasma
Tags: #frameworks
Differential Revision: https://phabricator.kde.org/D28470
2020-03-31 22:37:34 +02:00
|
|
|
m_iconItemSource.reset(new QIconSource(icon, this));
|
2015-10-20 11:44:52 +02:00
|
|
|
|
[PlasmaCore.IconItem] Refactor source handling for different types
Summary: There are 3 possible strategies: QIcon, QImage and SVG. This change moves logic of each of these strategies into separate class.
Test Plan: Should behave exactly the same
Reviewers: #plasma, broulik, apol, davidedmundson, #frameworks
Reviewed By: #plasma, davidedmundson
Subscribers: mart, davidre, cblack, kde-frameworks-devel, #plasma
Tags: #frameworks
Differential Revision: https://phabricator.kde.org/D28470
2020-03-31 22:37:34 +02:00
|
|
|
//since QIcon is rendered by KIconLoader, watch for when its configuration changes now and reload as needed.
|
|
|
|
connect(KIconLoader::global(), &KIconLoader::iconChanged, this, &IconItem::iconLoaderIconChanged);
|
2014-11-26 15:13:33 +01:00
|
|
|
}
|
2012-11-26 20:49:16 +01:00
|
|
|
}
|
|
|
|
|
2016-01-19 10:14:49 +01:00
|
|
|
} else if (source.canConvert<QIcon>()) {
|
[PlasmaCore.IconItem] Refactor source handling for different types
Summary: There are 3 possible strategies: QIcon, QImage and SVG. This change moves logic of each of these strategies into separate class.
Test Plan: Should behave exactly the same
Reviewers: #plasma, broulik, apol, davidedmundson, #frameworks
Reviewed By: #plasma, davidedmundson
Subscribers: mart, davidre, cblack, kde-frameworks-devel, #plasma
Tags: #frameworks
Differential Revision: https://phabricator.kde.org/D28470
2020-03-31 22:37:34 +02:00
|
|
|
m_iconItemSource.reset(new QIconSource(source.value<QIcon>(), this));
|
2012-11-26 20:49:16 +01:00
|
|
|
} else if (source.canConvert<QImage>()) {
|
[PlasmaCore.IconItem] Refactor source handling for different types
Summary: There are 3 possible strategies: QIcon, QImage and SVG. This change moves logic of each of these strategies into separate class.
Test Plan: Should behave exactly the same
Reviewers: #plasma, broulik, apol, davidedmundson, #frameworks
Reviewed By: #plasma, davidedmundson
Subscribers: mart, davidre, cblack, kde-frameworks-devel, #plasma
Tags: #frameworks
Differential Revision: https://phabricator.kde.org/D28470
2020-03-31 22:37:34 +02:00
|
|
|
m_iconItemSource.reset(new QImageSource(source.value<QImage>(), this));
|
2012-11-26 20:49:16 +01:00
|
|
|
} else {
|
[PlasmaCore.IconItem] Refactor source handling for different types
Summary: There are 3 possible strategies: QIcon, QImage and SVG. This change moves logic of each of these strategies into separate class.
Test Plan: Should behave exactly the same
Reviewers: #plasma, broulik, apol, davidedmundson, #frameworks
Reviewed By: #plasma, davidedmundson
Subscribers: mart, davidre, cblack, kde-frameworks-devel, #plasma
Tags: #frameworks
Differential Revision: https://phabricator.kde.org/D28470
2020-03-31 22:37:34 +02:00
|
|
|
m_iconItemSource.reset(new NullSource(this));
|
2012-11-26 20:49:16 +01:00
|
|
|
}
|
|
|
|
|
2013-02-14 04:33:26 +01:00
|
|
|
if (width() > 0 && height() > 0) {
|
2015-12-22 18:36:23 +01:00
|
|
|
schedulePixmapUpdate();
|
2013-02-14 04:33:26 +01:00
|
|
|
}
|
2012-11-26 20:49:16 +01:00
|
|
|
|
2017-03-24 06:19:15 +09:00
|
|
|
updateImplicitSize();
|
|
|
|
|
2012-11-26 20:49:16 +01:00
|
|
|
emit sourceChanged();
|
2017-12-02 11:39:43 +01:00
|
|
|
|
|
|
|
if (isValid() != oldValid) {
|
|
|
|
emit validChanged();
|
|
|
|
}
|
2012-11-26 20:49:16 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
QVariant IconItem::source() const
|
|
|
|
{
|
|
|
|
return m_source;
|
|
|
|
}
|
|
|
|
|
2014-06-18 19:22:02 +02:00
|
|
|
void IconItem::setColorGroup(Plasma::Theme::ColorGroup group)
|
2014-06-09 19:35:58 +02:00
|
|
|
{
|
2014-06-13 15:40:16 +02:00
|
|
|
if (m_colorGroup == group) {
|
2014-06-09 19:35:58 +02:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2014-06-13 15:40:16 +02:00
|
|
|
m_colorGroup = group;
|
|
|
|
emit colorGroupChanged();
|
2014-06-09 19:35:58 +02:00
|
|
|
}
|
|
|
|
|
2014-06-18 19:22:02 +02:00
|
|
|
Plasma::Theme::ColorGroup IconItem::colorGroup() const
|
2014-06-09 19:35:58 +02:00
|
|
|
{
|
2014-06-13 15:40:16 +02:00
|
|
|
return m_colorGroup;
|
2014-06-09 19:35:58 +02:00
|
|
|
}
|
|
|
|
|
2016-08-02 21:43:30 +05:30
|
|
|
|
|
|
|
void IconItem::setOverlays(const QStringList &overlays)
|
|
|
|
{
|
|
|
|
if (overlays == m_overlays) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
m_overlays = overlays;
|
2017-12-02 18:11:24 +01:00
|
|
|
schedulePixmapUpdate();
|
2016-08-02 21:43:30 +05:30
|
|
|
emit overlaysChanged();
|
|
|
|
}
|
|
|
|
|
|
|
|
QStringList IconItem::overlays() const
|
|
|
|
{
|
|
|
|
return m_overlays;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2012-11-26 20:49:16 +01:00
|
|
|
bool IconItem::isActive() const
|
|
|
|
{
|
|
|
|
return m_active;
|
|
|
|
}
|
|
|
|
|
|
|
|
void IconItem::setActive(bool active)
|
|
|
|
{
|
|
|
|
if (m_active == active) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
m_active = active;
|
2016-05-31 11:10:47 +02:00
|
|
|
|
2014-12-15 20:21:06 +01:00
|
|
|
if (isComponentComplete()) {
|
2016-03-11 14:07:44 +01:00
|
|
|
m_allowNextAnimation = true;
|
2015-12-22 18:36:23 +01:00
|
|
|
schedulePixmapUpdate();
|
2014-12-15 20:21:06 +01:00
|
|
|
}
|
2012-11-26 20:49:16 +01:00
|
|
|
emit activeChanged();
|
|
|
|
}
|
|
|
|
|
2016-01-06 20:21:15 +01:00
|
|
|
bool IconItem::isAnimated() const
|
|
|
|
{
|
|
|
|
return m_animated;
|
|
|
|
}
|
|
|
|
|
|
|
|
void IconItem::setAnimated(bool animated)
|
|
|
|
{
|
|
|
|
if (m_animated == animated) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
m_animated = animated;
|
|
|
|
emit animatedChanged();
|
|
|
|
}
|
|
|
|
|
2016-01-20 11:28:56 +01:00
|
|
|
bool IconItem::usesPlasmaTheme() const
|
|
|
|
{
|
|
|
|
return m_usesPlasmaTheme;
|
|
|
|
}
|
|
|
|
|
|
|
|
void IconItem::setUsesPlasmaTheme(bool usesPlasmaTheme)
|
|
|
|
{
|
|
|
|
if (m_usesPlasmaTheme == usesPlasmaTheme) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
m_usesPlasmaTheme = usesPlasmaTheme;
|
|
|
|
|
|
|
|
// Reload icon with new settings
|
2017-05-05 20:18:19 +02:00
|
|
|
const QVariant src = m_source;
|
|
|
|
m_source.clear();
|
|
|
|
setSource(src);
|
2016-01-20 11:28:56 +01:00
|
|
|
|
2017-05-05 20:18:19 +02:00
|
|
|
update();
|
2016-01-20 11:28:56 +01:00
|
|
|
emit usesPlasmaThemeChanged();
|
|
|
|
}
|
|
|
|
|
2017-02-26 11:27:58 +01:00
|
|
|
bool IconItem::roundToIconSize() const
|
|
|
|
{
|
|
|
|
return m_roundToIconSize;
|
|
|
|
}
|
|
|
|
|
|
|
|
void IconItem::setRoundToIconSize(bool roundToIconSize)
|
|
|
|
{
|
|
|
|
if (m_roundToIconSize == roundToIconSize) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
const QSize oldPaintedSize = paintedSize();
|
|
|
|
|
|
|
|
m_roundToIconSize = roundToIconSize;
|
|
|
|
emit roundToIconSizeChanged();
|
|
|
|
|
|
|
|
if (oldPaintedSize != paintedSize()) {
|
|
|
|
emit paintedSizeChanged();
|
|
|
|
}
|
|
|
|
|
|
|
|
schedulePixmapUpdate();
|
|
|
|
}
|
|
|
|
|
2012-11-26 20:49:16 +01:00
|
|
|
bool IconItem::isValid() const
|
|
|
|
{
|
[PlasmaCore.IconItem] Refactor source handling for different types
Summary: There are 3 possible strategies: QIcon, QImage and SVG. This change moves logic of each of these strategies into separate class.
Test Plan: Should behave exactly the same
Reviewers: #plasma, broulik, apol, davidedmundson, #frameworks
Reviewed By: #plasma, davidedmundson
Subscribers: mart, davidre, cblack, kde-frameworks-devel, #plasma
Tags: #frameworks
Differential Revision: https://phabricator.kde.org/D28470
2020-03-31 22:37:34 +02:00
|
|
|
return m_iconItemSource->isValid();
|
2012-11-26 20:49:16 +01:00
|
|
|
}
|
|
|
|
|
2016-01-04 18:17:33 +01:00
|
|
|
int IconItem::paintedWidth() const
|
|
|
|
{
|
2017-01-05 15:15:14 +01:00
|
|
|
return paintedSize(boundingRect().size()).width();
|
2016-01-04 18:17:33 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
int IconItem::paintedHeight() const
|
|
|
|
{
|
2017-01-05 15:15:14 +01:00
|
|
|
return paintedSize(boundingRect().size()).height();
|
|
|
|
}
|
|
|
|
|
|
|
|
QSize IconItem::paintedSize(const QSizeF &containerSize) const
|
|
|
|
{
|
|
|
|
const QSize &actualContainerSize = (containerSize.isValid() ? containerSize : boundingRect().size()).toSize();
|
|
|
|
|
|
|
|
const QSize paintedSize = m_iconPixmap.size().scaled(actualContainerSize, Qt::KeepAspectRatio);
|
|
|
|
|
|
|
|
const int width = paintedSize.width();
|
|
|
|
const int height = paintedSize.height();
|
|
|
|
|
|
|
|
if (width == height) {
|
2017-02-26 11:27:58 +01:00
|
|
|
if (m_roundToIconSize) {
|
|
|
|
return QSize(Units::roundToIconSize(width), Units::roundToIconSize(height));
|
|
|
|
} else {
|
|
|
|
return QSize(width, height);
|
|
|
|
}
|
2017-01-05 15:15:14 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
// if we don't have a square image, we still want it to be rounded to icon size
|
|
|
|
// but we cannot just blindly round both as we might erroneously change a 50x45 image to be 48x32
|
|
|
|
// instead, round the bigger of the two and then downscale the smaller with the ratio
|
|
|
|
if (width > height) {
|
2017-02-26 11:27:58 +01:00
|
|
|
const int roundedWidth = m_roundToIconSize ? Units::roundToIconSize(width) : width;
|
2017-01-05 15:15:14 +01:00
|
|
|
return QSize(roundedWidth, qRound(height * (roundedWidth / static_cast<qreal>(width))));
|
|
|
|
} else {
|
2017-02-26 11:27:58 +01:00
|
|
|
const int roundedHeight = m_roundToIconSize ? Units::roundToIconSize(height) : height;
|
2017-01-05 15:15:14 +01:00
|
|
|
return QSize(qRound(width * (roundedHeight / static_cast<qreal>(height))), roundedHeight);
|
|
|
|
}
|
2016-01-04 18:17:33 +01:00
|
|
|
}
|
|
|
|
|
2016-06-01 14:47:56 +02:00
|
|
|
void IconItem::setStatus(Plasma::Svg::Status status)
|
2016-05-31 11:10:47 +02:00
|
|
|
{
|
2016-06-01 14:47:56 +02:00
|
|
|
if (m_status == status) {
|
2016-05-31 11:10:47 +02:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2016-06-01 14:47:56 +02:00
|
|
|
m_status = status;
|
|
|
|
emit statusChanged();
|
2016-05-31 11:10:47 +02:00
|
|
|
}
|
|
|
|
|
2016-06-01 14:47:56 +02:00
|
|
|
Plasma::Svg::Status IconItem::status() const
|
2016-05-31 11:10:47 +02:00
|
|
|
{
|
2016-06-01 14:47:56 +02:00
|
|
|
return m_status;
|
2016-05-31 11:10:47 +02:00
|
|
|
}
|
|
|
|
|
2017-04-03 15:42:29 +02:00
|
|
|
void IconItem::setImplicitHeight2(int height)
|
|
|
|
{
|
|
|
|
m_implicitHeightSetByUser = true;
|
|
|
|
setImplicitHeight(height);
|
|
|
|
emit implicitHeightChanged2();
|
|
|
|
}
|
|
|
|
|
|
|
|
void IconItem::setImplicitWidth2(int width)
|
|
|
|
{
|
|
|
|
m_implicitWidthSetByUser = true;
|
|
|
|
setImplicitWidth(width);
|
|
|
|
emit implicitWidthChanged2();
|
|
|
|
}
|
|
|
|
|
2015-12-22 18:36:23 +01:00
|
|
|
void IconItem::updatePolish()
|
|
|
|
{
|
|
|
|
QQuickItem::updatePolish();
|
|
|
|
loadPixmap();
|
|
|
|
}
|
|
|
|
|
2014-05-12 18:47:49 +02:00
|
|
|
QSGNode* IconItem::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *updatePaintNodeData)
|
2012-11-26 20:49:16 +01:00
|
|
|
{
|
2014-05-12 18:47:49 +02:00
|
|
|
Q_UNUSED(updatePaintNodeData)
|
|
|
|
|
2018-04-13 09:05:17 +02:00
|
|
|
if (m_iconPixmap.isNull() || width() == 0.0 || height() == 0.0) {
|
2014-05-12 18:47:49 +02:00
|
|
|
delete oldNode;
|
2017-01-16 18:17:34 +01:00
|
|
|
return nullptr;
|
2012-11-26 20:49:16 +01:00
|
|
|
}
|
2013-02-02 04:43:20 +01:00
|
|
|
|
2014-05-12 18:47:49 +02:00
|
|
|
if (m_animation->state() == QAbstractAnimation::Running) {
|
2014-05-22 07:53:55 +02:00
|
|
|
FadingNode *animatingNode = dynamic_cast<FadingNode*>(oldNode);
|
2012-11-26 20:49:16 +01:00
|
|
|
|
2014-05-12 18:47:49 +02:00
|
|
|
if (!animatingNode || m_textureChanged) {
|
|
|
|
delete oldNode;
|
2014-02-17 15:39:01 +01:00
|
|
|
|
2018-03-06 11:09:55 +00:00
|
|
|
QSGTexture *source = window()->createTextureFromImage(m_oldIconPixmap.toImage(), QQuickWindow::TextureCanUseAtlas);
|
SvgItem, IconItem: drop "smooth" property override, update node on change
Summary:
QQuickItem already has a "smooth" property, which was shadowed by the
custom ones with the same name. As the property was not part of public
symbols, but instead is dynamically looked up without the class name part
of the property, we just remove the custom versions and instead switch
all custom code to use the inherited property.
While doing that the code is also fixed to properly update the
textureNodes to the current value of the "smooth" property.
As well as not set the filtering only on the texture, when it is passed
to a texturenode which will set its own filtering state to the texture
right before the bind call and thus wipe any previous direct setting
of the filter mode on the texture.
This also changed the default to smooth=true for SvgItem, though
effectively smooth was always true, as the texturenode was hardcoded
to get a QSGTexture::Linear filtering (which, as said above, is forced
onto its texture, no matter what was otherwise set before).
Reviewers: #plasma, davidedmundson, mart
Reviewed By: #plasma, davidedmundson
Subscribers: kde-frameworks-devel
Tags: #frameworks
Differential Revision: https://phabricator.kde.org/D20510
2019-04-13 17:23:20 +02:00
|
|
|
source->setFiltering(smooth() ? QSGTexture::Linear : QSGTexture::Nearest);
|
2018-03-06 11:09:55 +00:00
|
|
|
QSGTexture *target = window()->createTextureFromImage(m_iconPixmap.toImage(), QQuickWindow::TextureCanUseAtlas);
|
SvgItem, IconItem: drop "smooth" property override, update node on change
Summary:
QQuickItem already has a "smooth" property, which was shadowed by the
custom ones with the same name. As the property was not part of public
symbols, but instead is dynamically looked up without the class name part
of the property, we just remove the custom versions and instead switch
all custom code to use the inherited property.
While doing that the code is also fixed to properly update the
textureNodes to the current value of the "smooth" property.
As well as not set the filtering only on the texture, when it is passed
to a texturenode which will set its own filtering state to the texture
right before the bind call and thus wipe any previous direct setting
of the filter mode on the texture.
This also changed the default to smooth=true for SvgItem, though
effectively smooth was always true, as the texturenode was hardcoded
to get a QSGTexture::Linear filtering (which, as said above, is forced
onto its texture, no matter what was otherwise set before).
Reviewers: #plasma, davidedmundson, mart
Reviewed By: #plasma, davidedmundson
Subscribers: kde-frameworks-devel
Tags: #frameworks
Differential Revision: https://phabricator.kde.org/D20510
2019-04-13 17:23:20 +02:00
|
|
|
target->setFiltering(smooth() ? QSGTexture::Linear : QSGTexture::Nearest);
|
2014-05-12 18:47:49 +02:00
|
|
|
animatingNode = new FadingNode(source, target);
|
|
|
|
m_sizeChanged = true;
|
|
|
|
m_textureChanged = false;
|
|
|
|
}
|
2012-11-26 20:49:16 +01:00
|
|
|
|
2014-05-12 18:47:49 +02:00
|
|
|
animatingNode->setProgress(m_animValue);
|
|
|
|
|
|
|
|
if (m_sizeChanged) {
|
2017-01-05 15:15:14 +01:00
|
|
|
const QSize newSize = paintedSize();
|
|
|
|
const QRect destRect(QPointF(boundingRect().center() - QPointF(newSize.width(), newSize.height()) / 2).toPoint(), newSize);
|
2014-05-12 18:47:49 +02:00
|
|
|
animatingNode->setRect(destRect);
|
|
|
|
m_sizeChanged = false;
|
|
|
|
}
|
|
|
|
|
|
|
|
return animatingNode;
|
2012-11-26 20:49:16 +01:00
|
|
|
} else {
|
2014-10-15 13:22:27 +02:00
|
|
|
ManagedTextureNode *textureNode = dynamic_cast<ManagedTextureNode*>(oldNode);
|
2014-05-12 18:47:49 +02:00
|
|
|
|
|
|
|
if (!textureNode || m_textureChanged) {
|
|
|
|
delete oldNode;
|
2014-10-15 13:22:27 +02:00
|
|
|
textureNode = new ManagedTextureNode;
|
2017-01-30 10:24:33 +00:00
|
|
|
textureNode->setTexture(QSharedPointer<QSGTexture>(window()->createTextureFromImage(m_iconPixmap.toImage(), QQuickWindow::TextureCanUseAtlas)));
|
2014-05-12 18:47:49 +02:00
|
|
|
m_sizeChanged = true;
|
|
|
|
m_textureChanged = false;
|
|
|
|
}
|
SvgItem, IconItem: drop "smooth" property override, update node on change
Summary:
QQuickItem already has a "smooth" property, which was shadowed by the
custom ones with the same name. As the property was not part of public
symbols, but instead is dynamically looked up without the class name part
of the property, we just remove the custom versions and instead switch
all custom code to use the inherited property.
While doing that the code is also fixed to properly update the
textureNodes to the current value of the "smooth" property.
As well as not set the filtering only on the texture, when it is passed
to a texturenode which will set its own filtering state to the texture
right before the bind call and thus wipe any previous direct setting
of the filter mode on the texture.
This also changed the default to smooth=true for SvgItem, though
effectively smooth was always true, as the texturenode was hardcoded
to get a QSGTexture::Linear filtering (which, as said above, is forced
onto its texture, no matter what was otherwise set before).
Reviewers: #plasma, davidedmundson, mart
Reviewed By: #plasma, davidedmundson
Subscribers: kde-frameworks-devel
Tags: #frameworks
Differential Revision: https://phabricator.kde.org/D20510
2019-04-13 17:23:20 +02:00
|
|
|
textureNode->setFiltering(smooth() ? QSGTexture::Linear : QSGTexture::Nearest);
|
2012-11-26 20:49:16 +01:00
|
|
|
|
2014-05-12 18:47:49 +02:00
|
|
|
if (m_sizeChanged) {
|
2017-01-05 15:15:14 +01:00
|
|
|
const QSize newSize = paintedSize();
|
|
|
|
const QRect destRect(QPointF(boundingRect().center() - QPointF(newSize.width(), newSize.height()) / 2).toPoint(), newSize);
|
2014-05-12 18:47:49 +02:00
|
|
|
textureNode->setRect(destRect);
|
|
|
|
m_sizeChanged = false;
|
|
|
|
}
|
|
|
|
return textureNode;
|
2012-11-26 20:49:16 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void IconItem::valueChanged(const QVariant &value)
|
|
|
|
{
|
|
|
|
m_animValue = value.toReal();
|
|
|
|
update();
|
|
|
|
}
|
|
|
|
|
2017-12-02 15:52:22 +01:00
|
|
|
void IconItem::onEnabledChanged()
|
2016-03-11 14:07:44 +01:00
|
|
|
{
|
|
|
|
m_allowNextAnimation = true;
|
|
|
|
schedulePixmapUpdate();
|
|
|
|
}
|
|
|
|
|
2014-05-12 18:47:49 +02:00
|
|
|
void IconItem::animationFinished()
|
|
|
|
{
|
|
|
|
m_oldIconPixmap = QPixmap();
|
|
|
|
m_textureChanged = true;
|
2014-05-22 07:53:55 +02:00
|
|
|
update();
|
2014-05-12 18:47:49 +02:00
|
|
|
}
|
|
|
|
|
2018-08-23 11:31:15 +02:00
|
|
|
void IconItem::iconLoaderIconChanged(int group)
|
|
|
|
{
|
|
|
|
Q_UNUSED(group);
|
|
|
|
schedulePixmapUpdate();
|
|
|
|
}
|
|
|
|
|
2019-02-28 15:58:26 +01:00
|
|
|
void IconItem::windowVisibleChanged(bool visible)
|
|
|
|
{
|
|
|
|
if (visible) {
|
|
|
|
m_blockNextAnimation = true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-12-22 18:36:23 +01:00
|
|
|
void IconItem::schedulePixmapUpdate()
|
|
|
|
{
|
|
|
|
polish();
|
|
|
|
}
|
|
|
|
|
2014-02-17 15:39:01 +01:00
|
|
|
void IconItem::loadPixmap()
|
|
|
|
{
|
2014-12-15 20:21:06 +01:00
|
|
|
if (!isComponentComplete()) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2017-02-26 11:27:58 +01:00
|
|
|
int size = qMin(qRound(width()), qRound(height()));
|
|
|
|
if (m_roundToIconSize) {
|
|
|
|
size = Units::roundToIconSize(size);
|
|
|
|
}
|
2014-02-17 15:39:01 +01:00
|
|
|
|
2012-11-26 20:49:16 +01:00
|
|
|
//final pixmap to paint
|
|
|
|
QPixmap result;
|
2014-04-26 01:45:47 +02:00
|
|
|
if (size <= 0) {
|
2015-02-12 16:35:28 +01:00
|
|
|
m_iconPixmap = QPixmap();
|
2013-02-14 04:33:26 +01:00
|
|
|
m_animation->stop();
|
|
|
|
update();
|
2013-02-07 12:11:51 +01:00
|
|
|
return;
|
[PlasmaCore.IconItem] Refactor source handling for different types
Summary: There are 3 possible strategies: QIcon, QImage and SVG. This change moves logic of each of these strategies into separate class.
Test Plan: Should behave exactly the same
Reviewers: #plasma, broulik, apol, davidedmundson, #frameworks
Reviewed By: #plasma, davidedmundson
Subscribers: mart, davidre, cblack, kde-frameworks-devel, #plasma
Tags: #frameworks
Differential Revision: https://phabricator.kde.org/D28470
2020-03-31 22:37:34 +02:00
|
|
|
}
|
|
|
|
if (m_iconItemSource->isValid()) {
|
|
|
|
result = m_iconItemSource->pixmap(QSize(size, size));
|
2012-11-26 20:49:16 +01:00
|
|
|
} else {
|
2014-05-12 18:47:49 +02:00
|
|
|
m_iconPixmap = QPixmap();
|
2013-02-14 04:33:26 +01:00
|
|
|
m_animation->stop();
|
|
|
|
update();
|
2012-11-26 20:49:16 +01:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2016-08-02 21:43:30 +05:30
|
|
|
// Strangely KFileItem::overlays() returns empty string-values, so
|
|
|
|
// we need to check first whether an overlay must be drawn at all.
|
|
|
|
// It is more efficient to do it here, as KIconLoader::drawOverlays()
|
|
|
|
// assumes that an overlay will be drawn and has some additional
|
|
|
|
// setup time.
|
2019-03-20 07:12:03 +01:00
|
|
|
for (const QString &overlay : qAsConst(m_overlays)) {
|
2016-08-02 21:43:30 +05:30
|
|
|
if (!overlay.isEmpty()) {
|
|
|
|
// There is at least one overlay, draw all overlays above m_pixmap
|
|
|
|
// and cancel the check
|
|
|
|
KIconLoader::global()->drawOverlays(m_overlays, result, KIconLoader::Desktop);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-11-26 20:49:16 +01:00
|
|
|
if (!isEnabled()) {
|
|
|
|
result = KIconLoader::global()->iconEffect()->apply(result, KIconLoader::Desktop, KIconLoader::DisabledState);
|
|
|
|
} else if (m_active) {
|
|
|
|
result = KIconLoader::global()->iconEffect()->apply(result, KIconLoader::Desktop, KIconLoader::ActiveState);
|
|
|
|
}
|
|
|
|
|
2017-01-05 15:15:14 +01:00
|
|
|
const QSize oldPaintedSize = paintedSize();
|
|
|
|
|
2014-05-12 18:47:49 +02:00
|
|
|
m_oldIconPixmap = m_iconPixmap;
|
|
|
|
m_iconPixmap = result;
|
|
|
|
m_textureChanged = true;
|
2014-02-17 15:39:01 +01:00
|
|
|
|
2017-01-05 15:15:14 +01:00
|
|
|
if (oldPaintedSize != paintedSize()) {
|
|
|
|
emit paintedSizeChanged();
|
|
|
|
}
|
|
|
|
|
2014-05-12 18:47:49 +02:00
|
|
|
//don't animate initial setting
|
2017-09-27 15:50:44 +01:00
|
|
|
bool animated = (m_animated || m_allowNextAnimation) && !m_oldIconPixmap.isNull() && !m_sizeChanged && !m_blockNextAnimation;
|
|
|
|
|
|
|
|
if (QQuickWindow::sceneGraphBackend() == QLatin1String("software")) {
|
|
|
|
animated = false;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (animated) {
|
2016-02-27 21:24:45 +01:00
|
|
|
m_animValue = 0.0;
|
2012-11-26 20:49:16 +01:00
|
|
|
m_animation->setStartValue((qreal)0);
|
|
|
|
m_animation->setEndValue((qreal)1);
|
|
|
|
m_animation->start();
|
2016-03-11 14:07:44 +01:00
|
|
|
m_allowNextAnimation = false;
|
2014-05-12 18:47:49 +02:00
|
|
|
} else {
|
|
|
|
m_animValue = 1.0;
|
2014-12-11 14:48:42 -05:00
|
|
|
m_animation->stop();
|
2016-07-12 10:02:47 +02:00
|
|
|
m_blockNextAnimation = false;
|
2012-11-26 20:49:16 +01:00
|
|
|
}
|
|
|
|
update();
|
|
|
|
}
|
|
|
|
|
2016-03-10 13:01:29 +01:00
|
|
|
void IconItem::itemChange(ItemChange change, const ItemChangeData &value)
|
|
|
|
{
|
|
|
|
if (change == ItemVisibleHasChanged && value.boolValue) {
|
2016-07-12 10:02:47 +02:00
|
|
|
m_blockNextAnimation = true;
|
2018-08-17 15:46:29 +02:00
|
|
|
} else if (change == ItemEnabledHasChanged) {
|
|
|
|
onEnabledChanged();
|
2017-12-02 18:12:31 +01:00
|
|
|
} else if (change == ItemSceneChange && value.window) {
|
2019-02-28 15:58:26 +01:00
|
|
|
if (m_window) {
|
|
|
|
disconnect(m_window.data(), &QWindow::visibleChanged, this, &IconItem::windowVisibleChanged);
|
|
|
|
}
|
|
|
|
m_window = value.window;
|
|
|
|
if (m_window) {
|
|
|
|
connect(m_window.data(), &QWindow::visibleChanged, this, &IconItem::windowVisibleChanged);
|
|
|
|
}
|
2017-12-02 18:12:31 +01:00
|
|
|
schedulePixmapUpdate();
|
2019-02-28 15:58:26 +01:00
|
|
|
|
2016-03-10 13:01:29 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
QQuickItem::itemChange(change, value);
|
|
|
|
}
|
|
|
|
|
2012-11-26 20:49:16 +01:00
|
|
|
void IconItem::geometryChanged(const QRectF &newGeometry,
|
|
|
|
const QRectF &oldGeometry)
|
|
|
|
{
|
|
|
|
if (newGeometry.size() != oldGeometry.size()) {
|
2014-05-21 16:54:05 +02:00
|
|
|
m_sizeChanged = true;
|
2013-02-14 04:33:26 +01:00
|
|
|
if (newGeometry.width() > 0 && newGeometry.height() > 0) {
|
2015-12-22 18:36:23 +01:00
|
|
|
schedulePixmapUpdate();
|
|
|
|
} else {
|
|
|
|
update();
|
2013-02-14 04:33:26 +01:00
|
|
|
}
|
2016-01-04 18:17:33 +01:00
|
|
|
|
2017-01-05 15:15:14 +01:00
|
|
|
if (paintedSize(oldGeometry.size()) != paintedSize(newGeometry.size())) {
|
2016-01-04 18:17:33 +01:00
|
|
|
emit paintedSizeChanged();
|
|
|
|
}
|
2013-02-14 04:33:26 +01:00
|
|
|
}
|
2014-02-17 14:32:35 +01:00
|
|
|
|
|
|
|
QQuickItem::geometryChanged(newGeometry, oldGeometry);
|
2012-11-26 20:49:16 +01:00
|
|
|
}
|
|
|
|
|
2014-12-15 20:21:06 +01:00
|
|
|
void IconItem::componentComplete()
|
|
|
|
{
|
|
|
|
QQuickItem::componentComplete();
|
2015-12-22 18:36:23 +01:00
|
|
|
schedulePixmapUpdate();
|
2014-12-15 20:21:06 +01:00
|
|
|
}
|