From 03845bfbc67c48295e3c6456795959b13ad7cb50 Mon Sep 17 00:00:00 2001 From: pajlada Date: Sun, 29 Jun 2025 13:27:37 +0200 Subject: [PATCH] feat(SvgButton): Allow custom color (#6268) --- CHANGELOG.md | 2 +- src/widgets/buttons/SvgButton.cpp | 23 ++++++++++++++++++++++- src/widgets/buttons/SvgButton.hpp | 11 +++++++++++ 3 files changed, 34 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 43393a04..02d7b355 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -63,7 +63,7 @@ - Dev: Simplified string literals to be a re-export of Qt functions. (#6175) - Dev: Fixed incorrect lua generation of static methods for typescript plugins. (#6190, #6223) - Dev: Merged top/bottom and left/right notebook layouts. (#6215) -- Dev: Refactored `Button` and friends. (#6102, #6255, #6266, #6302) +- Dev: Refactored `Button` and friends. (#6102, #6255, #6266, #6302, #6268) - Dev: Made Settings & Account button on Linux/macOS SVGs. (#6267) - Dev: Emoji style / set is now stored lowercase (and matched case-insensitively). Changing emoji style from this point on and then running an old version might mean you will use the Twitter emoji style by default. (#6300) - Dev: `OnceFlag`'s internal flag is now atomic. (#6237) diff --git a/src/widgets/buttons/SvgButton.cpp b/src/widgets/buttons/SvgButton.cpp index 1269de91..f1a58b85 100644 --- a/src/widgets/buttons/SvgButton.cpp +++ b/src/widgets/buttons/SvgButton.cpp @@ -23,6 +23,12 @@ void SvgButton::setSource(Src source) this->invalidateContent(); } +void SvgButton::setColor(std::optional color) +{ + this->color_ = color; + this->invalidateContent(); +} + void SvgButton::setPadding(QSize padding) { if (this->padding_ == padding) @@ -65,7 +71,22 @@ void SvgButton::paintContent(QPainter &painter) QSize actualPadding = this->scale() * this->padding_; QPoint topLeft{actualPadding.width(), actualPadding.height()}; QSize contentSize = this->size() - 2 * actualPadding; - this->svg_->render(&painter, {topLeft, contentSize}); + auto bounds = QRectF{topLeft, contentSize}; + this->svg_->render(&painter, bounds); + + if (this->color_.has_value()) + { + painter.save(); + + // Set the composition mode so that the upcoming color fill only applies the color + // on top of the pre-existing SVG contents + // + // More info on how the composition modes work can be found here: https://doc.qt.io/qt-6/qpainter.html#CompositionMode-enum + painter.setCompositionMode(QPainter::CompositionMode_SourceIn); + painter.fillRect(bounds, *this->color_); + + painter.restore(); + } } QString SvgButton::currentSvgPath() const diff --git a/src/widgets/buttons/SvgButton.hpp b/src/widgets/buttons/SvgButton.hpp index 6630d16b..c178a294 100644 --- a/src/widgets/buttons/SvgButton.hpp +++ b/src/widgets/buttons/SvgButton.hpp @@ -2,8 +2,11 @@ #include "widgets/buttons/Button.hpp" +#include #include +#include + class QSvgRenderer; namespace chatterino { @@ -41,6 +44,13 @@ public: /// Setter for #source() void setSource(Src source); + /// Sets a custom color to render over the SVG. + /// This allows you to change the color of a button to a solid color + /// of your choice without using multiple SVG resources. + /// + /// Set to std::nullopt to not override the color. + void setColor(std::optional color); + /// @brief Returns the padding inside the button. /// /// `width` is the padding applied horizontally (left and right). @@ -65,6 +75,7 @@ private: Src source_; QSvgRenderer *svg_; QSize padding_; + std::optional color_; }; } // namespace chatterino