From 6ce97df535da292c7ce3383dac51c99933fd5440 Mon Sep 17 00:00:00 2001 From: 2 * r + 2 * t <61896496+soramanew@users.noreply.github.com> Date: Sat, 30 Aug 2025 16:58:26 +1000 Subject: plugin/cim: respect image fill mode Also prevent duplicate sha calcs --- plugin/src/Caelestia/cachingimagemanager.cpp | 57 ++++++++++++++++++---------- plugin/src/Caelestia/cachingimagemanager.hpp | 2 + 2 files changed, 39 insertions(+), 20 deletions(-) diff --git a/plugin/src/Caelestia/cachingimagemanager.cpp b/plugin/src/Caelestia/cachingimagemanager.cpp index 01d518f..bbfadff 100644 --- a/plugin/src/Caelestia/cachingimagemanager.cpp +++ b/plugin/src/Caelestia/cachingimagemanager.cpp @@ -7,7 +7,7 @@ #include #include #include -#include +#include qreal CachingImageManager::effectiveScale() const { if (m_item->window()) { @@ -93,14 +93,22 @@ void CachingImageManager::updateSource() { } void CachingImageManager::updateSource(const QString& path) { - if (path.isEmpty()) { + if (path.isEmpty() || path == m_shaPath) { + // Path is empty or already calculating sha for path return; } + m_shaPath = path; + QThreadPool::globalInstance()->start([path, this] { const QString sha = sha256sum(path); QMetaObject::invokeMethod(this, [path, sha, this]() { + if (m_path != path) { + // Path has changed, ignore + return; + } + int width = effectiveWidth(); int height = effectiveHeight(); const QString filename = QString("%1@%2x%3.png").arg(sha).arg(width).arg(height); @@ -126,6 +134,11 @@ void CachingImageManager::updateSource(const QString& path) { m_item->setProperty("source", QUrl::fromLocalFile(path)); createCache(path, cache.toLocalFile(), QSize(width, height)); } + + // Clear current running sha if same + if (m_shaPath == path) { + m_shaPath = QString(); + } }, Qt::QueuedConnection); }); } @@ -135,31 +148,35 @@ QUrl CachingImageManager::cachePath() const { } void CachingImageManager::createCache(const QString& path, const QString& cache, const QSize& size) const { - QThreadPool::globalInstance()->start([path, cache, size] { - QImageReader reader(path); + QString fillMode = m_item->property("fillMode").toString(); + + QThreadPool::globalInstance()->start([fillMode, path, cache, size] { + QImage image(path); - QSize imgSize = reader.size(); - if (!imgSize.isValid()) { - qWarning() << "CachingImageManager::createCache: unable to get size of" << path; + if (image.isNull()) { + qWarning() << "CachingImageManager::createCache: failed to read" << path; return; } - qreal scale = std::max( - qreal(size.width()) / imgSize.width(), - qreal(size.height()) / imgSize.height() - ); - QSizeF scaledSize(imgSize.width() * scale, imgSize.height() * scale); - qreal xOff = (scaledSize.width() - size.width()) / 2.0; - qreal yOff = (scaledSize.height() - size.height()) / 2.0; + image.convertTo(QImage::Format_ARGB32); - reader.setScaledSize(scaledSize.toSize()); - reader.setScaledClipRect(QRectF(xOff, yOff, size.width(), size.height()).toRect()); + if (fillMode == "PreserveAspectCrop") { + image = image.scaled(size, Qt::KeepAspectRatioByExpanding, Qt::SmoothTransformation); + } else if (fillMode == "PreserveAspectFit") { + image = image.scaled(size, Qt::KeepAspectRatio, Qt::SmoothTransformation); + } else { + image = image.scaled(size, Qt::IgnoreAspectRatio, Qt::SmoothTransformation); + } - QImage image = reader.read(); + if (fillMode == "PreserveAspectCrop" || fillMode == "PreserveAspectFit") { + QImage canvas(size, QImage::Format_ARGB32); + canvas.fill(Qt::transparent); - if (image.isNull()) { - qWarning() << "CachingImageManager::createCache: failed to read" << path; - return; + QPainter painter(&canvas); + painter.drawImage((size.width() - image.width()) / 2, (size.height() - image.height()) / 2, image); + painter.end(); + + image = canvas; } const QString parent = QFileInfo(cache).absolutePath(); diff --git a/plugin/src/Caelestia/cachingimagemanager.hpp b/plugin/src/Caelestia/cachingimagemanager.hpp index c78dcda..b9bfb7f 100644 --- a/plugin/src/Caelestia/cachingimagemanager.hpp +++ b/plugin/src/Caelestia/cachingimagemanager.hpp @@ -40,6 +40,8 @@ signals: void usingCacheChanged(); private: + QString m_shaPath; + QQuickItem* m_item; QUrl m_cacheDir; -- cgit v1.2.3-freya