From f4531c149c0259f1caf990e77d7e31151963d5a8 Mon Sep 17 00:00:00 2001 From: Peter Hartmann Date: Fri, 24 Feb 2023 15:37:31 +0100 Subject: [PATCH] color filter: Add option to substitute alpha value Resolves #253 --- skins/material3/QskMaterial3Skin.cpp | 9 +++++++ src/graphic/QskColorFilter.cpp | 38 ++++++++++++++++++---------- src/graphic/QskColorFilter.h | 4 +++ 3 files changed, 38 insertions(+), 13 deletions(-) diff --git a/skins/material3/QskMaterial3Skin.cpp b/skins/material3/QskMaterial3Skin.cpp index 5f716cbc..977cb650 100644 --- a/skins/material3/QskMaterial3Skin.cpp +++ b/skins/material3/QskMaterial3Skin.cpp @@ -670,6 +670,7 @@ void Editor::setupPushButton() setColor( Q::Text, m_pal.onPrimary ); setColor( Q::Text | Q::Disabled, m_pal.onSurface38 ); + setGraphicRole( Q::Graphic | Q::Disabled, QskMaterial3Skin::GraphicRoleOnSurface38 ); setTextOptions( Q::Text, Qt::ElideMiddle, QskTextOptions::NoWrap ); @@ -1337,34 +1338,42 @@ void QskMaterial3Skin::setupFonts() void QskMaterial3Skin::setupGraphicFilters( const QskMaterial3Theme& palette ) { QskColorFilter onPrimaryFilter; + onPrimaryFilter.setSubstituteAlphaValue( true ); onPrimaryFilter.addColorSubstitution( Qt::white, palette.onPrimary ); setGraphicFilter( GraphicRoleOnPrimary, onPrimaryFilter ); QskColorFilter onSecondaryContainerFilter; + onSecondaryContainerFilter.setSubstituteAlphaValue( true ); onSecondaryContainerFilter.addColorSubstitution( Qt::white, palette.onSecondaryContainer ); setGraphicFilter( GraphicRoleOnSecondaryContainer, onSecondaryContainerFilter ); QskColorFilter onErrorFilter; + onErrorFilter.setSubstituteAlphaValue( true ); onErrorFilter.addColorSubstitution( Qt::white, palette.onError ); setGraphicFilter( GraphicRoleOnError, onErrorFilter ); QskColorFilter onSurfaceFilter; + onSurfaceFilter.setSubstituteAlphaValue( true ); onSurfaceFilter.addColorSubstitution( Qt::white, palette.onSurface ); setGraphicFilter( GraphicRoleOnSurface, onSurfaceFilter ); QskColorFilter onSurfaceFilter38; + onSurfaceFilter38.setSubstituteAlphaValue( true ); onSurfaceFilter38.addColorSubstitution( Qt::white, palette.onSurface38 ); setGraphicFilter( GraphicRoleOnSurface38, onSurfaceFilter38 ); QskColorFilter onSurfaceVariantFilter; + onSurfaceVariantFilter.setSubstituteAlphaValue( true ); onSurfaceVariantFilter.addColorSubstitution( Qt::white, palette.onSurfaceVariant ); setGraphicFilter( GraphicRoleOnSurfaceVariant, onSurfaceVariantFilter ); QskColorFilter primaryFilter; + primaryFilter.setSubstituteAlphaValue( true ); primaryFilter.addColorSubstitution( Qt::white, palette.primary ); setGraphicFilter( GraphicRolePrimary, primaryFilter ); QskColorFilter surfaceFilter; + surfaceFilter.setSubstituteAlphaValue( true ); surfaceFilter.addColorSubstitution( Qt::white, palette.surface ); setGraphicFilter( GraphicRoleSurface, surfaceFilter ); } diff --git a/src/graphic/QskColorFilter.cpp b/src/graphic/QskColorFilter.cpp index e6094bd3..ab931545 100644 --- a/src/graphic/QskColorFilter.cpp +++ b/src/graphic/QskColorFilter.cpp @@ -11,19 +11,21 @@ #include static inline QRgb qskSubstitutedRgb( - const QVector< QPair< QRgb, QRgb > >& substitions, QRgb rgba ) + const QVector< QPair< QRgb, QRgb > >& substitions, QRgb rgba, bool substituteAlpha ) { // usually we have 2-3 substitutions, so we can simply iterate // and don't need to introduce some sort of sorting or search index - const QRgb rgb = rgba | QskRgb::AlphaMask; + const QRgb rgb = substituteAlpha ? rgba : ( rgba | QskRgb::AlphaMask ); for ( const auto& s : substitions ) { if ( rgb == s.first ) { - return ( s.second & QskRgb::ColorMask ) | - ( rgba & QskRgb::AlphaMask ); + const auto ret = substituteAlpha ? s.second + : ( s.second & QskRgb::ColorMask ) + | ( rgba & QskRgb::AlphaMask ); + return ret; } } @@ -31,13 +33,13 @@ static inline QRgb qskSubstitutedRgb( } static inline QColor qskSubstitutedColor( - const QVector< QPair< QRgb, QRgb > >& substitions, const QColor& color ) + const QVector< QPair< QRgb, QRgb > >& substitions, const QColor& color, bool substituteAlpha ) { - return QColor::fromRgba( qskSubstitutedRgb( substitions, color.rgba() ) ); + return QColor::fromRgba( qskSubstitutedRgb( substitions, color.rgba(), substituteAlpha ) ); } static inline QBrush qskSubstitutedBrush( - const QVector< QPair< QRgb, QRgb > >& substitions, const QBrush& brush ) + const QVector< QPair< QRgb, QRgb > >& substitions, const QBrush& brush, bool substituteAlpha ) { QBrush newBrush; @@ -48,7 +50,7 @@ static inline QBrush qskSubstitutedBrush( auto stops = gradient->stops(); for ( auto& stop : stops ) { - const QColor c = qskSubstitutedColor( substitions, stop.second ); + const QColor c = qskSubstitutedColor( substitions, stop.second, substituteAlpha ); if ( c != stop.second ) { stop.second = c; @@ -66,7 +68,7 @@ static inline QBrush qskSubstitutedBrush( } else { - const QColor c = qskSubstitutedColor( substitions, brush.color() ); + const QColor c = qskSubstitutedColor( substitions, brush.color(), substituteAlpha ); if ( c != brush.color() ) { newBrush = brush; @@ -166,7 +168,7 @@ QPen QskColorFilter::substituted( const QPen& pen ) const if ( m_substitutions.isEmpty() || pen.style() == Qt::NoPen ) return pen; - const auto newBrush = qskSubstitutedBrush( m_substitutions, pen.brush() ); + const auto newBrush = qskSubstitutedBrush( m_substitutions, pen.brush(), m_substituteAlphaValue ); if ( newBrush.style() == Qt::NoBrush ) return pen; @@ -180,18 +182,28 @@ QBrush QskColorFilter::substituted( const QBrush& brush ) const if ( m_substitutions.isEmpty() || brush.style() == Qt::NoBrush ) return brush; - const auto newBrush = qskSubstitutedBrush( m_substitutions, brush ); + const auto newBrush = qskSubstitutedBrush( m_substitutions, brush, m_substituteAlphaValue ); return ( newBrush.style() != Qt::NoBrush ) ? newBrush : brush; } QColor QskColorFilter::substituted( const QColor& color ) const { - return qskSubstitutedColor( m_substitutions, color ); + return qskSubstitutedColor( m_substitutions, color, m_substituteAlphaValue ); } QRgb QskColorFilter::substituted( const QRgb& rgb ) const { - return qskSubstitutedRgb( m_substitutions, rgb ); + return qskSubstitutedRgb( m_substitutions, rgb, m_substituteAlphaValue ); +} + +bool QskColorFilter::substituteAlphaValue() const noexcept +{ + return m_substituteAlphaValue; +} + +void QskColorFilter::setSubstituteAlphaValue( bool on ) +{ + m_substituteAlphaValue = on; } QskColorFilter QskColorFilter::interpolated( diff --git a/src/graphic/QskColorFilter.h b/src/graphic/QskColorFilter.h index 92bb9999..dedac055 100644 --- a/src/graphic/QskColorFilter.h +++ b/src/graphic/QskColorFilter.h @@ -37,6 +37,9 @@ class QSK_EXPORT QskColorFilter bool isIdentity() const noexcept; + bool substituteAlphaValue() const noexcept; + void setSubstituteAlphaValue( bool ); + bool operator==( const QskColorFilter& other ) const noexcept; bool operator!=( const QskColorFilter& other ) const noexcept; @@ -51,6 +54,7 @@ class QSK_EXPORT QskColorFilter private: QVector< QPair< QRgb, QRgb > > m_substitutions; + bool m_substituteAlphaValue = false; }; inline bool QskColorFilter::isIdentity() const noexcept