added gif emotes

This commit is contained in:
fourtf 2017-02-07 00:03:15 +01:00
parent 5673efa0db
commit 5b03712a82
9 changed files with 118 additions and 16 deletions

View file

@ -26,6 +26,7 @@ ConcurrentMap<int, messages::LazyLoadedImage *>
Emotes::ffzChannelEmoteFromCaches; Emotes::ffzChannelEmoteFromCaches;
ConcurrentMap<long, messages::LazyLoadedImage *> Emotes::twitchEmoteFromCache; ConcurrentMap<long, messages::LazyLoadedImage *> Emotes::twitchEmoteFromCache;
ConcurrentMap<QString, messages::LazyLoadedImage *> Emotes::miscImageFromCache; ConcurrentMap<QString, messages::LazyLoadedImage *> Emotes::miscImageFromCache;
boost::signals2::signal<void()> Emotes::gifUpdateTimerSignal;
QTimer Emotes::gifUpdateTimer; QTimer Emotes::gifUpdateTimer;
bool Emotes::gifUpdateTimerInitiated(false); bool Emotes::gifUpdateTimerInitiated(false);

View file

@ -6,10 +6,12 @@
#include "concurrentmap.h" #include "concurrentmap.h"
#include "messages/lazyloadedimage.h" #include "messages/lazyloadedimage.h"
#include "twitchemotevalue.h" #include "twitchemotevalue.h"
#include "windows.h"
#include <QMap> #include <QMap>
#include <QMutex> #include <QMutex>
#include <QTimer> #include <QTimer>
#include <boost/signals2.hpp>
namespace chatterino { namespace chatterino {
@ -85,17 +87,22 @@ public:
generation++; generation++;
} }
static QTimer & static boost::signals2::signal<void()> &
getGifUpdateTimer() getGifUpdateSignal()
{ {
if (!gifUpdateTimerInitiated) { if (!gifUpdateTimerInitiated) {
gifUpdateTimerInitiated = true; gifUpdateTimerInitiated = true;
gifUpdateTimer.setInterval(GIF_FRAME_LENGTH); gifUpdateTimer.setInterval(30);
gifUpdateTimer.start(); gifUpdateTimer.start();
QObject::connect(&gifUpdateTimer, &QTimer::timeout, [] {
gifUpdateTimerSignal();
Windows::repaintGifEmotes();
});
} }
return gifUpdateTimer; return gifUpdateTimerSignal;
} }
private: private:
@ -125,6 +132,8 @@ private:
static void loadBttvEmotes(); static void loadBttvEmotes();
static int generation; static int generation;
static boost::signals2::signal<void()> gifUpdateTimerSignal;
}; };
} }

View file

@ -90,8 +90,9 @@ LazyLoadedImage::loadImage()
} }
if (allFrames.size() > 1) { if (allFrames.size() > 1) {
QObject::connect(&Emotes::getGifUpdateTimer(), &QTimer::timeout, this->animated = true;
[this] { gifUpdateTimout(); });
Emotes::getGifUpdateSignal().connect([this] { gifUpdateTimout(); });
} }
Emotes::incGeneration(); Emotes::incGeneration();

View file

@ -8,7 +8,9 @@
#include <math.h> #include <math.h>
#include <QDebug> #include <QDebug>
#include <QGraphicsBlurEffect>
#include <QPainter> #include <QPainter>
#include <chrono>
#include <functional> #include <functional>
namespace chatterino { namespace chatterino {
@ -18,7 +20,9 @@ ChatWidgetView::ChatWidgetView(ChatWidget *parent)
: QWidget() : QWidget()
, chatWidget(parent) , chatWidget(parent)
, scrollbar(this) , scrollbar(this)
, onlyUpdateEmotes(false)
{ {
this->setAttribute(Qt::WA_OpaquePaintEvent);
this->scrollbar.setSmallChange(5); this->scrollbar.setSmallChange(5);
QObject::connect(&Settings::getInstance(), &Settings::wordTypeMaskChanged, QObject::connect(&Settings::getInstance(), &Settings::wordTypeMaskChanged,
@ -90,6 +94,10 @@ ChatWidgetView::layoutMessages()
this->scrollbar.setVisible(showScrollbar); this->scrollbar.setVisible(showScrollbar);
if (!showScrollbar) {
this->scrollbar.setDesiredValue(0);
}
this->scrollbar.setMaximum(messages.getLength()); this->scrollbar.setMaximum(messages.getLength());
return redraw; return redraw;
@ -102,10 +110,12 @@ ChatWidgetView::resizeEvent(QResizeEvent *)
this->scrollbar.move(width() - this->scrollbar.width(), 0); this->scrollbar.move(width() - this->scrollbar.width(), 0);
layoutMessages(); layoutMessages();
update();
} }
void void
ChatWidgetView::paintEvent(QPaintEvent *) ChatWidgetView::paintEvent(QPaintEvent *event)
{ {
QPainter _painter(this); QPainter _painter(this);
@ -113,6 +123,24 @@ ChatWidgetView::paintEvent(QPaintEvent *)
ColorScheme &scheme = ColorScheme::getInstance(); 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 // code for tesing colors
/* /*
QColor color; QColor color;
@ -171,16 +199,13 @@ ChatWidgetView::paintEvent(QPaintEvent *)
updateBuffer = true; updateBuffer = true;
} }
// update messages that have been changed
if (updateBuffer) { if (updateBuffer) {
QPainter painter(buffer); QPainter painter(buffer);
painter.fillRect(buffer->rect(), scheme.ChatBackground); painter.fillRect(buffer->rect(), scheme.ChatBackground);
for (messages::WordPart const &wordPart : for (messages::WordPart const &wordPart :
messageRef->getWordParts()) { messageRef->getWordParts()) {
painter.setPen(QColor(255, 0, 0));
painter.drawRect(wordPart.getX(), wordPart.getY(),
wordPart.getWidth(), wordPart.getHeight());
// image // image
if (wordPart.getWord().isImage()) { if (wordPart.getWord().isImage()) {
messages::LazyLoadedImage &lli = messages::LazyLoadedImage &lli =
@ -214,6 +239,24 @@ ChatWidgetView::paintEvent(QPaintEvent *)
messageRef->updateBuffer = false; 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; messageRef->buffer = bufferPtr;
_painter.drawPixmap(0, y, *buffer); _painter.drawPixmap(0, y, *buffer);
@ -224,6 +267,12 @@ ChatWidgetView::paintEvent(QPaintEvent *)
break; break;
} }
} }
for (GifEmoteData &item : this->gifEmotes) {
_painter.fillRect(item.rect, scheme.ChatBackground);
_painter.drawPixmap(item.rect, *item.image->getPixmap());
}
} }
void void

View file

@ -2,6 +2,7 @@
#define CHATVIEW_H #define CHATVIEW_H
#include "channel.h" #include "channel.h"
#include "messages/lazyloadedimage.h"
#include "messages/messageref.h" #include "messages/messageref.h"
#include "messages/word.h" #include "messages/word.h"
#include "widgets/scrollbar.h" #include "widgets/scrollbar.h"
@ -25,6 +26,13 @@ public:
bool layoutMessages(); bool layoutMessages();
void
updateGifEmotes()
{
this->onlyUpdateEmotes = true;
this->update();
}
protected: protected:
void resizeEvent(QResizeEvent *); void resizeEvent(QResizeEvent *);
@ -32,18 +40,24 @@ protected:
void wheelEvent(QWheelEvent *event); void wheelEvent(QWheelEvent *event);
private: private:
struct GifEmoteData {
messages::LazyLoadedImage *image;
QRect rect;
};
std::vector<GifEmoteData> gifEmotes;
ChatWidget *chatWidget; ChatWidget *chatWidget;
ScrollBar scrollbar; ScrollBar scrollbar;
bool onlyUpdateEmotes;
private slots: private slots:
void void
wordTypeMaskChanged() wordTypeMaskChanged()
{ {
if (layoutMessages()) {
update(); update();
} }
}
}; };
} }
} }

View file

@ -44,7 +44,7 @@ MainWindow::layoutVisibleChatWidgets(Channel *channel)
if (channel == NULL || channel == widget->getChannel().get()) { if (channel == NULL || channel == widget->getChannel().get()) {
if (widget->getView().layoutMessages()) { if (widget->getView().layoutMessages()) {
widget->update(); widget->getView().update();
} }
} }
} }
@ -66,11 +66,29 @@ MainWindow::repaintVisibleChatWidgets(Channel *channel)
if (channel == NULL || channel == widget->getChannel().get()) { if (channel == NULL || channel == widget->getChannel().get()) {
widget->getView().layoutMessages(); widget->getView().layoutMessages();
widget->update(); widget->getView().update();
} }
} }
} }
void
MainWindow::repaintGifEmotes()
{
auto *page = notebook.getSelectedPage();
if (page == NULL) {
return;
}
const std::vector<ChatWidget *> &widgets = page->getChatWidgets();
for (auto it = widgets.begin(); it != widgets.end(); ++it) {
ChatWidget *widget = *it;
widget->getView().updateGifEmotes();
}
}
void void
MainWindow::load(const boost::property_tree::ptree &tree) MainWindow::load(const boost::property_tree::ptree &tree)
{ {

View file

@ -20,6 +20,7 @@ public:
void layoutVisibleChatWidgets(Channel *channel = NULL); void layoutVisibleChatWidgets(Channel *channel = NULL);
void repaintVisibleChatWidgets(Channel *channel = NULL); void repaintVisibleChatWidgets(Channel *channel = NULL);
void repaintGifEmotes();
void load(const boost::property_tree::ptree &tree); void load(const boost::property_tree::ptree &tree);
boost::property_tree::ptree save(); boost::property_tree::ptree save();

View file

@ -38,6 +38,14 @@ Windows::repaintVisibleChatWidgets(Channel *channel)
} }
} }
void
Windows::repaintGifEmotes()
{
if (Windows::mainWindow != nullptr) {
Windows::mainWindow->repaintGifEmotes();
}
}
void void
Windows::updateAll() Windows::updateAll()
{ {

View file

@ -12,6 +12,7 @@ class Windows
public: public:
static void layoutVisibleChatWidgets(Channel *channel = NULL); static void layoutVisibleChatWidgets(Channel *channel = NULL);
static void repaintVisibleChatWidgets(Channel *channel = NULL); static void repaintVisibleChatWidgets(Channel *channel = NULL);
static void repaintGifEmotes();
static void updateAll(); static void updateAll();
static widgets::MainWindow & static widgets::MainWindow &