From dbce128cc3400151e44fdf8a188fa7a5c010b430 Mon Sep 17 00:00:00 2001 From: Rasmus Karlsson Date: Sun, 8 Sep 2019 11:30:06 +0200 Subject: [PATCH] Remove "custom on success" logic from Image. Create a new message element and message layout element type for mod badges. --- src/messages/Image.cpp | 10 ----- src/messages/Image.hpp | 6 --- src/messages/MessageElement.cpp | 23 ++++++++++- src/messages/MessageElement.hpp | 16 ++++++++ src/messages/layouts/MessageLayoutElement.cpp | 27 +++++++++++++ src/messages/layouts/MessageLayoutElement.hpp | 14 ++++++- src/providers/ffz/FfzEmotes.cpp | 39 +++---------------- src/providers/twitch/TwitchMessageBuilder.cpp | 2 +- 8 files changed, 84 insertions(+), 53 deletions(-) diff --git a/src/messages/Image.cpp b/src/messages/Image.cpp index ef19d3702..a0c82418d 100644 --- a/src/messages/Image.cpp +++ b/src/messages/Image.cpp @@ -349,9 +349,6 @@ void Image::actuallyLoad() if (!shared) return Failure; - if (shared->customOnSuccess_) - return shared->customOnSuccess_(shared, result); - auto data = result.getData(); // const cast since we are only reading from it @@ -396,11 +393,4 @@ bool Image::operator!=(const Image &other) const return !this->operator==(other); } -ImagePtr Image::setCustomOnSuccess( - std::function customOnSuccess) -{ - this->customOnSuccess_ = customOnSuccess; - return shared_from_this(); -} - } // namespace chatterino diff --git a/src/messages/Image.hpp b/src/messages/Image.hpp index 24af6a529..5a5adf81e 100644 --- a/src/messages/Image.hpp +++ b/src/messages/Image.hpp @@ -68,18 +68,13 @@ public: bool operator==(const Image &image) const; bool operator!=(const Image &image) const; - ImagePtr setCustomOnSuccess( - std::function onSuccess); - private: Image(); Image(const Url &url, qreal scale); Image(qreal scale); -public: void setPixmap(const QPixmap &pixmap); -private: void actuallyLoad(); Url url_{}; @@ -88,6 +83,5 @@ private: bool shouldLoad_{false}; std::unique_ptr frames_{}; QObject object_{}; - std::function customOnSuccess_{}; }; } // namespace chatterino diff --git a/src/messages/MessageElement.cpp b/src/messages/MessageElement.cpp index 907bcc54a..0defed597 100644 --- a/src/messages/MessageElement.cpp +++ b/src/messages/MessageElement.cpp @@ -145,7 +145,7 @@ void EmoteElement::addToContainer(MessageLayoutContainer &container, QSize(int(container.getScale() * image->width() * emoteScale), int(container.getScale() * image->height() * emoteScale)); - container.addElement((new ImageLayoutElement(*this, image, size)) + container.addElement(this->makeImageLayoutElement(image, size) ->setLink(this->getLink())); } else @@ -159,6 +159,27 @@ void EmoteElement::addToContainer(MessageLayoutContainer &container, } } +MessageLayoutElement *EmoteElement::makeImageLayoutElement( + const ImagePtr &image, const QSize &size) +{ + return new ImageLayoutElement(*this, image, size); +} + +// MOD BADGE +ModBadgeElement::ModBadgeElement(const EmotePtr &data, + MessageElementFlags flags_) + : EmoteElement(data, flags_) +{ +} + +MessageLayoutElement *ModBadgeElement::makeImageLayoutElement( + const ImagePtr &image, const QSize &size) +{ + static const QColor modBadgeBackgroundColor("#34AE0A"); + return new ImageWithBackgroundLayoutElement(*this, image, size, + modBadgeBackgroundColor); +} + // BADGE BadgeElement::BadgeElement(const EmotePtr &emote, MessageElementFlags flags) : MessageElement(flags) diff --git a/src/messages/MessageElement.hpp b/src/messages/MessageElement.hpp index 3259405a6..0e18f6a26 100644 --- a/src/messages/MessageElement.hpp +++ b/src/messages/MessageElement.hpp @@ -17,6 +17,7 @@ namespace chatterino { class Channel; struct MessageLayoutContainer; +class MessageLayoutElement; class Image; using ImagePtr = std::shared_ptr; @@ -209,11 +210,26 @@ public: MessageElementFlags flags_) override; EmotePtr getEmote() const; +protected: + virtual MessageLayoutElement *makeImageLayoutElement(const ImagePtr &image, + const QSize &size); + private: std::unique_ptr textElement_; EmotePtr emote_; }; +// Behaves like an emote element, except it creates a different image layout element that draws the mod badge background +class ModBadgeElement : public EmoteElement +{ +public: + ModBadgeElement(const EmotePtr &data, MessageElementFlags flags_); + +protected: + MessageLayoutElement *makeImageLayoutElement(const ImagePtr &image, + const QSize &size) override; +}; + class BadgeElement : public MessageElement { public: diff --git a/src/messages/layouts/MessageLayoutElement.cpp b/src/messages/layouts/MessageLayoutElement.cpp index 53095ccbf..7990d6a6c 100644 --- a/src/messages/layouts/MessageLayoutElement.cpp +++ b/src/messages/layouts/MessageLayoutElement.cpp @@ -168,6 +168,33 @@ int ImageLayoutElement::getXFromIndex(int index) } } +// +// IMAGE WITH BACKGROUND +// +ImageWithBackgroundLayoutElement::ImageWithBackgroundLayoutElement( + MessageElement &creator, ImagePtr image, const QSize &size, QColor color) + : ImageLayoutElement(creator, image, size) + , color_(color) +{ +} + +void ImageWithBackgroundLayoutElement::paint(QPainter &painter) +{ + if (this->image_ == nullptr) + { + return; + } + + auto pixmap = this->image_->pixmapOrLoad(); + if (pixmap && !this->image_->animated()) + { + painter.fillRect(QRectF(this->getRect()), this->color_); + + // fourtf: make it use qreal values + painter.drawPixmap(QRectF(this->getRect()), *pixmap, QRectF()); + } +} + // // TEXT // diff --git a/src/messages/layouts/MessageLayoutElement.hpp b/src/messages/layouts/MessageLayoutElement.hpp index a7214937a..60d166a4c 100644 --- a/src/messages/layouts/MessageLayoutElement.hpp +++ b/src/messages/layouts/MessageLayoutElement.hpp @@ -72,10 +72,22 @@ protected: int getMouseOverIndex(const QPoint &abs) const override; int getXFromIndex(int index) override; -private: ImagePtr image_; }; +class ImageWithBackgroundLayoutElement : public ImageLayoutElement +{ +public: + ImageWithBackgroundLayoutElement(MessageElement &creator, ImagePtr image, + const QSize &size, QColor color); + +protected: + void paint(QPainter &painter) override; + +private: + QColor color_; +}; + // TEXT class TextLayoutElement : public MessageLayoutElement { diff --git a/src/providers/ffz/FfzEmotes.cpp b/src/providers/ffz/FfzEmotes.cpp index 3e1345545..a0244ddf3 100644 --- a/src/providers/ffz/FfzEmotes.cpp +++ b/src/providers/ffz/FfzEmotes.cpp @@ -15,30 +15,6 @@ namespace chatterino { namespace { - Outcome addModBadgeBackground(ImagePtr image, NetworkResult result) - { - auto data = result.getData(); - - QBuffer buffer(const_cast(&data)); - buffer.open(QIODevice::ReadOnly); - QImageReader reader(&buffer); - if (reader.imageCount() == 0) - return Failure; - - QPixmap badgeOverlay = QPixmap::fromImageReader(&reader); - QPixmap badgePixmap(badgeOverlay.width(), badgeOverlay.height()); - - // the default mod badge green color - badgePixmap.fill(QColor("#34AE0A")); - QPainter painter(&badgePixmap); - QRectF rect(0, 0, badgeOverlay.width(), badgeOverlay.height()); - painter.drawPixmap(rect, badgeOverlay, rect); - - image->setPixmap(badgePixmap); - - return Success; - } - Url getEmoteLink(const QJsonObject &urls, const QString &emoteScale) { auto emote = urls.value(emoteScale); @@ -123,16 +99,11 @@ namespace { auto modBadge3x = getEmoteLink(modUrls, "4"); auto modBadgeImageSet = ImageSet{ - Image::fromUrl(modBadge1x, 1) - ->setCustomOnSuccess(addModBadgeBackground), - modBadge2x.string.isEmpty() - ? Image::getEmpty() - : Image::fromUrl(modBadge2x, 0.5) - ->setCustomOnSuccess(addModBadgeBackground), - modBadge3x.string.isEmpty() - ? Image::getEmpty() - : Image::fromUrl(modBadge3x, 0.25) - ->setCustomOnSuccess(addModBadgeBackground), + Image::fromUrl(modBadge1x, 1), + modBadge2x.string.isEmpty() ? Image::getEmpty() + : Image::fromUrl(modBadge2x, 0.5), + modBadge3x.string.isEmpty() ? Image::getEmpty() + : Image::fromUrl(modBadge3x, 0.25), }; modBadge = std::make_shared(Emote{ diff --git a/src/providers/twitch/TwitchMessageBuilder.cpp b/src/providers/twitch/TwitchMessageBuilder.cpp index 0afcb6a68..805592275 100644 --- a/src/providers/twitch/TwitchMessageBuilder.cpp +++ b/src/providers/twitch/TwitchMessageBuilder.cpp @@ -1171,7 +1171,7 @@ void TwitchMessageBuilder::appendTwitchBadges() { if (auto customModBadge = this->twitchChannel->ffzCustomModBadge()) { - this->emplace( + this->emplace( customModBadge.get(), MessageElementFlag::BadgeChannelAuthority) ->setTooltip((*customModBadge)->tooltip.string);