From ba9eb86a9d5c21911841e824261d419857457c24 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Olivier=20Cl=C3=A9ro?= Date: Mon, 11 Nov 2024 18:22:19 +0100 Subject: [PATCH] Fix QLineEdit "clear" button foreground color when changing theme --- lib/src/style/EventFilters.cpp | 35 +++++++++++++++++++++++-------- lib/src/style/EventFilters.hpp | 5 +++-- lib/src/style/QlementineStyle.cpp | 2 +- 3 files changed, 30 insertions(+), 12 deletions(-) diff --git a/lib/src/style/EventFilters.cpp b/lib/src/style/EventFilters.cpp index fe5856a..3883461 100644 --- a/lib/src/style/EventFilters.cpp +++ b/lib/src/style/EventFilters.cpp @@ -27,7 +27,7 @@ namespace oclero::qlementine { LineEditButtonEventFilter::LineEditButtonEventFilter( - QlementineStyle& style, WidgetAnimationManager& animManager, QToolButton* button) + QlementineStyle* style, WidgetAnimationManager& animManager, QToolButton* button) : QObject(button) , _style(style) , _animManager(animManager) @@ -52,7 +52,7 @@ bool LineEditButtonEventFilter::eventFilter(QObject* watchedObject, QEvent* evt) // Instead, place the button by ourselves. const auto* parentLineEdit = _button->parentWidget(); const auto parentRect = parentLineEdit->rect(); - const auto& theme = _style.theme(); + const auto& theme = _style ? _style->theme() : Theme{}; const auto buttonH = theme.controlHeightMedium; const auto buttonW = buttonH; const auto spacing = theme.spacing / 2; @@ -71,29 +71,46 @@ bool LineEditButtonEventFilter::eventFilter(QObject* watchedObject, QEvent* evt) const auto hovered = _button->underMouse(); const auto pressed = _button->isDown(); const auto mouse = getMouseState(pressed, hovered, enabled); - const auto& theme = _style.theme(); + const auto& theme = _style ? _style->theme() : Theme{}; const auto rect = _button->rect(); - const auto& bgColor = _style.toolButtonBackgroundColor(mouse, ColorRole::Secondary); + + const auto& bgColor = + _style ? _style->toolButtonBackgroundColor(mouse, ColorRole::Secondary) + : _button->style()->standardPalette().color(getPaletteColorGroup(mouse), QPalette::ColorRole::ButtonText); + const auto& fgColor = + _style ? _style->toolButtonForegroundColor(mouse, ColorRole::Secondary) + : _button->style()->standardPalette().color(getPaletteColorGroup(mouse), QPalette::ColorRole::Button); + const auto animationDuration = _style ? _style->theme().animationDuration : 0; + const auto& currentBgColor = _animManager.animateBackgroundColor(_button, bgColor, animationDuration); + const auto& currentFgColor = _animManager.animateForegroundColor(_button, fgColor, animationDuration); + + // Get opacity animated in qlinedit_p.cpp:436 + const auto opacity = _button->property(QByteArrayLiteral("opacity")).toDouble(); + const auto circleH = theme.controlHeightMedium; const auto circleW = circleH; const auto circleX = rect.x() + (rect.width() - circleW) / 2; const auto circleY = rect.y() + (rect.height() - circleH) / 2; const auto circleRect = QRect(QPoint{ circleX, circleY }, QSize{ circleW, circleH }); - // Get opacity animated in qlinedit_p.cpp:436 - const auto opacity = _button->property(QByteArrayLiteral("opacity")).toDouble(); + const auto pixmap = getPixmap(_button->icon(), theme.iconSize, mouse, CheckState::NotChecked, _button); + const auto autoIconColor = _style ? _style->autoIconColor(_button) : AutoIconColor::None; + const auto& colorizedPixmap = _style->getColorizedPixmap(pixmap, autoIconColor, currentFgColor, currentFgColor); const auto pixmapX = circleRect.x() + (circleRect.width() - theme.iconSize.width()) / 2; const auto pixmapY = circleRect.y() + (circleRect.height() - theme.iconSize.height()) / 2; const auto pixmapRect = QRect{ { pixmapX, pixmapY }, theme.iconSize }; - const auto& currentBgColor = _animManager.animateBackgroundColor(_button, bgColor, theme.animationDuration); QPainter p(_button); p.setOpacity(opacity); p.setPen(Qt::NoPen); - p.setBrush(currentBgColor); p.setRenderHint(QPainter::Antialiasing, true); + + // Background. + p.setBrush(currentBgColor); p.drawEllipse(circleRect); - p.drawPixmap(pixmapRect, pixmap); + + // Foreground. + p.drawPixmap(pixmapRect, colorizedPixmap); evt->accept(); return true; diff --git a/lib/src/style/EventFilters.hpp b/lib/src/style/EventFilters.hpp index 5a3aca5..dd4868c 100644 --- a/lib/src/style/EventFilters.hpp +++ b/lib/src/style/EventFilters.hpp @@ -11,16 +11,17 @@ #include #include #include +#include namespace oclero::qlementine { class LineEditButtonEventFilter : public QObject { public: - LineEditButtonEventFilter(QlementineStyle& style, WidgetAnimationManager& animManager, QToolButton* button); + LineEditButtonEventFilter(QlementineStyle* style, WidgetAnimationManager& animManager, QToolButton* button); bool eventFilter(QObject* watchedObject, QEvent* evt) override; private: - QlementineStyle& _style; + QPointer _style; WidgetAnimationManager& _animManager; QToolButton* _button{ nullptr }; }; diff --git a/lib/src/style/QlementineStyle.cpp b/lib/src/style/QlementineStyle.cpp index 7b5fd6a..a40ef06 100644 --- a/lib/src/style/QlementineStyle.cpp +++ b/lib/src/style/QlementineStyle.cpp @@ -4766,7 +4766,7 @@ void QlementineStyle::polish(QWidget* w) { // Special case for the Qt-private buttons in a QLineEdit. if (w->inherits("QLineEditIconButton")) { - w->installEventFilter(new LineEditButtonEventFilter(*this, _impl->animations, qobject_cast(w))); + w->installEventFilter(new LineEditButtonEventFilter(this, _impl->animations, qobject_cast(w))); w->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed); // Fix hardcoded width in qlineedit_p.cpp:493 w->setFixedSize(_impl->theme.controlHeightMedium, _impl->theme.controlHeightMedium);