summary refs log tree commit diff
path: root/src/ui
diff options
context:
space:
mode:
authorNicolas Werner <nicolas.werner@hotmail.de>2022-09-30 04:03:39 +0200
committerNicolas Werner <nicolas.werner@hotmail.de>2022-09-30 04:03:39 +0200
commit78784babd1bac589216fc768d927c7af6bc67226 (patch)
treea802abce4a86856872f1dd7ec199624b5edb1109 /src/ui
parentDisable manpage on debian (diff)
downloadnheko-78784babd1bac589216fc768d927c7af6bc67226.tar.xz
Revert accidental animated image change
Diffstat (limited to 'src/ui')
-rw-r--r--src/ui/MxcAnimatedImage.cpp47
-rw-r--r--src/ui/MxcAnimatedImage.h31
2 files changed, 31 insertions, 47 deletions
diff --git a/src/ui/MxcAnimatedImage.cpp b/src/ui/MxcAnimatedImage.cpp
index 90066fa0..8ecea7d9 100644
--- a/src/ui/MxcAnimatedImage.cpp
+++ b/src/ui/MxcAnimatedImage.cpp
@@ -8,7 +8,6 @@
 #include <QDir>
 #include <QFileInfo>
 #include <QMimeDatabase>
-#include <QMovie>
 #include <QQuickWindow>
 #include <QSGImageNode>
 #include <QStandardPaths>
@@ -35,12 +34,8 @@ MxcAnimatedImage::startDownload()
 
     QByteArray mimeType = QString::fromStdString(mtx::accessors::mimetype(*event)).toUtf8();
 
-    static const auto movieFormats = QMovie::supportedFormats();
-    QByteArray imageFormat;
-    const auto imageFormats = QImageReader::imageFormatsForMimeType(mimeType);
-    if (!imageFormats.isEmpty())
-        imageFormat = imageFormats.front();
-    animatable_ = movieFormats.contains(imageFormat);
+    static const auto formats = QMovie::supportedFormats();
+    animatable_               = formats.contains(mimeType.split('/').back());
     animatableChanged();
 
     if (!animatable_)
@@ -71,14 +66,14 @@ MxcAnimatedImage::startDownload()
 
     QPointer<MxcAnimatedImage> self = this;
 
-    auto processBuffer = [this, imageFormat, encryptionInfo, self](QIODevice &device) {
+    auto processBuffer = [this, mimeType, encryptionInfo, self](QIODevice &device) {
         if (!self)
             return;
 
         try {
             if (buffer.isOpen()) {
-                frameTimer.stop();
-                movie->setDevice(nullptr);
+                movie.stop();
+                movie.setDevice(nullptr);
                 buffer.close();
             }
 
@@ -97,22 +92,21 @@ MxcAnimatedImage::startDownload()
             nhlog::net()->error("Failed to setup animated image buffer: {}", e.what());
         }
 
-        QTimer::singleShot(0, this, [this, imageFormat] {
+        QTimer::singleShot(0, this, [this, mimeType] {
             nhlog::ui()->info(
               "Playing movie with size: {}, {}", buffer.bytesAvailable(), buffer.isOpen());
-            movie->setFormat(imageFormat);
-            movie->setDevice(&buffer);
+            movie.setFormat(mimeType);
+            movie.setDevice(&buffer);
 
             if (height() != 0 && width() != 0)
-                movie->setScaledSize(this->size().toSize());
-
-            if (movie->supportsAnimation())
-                frameTimer.setInterval(movie->nextImageDelay());
-
+                movie.setScaledSize(this->size().toSize());
+            if (buffer.bytesAvailable() <
+                4LL * 1024 * 1024 * 1024) // cache images smaller than 4MB in RAM
+                movie.setCacheMode(QMovie::CacheAll);
             if (play_)
-                frameTimer.start();
+                movie.start();
             else
-                movie->jumpToImage(0);
+                movie.jumpToFrame(0);
             emit loadedChanged();
             update();
         });
@@ -165,9 +159,9 @@ MxcAnimatedImage::geometryChanged(const QRectF &newGeometry, const QRectF &oldGe
 
     if (newGeometry.size() != oldGeometry.size()) {
         if (height() != 0 && width() != 0) {
-            QSizeF r = movie->scaledSize();
+            QSizeF r = movie.scaledSize();
             r.scale(newGeometry.size(), Qt::KeepAspectRatio);
-            movie->setScaledSize(r.toSize());
+            movie.setScaledSize(r.toSize());
             imageDirty = true;
             update();
         }
@@ -190,15 +184,16 @@ MxcAnimatedImage::updatePaintNode(QSGNode *oldNode, QQuickItem::UpdatePaintNodeD
         n->setFlags(QSGNode::OwnedByParent);
     }
 
-    n->setSourceRect(currentFrame.rect());
-    if (!currentFrame.isNull())
-        n->setTexture(window()->createTextureFromImage(currentFrame));
+    auto img = movie.currentImage();
+    n->setSourceRect(img.rect());
+    if (!img.isNull())
+        n->setTexture(window()->createTextureFromImage(std::move(img)));
     else {
         delete n;
         return nullptr;
     }
 
-    QSizeF r = currentFrame.size();
+    QSizeF r = img.size();
     r.scale(size(), Qt::KeepAspectRatio);
 
     n->setRect((width() - r.width()) / 2, (height() - r.height()) / 2, r.width(), r.height());
diff --git a/src/ui/MxcAnimatedImage.h b/src/ui/MxcAnimatedImage.h
index 2b067166..8891e57e 100644
--- a/src/ui/MxcAnimatedImage.h
+++ b/src/ui/MxcAnimatedImage.h
@@ -6,7 +6,7 @@
 #pragma once
 
 #include <QBuffer>
-#include <QImageReader>
+#include <QMovie>
 #include <QObject>
 #include <QQuickItem>
 
@@ -24,11 +24,10 @@ class MxcAnimatedImage : public QQuickItem
 public:
     MxcAnimatedImage(QQuickItem *parent = nullptr)
       : QQuickItem(parent)
-      , movie(new QImageReader())
     {
         connect(this, &MxcAnimatedImage::eventIdChanged, &MxcAnimatedImage::startDownload);
         connect(this, &MxcAnimatedImage::roomChanged, &MxcAnimatedImage::startDownload);
-        connect(&frameTimer, &QTimer::timeout, this, &MxcAnimatedImage::newFrame);
+        connect(&movie, &QMovie::frameChanged, this, &MxcAnimatedImage::newFrame);
         setFlag(QQuickItem::ItemHasContents);
         // setAcceptHoverEvents(true);
     }
@@ -56,10 +55,7 @@ public:
     {
         if (play_ != newPlay) {
             play_ = newPlay;
-            if (play_)
-                frameTimer.start();
-            else
-                frameTimer.stop();
+            movie.setPaused(!play_);
             emit playChanged();
         }
     }
@@ -77,16 +73,10 @@ signals:
 
 private slots:
     void startDownload();
-    void newFrame()
+    void newFrame(int frame)
     {
-        if (movie->currentImageNumber() > 0 && !movie->canRead() && movie->imageCount() > 1) {
-            buffer.seek(0);
-            movie.reset(new QImageReader(movie->device(), movie->format()));
-            if (height() != 0 && width() != 0)
-                movie->setScaledSize(this->size().toSize());
-        }
-        movie->read(&currentFrame);
-        imageDirty = true;
+        currentFrame = frame;
+        imageDirty   = true;
         update();
     }
 
@@ -96,9 +86,8 @@ private:
     QString filename_;
     bool animatable_ = false;
     QBuffer buffer;
-    std::unique_ptr<QImageReader> movie;
-    bool imageDirty = true;
-    bool play_      = true;
-    QTimer frameTimer;
-    QImage currentFrame;
+    QMovie movie;
+    int currentFrame = 0;
+    bool imageDirty  = true;
+    bool play_       = true;
 };