Remove IconItem class

This commit is contained in:
cutefishd 2021-03-24 23:42:43 +08:00
parent bdc3b08027
commit b859b34a67
9 changed files with 3 additions and 592 deletions

View file

@ -31,8 +31,6 @@ set(SRCS
src/popupwindow.cpp
src/fakewindow.cpp
src/iconitem.cpp
src/managedtexturenode.cpp
)
set(RESOURCES

View file

@ -50,7 +50,7 @@ Item {
dragStarted = false
}
IconItem {
Meui.IconItem {
id: icon
anchors.centerIn: parent
width: control.iconSize

View file

@ -1,427 +0,0 @@
/*
* Copyright (C) 2021 CutefishOS Team.
*
* Author: cutefish <cutefishos@foxmail.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "iconitem.h"
#include <QDebug>
#include <QPainter>
#include <QPaintEngine>
#include <QApplication>
#include <QQuickWindow>
#include <QPixmap>
#include <QImageReader>
#include "managedtexturenode.h"
template<class T>
typename std::enable_if <!std::is_integral<T>(), bool>::type almost_equal(T x, T y, int ulp)
{
return std::abs(x - y) <std::numeric_limits<T>::epsilon() * std::abs(x + y) * ulp
|| std::abs(x - y) <std::numeric_limits<T>::min();
}
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
{
QPixmap result = m_icon.pixmap(window(), m_icon.actualSize(size));
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_reader.setFileName(sourceString);
}
bool isValid() const override {
return m_reader.canRead();
}
const QSize size() const override {
return QSize();
}
QPixmap pixmap(const QSize &size) override {
m_reader.setScaledSize(size * devicePixelRatio());
return QPixmap::fromImage(m_reader.read());
}
private:
qreal devicePixelRatio() {
return window() ? window()->devicePixelRatio() : qApp->devicePixelRatio();
}
QImageReader m_reader;
QString m_svgIconName;
};
IconItem::IconItem(QQuickItem *parent)
: QQuickItem(parent)
, m_iconItemSource(new NullSource(this))
, m_active(false)
, m_animated(false)
, m_roundToIconSize(true)
, m_textureChanged(false)
, m_sizeChanged(false)
{
setFlag(ItemHasContents, true);
setSmooth(true);
}
void IconItem::setSource(const QVariant &source)
{
if (source == m_source) {
return;
}
const bool oldValid = isValid();
m_source = source;
QString sourceString = source.toString();
// If the QIcon was created with QIcon::fromTheme(), try to load it as svg
if (source.canConvert<QIcon>() && !source.value<QIcon>().name().isEmpty()) {
sourceString = source.value<QIcon>().name();
}
if (!sourceString.isEmpty()) {
// If a file:// URL or a absolute path is passed, take the image pointed by that from disk
QString localFile;
if (sourceString.startsWith(QLatin1String("file:"))) {
localFile = QUrl(sourceString).toLocalFile();
} else if (sourceString.startsWith(QLatin1Char('/'))) {
localFile = sourceString;
} else if (sourceString.startsWith("qrc:/")) {
localFile = sourceString.remove(0, 3);
} else if (sourceString.startsWith(":/")) {
localFile = sourceString;
}
if (!localFile.isEmpty()) {
if (sourceString.endsWith(QLatin1String(".svg"))
|| sourceString.endsWith(QLatin1String(".svgz"))
|| sourceString.endsWith(QLatin1String(".ico"))) {
QIcon icon = QIcon(localFile);
m_iconItemSource.reset(new QIconSource(icon, this));
} else {
QImage imageIcon = QImage(localFile);
m_iconItemSource.reset(new QImageSource(imageIcon, this));
}
} else {
// if (sourceString.startsWith("qrc:/"))
// m_iconItemSource.reset(new SvgSource(sourceString.remove(0, 3), this));
// else if (sourceString.startsWith(":/"))
// m_iconItemSource.reset(new SvgSource(sourceString, this));
if (!m_iconItemSource->isValid()) {
// if we started with a QIcon use that.
QIcon icon = source.value<QIcon>();
if (icon.isNull()) {
icon = QIcon::fromTheme(sourceString, QIcon::fromTheme("application-x-desktop"));
}
m_iconItemSource.reset(new QIconSource(icon, this));
}
}
} else if (source.canConvert<QIcon>()) {
m_iconItemSource.reset(new QIconSource(source.value<QIcon>(), this));
} else if (source.canConvert<QImage>()) {
m_iconItemSource.reset(new QImageSource(source.value<QImage>(), this));
} else {
m_iconItemSource.reset(new NullSource(this));
}
if (width() > 0 && height() > 0) {
schedulePixmapUpdate();
}
updateImplicitSize();
emit sourceChanged();
if (isValid() != oldValid) {
Q_EMIT validChanged();
}
}
QVariant IconItem::source() const
{
return m_source;
}
void IconItem::updateImplicitSize()
{
if (m_iconItemSource->isValid()) {
const QSize s = m_iconItemSource->size();
if (s.isValid()) {
if (!m_implicitWidthSetByUser && !m_implicitHeightSetByUser) {
setImplicitSize(s.width(), s.height());
} else if (!m_implicitWidthSetByUser) {
setImplicitWidth(s.width());
} else if (!m_implicitHeightSetByUser) {
setImplicitHeight(s.height());
}
return;
}
}
// Fall back to initializing implicit size to the Dialog size.
const int implicitSize = 16;
if (!m_implicitWidthSetByUser && !m_implicitHeightSetByUser) {
setImplicitSize(implicitSize, implicitSize);
} else if (!m_implicitWidthSetByUser) {
setImplicitWidth(implicitSize);
} else if (!m_implicitHeightSetByUser) {
setImplicitHeight(implicitSize);
}
}
bool IconItem::isValid() const
{
return m_iconItemSource->isValid();
}
int IconItem::paintedWidth() const
{
return boundingRect().size().toSize().width();
}
int IconItem::paintedHeight() const
{
return boundingRect().size().toSize().height();
}
void IconItem::updateIcon()
{
updatePolish();
}
void IconItem::updatePolish()
{
QQuickItem::updatePolish();
loadPixmap();
}
QSGNode *IconItem::updatePaintNode(QSGNode *oldNode, QQuickItem::UpdatePaintNodeData *updatePaintNodeData)
{
Q_UNUSED(updatePaintNodeData)
if (m_iconPixmap.isNull() || width() == 0.0 || height() == 0.0) {
delete oldNode;
return nullptr;
}
ManagedTextureNode *textureNode = dynamic_cast<ManagedTextureNode *>(oldNode);
if (!textureNode || m_textureChanged) {
delete oldNode;
textureNode = new ManagedTextureNode;
textureNode->setTexture(QSharedPointer<QSGTexture>(window()->createTextureFromImage(m_iconPixmap.toImage(), QQuickWindow::TextureCanUseAtlas)));
m_sizeChanged = true;
m_textureChanged = false;
}
textureNode->setFiltering(smooth() ? QSGTexture::Linear : QSGTexture::Nearest);
if (m_sizeChanged) {
const QSize newSize = QSize(paintedWidth(), paintedHeight());
const QRect destRect(QPointF(boundingRect().center() - QPointF(newSize.width(), newSize.height()) / 2).toPoint(), newSize);
textureNode->setRect(destRect);
m_sizeChanged = false;
}
return textureNode;
}
void IconItem::itemChange(QQuickItem::ItemChange change, const QQuickItem::ItemChangeData &value)
{
QQuickItem::itemChange(change, value);
}
void IconItem::geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry)
{
if (newGeometry.size() != oldGeometry.size()) {
m_sizeChanged = true;
if (newGeometry.width() > 1 && newGeometry.height() > 1) {
schedulePixmapUpdate();
} else {
update();
}
const auto oldSize = qMin(oldGeometry.size().width(), oldGeometry.size().height());
const auto newSize = qMin(newGeometry.size().width(), newGeometry.size().height());
if (!almost_equal(oldSize, newSize, 2)) {
emit paintedSizeChanged();
}
}
QQuickItem::geometryChanged(newGeometry, oldGeometry);
}
void IconItem::componentComplete()
{
QQuickItem::componentComplete();
schedulePixmapUpdate();
}
void IconItem::schedulePixmapUpdate()
{
polish();
}
void IconItem::loadPixmap()
{
if (!isComponentComplete()) {
return;
}
int size = qMin(qRound(width()), qRound(height()));
QPixmap result;
if (size <= 0) {
m_iconPixmap = QPixmap();
update();
return;
}
if (m_iconItemSource->isValid()) {
result = m_iconItemSource->pixmap(QSize(size * qApp->devicePixelRatio(),
size * qApp->devicePixelRatio()));
result.setDevicePixelRatio(qApp->devicePixelRatio());
} else {
m_iconPixmap = QPixmap();
update();
return;
}
m_oldIconPixmap = m_iconPixmap;
m_iconPixmap = result;
m_textureChanged = true;
update();
}

View file

@ -1,100 +0,0 @@
/*
* Copyright (C) 2021 CutefishOS Team.
*
* Author: cutefish <cutefishos@foxmail.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef ICONITEM_H
#define ICONITEM_H
#include <QQuickItem>
#include <QIcon>
#include <QImage>
#include <QPixmap>
#include <QSharedPointer>
class IconItemSource;
class IconItem : public QQuickItem
{
Q_OBJECT
Q_PROPERTY(QVariant source READ source WRITE setSource NOTIFY sourceChanged)
Q_PROPERTY(bool valid READ isValid NOTIFY validChanged)
Q_PROPERTY(int paintedWidth READ paintedWidth NOTIFY paintedSizeChanged)
Q_PROPERTY(int paintedHeight READ paintedHeight NOTIFY paintedSizeChanged)
public:
explicit IconItem(QQuickItem *parent = nullptr);
void setSource(const QVariant &source);
QVariant source() const;
void updateImplicitSize();
bool isValid() const;
int paintedWidth() const;
int paintedHeight() const;
Q_INVOKABLE void updateIcon();
void updatePolish() override;
QSGNode *updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *updatePaintNodeData) override;
void itemChange(ItemChange change, const ItemChangeData &value) override;
void geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry) override;
void componentComplete() override;
signals:
void overlaysChanged();
void activeChanged();
void sourceChanged();
void animatedChanged();
void roundToIconSizeChanged();
void validChanged();
void colorGroupChanged();
void paintedSizeChanged();
void statusChanged();
void implicitHeightChanged2();
void implicitWidthChanged2();
private slots:
void schedulePixmapUpdate();
private:
void loadPixmap();
private:
QSharedPointer<IconItemSource> m_iconItemSource;
QVariant m_source;
bool m_active;
bool m_animated;
bool m_roundToIconSize;
bool m_textureChanged;
bool m_sizeChanged;
bool m_allowNextAnimation;
bool m_blockNextAnimation;
bool m_implicitHeightSetByUser;
bool m_implicitWidthSetByUser;
QPixmap m_iconPixmap;
QPixmap m_oldIconPixmap;
};
#endif // ICONITEM_H

View file

@ -26,7 +26,6 @@
#include "applicationmodel.h"
#include "mainwindow.h"
#include "iconitem.h"
#include "popupwindow.h"
int main(int argc, char *argv[])
@ -35,7 +34,6 @@ int main(int argc, char *argv[])
QApplication app(argc, argv);
qmlRegisterType<DockSettings>("Cutefish.Dock", 1, 0, "DockSettings");
qmlRegisterType<IconItem>("Cutefish.Dock", 1, 0, "IconItem");
qmlRegisterType<PopupWindow>("Cutefish.Dock", 1, 0, "PopupWindow");
QString qmFilePath = QString("%1/%2.qm").arg("/usr/share/cutefish-dock/translations/").arg(QLocale::system().name());

View file

@ -39,7 +39,7 @@ MainWindow::MainWindow(QQuickView *parent)
, m_appModel(new ApplicationModel)
, m_fakeWindow(nullptr)
{
// setDefaultAlphaBuffer(false);
setDefaultAlphaBuffer(false);
setColor(Qt::transparent);
setFlags(Qt::FramelessWindowHint | Qt::WindowDoesNotAcceptFocus);

View file

@ -1,16 +0,0 @@
/*
SPDX-FileCopyrightText: 2014 Aleix Pol Gonzalez <aleixpol@blue-systems.com>
SPDX-License-Identifier: LGPL-2.0-or-later
*/
#include "managedtexturenode.h"
ManagedTextureNode::ManagedTextureNode()
{
}
void ManagedTextureNode::setTexture(QSharedPointer<QSGTexture> texture)
{
m_texture = texture;
QSGSimpleTextureNode::setTexture(texture.data());
}

View file

@ -1,43 +0,0 @@
/*
SPDX-FileCopyrightText: 2014 Aleix Pol Gonzalez <aleixpol@blue-systems.com>
SPDX-License-Identifier: LGPL-2.0-or-later
*/
#ifndef MANAGEDTEXTURENODE_H
#define MANAGEDTEXTURENODE_H
#include <QSGSimpleTextureNode>
#include <QSGTexture>
#include <QSharedPointer>
#include <qglobal.h>
/**
* @class ManagedTextureNode managedtexturenode.h KQuickAddons/ManagedTextureNode
*
* @short Node that contains a reference counted texture
*
* Usually when assigning textures within a node, we'll want to delete the
* texture with the node. This class will take a shared texture and display it
* within the node.
*
* It's especially interesting to use this class together with the ImageTexturesCache
* that will offer us shareable textures and cache them transparently, when asking
* it to create the texture.
*
* @see ImageTexturesCache
*/
class ManagedTextureNode : public QSGSimpleTextureNode
{
Q_DISABLE_COPY(ManagedTextureNode)
public:
ManagedTextureNode();
void setTexture(QSharedPointer<QSGTexture> texture);
private:
QSharedPointer<QSGTexture> m_texture;
};
#endif

View file

@ -2,6 +2,7 @@
#define TOPLEVELMENU_H
#include <QQuickWindow>
#include <QQuickItem>
class PopupWindow : public QQuickWindow
{