From 80934fa07fc23df94359318a874f5d9c2c156c8b Mon Sep 17 00:00:00 2001 From: Uwe Rathmann Date: Fri, 25 Oct 2024 18:56:02 +0200 Subject: [PATCH] QskCheckBox::Halo replaced by using a box shadow --- designsystems/material3/QskMaterial3Skin.cpp | 127 ++++++++++--------- src/controls/QskCheckBox.cpp | 1 - src/controls/QskCheckBox.h | 2 +- src/controls/QskCheckBoxSkinlet.cpp | 23 +--- src/controls/QskCheckBoxSkinlet.h | 2 - 5 files changed, 71 insertions(+), 84 deletions(-) diff --git a/designsystems/material3/QskMaterial3Skin.cpp b/designsystems/material3/QskMaterial3Skin.cpp index 5fe6ef31..c440e193 100644 --- a/designsystems/material3/QskMaterial3Skin.cpp +++ b/designsystems/material3/QskMaterial3Skin.cpp @@ -194,83 +194,95 @@ namespace void Editor::setupCheckBox() { - // skin hints are ordered according to - // https://m3.material.io/components/checkbox/specs - using Q = QskCheckBox; + using A = QskAspect; + + // == metrics setSpacing( Q::Panel, 40_dp ); - setStrutSize( Q::Box, 18_dp, 18_dp ); - setBoxShape( Q::Box, 2_dp ); - - setBoxBorderColors( Q::Box, m_pal.onSurface ); -#if 1 - // hack: if border metrics == box shape, alpha value will be discarded - setBoxBorderMetrics( Q::Box, 1.99_dp ); -#endif - - setGradient( Q::Box, m_pal.background ); // not mentioned in the specs, but needed for animation - setGradient( Q::Box | Q::Checked, m_pal.primary ); - setBoxBorderMetrics( Q::Box | Q::Checked, 0 ); - - setPadding( Q::Box, 3_dp ); // "icon size" - - setGraphicRole( Q::Indicator, QskMaterial3Skin::GraphicRoleOnPrimary ); - - setBoxBorderColors( Q::Box | Q::Error, m_pal.error ); - - setGradient( Q::Box | Q::Checked | Q::Error, m_pal.error ); - - setGraphicRole( Q::Indicator | Q::Error, QskMaterial3Skin::GraphicRoleOnError ); - - const auto checkMark = symbol( "check_small" ); - for ( auto state : { QskAspect::NoState, Q::Disabled } ) { - const auto aspect = Q::Indicator | Q::Checked | state; - setSymbol( aspect, checkMark ); - setSymbol( aspect | Q::Error, checkMark ); + setStrutSize( Q::Box, 18_dp, 18_dp ); + setBoxBorderMetrics( Q::Box, 2_dp ); + setBoxShape( Q::Box, 2_dp ); + setPadding( Q::Box, 3_dp ); // "icon size" + + QskShadowMetrics shadowMetrics( 12_dp, 0.0 ); + shadowMetrics.setShapeMode( QskShadowMetrics::Ellipse ); + setShadowMetrics( Q::Box, shadowMetrics ); } - setStrutSize( Q::Halo, 40_dp, 40_dp ); - setBoxShape( Q::Halo, 100, Qt::RelativeSize ); - setGradient( Q::Halo, Qt::transparent ); + { + setGraphicRole( Q::Indicator, QskMaterial3Skin::GraphicRoleOnPrimary ); + setGraphicRole( Q::Indicator | Q::Error, QskMaterial3Skin::GraphicRoleOnError ); + setGraphicRole( Q::Indicator | Q::Disabled | Q::Checked, + QskMaterial3Skin::GraphicRoleSurface ); + + const auto checkMark = symbol( "check_small" ); + for ( auto state : { A::NoState, Q::Disabled } ) + { + const auto aspect = Q::Indicator | Q::Checked | state; + setSymbol( aspect, checkMark ); + setSymbol( aspect | Q::Error, checkMark ); + } + } + + // === colors setColor( Q::Text, m_pal.onBackground ); // not mentioned in the specs - // States + for ( auto state1 : { Q::Hovered, Q::Focused, Q::Pressed } ) + { + const auto opacity = m_pal.stateOpacity( state1 ); - // 2. Disabled + for ( auto state2 : { A::NoState, Q::Checked } ) + { + const auto aspect = Q::Box | state1 | state2; - setBoxBorderColors( Q::Box | Q::Disabled, m_pal.onSurface38 ); - setBoxShape( Q::Box | Q::Disabled, 2_dp ); + const auto rgb = ( state2 == Q::Checked ) ? m_pal.primary : m_pal.onSurface; + setShadowColor( aspect, stateLayerColor( rgb, opacity ) ); - setGradient( Q::Box | Q::Disabled | Q::Checked, m_pal.onSurface38 ); - setGradient( Q::Box | Q::Disabled | Q::Checked | Q::Error, m_pal.onSurface38 ); + setShadowColor( aspect | Q::Error, stateLayerColor( m_pal.error, opacity ) ); + } + } - setGraphicRole( Q::Indicator | Q::Disabled | Q::Checked, QskMaterial3Skin::GraphicRoleSurface ); + for ( auto state1 : { A::NoState, Q::Disabled, Q::Hovered, Q::Focused, Q::Pressed } ) + { + for ( auto state2 : { A::NoState, Q::Checked } ) + { + const auto aspect = Q::Box | state1 | state2; - // 3. Hovered + QRgb rgb, rgbError; - setGradient( Q::Halo | Q::Hovered | Q::Checked, m_pal.primary8 ); - setGradient( Q::Halo | Q::Hovered, m_pal.onSurface8 ); - setGradient( Q::Halo | Q::Error | Q::Hovered, m_pal.error8 ); - setGradient( Q::Halo | Q::Error | Q::Hovered | Q::Checked, m_pal.error8 ); + if ( state1 == A::NoState ) + { + rgb = ( state2 == Q::Checked ) + ? m_pal.primary : m_pal.onSurfaceVariant; - // 4. Focused + rgbError = m_pal.error; + } + else if ( state1 == Q::Disabled ) + { + rgb = rgbError = m_pal.onSurface38; + } + else + { + rgb = ( state2 == Q::Checked ) + ? m_pal.primary : m_pal.onSurfaceVariant; - setGradient( Q::Halo | Q::Focused | Q::Checked, m_pal.primary12 ); - setGradient( Q::Halo | Q::Focused, m_pal.onSurface12 ); - setGradient( Q::Halo | Q::Error | Q::Focused, m_pal.error12 ); - setGradient( Q::Halo | Q::Error | Q::Focused | Q::Checked, m_pal.error12 ); + rgbError = m_pal.error; + } - // 5. Pressed + setBoxBorderColors( aspect, rgb ); + setBoxBorderColors( aspect | Q::Error, rgbError ); - setGradient( Q::Halo | Q::Pressed, m_pal.primary12 ); - setGradient( Q::Halo | Q::Pressed | Q::Checked, m_pal.primary12 ); - setGradient( Q::Halo | Q::Hovered | Q::Pressed, m_pal.primary12 ); - setGradient( Q::Halo | Q::Error | Q::Pressed, m_pal.error12 ); - setGradient( Q::Halo | Q::Error | Q::Pressed | Q::Checked, m_pal.error12 ); + if ( state2 == Q::Checked ) + { + setGradient( aspect, rgb ); + setGradient( aspect | Q::Error, rgbError ); + } + } + } } void Editor::setupComboBox() @@ -1045,7 +1057,6 @@ void Editor::setupSwitchButton() } } - setGradient( Q::Handle | Q::Disabled, m_pal.onSurface38 ); setGradient( Q::Handle | Q::Disabled | Q::Checked, m_pal.surface ); diff --git a/src/controls/QskCheckBox.cpp b/src/controls/QskCheckBox.cpp index c457c9fc..3d42f02b 100644 --- a/src/controls/QskCheckBox.cpp +++ b/src/controls/QskCheckBox.cpp @@ -9,7 +9,6 @@ QSK_SUBCONTROL( QskCheckBox, Panel ) QSK_SUBCONTROL( QskCheckBox, Box ) QSK_SUBCONTROL( QskCheckBox, Indicator ) QSK_SUBCONTROL( QskCheckBox, Text ) -QSK_SUBCONTROL( QskCheckBox, Halo ) QSK_SYSTEM_STATE( QskCheckBox, Error, QskAspect::FirstSystemState << 1 ) diff --git a/src/controls/QskCheckBox.h b/src/controls/QskCheckBox.h index 2096ae75..6b5877b7 100644 --- a/src/controls/QskCheckBox.h +++ b/src/controls/QskCheckBox.h @@ -17,7 +17,7 @@ class QSK_EXPORT QskCheckBox : public QskAbstractButton using Inherited = QskAbstractButton; public: - QSK_SUBCONTROLS( Panel, Box, Indicator, Text, Halo ) + QSK_SUBCONTROLS( Panel, Box, Indicator, Text ) QSK_STATES( Error ) QskCheckBox( QQuickItem* parent = nullptr ); diff --git a/src/controls/QskCheckBoxSkinlet.cpp b/src/controls/QskCheckBoxSkinlet.cpp index 47193a8e..e279b97b 100644 --- a/src/controls/QskCheckBoxSkinlet.cpp +++ b/src/controls/QskCheckBoxSkinlet.cpp @@ -11,7 +11,7 @@ QskCheckBoxSkinlet::QskCheckBoxSkinlet( QskSkin* skin ) : QskSkinlet( skin ) { - setNodeRoles( { BoxRole, IndicatorRole, TextRole, HaloRole } ); + setNodeRoles( { BoxRole, IndicatorRole, TextRole } ); } QskCheckBoxSkinlet::~QskCheckBoxSkinlet() @@ -40,9 +40,6 @@ QRectF QskCheckBoxSkinlet::subControlRect( const QskSkinnable* skinnable, if ( subControl == Q::Text ) return textRect( checkBox, contentsRect ); - if ( subControl == Q::Halo ) - return haloRect( checkBox, contentsRect ); - return contentsRect; } @@ -83,21 +80,6 @@ QRectF QskCheckBoxSkinlet::boxRect( return r; } -QRectF QskCheckBoxSkinlet::haloRect( - const QskCheckBox* checkBox, const QRectF& rect ) const -{ - const auto haloSize = checkBox->strutSizeHint( QskCheckBox::Halo ); - const auto boxSize = checkBox->strutSizeHint( QskCheckBox::Box ); - - const auto w = ( haloSize.width() - boxSize.width() ) / 2; - const auto h = ( haloSize.height() - boxSize.height() ) / 2; - - auto r = boxRect( checkBox, rect ); - r = r.marginsAdded( { w, h, w, h } ); - - return r; -} - QSGNode* QskCheckBoxSkinlet::updateSubNode( const QskSkinnable* skinnable, quint8 nodeRole, QSGNode* node ) const { @@ -118,9 +100,6 @@ QSGNode* QskCheckBoxSkinlet::updateSubNode( case TextRole: return updateTextNode( checkBox, node ); - - case HaloRole: - return updateBoxNode( checkBox, node, Q::Halo ); } return Inherited::updateSubNode( skinnable, nodeRole, node ); diff --git a/src/controls/QskCheckBoxSkinlet.h b/src/controls/QskCheckBoxSkinlet.h index 60f46be5..c13b528c 100644 --- a/src/controls/QskCheckBoxSkinlet.h +++ b/src/controls/QskCheckBoxSkinlet.h @@ -23,7 +23,6 @@ class QSK_EXPORT QskCheckBoxSkinlet : public QskSkinlet BoxRole, IndicatorRole, TextRole, - HaloRole, RoleCount }; @@ -44,7 +43,6 @@ class QSK_EXPORT QskCheckBoxSkinlet : public QskSkinlet private: QRectF textRect( const QskCheckBox*, const QRectF& ) const; QRectF boxRect( const QskCheckBox*, const QRectF& ) const; - QRectF haloRect( const QskCheckBox*, const QRectF& ) const; QSGNode* updateTextNode( const QskCheckBox*, QSGNode* ) const; };