From 33ba35471f5beb6f233108042fa9e6afe7251156 Mon Sep 17 00:00:00 2001 From: fourtf Date: Mon, 6 Feb 2017 17:42:28 +0100 Subject: [PATCH] added gif frame updating --- emotes.cpp | 3 ++ emotes.h | 17 +++++++++++ messages/lazyloadedimage.cpp | 57 ++++++++++++++++++++++++++++++------ messages/lazyloadedimage.h | 25 +++++++++++----- 4 files changed, 85 insertions(+), 17 deletions(-) diff --git a/emotes.cpp b/emotes.cpp index 95d8e528b..cade3b075 100644 --- a/emotes.cpp +++ b/emotes.cpp @@ -27,6 +27,9 @@ ConcurrentMap ConcurrentMap Emotes::twitchEmoteFromCache; ConcurrentMap Emotes::miscImageFromCache; +QTimer Emotes::gifUpdateTimer; +bool Emotes::gifUpdateTimerInitiated(false); + int Emotes::generation = 0; Emotes::Emotes() diff --git a/emotes.h b/emotes.h index 50df0aa76..62d1f7a33 100644 --- a/emotes.h +++ b/emotes.h @@ -7,6 +7,7 @@ #include #include +#include namespace chatterino { @@ -82,6 +83,19 @@ public: generation++; } + static QTimer & + getGifUpdateTimer() + { + if (!gifUpdateTimerInitiated) { + gifUpdateTimerInitiated = true; + + gifUpdateTimer.setInterval(33); + gifUpdateTimer.start(); + } + + return gifUpdateTimer; + } + private: Emotes(); @@ -102,6 +116,9 @@ private: static QString getTwitchEmoteLink(long id, qreal &scale); + static QTimer gifUpdateTimer; + static bool gifUpdateTimerInitiated; + static void loadFfzEmotes(); static void loadBttvEmotes(); diff --git a/messages/lazyloadedimage.cpp b/messages/lazyloadedimage.cpp index 09a9ad37c..3854d1e7a 100644 --- a/messages/lazyloadedimage.cpp +++ b/messages/lazyloadedimage.cpp @@ -5,9 +5,12 @@ #include "ircmanager.h" #include "windows.h" +#include +#include #include #include #include +#include #include namespace chatterino { @@ -16,7 +19,9 @@ namespace messages { LazyLoadedImage::LazyLoadedImage(const QString &url, qreal scale, const QString &name, const QString &tooltip, const QMargins &margin, bool isHat) - : pixmap(NULL) + : currentPixmap(NULL) + , allFrames() + , currentFrame(0) , url(url) , name(name) , tooltip(tooltip) @@ -31,7 +36,9 @@ LazyLoadedImage::LazyLoadedImage(const QString &url, qreal scale, LazyLoadedImage::LazyLoadedImage(QPixmap *image, qreal scale, const QString &name, const QString &tooltip, const QMargins &margin, bool isHat) - : pixmap(image) + : currentPixmap(image) + , allFrames() + , currentFrame(0) , url() , name(name) , tooltip(tooltip) @@ -46,7 +53,6 @@ LazyLoadedImage::LazyLoadedImage(QPixmap *image, qreal scale, void LazyLoadedImage::loadImage() { - // QThreadPool::globalInstance()->start(new LambdaQRunnable([=] { QNetworkAccessManager *manager = new QNetworkAccessManager(); QUrl url(this->url); @@ -55,21 +61,54 @@ LazyLoadedImage::loadImage() QNetworkReply *reply = manager->get(request); QObject::connect(reply, &QNetworkReply::finished, [=] { - QPixmap *pixmap = new QPixmap(); - pixmap->loadFromData(reply->readAll()); + QByteArray array = reply->readAll(); + QBuffer buffer(&array); + buffer.open(QIODevice::ReadOnly); - if (pixmap->isNull()) { - return; + QImage image; + QImageReader reader(&buffer); + + bool first = true; + + for (int index = 0; index < reader.imageCount(); ++index) { + if (reader.read(&image)) { + auto pixmap = new QPixmap(QPixmap::fromImage(image)); + + if (first) { + first = false; + this->currentPixmap = pixmap; + } + + FrameData data; + data.duration = std::max(20, reader.nextImageDelay()); + data.image = pixmap; + + allFrames.push_back(data); + } + } + + if (allFrames.size() > 1) { + QObject::connect(&Emotes::getGifUpdateTimer(), &QTimer::timeout, + [this] { gifUpdateTimout(); }); } - this->pixmap = pixmap; Emotes::incGeneration(); Windows::layoutVisibleChatWidgets(); reply->deleteLater(); manager->deleteLater(); }); - // })); +} + +void +LazyLoadedImage::gifUpdateTimout() +{ + if (this->currentFrame >= this->allFrames.size() - 1) { + this->currentFrame = 0; + this->currentPixmap = this->allFrames.at(0).image; + } else { + this->currentPixmap = this->allFrames.at(++this->currentFrame).image; + } } } } diff --git a/messages/lazyloadedimage.h b/messages/lazyloadedimage.h index 482af09cf..138f731bb 100644 --- a/messages/lazyloadedimage.h +++ b/messages/lazyloadedimage.h @@ -7,7 +7,7 @@ namespace chatterino { namespace messages { -class LazyLoadedImage +class LazyLoadedImage : QObject { public: explicit LazyLoadedImage(const QString &url, qreal scale = 1, @@ -15,7 +15,7 @@ public: const QString &tooltip = "", const QMargins &margin = QMargins(), bool isHat = false); - explicit LazyLoadedImage(QPixmap *pixmap, qreal scale = 1, + explicit LazyLoadedImage(QPixmap *currentPixmap, qreal scale = 1, const QString &name = "", const QString &tooltip = "", const QMargins &margin = QMargins(), @@ -29,7 +29,7 @@ public: loadImage(); } - return pixmap; + return currentPixmap; } qreal @@ -77,23 +77,30 @@ public: int getWidth() const { - if (pixmap == NULL) { + if (currentPixmap == NULL) { return 16; } - return pixmap->width(); + return currentPixmap->width(); } int getHeight() const { - if (pixmap == NULL) { + if (currentPixmap == NULL) { return 16; } - return pixmap->height(); + return currentPixmap->height(); } private: - QPixmap *pixmap; + struct FrameData { + QPixmap *image; + float duration; + }; + + QPixmap *currentPixmap; + std::vector allFrames; + int currentFrame; QString url; QString name; @@ -106,6 +113,8 @@ private: bool isLoading; void loadImage(); + + void gifUpdateTimout(); }; } }