From 5b03712a8243fb84953a3813fbccd6c578985dea Mon Sep 17 00:00:00 2001 From: fourtf Date: Tue, 7 Feb 2017 00:03:15 +0100 Subject: [PATCH] added gif emotes --- emotes.cpp | 1 + emotes.h | 17 ++++++++--- messages/lazyloadedimage.cpp | 5 +-- widgets/chatwidgetview.cpp | 59 +++++++++++++++++++++++++++++++++--- widgets/chatwidgetview.h | 20 ++++++++++-- widgets/mainwindow.cpp | 22 ++++++++++++-- widgets/mainwindow.h | 1 + windows.cpp | 8 +++++ windows.h | 1 + 9 files changed, 118 insertions(+), 16 deletions(-) diff --git a/emotes.cpp b/emotes.cpp index cade3b07..dd8ab5b1 100644 --- a/emotes.cpp +++ b/emotes.cpp @@ -26,6 +26,7 @@ ConcurrentMap Emotes::ffzChannelEmoteFromCaches; ConcurrentMap Emotes::twitchEmoteFromCache; ConcurrentMap Emotes::miscImageFromCache; +boost::signals2::signal Emotes::gifUpdateTimerSignal; QTimer Emotes::gifUpdateTimer; bool Emotes::gifUpdateTimerInitiated(false); diff --git a/emotes.h b/emotes.h index c733ed7d..1ae669b4 100644 --- a/emotes.h +++ b/emotes.h @@ -6,10 +6,12 @@ #include "concurrentmap.h" #include "messages/lazyloadedimage.h" #include "twitchemotevalue.h" +#include "windows.h" #include #include #include +#include namespace chatterino { @@ -85,17 +87,22 @@ public: generation++; } - static QTimer & - getGifUpdateTimer() + static boost::signals2::signal & + getGifUpdateSignal() { if (!gifUpdateTimerInitiated) { gifUpdateTimerInitiated = true; - gifUpdateTimer.setInterval(GIF_FRAME_LENGTH); + gifUpdateTimer.setInterval(30); gifUpdateTimer.start(); + + QObject::connect(&gifUpdateTimer, &QTimer::timeout, [] { + gifUpdateTimerSignal(); + Windows::repaintGifEmotes(); + }); } - return gifUpdateTimer; + return gifUpdateTimerSignal; } private: @@ -125,6 +132,8 @@ private: static void loadBttvEmotes(); static int generation; + + static boost::signals2::signal gifUpdateTimerSignal; }; } diff --git a/messages/lazyloadedimage.cpp b/messages/lazyloadedimage.cpp index 1fbbf572..4886d17e 100644 --- a/messages/lazyloadedimage.cpp +++ b/messages/lazyloadedimage.cpp @@ -90,8 +90,9 @@ LazyLoadedImage::loadImage() } if (allFrames.size() > 1) { - QObject::connect(&Emotes::getGifUpdateTimer(), &QTimer::timeout, - [this] { gifUpdateTimout(); }); + this->animated = true; + + Emotes::getGifUpdateSignal().connect([this] { gifUpdateTimout(); }); } Emotes::incGeneration(); diff --git a/widgets/chatwidgetview.cpp b/widgets/chatwidgetview.cpp index 29059568..cd37f1ac 100644 --- a/widgets/chatwidgetview.cpp +++ b/widgets/chatwidgetview.cpp @@ -8,7 +8,9 @@ #include #include +#include #include +#include #include namespace chatterino { @@ -18,7 +20,9 @@ ChatWidgetView::ChatWidgetView(ChatWidget *parent) : QWidget() , chatWidget(parent) , scrollbar(this) + , onlyUpdateEmotes(false) { + this->setAttribute(Qt::WA_OpaquePaintEvent); this->scrollbar.setSmallChange(5); QObject::connect(&Settings::getInstance(), &Settings::wordTypeMaskChanged, @@ -90,6 +94,10 @@ ChatWidgetView::layoutMessages() this->scrollbar.setVisible(showScrollbar); + if (!showScrollbar) { + this->scrollbar.setDesiredValue(0); + } + this->scrollbar.setMaximum(messages.getLength()); return redraw; @@ -102,10 +110,12 @@ ChatWidgetView::resizeEvent(QResizeEvent *) this->scrollbar.move(width() - this->scrollbar.width(), 0); layoutMessages(); + + update(); } void -ChatWidgetView::paintEvent(QPaintEvent *) +ChatWidgetView::paintEvent(QPaintEvent *event) { QPainter _painter(this); @@ -113,6 +123,24 @@ ChatWidgetView::paintEvent(QPaintEvent *) ColorScheme &scheme = ColorScheme::getInstance(); + // only update gif emotes + if (onlyUpdateEmotes) { + onlyUpdateEmotes = false; + + for (GifEmoteData &item : this->gifEmotes) { + _painter.fillRect(item.rect, scheme.ChatBackground); + + _painter.drawPixmap(item.rect, *item.image->getPixmap()); + } + + return; + } + + // update all messages + gifEmotes.clear(); + + _painter.fillRect(rect(), scheme.ChatBackground); + // code for tesing colors /* QColor color; @@ -171,16 +199,13 @@ ChatWidgetView::paintEvent(QPaintEvent *) updateBuffer = true; } + // update messages that have been changed if (updateBuffer) { QPainter painter(buffer); painter.fillRect(buffer->rect(), scheme.ChatBackground); for (messages::WordPart const &wordPart : messageRef->getWordParts()) { - painter.setPen(QColor(255, 0, 0)); - painter.drawRect(wordPart.getX(), wordPart.getY(), - wordPart.getWidth(), wordPart.getHeight()); - // image if (wordPart.getWord().isImage()) { messages::LazyLoadedImage &lli = @@ -214,6 +239,24 @@ ChatWidgetView::paintEvent(QPaintEvent *) messageRef->updateBuffer = false; } + // get gif emotes + for (messages::WordPart const &wordPart : messageRef->getWordParts()) { + if (wordPart.getWord().isImage()) { + messages::LazyLoadedImage &lli = wordPart.getWord().getImage(); + + if (lli.getAnimated()) { + GifEmoteData data; + data.image = &lli; + QRect rect(wordPart.getX(), wordPart.getY() + y, + wordPart.getWidth(), wordPart.getHeight()); + + data.rect = rect; + + gifEmotes.push_back(data); + } + } + } + messageRef->buffer = bufferPtr; _painter.drawPixmap(0, y, *buffer); @@ -224,6 +267,12 @@ ChatWidgetView::paintEvent(QPaintEvent *) break; } } + + for (GifEmoteData &item : this->gifEmotes) { + _painter.fillRect(item.rect, scheme.ChatBackground); + + _painter.drawPixmap(item.rect, *item.image->getPixmap()); + } } void diff --git a/widgets/chatwidgetview.h b/widgets/chatwidgetview.h index 086a12f8..dc195d64 100644 --- a/widgets/chatwidgetview.h +++ b/widgets/chatwidgetview.h @@ -2,6 +2,7 @@ #define CHATVIEW_H #include "channel.h" +#include "messages/lazyloadedimage.h" #include "messages/messageref.h" #include "messages/word.h" #include "widgets/scrollbar.h" @@ -25,6 +26,13 @@ public: bool layoutMessages(); + void + updateGifEmotes() + { + this->onlyUpdateEmotes = true; + this->update(); + } + protected: void resizeEvent(QResizeEvent *); @@ -32,17 +40,23 @@ protected: void wheelEvent(QWheelEvent *event); private: + struct GifEmoteData { + messages::LazyLoadedImage *image; + QRect rect; + }; + + std::vector gifEmotes; + ChatWidget *chatWidget; ScrollBar scrollbar; + bool onlyUpdateEmotes; private slots: void wordTypeMaskChanged() { - if (layoutMessages()) { - update(); - } + update(); } }; } diff --git a/widgets/mainwindow.cpp b/widgets/mainwindow.cpp index a910938a..f684ffa1 100644 --- a/widgets/mainwindow.cpp +++ b/widgets/mainwindow.cpp @@ -44,7 +44,7 @@ MainWindow::layoutVisibleChatWidgets(Channel *channel) if (channel == NULL || channel == widget->getChannel().get()) { if (widget->getView().layoutMessages()) { - widget->update(); + widget->getView().update(); } } } @@ -66,11 +66,29 @@ MainWindow::repaintVisibleChatWidgets(Channel *channel) if (channel == NULL || channel == widget->getChannel().get()) { widget->getView().layoutMessages(); - widget->update(); + widget->getView().update(); } } } +void +MainWindow::repaintGifEmotes() +{ + auto *page = notebook.getSelectedPage(); + + if (page == NULL) { + return; + } + + const std::vector &widgets = page->getChatWidgets(); + + for (auto it = widgets.begin(); it != widgets.end(); ++it) { + ChatWidget *widget = *it; + + widget->getView().updateGifEmotes(); + } +} + void MainWindow::load(const boost::property_tree::ptree &tree) { diff --git a/widgets/mainwindow.h b/widgets/mainwindow.h index 560dd4a7..e77e587d 100644 --- a/widgets/mainwindow.h +++ b/widgets/mainwindow.h @@ -20,6 +20,7 @@ public: void layoutVisibleChatWidgets(Channel *channel = NULL); void repaintVisibleChatWidgets(Channel *channel = NULL); + void repaintGifEmotes(); void load(const boost::property_tree::ptree &tree); boost::property_tree::ptree save(); diff --git a/windows.cpp b/windows.cpp index 317deedb..0d298dbe 100644 --- a/windows.cpp +++ b/windows.cpp @@ -38,6 +38,14 @@ Windows::repaintVisibleChatWidgets(Channel *channel) } } +void +Windows::repaintGifEmotes() +{ + if (Windows::mainWindow != nullptr) { + Windows::mainWindow->repaintGifEmotes(); + } +} + void Windows::updateAll() { diff --git a/windows.h b/windows.h index 0265815d..49aa73c0 100644 --- a/windows.h +++ b/windows.h @@ -12,6 +12,7 @@ class Windows public: static void layoutVisibleChatWidgets(Channel *channel = NULL); static void repaintVisibleChatWidgets(Channel *channel = NULL); + static void repaintGifEmotes(); static void updateAll(); static widgets::MainWindow &