From 4b9633a438f35cca0009b9abdc1d55ad3ac43cb7 Mon Sep 17 00:00:00 2001 From: Christophe Thiery Date: Tue, 17 Oct 2023 15:32:18 +0200 Subject: [PATCH 1/7] Allow more customization of auto icon color --- .../qlementine/style/QlementineStyle.hpp | 13 ++- .../oclero/qlementine/utils/ImageUtils.hpp | 13 +++ lib/src/style/Delegates.cpp | 6 +- lib/src/style/EventFilters.cpp | 4 +- lib/src/style/QlementineStyle.cpp | 93 ++++++++++--------- lib/src/widgets/IconWidget.cpp | 9 +- lib/src/widgets/LineEdit.cpp | 4 +- 7 files changed, 81 insertions(+), 61 deletions(-) diff --git a/lib/include/oclero/qlementine/style/QlementineStyle.hpp b/lib/include/oclero/qlementine/style/QlementineStyle.hpp index 181eb85..0cd992f 100644 --- a/lib/include/oclero/qlementine/style/QlementineStyle.hpp +++ b/lib/include/oclero/qlementine/style/QlementineStyle.hpp @@ -23,6 +23,7 @@ #pragma once #include +#include #include @@ -83,12 +84,14 @@ class QlementineStyle : public QCommonStyle { void triggerCompleteRepaint(); - void setAutoIconColorEnabled(bool enabled); - bool isAutoIconColorEnabled() const; + void setAutoIconColor(AutoIconColor autoIconColor); + AutoIconColor autoIconColor() const; - void setAutoIconColorEnabled(QWidget* widget, bool enabled); - bool isAutoIconColorEnabled(const QWidget* widget) const; + static void setAutoIconColor(QWidget* widget, AutoIconColor autoIconColor); + AutoIconColor autoIconColor(const QWidget* widget) const; + QPixmap getColorizedPixmap(const QPixmap& input, AutoIconColor autoIconColor, + const QColor& fgcolor, const QColor& textColor) const; static QIcon makeIcon(const QString& svgPath); public: // QStyle overrides. @@ -191,7 +194,7 @@ class QlementineStyle : public QCommonStyle { ActiveState const active, const QModelIndex& index, const QWidget* widget = nullptr) const; virtual QColor const& listItemForegroundColor( MouseState const mouse, SelectionState const selected, FocusState const focus, ActiveState const active) const; - virtual bool listItemIsAutoIconColorEnabled(MouseState const mouse, SelectionState const selected, + virtual AutoIconColor listItemAutoIconColor(MouseState const mouse, SelectionState const selected, FocusState const focus, ActiveState const active, const QModelIndex& index, const QWidget* widget = nullptr) const; virtual QColor const& listItemCaptionForegroundColor( MouseState const mouse, SelectionState const selected, FocusState const focus, ActiveState const active) const; diff --git a/lib/include/oclero/qlementine/utils/ImageUtils.hpp b/lib/include/oclero/qlementine/utils/ImageUtils.hpp index 821d78b..3508a98 100644 --- a/lib/include/oclero/qlementine/utils/ImageUtils.hpp +++ b/lib/include/oclero/qlementine/utils/ImageUtils.hpp @@ -87,6 +87,17 @@ enum class ColorizeMode { Tint, }; +/// Specifies which color to apply when colorizing an icon. +enum class AutoIconColor { + // No automatic icon recolorization. + None, + // Recoloize with the foreground color. + ForegroundColor, + // Recolorize with the current text color, which might be different from the foreground color + // if the text color was customized in the palette. + TextColor, +}; + /// Gets the pixmap in the cache, or creates it if not yet there. QPixmap getCachedPixmap(QPixmap const& input, QColor const& color, ColorizeMode mode); @@ -130,3 +141,5 @@ QPixmap getDropShadowPixmap(QPixmap const& input, double blurRadius, QColor cons /// Gets a drop shadow for a QRect. QPixmap getDropShadowPixmap(QSize const& size, double borderRadius, double blurRadius, QColor const& color = Qt::black); } // namespace oclero::qlementine + +Q_DECLARE_METATYPE(oclero::qlementine::AutoIconColor); diff --git a/lib/src/style/Delegates.cpp b/lib/src/style/Delegates.cpp index 24fd0b2..2f6dae2 100644 --- a/lib/src/style/Delegates.cpp +++ b/lib/src/style/Delegates.cpp @@ -92,7 +92,7 @@ void ComboBoxDelegate::paint(QPainter* p, const QStyleOptionViewItem& opt, const const auto& iconSize = opt.decorationSize; // Get icon size. const auto pixmap = getPixmap(icon, iconSize, mouse, CheckState::NotChecked, _widget); const auto* qlementineStyle = qobject_cast(_widget->style()); - const auto colorize = qlementineStyle && qlementineStyle->isAutoIconColorEnabled(_widget); + const auto autoIconColor = qlementineStyle ? qlementineStyle->autoIconColor(_widget) : AutoIconColor::None; const auto pixmapPixelRatio = pixmap.devicePixelRatio(); const auto pixmapW = pixmapPixelRatio != 0 ? static_cast((qreal) pixmap.width() / pixmapPixelRatio) : 0; const auto pixmapH = pixmapPixelRatio != 0 ? static_cast((qreal) pixmap.height() / pixmapPixelRatio) : 0; @@ -102,7 +102,7 @@ void ComboBoxDelegate::paint(QPainter* p, const QStyleOptionViewItem& opt, const availableW -= iconSize.width() + spacing; availableX += iconSize.width() + spacing; - if (mouse == MouseState::Disabled && !colorize) { + if (mouse == MouseState::Disabled && autoIconColor == AutoIconColor::None) { // Change only the icon's tint and opacity, so it looks disabled. const auto& sourceOverBgColor = qlementineStyle ? qlementineStyle->listItemBackgroundColor( MouseState::Normal, selected, focus, active, idx, _widget) @@ -116,7 +116,7 @@ void ComboBoxDelegate::paint(QPainter* p, const QStyleOptionViewItem& opt, const p->setOpacity(backupOpacity); } else { // Actually color the whole icon if needed. - const auto& colorizedPixmap = colorize ? getColorizedPixmap(pixmap, fgColor) : pixmap; + const auto& colorizedPixmap = qlementineStyle ? qlementineStyle->getColorizedPixmap(pixmap, autoIconColor, fgColor, fgColor) : pixmap; p->drawPixmap(pixmapRect, colorizedPixmap); } } diff --git a/lib/src/style/EventFilters.cpp b/lib/src/style/EventFilters.cpp index 3b55136..87706d2 100644 --- a/lib/src/style/EventFilters.cpp +++ b/lib/src/style/EventFilters.cpp @@ -205,14 +205,14 @@ TabBarEventFilter::TabBarEventFilter(QlementineStyle& style, QTabBar* tabBar) _leftButton->setFocusPolicy(Qt::NoFocus); _leftButton->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed); _leftButton->setFixedSize(_leftButton->sizeHint()); - style.setAutoIconColorEnabled(_leftButton, false); + style.setAutoIconColor(_leftButton, AutoIconColor::None); _leftButton->installEventFilter(buttonEvtFilter); _rightButton = toolButtons.at(1); _rightButton->setFocusPolicy(Qt::NoFocus); _rightButton->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed); _rightButton->setFixedSize(_rightButton->sizeHint()); - style.setAutoIconColorEnabled(_rightButton, false); + style.setAutoIconColor(_rightButton, AutoIconColor::None); _rightButton->installEventFilter(buttonEvtFilter); } } diff --git a/lib/src/style/QlementineStyle.cpp b/lib/src/style/QlementineStyle.cpp index a118972..a424a18 100644 --- a/lib/src/style/QlementineStyle.cpp +++ b/lib/src/style/QlementineStyle.cpp @@ -83,8 +83,8 @@ constexpr auto hardcodedLineEditHMargin = 2; // qlinedit_p.cpp line 69 // A pen width of 1 causes visual bugs. constexpr auto iconPenWidth = 1.01; -// Used to determine if the icon must be colorized according to the Theme's colorsor not. -constexpr auto Property_DisableAutoIconColor = "disableAutoIconColor"; +// Used to determine if the icon must be colorized according to the Theme's colors or not. +constexpr auto Property_AutoIconColor = "autoIconColor"; struct QlementineStyleImpl { QlementineStyleImpl(QlementineStyle& o) @@ -205,7 +205,7 @@ struct QlementineStyleImpl { std::unordered_map standardIconCache; std::unordered_map standardIconExtCache; bool useMenuForComboBoxPopup{ false }; - bool autoIconColorEnabled{ false }; + AutoIconColor autoIconColor{ AutoIconColor::None }; }; QlementineStyle::QlementineStyle(QObject* parent) @@ -281,33 +281,45 @@ void QlementineStyle::triggerCompleteRepaint() { } } -// Sets whether automatic icon colorization is enabled for the style. -void QlementineStyle::setAutoIconColorEnabled(bool enabled) { - _impl->autoIconColorEnabled = enabled; +// Sets automatic icon colorization for the style. +void QlementineStyle::setAutoIconColor(AutoIconColor autoIconColor) { + _impl->autoIconColor = autoIconColor; triggerCompleteRepaint(); } -bool QlementineStyle::isAutoIconColorEnabled() const { - return _impl->autoIconColorEnabled; +AutoIconColor QlementineStyle::autoIconColor() const { + return _impl->autoIconColor; } -// Sets whether automatic icon colorization is enabled for a specific widget. -// This overrides the default value from isAutoIconColorEnabled(). -void QlementineStyle::setAutoIconColorEnabled(QWidget* widget, bool enabled) { +// Sets automatic icon colorization for a specific widget. +// This overrides the default value from autoIconColorEnabled(). +void QlementineStyle::setAutoIconColor(QWidget* widget, AutoIconColor mode) { if (widget) { - widget->setProperty(Property_DisableAutoIconColor, !enabled); + widget->setProperty(Property_AutoIconColor, QVariant::fromValue(mode)); } } -bool QlementineStyle::isAutoIconColorEnabled(const QWidget* widget) const { +AutoIconColor QlementineStyle::autoIconColor(const QWidget* widget) const { if (!widget) { - return isAutoIconColorEnabled(); + return autoIconColor(); } - const auto property = widget->property(Property_DisableAutoIconColor); + const auto property = widget->property(Property_AutoIconColor); if (!property.isValid()) { - return isAutoIconColorEnabled(); + return autoIconColor(); + } + return property.value(); +} + +QPixmap QlementineStyle::getColorizedPixmap(const QPixmap& input, AutoIconColor autoIconColor, + const QColor& fgColor, const QColor& textColor) const { + switch (autoIconColor) { + case AutoIconColor::None: + return input; + case AutoIconColor::ForegroundColor: + return qlementine::getColorizedPixmap(input, fgColor); + case AutoIconColor::TextColor: + return qlementine::getColorizedPixmap(input, textColor); } - return !property.toBool(); } QIcon QlementineStyle::makeIcon(const QString& svgPath) { @@ -986,8 +998,7 @@ void QlementineStyle::drawControl(ControlElement ce, const QStyleOption* opt, QP const auto centered = !hasMenu; const auto checked = getCheckState(optButton->state); const auto pixmap = getPixmap(optButton->icon, optButton->iconSize, mouse, checked, w); - const auto colorize = QlementineStyle::isAutoIconColorEnabled(w); - const auto& colorizedPixmap = colorize ? getColorizedPixmap(pixmap, currentFgColor) : pixmap; + const auto& colorizedPixmap = getColorizedPixmap(pixmap, autoIconColor(w), currentFgColor, currentFgColor); const auto pixmapPixelRatio = colorizedPixmap.devicePixelRatio(); const auto iconW = colorizedPixmap.isNull() ? 0 : static_cast(colorizedPixmap.width() / pixmapPixelRatio); const auto fmFlags = hasMenu ? Qt::AlignLeft : Qt::AlignCenter; @@ -1071,8 +1082,7 @@ void QlementineStyle::drawControl(ControlElement ce, const QStyleOption* opt, QP const auto spacing = _impl->theme.spacing; const auto checked = getCheckState(optButton->state); const auto pixmap = getPixmap(optButton->icon, optButton->iconSize, mouse, checked, w); - const auto colorize = QlementineStyle::isAutoIconColorEnabled(w); - const auto& colorizedPixmap = colorize ? getColorizedPixmap(pixmap, fgColor) : pixmap; + const auto& colorizedPixmap = getColorizedPixmap(pixmap, autoIconColor(w), fgColor, fgColor); const auto pixmapPixelRatio = colorizedPixmap.devicePixelRatio(); const auto iconW = colorizedPixmap.isNull() ? 0 : static_cast((qreal) colorizedPixmap.width() / (pixmapPixelRatio)); @@ -1204,8 +1214,7 @@ void QlementineStyle::drawControl(ControlElement ce, const QStyleOption* opt, QP if (!iconSize.isEmpty()) { const auto checked = selection == SelectionState::Selected ? CheckState::Checked : CheckState::NotChecked; const auto pixmap = getPixmap(icon, iconSize, mouse, checked, w); - const auto colorize = QlementineStyle::isAutoIconColorEnabled(w); - const auto& colorizedPixmap = colorize ? getColorizedPixmap(pixmap, fgColor) : pixmap; + const auto& colorizedPixmap = getColorizedPixmap(pixmap, autoIconColor(w), fgColor, fgColor); const auto pixmapPixelRatio = colorizedPixmap.devicePixelRatio(); const auto pixmapW = pixmapPixelRatio != 0 ? (int) ((qreal) colorizedPixmap.width() / pixmapPixelRatio) : 0; const auto pixmapH = pixmapPixelRatio != 0 ? (int) ((qreal) colorizedPixmap.height() / pixmapPixelRatio) : 0; @@ -1380,8 +1389,7 @@ void QlementineStyle::drawControl(ControlElement ce, const QStyleOption* opt, QP // Icon. const auto pixmap = getPixmap(optMenuItem->icon, _impl->theme.iconSize, mouse, checkState, w); if (!pixmap.isNull()) { - const auto colorize = QlementineStyle::isAutoIconColorEnabled(w); - const auto& colorizedPixmap = colorize ? getColorizedPixmap(pixmap, fgColor) : pixmap; + const auto& colorizedPixmap = getColorizedPixmap(pixmap, autoIconColor(w), fgColor, fgColor); const auto targetPxRatio = colorizedPixmap.devicePixelRatio(); const auto pixmapW = targetPxRatio != 0 ? (int) ((qreal) colorizedPixmap.width() / targetPxRatio) : 0; const auto pixmapH = targetPxRatio != 0 ? (int) ((qreal) colorizedPixmap.height() / targetPxRatio) : 0; @@ -1576,8 +1584,7 @@ void QlementineStyle::drawControl(ControlElement ce, const QStyleOption* opt, QP // Icon. if (hasIcon) { const auto pixmap = getPixmap(icon, iconSize, mouse, checked, w); - const auto colorize = QlementineStyle::isAutoIconColorEnabled(w); - const auto& colorizedPixmap = colorize ? getColorizedPixmap(pixmap, fgColor) : pixmap; + const auto& colorizedPixmap = getColorizedPixmap(pixmap, autoIconColor(w), fgColor, fgColor); const auto pixmapPixelRatio = colorizedPixmap.devicePixelRatio(); const auto pixmapW = pixmapPixelRatio != 0 ? (int) ((qreal) colorizedPixmap.width() / pixmapPixelRatio) : 0; const auto pixmapH = pixmapPixelRatio != 0 ? (int) ((qreal) colorizedPixmap.height() / pixmapPixelRatio) : 0; @@ -1733,8 +1740,8 @@ void QlementineStyle::drawControl(ControlElement ce, const QStyleOption* opt, QP const auto iconRect = QRect(iconX, iconY, iconExtent, iconExtent); if (!hasArrow || iconRect.right() <= maxLabelX) { - const auto colorize = - QlementineStyle::isAutoIconColorEnabled() && QlementineStyle::isAutoIconColorEnabled(w); + const auto autoIconColor = this->autoIconColor(w); + const auto colorize = autoIconColor != AutoIconColor::None; const auto iconMode = (optHeader->state & State_Enabled || colorize) ? QIcon::Normal : QIcon::Disabled; #if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) const auto iconPixmap = icon.pixmap(qlementine::getWindow(w), { iconExtent, iconExtent }, iconMode); @@ -2002,8 +2009,7 @@ void QlementineStyle::drawControl(ControlElement ce, const QStyleOption* opt, QP const auto contentRect = totalRect.marginsRemoved({ contentLeftPadding, 0, contentRightPadding, 0 }); const auto pixmap = getPixmap(optComboBox->currentIcon, optComboBox->iconSize, mouse, CheckState::NotChecked, w); - const auto colorize = QlementineStyle::isAutoIconColorEnabled(w); - const auto& colorizedPixmap = colorize ? getColorizedPixmap(pixmap, fgColor) : pixmap; // No animation for icon? + const auto& colorizedPixmap = getColorizedPixmap(pixmap, autoIconColor(w), fgColor, fgColor); // No animation for icon? const auto iconW = colorizedPixmap.isNull() ? 0 : colorizedPixmap.width() / colorizedPixmap.devicePixelRatio(); const auto iconSpacing = iconW > 0 ? spacing : 0; auto availableW = contentRect.width(); @@ -2119,7 +2125,7 @@ void QlementineStyle::drawControl(ControlElement ce, const QStyleOption* opt, QP const auto& fgColor = listItemForegroundColor(itemMouse, selected, focus, active); constexpr auto paletteColorRole = QPalette::ColorRole::Text; const auto paletteColorGroup = getPaletteColorGroup(optItem->state); - const auto& actualFgColor = + const auto& textColor = focus == FocusState::Focused ? fgColor : optItem->palette.color(paletteColorGroup, paletteColorRole); const auto contentRect = fgRect.adjusted(checkBoxSpace, 0, 0, 0); @@ -2131,7 +2137,7 @@ void QlementineStyle::drawControl(ControlElement ce, const QStyleOption* opt, QP const auto iconW = iconSize.width(); const auto iconSpacing = iconW > 0 ? spacing : 0; const auto pixmap = getPixmap(optItem->icon, iconSize, itemMouse, checked, w); - const auto colorize = listItemIsAutoIconColorEnabled(itemMouse, selected, focus, active, optItem->index, w); + const auto autoIconColor = listItemAutoIconColor(itemMouse, selected, focus, active, optItem->index, w); const auto pixmapPixelRatio = pixmap.devicePixelRatio(); const auto pixmapW = pixmapPixelRatio != 0 ? (int) ((qreal) pixmap.width() / pixmapPixelRatio) : 0; const auto pixmapH = pixmapPixelRatio != 0 ? (int) ((qreal) pixmap.height() / pixmapPixelRatio) : 0; @@ -2141,10 +2147,10 @@ void QlementineStyle::drawControl(ControlElement ce, const QStyleOption* opt, QP availableW -= iconW + iconSpacing; availableX += iconW + iconSpacing; - if (itemMouse == MouseState::Disabled && !colorize) { + if (itemMouse == MouseState::Disabled && autoIconColor == AutoIconColor::None) { const auto& bgColor = listItemBackgroundColor(MouseState::Normal, selected, focus, active, optItem->index, w); - const auto premultipiedColor = getColorSourceOver(bgColor, actualFgColor); + const auto premultipiedColor = getColorSourceOver(bgColor, fgColor); const auto& tintedPixmap = getTintedPixmap(pixmap, premultipiedColor); const auto opacity = selected == SelectionState::Selected ? 0.3 : 0.25; const auto backupOpacity = p->opacity(); @@ -2152,7 +2158,7 @@ void QlementineStyle::drawControl(ControlElement ce, const QStyleOption* opt, QP p->drawPixmap(pixmapRect, tintedPixmap); p->setOpacity(backupOpacity); } else { - const auto& colorizedPixmap = colorize ? getColorizedPixmap(pixmap, actualFgColor) : pixmap; + const auto& colorizedPixmap = getColorizedPixmap(pixmap, autoIconColor, fgColor, textColor); auto iconRect = subElementRect(SE_ItemViewItemDecoration, optItem, w); iconRect.moveLeft(pixmapRect.left()); p->drawPixmap(iconRect, colorizedPixmap); @@ -2170,7 +2176,7 @@ void QlementineStyle::drawControl(ControlElement ce, const QStyleOption* opt, QP | (textAlignment.testFlag(Qt::AlignRight) ? Qt::AlignRight : Qt::AlignLeft); p->setFont(optItem->font); p->setBrush(Qt::NoBrush); - p->setPen(actualFgColor); + p->setPen(textColor); p->drawText(textRect, int(textFlags), elidedText, nullptr); } } @@ -2616,8 +2622,8 @@ void QlementineStyle::drawComplexControl( if (qobject_cast(w)) { const auto pixelRatio = getPixelRatio(w); const auto& icon = _impl->getStandardIconExt(StandardPixmapExt::SP_Calendar, indicatorSize * pixelRatio); - const auto colorize = - QlementineStyle::isAutoIconColorEnabled() && QlementineStyle::isAutoIconColorEnabled(w); + const auto autoIconColor = this->autoIconColor(w); + const auto colorize = autoIconColor != AutoIconColor::None; drawIcon(indicatorRect, p, icon, mouse, CheckState::Checked, w, colorize, currentFgColor); } else { p->setBrush(Qt::NoBrush); @@ -4955,8 +4961,7 @@ void QlementineStyle::drawPrimitiveExt( if (!pixmap.isNull() && !iconRect.isEmpty()) { const auto& iconColor = commandButtonIconColor(mouse, role); - const auto colorize = isAutoIconColorEnabled(w); - const auto& colorizedPixmap = colorize ? getColorizedPixmap(pixmap, iconColor) : pixmap; + const auto& colorizedPixmap = getColorizedPixmap(pixmap, autoIconColor(w), iconColor, iconColor); // The pixmap may be smaller than the requested size, so we center it in the rect by default. const auto pixmapPixelRatio = colorizedPixmap.devicePixelRatio(); @@ -5397,16 +5402,16 @@ QColor const& QlementineStyle::listItemForegroundColor( } } -// Returns whether an icon in an item view should be colorized with the foreground color. +// Returns whether an icon in an item view should be colorized with a color. // Subclasses can override this to customize the behavior depending on the index or state. -bool QlementineStyle::listItemIsAutoIconColorEnabled(MouseState const mouse, SelectionState const selected, +AutoIconColor QlementineStyle::listItemAutoIconColor(MouseState const mouse, SelectionState const selected, FocusState const focus, ActiveState const active, const QModelIndex& index, const QWidget* widget) const { Q_UNUSED(mouse) Q_UNUSED(selected) Q_UNUSED(focus) Q_UNUSED(active) Q_UNUSED(index) - return isAutoIconColorEnabled(widget); + return autoIconColor(widget); } QColor const& QlementineStyle::listItemCaptionForegroundColor( diff --git a/lib/src/widgets/IconWidget.cpp b/lib/src/widgets/IconWidget.cpp index 44f4e58..f74f95d 100644 --- a/lib/src/widgets/IconWidget.cpp +++ b/lib/src/widgets/IconWidget.cpp @@ -86,15 +86,14 @@ QSize IconWidget::sizeHint() const { void IconWidget::paintEvent(QPaintEvent*) { const auto* qlementineStyle = qobject_cast(style()); - const auto autoColorize = qlementineStyle && qlementineStyle->isAutoIconColorEnabled(this); - const auto iconMode = isEnabled() || autoColorize ? QIcon::Mode::Normal : QIcon::Mode::Disabled; + const auto autoIconColor = qlementineStyle ? qlementineStyle->autoIconColor(this) : AutoIconColor::None; + const auto iconMode = isEnabled() || autoIconColor != AutoIconColor::None ? QIcon::Mode::Normal : QIcon::Mode::Disabled; const auto pixmap = _icon.pixmap(_iconSize.height(), iconMode, QIcon::State::Off); if (pixmap.isNull()) return; - const auto& colorizedPixmap = autoColorize ? colorizePixmap(pixmap, - palette().color(isEnabled() ? QPalette::Normal : QPalette::Disabled, QPalette::Text)) - : pixmap; + const auto color = palette().color(isEnabled() ? QPalette::Normal : QPalette::Disabled, QPalette::Text); + const auto& colorizedPixmap = autoIconColor != AutoIconColor::None ? colorizePixmap(pixmap, color) : pixmap; QPainter p(this); p.setRenderHint(QPainter::Antialiasing, true); diff --git a/lib/src/widgets/LineEdit.cpp b/lib/src/widgets/LineEdit.cpp index df917ba..7950a3a 100644 --- a/lib/src/widgets/LineEdit.cpp +++ b/lib/src/widgets/LineEdit.cpp @@ -89,8 +89,8 @@ QPixmap LineEdit::getPixmap() const { const auto iconSize = QSize{ iconExtent, iconExtent }; const auto* qlementineStyle = qobject_cast(style()); - const auto autoColorize = qlementineStyle && qlementineStyle->isAutoIconColorEnabled(this); - if (autoColorize) { + const auto autoIconColor = qlementineStyle ? qlementineStyle->autoIconColor(this) : AutoIconColor::None; + if (autoIconColor != AutoIconColor::None) { const auto pixmap = qlementine::getPixmap(_icon, iconSize, MouseState::Normal, CheckState::NotChecked, this); const auto colorGroup = isEnabled() ? QPalette::ColorGroup::Normal : QPalette::ColorGroup::Disabled; const auto& color = palette().color(colorGroup, QPalette::ColorRole::Text); From 61a558e45ed110104bc192800093119b4a464cd7 Mon Sep 17 00:00:00 2001 From: Christophe Thiery Date: Mon, 30 Oct 2023 17:03:59 +0100 Subject: [PATCH 2/7] Make auto-icon color property inherit the one from parent widgets --- lib/include/oclero/qlementine/utils/ImageUtils.hpp | 2 +- lib/src/style/QlementineStyle.cpp | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/lib/include/oclero/qlementine/utils/ImageUtils.hpp b/lib/include/oclero/qlementine/utils/ImageUtils.hpp index 3508a98..b3c0604 100644 --- a/lib/include/oclero/qlementine/utils/ImageUtils.hpp +++ b/lib/include/oclero/qlementine/utils/ImageUtils.hpp @@ -91,7 +91,7 @@ enum class ColorizeMode { enum class AutoIconColor { // No automatic icon recolorization. None, - // Recoloize with the foreground color. + // Recolorize with the foreground color. ForegroundColor, // Recolorize with the current text color, which might be different from the foreground color // if the text color was customized in the palette. diff --git a/lib/src/style/QlementineStyle.cpp b/lib/src/style/QlementineStyle.cpp index a424a18..19d949d 100644 --- a/lib/src/style/QlementineStyle.cpp +++ b/lib/src/style/QlementineStyle.cpp @@ -292,10 +292,10 @@ AutoIconColor QlementineStyle::autoIconColor() const { } // Sets automatic icon colorization for a specific widget. -// This overrides the default value from autoIconColorEnabled(). -void QlementineStyle::setAutoIconColor(QWidget* widget, AutoIconColor mode) { +// This overrides the default value from ist parent or from autoIconColorEnabled(). +void QlementineStyle::setAutoIconColor(QWidget* widget, AutoIconColor autoIconColor) { if (widget) { - widget->setProperty(Property_AutoIconColor, QVariant::fromValue(mode)); + widget->setProperty(Property_AutoIconColor, QVariant::fromValue(autoIconColor)); } } @@ -305,7 +305,7 @@ AutoIconColor QlementineStyle::autoIconColor(const QWidget* widget) const { } const auto property = widget->property(Property_AutoIconColor); if (!property.isValid()) { - return autoIconColor(); + return autoIconColor(widget->parentWidget()); } return property.value(); } From 1455888f6d959daba76d2ac4bee5251a21dc1198 Mon Sep 17 00:00:00 2001 From: Christophe Thiery Date: Mon, 30 Oct 2023 17:04:27 +0100 Subject: [PATCH 3/7] Always recolorize calendar button icon --- lib/src/style/QlementineStyle.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/lib/src/style/QlementineStyle.cpp b/lib/src/style/QlementineStyle.cpp index 19d949d..e77ca9f 100644 --- a/lib/src/style/QlementineStyle.cpp +++ b/lib/src/style/QlementineStyle.cpp @@ -2622,8 +2622,7 @@ void QlementineStyle::drawComplexControl( if (qobject_cast(w)) { const auto pixelRatio = getPixelRatio(w); const auto& icon = _impl->getStandardIconExt(StandardPixmapExt::SP_Calendar, indicatorSize * pixelRatio); - const auto autoIconColor = this->autoIconColor(w); - const auto colorize = autoIconColor != AutoIconColor::None; + const auto colorize = true; drawIcon(indicatorRect, p, icon, mouse, CheckState::Checked, w, colorize, currentFgColor); } else { p->setBrush(Qt::NoBrush); From b2bef2de268cf2c5f44de713859ef9c66581ab40 Mon Sep 17 00:00:00 2001 From: Christophe Thiery Date: Tue, 31 Oct 2023 16:14:22 +0100 Subject: [PATCH 4/7] Simplify code --- lib/src/style/QlementineStyle.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/lib/src/style/QlementineStyle.cpp b/lib/src/style/QlementineStyle.cpp index e77ca9f..bd4863f 100644 --- a/lib/src/style/QlementineStyle.cpp +++ b/lib/src/style/QlementineStyle.cpp @@ -2622,8 +2622,7 @@ void QlementineStyle::drawComplexControl( if (qobject_cast(w)) { const auto pixelRatio = getPixelRatio(w); const auto& icon = _impl->getStandardIconExt(StandardPixmapExt::SP_Calendar, indicatorSize * pixelRatio); - const auto colorize = true; - drawIcon(indicatorRect, p, icon, mouse, CheckState::Checked, w, colorize, currentFgColor); + drawIcon(indicatorRect, p, icon, mouse, CheckState::Checked, w, true, currentFgColor); } else { p->setBrush(Qt::NoBrush); p->setPen(QPen(currentFgColor, iconPenWidth, Qt::SolidLine, Qt::FlatCap)); From 5ea1412bcd826dbf366c0425554e9c9ce1233f7f Mon Sep 17 00:00:00 2001 From: Christophe Thiery Date: Tue, 7 Nov 2023 08:48:31 +0100 Subject: [PATCH 5/7] Fix IconWidget paint coordinates On my screen it was trying to draw at -16,-16. iconSize() is 32,32 but colorizedPixmap.size() is 64,64 due to device pixel ratio. --- lib/src/widgets/IconWidget.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/src/widgets/IconWidget.cpp b/lib/src/widgets/IconWidget.cpp index f74f95d..71eaab8 100644 --- a/lib/src/widgets/IconWidget.cpp +++ b/lib/src/widgets/IconWidget.cpp @@ -97,8 +97,8 @@ void IconWidget::paintEvent(QPaintEvent*) { QPainter p(this); p.setRenderHint(QPainter::Antialiasing, true); - const auto x = (width() - colorizedPixmap.width()) / 2; - const auto y = (height() - colorizedPixmap.height()) / 2; + const auto x = (width() - _iconSize.width()) / 2; + const auto y = (height() - _iconSize.height()) / 2; p.drawPixmap(x, y, colorizedPixmap); } } // namespace oclero::qlementine From e0632c51ad249aac593a120eb1021a394d72af34 Mon Sep 17 00:00:00 2001 From: Christophe Thiery Date: Tue, 7 Nov 2023 18:25:19 +0100 Subject: [PATCH 6/7] Fix build issue --- lib/src/style/QlementineStyle.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/src/style/QlementineStyle.cpp b/lib/src/style/QlementineStyle.cpp index bd4863f..69ab101 100644 --- a/lib/src/style/QlementineStyle.cpp +++ b/lib/src/style/QlementineStyle.cpp @@ -320,6 +320,7 @@ QPixmap QlementineStyle::getColorizedPixmap(const QPixmap& input, AutoIconColor case AutoIconColor::TextColor: return qlementine::getColorizedPixmap(input, textColor); } + return input; } QIcon QlementineStyle::makeIcon(const QString& svgPath) { From eed65fe024edbe2cfaec6e5d957f81b6423a3ae8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Olivier=20Cl=C3=A9ro?= Date: Sat, 11 Nov 2023 01:02:14 +0000 Subject: [PATCH 7/7] Fix sandbox compilation (autoIconColor changes) --- sandbox/src/SandboxWindow.cpp | 9 ++++----- sandbox/src/main.cpp | 2 +- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/sandbox/src/SandboxWindow.cpp b/sandbox/src/SandboxWindow.cpp index c27b7eb..0abcca1 100644 --- a/sandbox/src/SandboxWindow.cpp +++ b/sandbox/src/SandboxWindow.cpp @@ -627,8 +627,7 @@ struct SandboxWindow::Impl { tableView->setSortingEnabled(true); if (auto* qlementineStyle = qobject_cast(tableView->style())) { - qlementineStyle->setAutoIconColorEnabled(false); - qlementineStyle->setAutoIconColorEnabled(tableView, false); + qlementineStyle->setAutoIconColor(tableView, oclero::qlementine::AutoIconColor::None); } constexpr auto columnCount = 3; @@ -678,7 +677,7 @@ struct SandboxWindow::Impl { treeWidget->setColumnCount(1); treeWidget->setHeaderHidden(true); treeWidget->setSelectionBehavior(QAbstractItemView::SelectRows); - qlementineStyle->setAutoIconColorEnabled(treeWidget, false); + qlementineStyle->setAutoIconColor(treeWidget, oclero::qlementine::AutoIconColor::None); for (auto i = 0; i < 3; ++i) { auto* root = new QTreeWidgetItem(treeWidget); @@ -872,7 +871,7 @@ struct SandboxWindow::Impl { auto* tabBar = new QTabBar(windowContent); tabBar->setFocusPolicy(Qt::NoFocus); tabBar->setSizePolicy(QSizePolicy::Ignored, QSizePolicy::Fixed); - qlementineStyle->setAutoIconColorEnabled(tabBar, false); + qlementineStyle->setAutoIconColor(tabBar, oclero::qlementine::AutoIconColor::None); // QTabBar features. tabBar->setTabsClosable(true); @@ -1051,7 +1050,7 @@ Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deseru treeWidget->setHeaderHidden(true); treeWidget->setSelectionBehavior(QAbstractItemView::SelectRows); treeWidget->setSelectionMode(QAbstractItemView::SelectionMode::ExtendedSelection); - qlementineStyle->setAutoIconColorEnabled(treeWidget, false); + qlementineStyle->setAutoIconColor(treeWidget, oclero::qlementine::AutoIconColor::None); for (auto i = 0; i < 3; ++i) { auto* root = new QTreeWidgetItem(treeWidget); diff --git a/sandbox/src/main.cpp b/sandbox/src/main.cpp index 23e9c8c..448ad96 100644 --- a/sandbox/src/main.cpp +++ b/sandbox/src/main.cpp @@ -35,7 +35,7 @@ int main(int argc, char* argv[]) { auto* const style = new oclero::qlementine::QlementineStyle(&qApplication); style->setAnimationsEnabled(true); style->setUseMenuForComboBoxPopup(false); - style->setAutoIconColorEnabled(true); + style->setAutoIconColor(oclero::qlementine::AutoIconColor::TextColor); style->setThemeJsonPath(QStringLiteral(":/light.json")); qApplication.setStyle(style); #endif