From fd53a3d0e94462a3b959b7d96d779661e0cda7cb Mon Sep 17 00:00:00 2001 From: cutefishd Date: Wed, 31 Mar 2021 14:13:10 +0800 Subject: [PATCH] Fix textfield --- CMakeLists.txt | 1 + qml/LauncherGridDelegate.qml | 8 +- qml/main.qml | 7 +- src/iconitem.cpp | 158 +++++++++++++++++++++++++++++++++++ src/iconitem.h | 44 ++++++++++ src/main.cpp | 2 + 6 files changed, 214 insertions(+), 6 deletions(-) create mode 100644 src/iconitem.cpp create mode 100644 src/iconitem.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 1797447..a491ed9 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -25,6 +25,7 @@ set(SRCS src/ucunits.cpp src/wallpaper.cpp src/listmodelmanager.cpp + src/iconitem.cpp ) set(RESOURCES diff --git a/qml/LauncherGridDelegate.qml b/qml/LauncherGridDelegate.qml index 2915596..2122cbc 100755 --- a/qml/LauncherGridDelegate.qml +++ b/qml/LauncherGridDelegate.qml @@ -2,6 +2,7 @@ import QtQuick 2.9 import QtQuick.Controls 2.1 import QtGraphicalEffects 1.0 import MeuiKit 1.0 as Meui +import Cutefish.Launcher 1.0 Item { id: control @@ -40,7 +41,7 @@ Item { // opacity: 0.5 // } - Image { + IconItem { id: icon anchors { @@ -52,13 +53,10 @@ Item { property real size: height - source: "image://icontheme/" + model.iconName - sourceSize.width: height - sourceSize.height: height width: height height: width - cache: true + source: model.iconName visible: !dragStarted ColorOverlay { diff --git a/qml/main.qml b/qml/main.qml index 5e2aa55..b1e606b 100755 --- a/qml/main.qml +++ b/qml/main.qml @@ -24,7 +24,8 @@ Item { sourceSize: Qt.size(width, height) fillMode: Image.PreserveAspectCrop clip: true - cache: false + cache: true + smooth: false } FastBlur { @@ -127,6 +128,7 @@ Item { Layout.fillHeight: true Layout.fillWidth: true + Keys.enabled: true Keys.forwardTo: grid LauncherGridView { @@ -147,6 +149,8 @@ Item { event.key === Qt.Key_Up || event.key === Qt.Key_Down) { return + } else { + textField.forceActiveFocus() } } @@ -198,6 +202,7 @@ Item { if (visible) { textField.focus = false grid.focus = true + grid.forceActiveFocus() } else { textField.text = "" } diff --git a/src/iconitem.cpp b/src/iconitem.cpp new file mode 100644 index 0000000..4efba95 --- /dev/null +++ b/src/iconitem.cpp @@ -0,0 +1,158 @@ +#include "iconitem.h" +#include +#include +#include +#include +#include + +IconItem::IconItem(QQuickItem *parent) + : QQuickItem(parent) +{ + setFlag(ItemHasContents, true); + setSmooth(true); +} + +void IconItem::setSource(const QVariant &source) +{ + if (source == m_source) + return; + + m_source.clear(); + m_source = source; + + // If the QIcon was created with QIcon::fromTheme(), try to load it as svg. + if (source.canConvert() && source.value().name().isEmpty()) { + m_source = source.value().name(); + } + + loadPixmap(); + emit sourceChanged(); +} + +QVariant IconItem::source() const +{ + return m_source; +} + +int IconItem::paintedWidth() const +{ + return boundingRect().size().toSize().width(); +} + +int IconItem::paintedHeight() const +{ + return boundingRect().size().toSize().height(); +} + +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; + } + + QSGSimpleTextureNode *textureNode = dynamic_cast(oldNode); + + if (!textureNode) { + delete oldNode; + textureNode = new QSGSimpleTextureNode; + textureNode->setTexture(window()->createTextureFromImage(m_iconPixmap.toImage(), QQuickWindow::TextureCanUseAtlas)); + } + + textureNode->setFiltering(smooth() ? QSGTexture::Linear : QSGTexture::Nearest); + + // Size changed + const QSize newSize = QSize(paintedWidth(), paintedHeight()); + const QRect destRect(QPointF(boundingRect().center() - QPointF(newSize.width(), newSize.height()) / 2).toPoint(), newSize); + textureNode->setRect(destRect); + + return textureNode; +} + +void IconItem::geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry) +{ + polish(); + update(); + + QQuickItem::geometryChanged(newGeometry, oldGeometry); +} + +void IconItem::componentComplete() +{ + QQuickItem::componentComplete(); + + polish(); +} + +void IconItem::updatePolish() +{ + QQuickItem::updatePolish(); + + loadPixmap(); +} + +void IconItem::refresh() +{ + polish(); +} + +void IconItem::loadPixmap() +{ + if (!isComponentComplete()) + return; + + int size = qMin(qRound(width()), qRound(height())); + + if (size <= 0) { + // Clear pixmap + delete &m_iconPixmap; + m_iconPixmap = QPixmap(); + update(); + return; + } + + QString sourceString = m_source.toString(); + + if (m_source.canConvert()) { + QIcon icon = m_source.value(); + m_iconPixmap = icon.pixmap(QSize(size * qApp->devicePixelRatio(), + size * qApp->devicePixelRatio())); + m_iconPixmap.setDevicePixelRatio(qApp->devicePixelRatio()); + } else if (m_source.canConvert()) { + QImage image = m_source.value(); + m_iconPixmap = QPixmap::fromImage(image).scaled(QSize(size * qApp->devicePixelRatio(), + size * qApp->devicePixelRatio())); + m_iconPixmap.setDevicePixelRatio(qApp->devicePixelRatio()); + } else if (!m_source.isNull()) { + QString localFile; + + if (sourceString.startsWith("file:")) + localFile = QUrl(sourceString).toLocalFile(); + else if (sourceString.startsWith('/')) + localFile = sourceString; + else if (sourceString.startsWith("qrc:/")) + localFile = sourceString.remove(0, 3); + else if (sourceString.startsWith(":/")) + localFile = sourceString; + + if (!localFile.isEmpty()) { + m_iconPixmap.load(localFile); + if (!m_iconPixmap.isNull()) { + m_iconPixmap = m_iconPixmap.scaled(QSize(size * qApp->devicePixelRatio(), + size * qApp->devicePixelRatio())); + m_iconPixmap.setDevicePixelRatio(qApp->devicePixelRatio()); + } + } + } + + if (m_iconPixmap.isNull()) { + QIcon icon = QIcon::fromTheme(sourceString, QIcon::fromTheme("application-x-desktop")); + m_iconPixmap = icon.pixmap(QSize(size * qApp->devicePixelRatio(), + size * qApp->devicePixelRatio())); + m_iconPixmap.setDevicePixelRatio(qApp->devicePixelRatio()); + } + + update(); +} diff --git a/src/iconitem.h b/src/iconitem.h new file mode 100644 index 0000000..c87902e --- /dev/null +++ b/src/iconitem.h @@ -0,0 +1,44 @@ +#ifndef ICONITEM_H +#define ICONITEM_H + +#include +#include +#include + +class IconItem : public QQuickItem +{ + Q_OBJECT + Q_PROPERTY(QVariant source READ source WRITE setSource NOTIFY sourceChanged) + 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; + + int paintedWidth() const; + int paintedHeight() const; + + QSGNode *updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *updatePaintNodeData) override; + void geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry) override; + + void componentComplete() override; + void updatePolish() override; + + Q_INVOKABLE void refresh(); + +private: + void loadPixmap(); + +signals: + void sourceChanged(); + void paintedSizeChanged(); + +private: + QVariant m_source; + QPixmap m_iconPixmap; +}; + +#endif // ICONITEM_H diff --git a/src/main.cpp b/src/main.cpp index ed579fc..fa6e6e8 100755 --- a/src/main.cpp +++ b/src/main.cpp @@ -26,6 +26,7 @@ #include "launchermodel.h" #include "pagemodel.h" #include "wallpaper.h" +#include "iconitem.h" #include #include @@ -45,6 +46,7 @@ int main(int argc, char *argv[]) qmlRegisterType(uri, 1, 0, "LauncherModel"); qmlRegisterType(uri, 1, 0, "PageModel"); qmlRegisterType(uri, 1, 0, "Wallpaper"); + qmlRegisterType(uri, 1, 0, "IconItem"); QApplication app(argc, argv); app.setApplicationName(QStringLiteral("cutefish-launcher"));