From 9fd5cf1cb2b2f1c5c6e67d3428ed4a578e13ed9f Mon Sep 17 00:00:00 2001 From: nerix Date: Sun, 15 Oct 2023 12:53:29 +0200 Subject: [PATCH] Refactor/cleanup paints and animated profile pictures (#249) --- src/messages/layouts/MessageLayoutElement.cpp | 17 +++--- .../seventv/paints/LinearGradientPaint.cpp | 28 ++++----- .../seventv/paints/LinearGradientPaint.hpp | 3 +- src/providers/seventv/paints/Paint.cpp | 58 ++++++++++--------- src/providers/seventv/paints/Paint.hpp | 18 +++--- .../seventv/paints/PaintDropShadow.cpp | 27 ++++----- .../seventv/paints/PaintDropShadow.hpp | 7 +-- .../seventv/paints/RadialGradientPaint.cpp | 26 ++++----- .../seventv/paints/RadialGradientPaint.hpp | 4 +- src/providers/seventv/paints/UrlPaint.cpp | 13 +++-- src/providers/seventv/paints/UrlPaint.hpp | 4 +- src/widgets/dialogs/UserInfoPopup.cpp | 58 ++++++------------- src/widgets/dialogs/UserInfoPopup.hpp | 5 +- 13 files changed, 122 insertions(+), 146 deletions(-) diff --git a/src/messages/layouts/MessageLayoutElement.cpp b/src/messages/layouts/MessageLayoutElement.cpp index 84a7fb9e37a..86f7af4790b 100644 --- a/src/messages/layouts/MessageLayoutElement.cpp +++ b/src/messages/layouts/MessageLayoutElement.cpp @@ -444,22 +444,23 @@ void TextLayoutElement::paint(QPainter &painter, text.prepend(RTL_EMBED); } - const auto font = getApp()->getFonts()->getFont(this->style_, this->scale_); + auto font = getApp()->getFonts()->getFont(this->style_, this->scale_); - const bool isNametag = - this->getLink().type == chatterino::Link::UserInfo || - this->getLink().type == chatterino::Link::UserWhisper; - const bool drawPaint = isNametag && getSettings()->displaySevenTVPaints; - const auto seventvPaint = + bool isNametag = this->getLink().type == chatterino::Link::UserInfo || + this->getLink().type == chatterino::Link::UserWhisper; + bool drawPaint = isNametag && getSettings()->displaySevenTVPaints; + auto seventvPaint = getApp()->seventvPaints->getPaint(this->getLink().value.toLower()); if (drawPaint && seventvPaint.has_value()) { if (seventvPaint.value()->animated()) + { return; + } - const auto paint = seventvPaint.value(); + const auto &paint = seventvPaint.value(); - const auto paintPixmap = + auto paintPixmap = paint->getPixmap(this->getText(), font, this->color_, this->getRect().size(), this->scale_); diff --git a/src/providers/seventv/paints/LinearGradientPaint.cpp b/src/providers/seventv/paints/LinearGradientPaint.cpp index e9619ee0ae9..6376b6a34d2 100644 --- a/src/providers/seventv/paints/LinearGradientPaint.cpp +++ b/src/providers/seventv/paints/LinearGradientPaint.cpp @@ -9,7 +9,7 @@ LinearGradientPaint::LinearGradientPaint( bool repeat, float angle, std::vector dropShadows) : Paint(std::move(id)) , name_(std::move(name)) - , color_(std::move(color)) + , color_(color) , stops_(std::move(stops)) , repeat_(repeat) , angle_(angle) @@ -48,7 +48,7 @@ QBrush LinearGradientPaint::asBrush(const QColor userColor, QLineF gradientAxis; gradientAxis.setP1(drawingRect.center()); - gradientAxis.setAngle(90.0f - this->angle_); + gradientAxis.setAngle(90.0F - this->angle_); QLineF colorStartAxis; colorStartAxis.setP1(startPoint); @@ -60,13 +60,8 @@ QBrush LinearGradientPaint::asBrush(const QColor userColor, QPointF gradientStart; QPointF gradientEnd; -#if QT_VERSION >= QT_VERSION_CHECK(5, 14, 0) gradientAxis.intersects(colorStartAxis, &gradientStart); gradientAxis.intersects(colorStopAxis, &gradientEnd); -#else - gradientAxis.intersect(colorStartAxis, &gradientStart); - gradientAxis.intersect(colorStopAxis, &gradientEnd); -#endif if (this->repeat_) { @@ -77,24 +72,25 @@ QBrush LinearGradientPaint::asBrush(const QColor userColor, QLinearGradient gradient(gradientStart, gradientEnd); - const auto spread = + auto spread = this->repeat_ ? QGradient::RepeatSpread : QGradient::PadSpread; gradient.setSpread(spread); - for (auto const &[position, color] : this->stops_) + for (const auto &[position, color] : this->stops_) { - const auto combinedColor = this->overlayColors(userColor, color); - const float offsetPosition = - this->repeat_ - ? this->offsetRepeatingStopPosition(position, this->stops_) - : position; + auto combinedColor = + LinearGradientPaint::overlayColors(userColor, color); + auto offsetPosition = + this->repeat_ ? LinearGradientPaint::offsetRepeatingStopPosition( + position, this->stops_) + : position; gradient.setColorAt(offsetPosition, combinedColor); } - return QBrush(gradient); + return {gradient}; } -std::vector LinearGradientPaint::getDropShadows() const +const std::vector &LinearGradientPaint::getDropShadows() const { return this->dropShadows_; } diff --git a/src/providers/seventv/paints/LinearGradientPaint.hpp b/src/providers/seventv/paints/LinearGradientPaint.hpp index 2bf9c3cfdc7..46a38d06e18 100644 --- a/src/providers/seventv/paints/LinearGradientPaint.hpp +++ b/src/providers/seventv/paints/LinearGradientPaint.hpp @@ -3,7 +3,6 @@ #include "Paint.hpp" #include -#include namespace chatterino { @@ -15,7 +14,7 @@ class LinearGradientPaint : public Paint std::vector dropShadows); QBrush asBrush(QColor userColor, QRectF drawingRect) const override; - std::vector getDropShadows() const override; + const std::vector &getDropShadows() const override; bool animated() const override; private: diff --git a/src/providers/seventv/paints/Paint.cpp b/src/providers/seventv/paints/Paint.cpp index 533444f988d..7a3e3f4feba 100644 --- a/src/providers/seventv/paints/Paint.cpp +++ b/src/providers/seventv/paints/Paint.cpp @@ -1,6 +1,7 @@ #include "providers/seventv/paints/Paint.hpp" #include "Application.hpp" +#include "common/Literals.hpp" #include "singletons/Theme.hpp" #include @@ -8,9 +9,10 @@ namespace chatterino { -QPixmap Paint::getPixmap(const QString text, const QFont font, - const QColor userColor, const QSize size, - const float scale) const +using namespace literals; + +QPixmap Paint::getPixmap(const QString &text, const QFont &font, + QColor userColor, QSize size, float scale) const { QPixmap pixmap(size); pixmap.fill(Qt::transparent); @@ -45,41 +47,40 @@ QPixmap Paint::getPixmap(const QString text, const QFont font, for (const auto &shadow : this->getDropShadows()) { if (!shadow.isValid()) + { continue; + } // HACK: create a QLabel from the pixmap to apply drop shadows QLabel label; - auto scaledShadow = shadow.scaled(scale / label.devicePixelRatioF()); + auto scaledShadow = shadow.scaled( + scale / static_cast(label.devicePixelRatioF())); // NOTE: avoid scaling issues on high DPI displays pixmap.setDevicePixelRatio(label.devicePixelRatioF()); label.setPixmap(pixmap); - auto dropShadow = scaledShadow.getGraphicsEffect(); - label.setGraphicsEffect(dropShadow); + QGraphicsDropShadowEffect dropShadow; + scaledShadow.apply(dropShadow); + label.setGraphicsEffect(&dropShadow); pixmap = label.grab(); pixmap.setDevicePixelRatio(1); - - label.deleteLater(); - delete dropShadow; } if (drawColon) { - const auto colonColor = - getApp()->getThemes()->messages.textColors.regular; + auto colonColor = getApp()->getThemes()->messages.textColors.regular; pixmapPainter.begin(&pixmap); pixmapPainter.setPen(QPen(colonColor)); pixmapPainter.setFont(font); - const QRectF colonBoundingRect(nametagBoundingRect.right(), 0, 10000, - 10000); - pixmapPainter.drawText(colonBoundingRect, ":", + QRectF colonBoundingRect(nametagBoundingRect.right(), 0, 10000, 10000); + pixmapPainter.drawText(colonBoundingRect, u":"_s, QTextOption(Qt::AlignLeft | Qt::AlignTop)); pixmapPainter.end(); } @@ -87,26 +88,27 @@ QPixmap Paint::getPixmap(const QString text, const QFont font, return pixmap; } -QColor Paint::overlayColors(const QColor background, - const QColor foreground) const +QColor Paint::overlayColors(QColor background, QColor foreground) { - const auto alpha = foreground.alphaF(); + auto alpha = foreground.alphaF(); - const auto r = (1 - alpha) * background.red() + alpha * foreground.red(); - const auto g = - (1 - alpha) * background.green() + alpha * foreground.green(); - const auto b = (1 - alpha) * background.blue() + alpha * foreground.blue(); + auto r = (1 - alpha) * static_cast(background.red()) + + alpha * static_cast(foreground.red()); + auto g = (1 - alpha) * static_cast(background.green()) + + alpha * static_cast(foreground.green()); + auto b = (1 - alpha) * static_cast(background.blue()) + + alpha * static_cast(foreground.blue()); - return QColor(r, g, b); + return {static_cast(r), static_cast(g), static_cast(b)}; } -float Paint::offsetRepeatingStopPosition(const float position, - const QGradientStops stops) const +qreal Paint::offsetRepeatingStopPosition(const qreal position, + const QGradientStops &stops) { - const float gradientStart = stops.first().first; - const float gradientEnd = stops.last().first; - const float gradientLength = gradientEnd - gradientStart; - const float offsetPosition = (position - gradientStart) / gradientLength; + const qreal gradientStart = stops.first().first; + const qreal gradientEnd = stops.last().first; + const qreal gradientLength = gradientEnd - gradientStart; + const qreal offsetPosition = (position - gradientStart) / gradientLength; return offsetPosition; } diff --git a/src/providers/seventv/paints/Paint.hpp b/src/providers/seventv/paints/Paint.hpp index d067977b985..ad411c6d4b3 100644 --- a/src/providers/seventv/paints/Paint.hpp +++ b/src/providers/seventv/paints/Paint.hpp @@ -13,23 +13,27 @@ class Paint { public: virtual QBrush asBrush(QColor userColor, QRectF drawingRect) const = 0; - virtual std::vector getDropShadows() const = 0; + virtual const std::vector &getDropShadows() const = 0; virtual bool animated() const = 0; - QPixmap getPixmap(QString text, QFont font, QColor userColor, QSize size, - float scale) const; + QPixmap getPixmap(const QString &text, const QFont &font, QColor userColor, + QSize size, float scale) const; Paint(QString id) : id(std::move(id)){}; virtual ~Paint() = default; + Paint(const Paint &) = default; + Paint(Paint &&) = delete; + Paint &operator=(const Paint &) = default; + Paint &operator=(Paint &&) = delete; + QString id; protected: - QColor overlayColors(const QColor background, - const QColor foreground) const; - float offsetRepeatingStopPosition(const float position, - const QGradientStops stops) const; + static QColor overlayColors(QColor background, QColor foreground); + static qreal offsetRepeatingStopPosition(qreal position, + const QGradientStops &stops); }; } // namespace chatterino diff --git a/src/providers/seventv/paints/PaintDropShadow.cpp b/src/providers/seventv/paints/PaintDropShadow.cpp index 9b9cfae11ce..475567cec3b 100644 --- a/src/providers/seventv/paints/PaintDropShadow.cpp +++ b/src/providers/seventv/paints/PaintDropShadow.cpp @@ -1,9 +1,9 @@ -#include "PaintDropShadow.hpp" +#include "providers/seventv/paints/PaintDropShadow.hpp" namespace chatterino { -PaintDropShadow::PaintDropShadow(const float xOffset, const float yOffset, - const float radius, const QColor color) +PaintDropShadow::PaintDropShadow(float xOffset, float yOffset, float radius, + QColor color) : xOffset_(xOffset) , yOffset_(yOffset) , radius_(radius) @@ -16,22 +16,19 @@ bool PaintDropShadow::isValid() const return radius_ > 0; } -PaintDropShadow PaintDropShadow::scaled(const float scale) const +PaintDropShadow PaintDropShadow::scaled(float scale) const { - return PaintDropShadow(this->xOffset_ * scale, this->yOffset_ * scale, - this->radius_ * scale, this->color_); + return {this->xOffset_ * scale, this->yOffset_ * scale, + this->radius_ * scale, this->color_}; } -QGraphicsDropShadowEffect *PaintDropShadow::getGraphicsEffect() const +void PaintDropShadow::apply(QGraphicsDropShadowEffect &effect) const { - auto effect = new QGraphicsDropShadowEffect(); - - effect->setXOffset(this->xOffset_); - effect->setYOffset(this->yOffset_); - effect->setBlurRadius(this->radius_); - effect->setColor(this->color_); - - return effect; + // We can't move here + effect.setXOffset(this->xOffset_); + effect.setYOffset(this->yOffset_); + effect.setBlurRadius(this->radius_); + effect.setColor(this->color_); } } // namespace chatterino diff --git a/src/providers/seventv/paints/PaintDropShadow.hpp b/src/providers/seventv/paints/PaintDropShadow.hpp index 7272c310029..98bbb66c5df 100644 --- a/src/providers/seventv/paints/PaintDropShadow.hpp +++ b/src/providers/seventv/paints/PaintDropShadow.hpp @@ -7,12 +7,11 @@ namespace chatterino { class PaintDropShadow { public: - PaintDropShadow(const float xOffset, const float yOffset, - const float radius, const QColor color); + PaintDropShadow(float xOffset, float yOffset, float radius, QColor color); bool isValid() const; - PaintDropShadow scaled(const float scale) const; - QGraphicsDropShadowEffect *getGraphicsEffect() const; + PaintDropShadow scaled(float scale) const; + void apply(QGraphicsDropShadowEffect &effect) const; private: const float xOffset_; diff --git a/src/providers/seventv/paints/RadialGradientPaint.cpp b/src/providers/seventv/paints/RadialGradientPaint.cpp index 541a6218a5c..3c615fcdd3b 100644 --- a/src/providers/seventv/paints/RadialGradientPaint.cpp +++ b/src/providers/seventv/paints/RadialGradientPaint.cpp @@ -1,7 +1,5 @@ #include "providers/seventv/paints/RadialGradientPaint.hpp" -#include - namespace chatterino { RadialGradientPaint::RadialGradientPaint( @@ -15,33 +13,33 @@ RadialGradientPaint::RadialGradientPaint( { } -QBrush RadialGradientPaint::asBrush(const QColor userColor, - const QRectF drawingRect) const +QBrush RadialGradientPaint::asBrush(QColor userColor, QRectF drawingRect) const { - const double x = drawingRect.x() + drawingRect.width() / 2; - const double y = drawingRect.y() + drawingRect.height() / 2; + double x = drawingRect.x() + drawingRect.width() / 2; + double y = drawingRect.y() + drawingRect.height() / 2; double radius = std::max(drawingRect.width(), drawingRect.height()) / 2; radius = this->repeat_ ? radius * this->stops_.back().first : radius; QRadialGradient gradient(x, y, radius); - const auto spread = + auto spread = this->repeat_ ? QGradient::RepeatSpread : QGradient::PadSpread; gradient.setSpread(spread); for (const auto &[position, color] : this->stops_) { - const auto combinedColor = this->overlayColors(userColor, color); - const float offsetPosition = - this->repeat_ - ? this->offsetRepeatingStopPosition(position, this->stops_) - : position; + auto combinedColor = + RadialGradientPaint::overlayColors(userColor, color); + auto offsetPosition = + this->repeat_ ? RadialGradientPaint::offsetRepeatingStopPosition( + position, this->stops_) + : position; gradient.setColorAt(offsetPosition, combinedColor); } - return QBrush(gradient); + return {gradient}; } bool RadialGradientPaint::animated() const @@ -49,7 +47,7 @@ bool RadialGradientPaint::animated() const return false; } -std::vector RadialGradientPaint::getDropShadows() const +const std::vector &RadialGradientPaint::getDropShadows() const { return this->dropShadows_; } diff --git a/src/providers/seventv/paints/RadialGradientPaint.hpp b/src/providers/seventv/paints/RadialGradientPaint.hpp index fa4d08b601b..ceb029087d3 100644 --- a/src/providers/seventv/paints/RadialGradientPaint.hpp +++ b/src/providers/seventv/paints/RadialGradientPaint.hpp @@ -8,10 +8,10 @@ class RadialGradientPaint : public Paint { public: RadialGradientPaint(QString name, QString id, QGradientStops stops, - bool repeat, std::vector); + bool repeat, std::vector dropShadows); QBrush asBrush(QColor userColor, QRectF drawingRect) const override; - std::vector getDropShadows() const override; + const std::vector &getDropShadows() const override; bool animated() const override; private: diff --git a/src/providers/seventv/paints/UrlPaint.cpp b/src/providers/seventv/paints/UrlPaint.cpp index bbcf14d6688..931fa96f325 100644 --- a/src/providers/seventv/paints/UrlPaint.cpp +++ b/src/providers/seventv/paints/UrlPaint.cpp @@ -24,7 +24,8 @@ QBrush UrlPaint::asBrush(const QColor userColor, const QRectF drawingRect) const { if (auto paintPixmap = this->image_->pixmapOrLoad()) { - paintPixmap = paintPixmap->scaledToWidth(drawingRect.width()); + auto rect = drawingRect.toRect(); + paintPixmap = paintPixmap->scaledToWidth(rect.width()); QPixmap userColorPixmap = QPixmap(paintPixmap->size()); userColorPixmap.fill(userColor); @@ -32,15 +33,15 @@ QBrush UrlPaint::asBrush(const QColor userColor, const QRectF drawingRect) const QPainter painter(&userColorPixmap); painter.drawPixmap(0, 0, *paintPixmap); - const QPixmap combinedPixmap = userColorPixmap.copy( - QRect(0, 0, drawingRect.width(), drawingRect.height())); - return QBrush(combinedPixmap); + const QPixmap combinedPixmap = + userColorPixmap.copy(QRect(0, 0, rect.width(), rect.height())); + return {combinedPixmap}; } - return QBrush(userColor); + return {userColor}; } -std::vector UrlPaint::getDropShadows() const +const std::vector &UrlPaint::getDropShadows() const { return this->dropShadows_; } diff --git a/src/providers/seventv/paints/UrlPaint.hpp b/src/providers/seventv/paints/UrlPaint.hpp index a6175cdf080..7f52d17a3e4 100644 --- a/src/providers/seventv/paints/UrlPaint.hpp +++ b/src/providers/seventv/paints/UrlPaint.hpp @@ -9,10 +9,10 @@ class UrlPaint : public Paint { public: UrlPaint(QString name, QString id, ImagePtr image, - std::vector); + std::vector dropShadows); QBrush asBrush(QColor userColor, QRectF drawingRect) const override; - std::vector getDropShadows() const override; + const std::vector &getDropShadows() const override; bool animated() const override; private: diff --git a/src/widgets/dialogs/UserInfoPopup.cpp b/src/widgets/dialogs/UserInfoPopup.cpp index 3818fc11e5b..ae9f936a01a 100644 --- a/src/widgets/dialogs/UserInfoPopup.cpp +++ b/src/widgets/dialogs/UserInfoPopup.cpp @@ -272,11 +272,6 @@ UserInfoPopup::UserInfoPopup(bool closeAutomatically, QWidget *parent, auto avatar = head.emplace