From 4f60c07e0540f89654b469d134095c37e238d3e8 Mon Sep 17 00:00:00 2001 From: 2 * r + 2 * t <61896496+soramanew@users.noreply.github.com> Date: Wed, 27 Aug 2025 20:32:51 +1000 Subject: plugin: create caching image manager No need for external proc --- plugin/src/Caelestia/cachingimagemanager.cpp | 122 +++++++++++++++++++++++++++ 1 file changed, 122 insertions(+) create mode 100644 plugin/src/Caelestia/cachingimagemanager.cpp (limited to 'plugin/src/Caelestia/cachingimagemanager.cpp') diff --git a/plugin/src/Caelestia/cachingimagemanager.cpp b/plugin/src/Caelestia/cachingimagemanager.cpp new file mode 100644 index 0000000..d557203 --- /dev/null +++ b/plugin/src/Caelestia/cachingimagemanager.cpp @@ -0,0 +1,122 @@ +#include "cachingimagemanager.hpp" + +#include +#include +#include +#include +#include +#include + +qreal CachingImageManager::effectiveScale() const { + if (m_item->window() && m_item->window()->screen()) { + return m_item->window()->screen()->devicePixelRatio(); + } + + return 1.0; +} + +int CachingImageManager::effectiveWidth() const { + int width = std::ceil(m_item->width() * effectiveScale()); + m_item->setProperty("sourceWidth", width); + return width; +} + +int CachingImageManager::effectiveHeight() const { + int height = std::ceil(m_item->height() * effectiveScale()); + m_item->setProperty("sourceHeight", height); + return height; +} + +QQuickItem* CachingImageManager::item() const { + return m_item; +} + +void CachingImageManager::setItem(QQuickItem* item) { + if (m_item == item) { + return; + } + + m_item = item; + emit itemChanged(); +} + +QUrl CachingImageManager::cacheDir() const { + return m_cacheDir; +} + +void CachingImageManager::setCacheDir(const QUrl& cacheDir) { + if (m_cacheDir == cacheDir) { + return; + } + + m_cacheDir = cacheDir; + emit cacheDirChanged(); +} + +QString CachingImageManager::path() const { + return m_path; +} + +void CachingImageManager::setPath(const QString& path) { + if (m_path == path) { + return; + } + + m_path = path; + emit pathChanged(); + + if (!path.isEmpty()) { + QThreadPool::globalInstance()->start([path, this] { + const QString filename = QString("%1@%2x%3.png") + .arg(sha256sum(path)) + .arg(effectiveWidth()) + .arg(effectiveHeight()); + + m_cachePath = m_cacheDir.resolved(QUrl(filename)); + emit cachePathChanged(); + + if (!m_cachePath.isLocalFile()) { + qWarning() << "CachingImageManager::setPath: cachePath" << m_cachePath << "is not a local file"; + return; + } + + if (QFile::exists(m_cachePath.toLocalFile())) { + QMetaObject::invokeMethod(m_item, [this]() { + m_item->setProperty("source", m_cachePath); + }, Qt::QueuedConnection); + + m_usingCache = true; + emit usingCacheChanged(); + } else { + QMetaObject::invokeMethod(m_item, [path, this]() { + m_item->setProperty("source", QUrl::fromLocalFile(path)); + }, Qt::QueuedConnection); + + m_usingCache = false; + emit usingCacheChanged(); + } + }); + } +} + +QUrl CachingImageManager::cachePath() const { + return m_cachePath; +} + +bool CachingImageManager::usingCache() const { + return m_usingCache; +} + +QString CachingImageManager::sha256sum(const QString& path) const { + QFile file(path); + if (!file.open(QIODevice::ReadOnly)) { + qWarning() << "CachingImageManager::sha256sum: failed to open" << path; + return ""; + } + + QCryptographicHash hash(QCryptographicHash::Sha256); + hash.addData(&file); + file.close(); + + return hash.result().toHex(); +} -- cgit v1.2.3-freya