CheckBox: Add error state and style for material

This commit is contained in:
Peter Hartmann 2023-01-08 18:22:33 +01:00 committed by uwerat
parent 4352410128
commit 3b45b90011
6 changed files with 93 additions and 32 deletions

View File

@ -84,7 +84,7 @@ namespace
{ {
public: public:
CheckButtonBox( QQuickItem* parent = nullptr ) CheckButtonBox( QQuickItem* parent = nullptr )
: QskLinearBox( Qt::Horizontal, parent ) : QskLinearBox( Qt::Horizontal, 2, parent )
{ {
setSpacing( 40 ); setSpacing( 40 );
setExtraSpacingAt( Qt::LeftEdge | Qt::RightEdge | Qt::BottomEdge ); setExtraSpacingAt( Qt::LeftEdge | Qt::RightEdge | Qt::BottomEdge );
@ -94,6 +94,9 @@ namespace
auto button2 = new QskCheckBox( "Options 2", this ); auto button2 = new QskCheckBox( "Options 2", this );
button2->setLayoutMirroring( true ); button2->setLayoutMirroring( true );
auto button3 = new QskCheckBox( "Error", this );
button3->setSkinStateFlag( QskCheckBox::Error );
} }
}; };
} }

View File

@ -9,6 +9,7 @@
#include <QskBox.h> #include <QskBox.h>
#include <QskCheckBox.h> #include <QskCheckBox.h>
#include <QskColorFilter.h>
#include <QskDialogButtonBox.h> #include <QskDialogButtonBox.h>
#include <QskFocusIndicator.h> #include <QskFocusIndicator.h>
#include <QskFunctions.h> #include <QskFunctions.h>
@ -221,37 +222,75 @@ void Editor::setupControl()
void Editor::setupCheckBox() void Editor::setupCheckBox()
{ {
// skin hints are ordered according to
// https://m3.material.io/components/checkbox/specs
using Q = QskCheckBox; using Q = QskCheckBox;
setSpacing( Q::Panel, 40_dp ); setSpacing( Q::Panel, 40_dp );
setStrutSize( Q::Box, 24_dp, 24_dp ); setStrutSize( Q::Box, 18_dp, 18_dp );
setPadding( Q::Box, 4_dp );
setBoxShape( Q::Box, 2_dp ); setBoxShape( Q::Box, 2_dp );
setBoxBorderMetrics( Q::Box, 2_dp );
setBoxBorderColors( Q::Box, m_pal.onBackground ); 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 ); setBoxBorderMetrics( Q::Box | Q::Checked, 0 );
setGradient( Q::Box, m_pal.background ); setPadding( Q::Box, 3_dp ); // "icon size"
setGradient( Q::Box | Q::Checked, m_pal.primary );
setGradient( Q::Box | Q::Disabled, m_pal.surfaceVariant12 );
setGradient( Q::Box | Q::Checked | Q::Disabled, m_pal.onSurface12 );
setColor( Q::Indicator, m_pal.background ); setGraphicRole( Q::Indicator, QskMaterial3Skin::GraphicRoleOnPrimary );
setColor( Q::Indicator | Q::Checked, m_pal.onPrimary );
setColor( Q::Indicator | Q::Checked | Q::Disabled, m_pal.onSurface38 );
setColor( Q::Text, m_pal.onBackground ); setBoxBorderColors( Q::Box | Q::Error, m_pal.error );
setTextOptions( Q::Text, Qt::ElideMiddle, QskTextOptions::NoWrap );
setStrutSize( Q::Ripple, { 53.33_dp, 53.33_dp } ); setGradient( Q::Box | Q::Checked | Q::Error, m_pal.error );
setGraphicRole( Q::Indicator | Q::Error, QskMaterial3Skin::GraphicRoleOnError );
setStrutSize( Q::Ripple, { 40_dp, 40_dp } );
setBoxShape( Q::Ripple, 100, Qt::RelativeSize ); setBoxShape( Q::Ripple, 100, Qt::RelativeSize );
setGradient( Q::Ripple, Qt::transparent ); setGradient( Q::Ripple, Qt::transparent );
setColor( Q::Text, m_pal.onBackground ); // not mentioned in the specs
// States
// 2. Disabled
setBoxBorderColors( Q::Box | Q::Disabled, m_pal.onSurface38 );
setBoxShape( Q::Box | Q::Disabled, 2_dp );
setGradient( Q::Box | Q::Disabled | Q::Checked, m_pal.onSurface38 );
setGradient( Q::Box | Q::Disabled | Q::Checked | Q::Error, m_pal.onSurface38 );
setGraphicRole( Q::Indicator | Q::Disabled | Q::Checked, QskMaterial3Skin::GraphicRoleSurface );
// 3. Hovered
setGradient( Q::Ripple | Q::Hovered | Q::Checked, m_pal.primary8 ); setGradient( Q::Ripple | Q::Hovered | Q::Checked, m_pal.primary8 );
setGradient( Q::Ripple | Q::Hovered, m_pal.onSurface8 ); setGradient( Q::Ripple | Q::Hovered, m_pal.onSurface8 );
setGradient( Q::Ripple | Q::Hovered | Q::Pressed, m_pal.primary12 ); setGradient( Q::Ripple | Q::Error | Q::Hovered, m_pal.error8 );
setGradient( Q::Ripple | Q::Error | Q::Hovered | Q::Checked, m_pal.error8 );
// 4. Focused
setGradient( Q::Ripple | Q::Focused | Q::Checked, m_pal.primary12 );
setGradient( Q::Ripple | Q::Focused, m_pal.onSurface12 );
setGradient( Q::Ripple | Q::Error | Q::Focused, m_pal.error12 );
setGradient( Q::Ripple | Q::Error | Q::Focused | Q::Checked, m_pal.error12 );
// 5. Pressed
setGradient( Q::Ripple | Q::Pressed, m_pal.primary12 ); setGradient( Q::Ripple | Q::Pressed, m_pal.primary12 );
setGradient( Q::Ripple | Q::Pressed | Q::Checked, m_pal.primary12 );
setGradient( Q::Ripple | Q::Hovered | Q::Pressed, m_pal.primary12 );
setGradient( Q::Ripple | Q::Error | Q::Pressed, m_pal.error12 );
setGradient( Q::Ripple | Q::Error | Q::Pressed | Q::Checked, m_pal.error12 );
} }
void Editor::setupBox() void Editor::setupBox()
@ -991,6 +1030,9 @@ QskMaterial3Theme::QskMaterial3Theme(Lightness lightness,
primary8 = QskRgb::toTransparentF( primary, 0.08 ); primary8 = QskRgb::toTransparentF( primary, 0.08 );
primary12 = QskRgb::toTransparentF( primary, 0.12 ); primary12 = QskRgb::toTransparentF( primary, 0.12 );
error8 = QskRgb::toTransparentF( error, 0.08 );
error12 = QskRgb::toTransparentF( error, 0.12 );
surface1 = flattenedColor( primary, background, 0.05 ); surface1 = flattenedColor( primary, background, 0.05 );
surface2 = flattenedColor( primary, background, 0.08 ); surface2 = flattenedColor( primary, background, 0.08 );
surface3 = flattenedColor( primary, background, 0.11 ); surface3 = flattenedColor( primary, background, 0.11 );
@ -1027,6 +1069,7 @@ QskMaterial3Skin::QskMaterial3Skin( const QskMaterial3Theme& palette, QObject* p
addGraphicProvider( {}, new QskMaterial3GraphicProvder() ); addGraphicProvider( {}, new QskMaterial3GraphicProvder() );
setupFonts(); setupFonts();
setupGraphicFilters( palette );
Editor editor( &hintTable(), palette ); Editor editor( &hintTable(), palette );
editor.setup(); editor.setup();
@ -1064,4 +1107,19 @@ void QskMaterial3Skin::setupFonts()
setFont( M3LabelLarge, createFont( "Roboto Medium", 20_dp, 14_dp, 0.1, QFont::Medium ) ); setFont( M3LabelLarge, createFont( "Roboto Medium", 20_dp, 14_dp, 0.1, QFont::Medium ) );
} }
void QskMaterial3Skin::setupGraphicFilters( const QskMaterial3Theme& palette )
{
QskColorFilter onPrimaryFilter;
onPrimaryFilter.addColorSubstitution( Qt::white, palette.onPrimary );
setGraphicFilter( GraphicRoleOnPrimary, onPrimaryFilter );
QskColorFilter onErrorFilter;
onErrorFilter.addColorSubstitution( Qt::white, palette.onError );
setGraphicFilter( GraphicRoleOnError, onErrorFilter );
QskColorFilter surfaceFilter;
surfaceFilter.addColorSubstitution( Qt::white, palette.surface );
setGraphicFilter( GraphicRoleSurface, surfaceFilter );
}
#include "moc_QskMaterial3Skin.cpp" #include "moc_QskMaterial3Skin.cpp"

View File

@ -57,6 +57,8 @@ class QSK_MATERIAL3_EXPORT QskMaterial3Theme
QRgb onTertiaryContainer; QRgb onTertiaryContainer;
QRgb error; QRgb error;
QRgb error8;
QRgb error12;
QRgb onError; QRgb onError;
QRgb errorContainer; QRgb errorContainer;
QRgb onErrorContainer; QRgb onErrorContainer;
@ -120,6 +122,13 @@ class QSK_MATERIAL3_EXPORT QskMaterial3Skin : public QskSkin
virtual QskGraphic symbol( int symbolType ) const override; virtual QskGraphic symbol( int symbolType ) const override;
enum GraphicRole
{
GraphicRoleOnError,
GraphicRoleOnPrimary,
GraphicRoleSurface,
};
enum FontRole enum FontRole
{ {
M3BodyMedium = QskSkin::HugeFont + 1, M3BodyMedium = QskSkin::HugeFont + 1,
@ -130,6 +139,7 @@ class QSK_MATERIAL3_EXPORT QskMaterial3Skin : public QskSkin
private: private:
void setupFonts(); void setupFonts();
void setupGraphicFilters( const QskMaterial3Theme& palette );
}; };
#endif #endif

View File

@ -11,6 +11,8 @@ QSK_SUBCONTROL( QskCheckBox, Indicator )
QSK_SUBCONTROL( QskCheckBox, Text ) QSK_SUBCONTROL( QskCheckBox, Text )
QSK_SUBCONTROL( QskCheckBox, Ripple ) QSK_SUBCONTROL( QskCheckBox, Ripple )
QSK_SYSTEM_STATE( QskCheckBox, Error, QskAspect::FirstSystemState << 1 )
class QskCheckBox::PrivateData class QskCheckBox::PrivateData
{ {
public: public:

View File

@ -18,6 +18,7 @@ class QSK_EXPORT QskCheckBox : public QskAbstractButton
public: public:
QSK_SUBCONTROLS( Panel, Box, Indicator, Text, Ripple ) QSK_SUBCONTROLS( Panel, Box, Indicator, Text, Ripple )
QSK_STATES( Error )
QskCheckBox( QQuickItem* parent = nullptr ); QskCheckBox( QQuickItem* parent = nullptr );
QskCheckBox( const QString&, QQuickItem* parent = nullptr ); QskCheckBox( const QString&, QQuickItem* parent = nullptr );

View File

@ -147,19 +147,6 @@ QSGNode* QskCheckBoxSkinlet::updateIndicatorNode(
} }
auto graphic = checkBox->effectiveSkin()->symbol( symbol ); auto graphic = checkBox->effectiveSkin()->symbol( symbol );
#if 1
/*
Our default skins do not have the concept of colorRoles
implemented. Until then we do the recoloring manually here
*/
QskColorFilter filter;
filter.addColorSubstitution( Qt::black,
checkBox->color( QskCheckBox::Indicator ).rgba() );
graphic = QskGraphic::fromGraphic( graphic, filter );
#endif
return updateGraphicNode( checkBox, node, graphic, QskCheckBox::Indicator ); return updateGraphicNode( checkBox, node, graphic, QskCheckBox::Indicator );
} }