diff options
Diffstat (limited to 'core')
-rw-r--r-- | core/imagedownloader.cpp | 39 | ||||
-rw-r--r-- | core/imagedownloader.h | 9 |
2 files changed, 39 insertions, 9 deletions
diff --git a/core/imagedownloader.cpp b/core/imagedownloader.cpp index 2949d83d9..cbff1489c 100644 --- a/core/imagedownloader.cpp +++ b/core/imagedownloader.cpp @@ -140,7 +140,8 @@ QImage getHashedImage(const QString &file) return res; } -Thumbnailer::Thumbnailer() +Thumbnailer::Thumbnailer() : failImage(QImage(":filter-close").scaled(maxThumbnailSize(), maxThumbnailSize(), Qt::KeepAspectRatio)), // TODO: Don't misuse filter close icon + dummyImage(QImage(":photo-icon").scaled(maxThumbnailSize(), maxThumbnailSize(), Qt::KeepAspectRatio)) // TODO: Don't misuse photo-icon { // Currently, we only process one image at a time. Stefan Fuchs reported problems when // calculating multiple thumbnails at once and this hopefully helps. @@ -200,16 +201,16 @@ static void addThumbnailToCache(const QImage &thumbnail, const QString &picture_ file.commit(); } -void Thumbnailer::processItem(QString filename, int size) +void Thumbnailer::processItem(QString filename) { QImage thumbnail = getThumbnailFromCache(filename); if (thumbnail.isNull()) { thumbnail = getHashedImage(filename); if (thumbnail.isNull()) { - // TODO: Don't misuse filter close icon - thumbnail = QImage(":filter-close").scaled(size, size, Qt::KeepAspectRatio); + thumbnail = failImage; } else { + int size = maxThumbnailSize(); thumbnail = thumbnail.scaled(size, size, Qt::KeepAspectRatio); addThumbnailToCache(thumbnail, filename); } @@ -220,7 +221,7 @@ void Thumbnailer::processItem(QString filename, int size) workingOn.remove(filename); } -QImage Thumbnailer::fetchThumbnail(PictureEntry &entry, int size) +QImage Thumbnailer::fetchThumbnail(PictureEntry &entry) { QMutexLocker l(&lock); @@ -228,9 +229,9 @@ QImage Thumbnailer::fetchThumbnail(PictureEntry &entry, int size) const QString &filename = entry.filename; if (!workingOn.contains(filename)) { workingOn.insert(filename, - QtConcurrent::run(&pool, [this, filename, size]() { processItem(filename, size); })); + QtConcurrent::run(&pool, [this, filename]() { processItem(filename); })); } - return QImage(":photo-icon").scaled(size, size, Qt::KeepAspectRatio); + return dummyImage; } void Thumbnailer::clearWorkQueue() @@ -240,3 +241,27 @@ void Thumbnailer::clearWorkQueue() it->cancel(); workingOn.clear(); } + +static const int maxZoom = 3; // Maximum zoom: thrice of standard size + +int Thumbnailer::defaultThumbnailSize() +{ + return defaultIconMetrics().sz_pic; +} + +int Thumbnailer::maxThumbnailSize() +{ + return defaultThumbnailSize() * maxZoom; +} + +int Thumbnailer::thumbnailSize(double zoomLevel) +{ + // Calculate size of thumbnails. The standard size is defaultIconMetrics().sz_pic. + // We use exponential scaling so that the central point is the standard + // size and the minimum and maximum extreme points are a third respectively + // three times the standard size. + // Naturally, these three zoom levels are then represented by + // -1.0 (minimum), 0 (standard) and 1.0 (maximum). The actual size is + // calculated as standard_size*3.0^zoomLevel. + return static_cast<int>(round(defaultThumbnailSize() * pow(maxZoom, zoomLevel))); +} diff --git a/core/imagedownloader.h b/core/imagedownloader.h index d8e9d2d7d..92edea0b6 100644 --- a/core/imagedownloader.h +++ b/core/imagedownloader.h @@ -28,18 +28,23 @@ public: // Schedule a thumbnail for fetching or calculation. // Returns a placehlder thumbnail. The actual thumbnail will be sent // via a signal later. - QImage fetchThumbnail(PictureEntry &entry, int size); + QImage fetchThumbnail(PictureEntry &entry); // If we change dive, clear all unfinished thumbnail creations void clearWorkQueue(); + static int maxThumbnailSize(); + static int defaultThumbnailSize(); + static int thumbnailSize(double zoomLevel); signals: void thumbnailChanged(QString filename, QImage thumbnail); private: Thumbnailer(); - void processItem(QString filename, int size); + void processItem(QString filename); mutable QMutex lock; QThreadPool pool; + QImage failImage; // Shown when image-fetching fails + QImage dummyImage; // Shown before thumbnail is fetched QMap<QString,QFuture<void>> workingOn; }; |