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

View File

@ -9,6 +9,7 @@
#include <QskBox.h>
#include <QskCheckBox.h>
#include <QskColorFilter.h>
#include <QskDialogButtonBox.h>
#include <QskFocusIndicator.h>
#include <QskFunctions.h>
@ -221,37 +222,75 @@ void Editor::setupControl()
void Editor::setupCheckBox()
{
// skin hints are ordered according to
// https://m3.material.io/components/checkbox/specs
using Q = QskCheckBox;
setSpacing( Q::Panel, 40_dp );
setStrutSize( Q::Box, 24_dp, 24_dp );
setPadding( Q::Box, 4_dp );
setStrutSize( Q::Box, 18_dp, 18_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 );
setGradient( Q::Box, m_pal.background );
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 );
setPadding( Q::Box, 3_dp ); // "icon size"
setColor( Q::Indicator, m_pal.background );
setColor( Q::Indicator | Q::Checked, m_pal.onPrimary );
setColor( Q::Indicator | Q::Checked | Q::Disabled, m_pal.onSurface38 );
setGraphicRole( Q::Indicator, QskMaterial3Skin::GraphicRoleOnPrimary );
setColor( Q::Text, m_pal.onBackground );
setTextOptions( Q::Text, Qt::ElideMiddle, QskTextOptions::NoWrap );
setBoxBorderColors( Q::Box | Q::Error, m_pal.error );
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 );
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, 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 | 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()
@ -917,8 +956,8 @@ QskMaterial3Theme::QskMaterial3Theme( Lightness lightness )
{
}
QskMaterial3Theme::QskMaterial3Theme(Lightness lightness,
std::array<QskHctColor, NumPaletteTypes> palettes )
QskMaterial3Theme::QskMaterial3Theme( Lightness lightness,
std::array< QskHctColor, NumPaletteTypes > palettes )
: m_palettes( palettes )
{
if ( lightness == Light )
@ -991,6 +1030,9 @@ QskMaterial3Theme::QskMaterial3Theme(Lightness lightness,
primary8 = QskRgb::toTransparentF( primary, 0.08 );
primary12 = QskRgb::toTransparentF( primary, 0.12 );
error8 = QskRgb::toTransparentF( error, 0.08 );
error12 = QskRgb::toTransparentF( error, 0.12 );
surface1 = flattenedColor( primary, background, 0.05 );
surface2 = flattenedColor( primary, background, 0.08 );
surface3 = flattenedColor( primary, background, 0.11 );
@ -1027,6 +1069,7 @@ QskMaterial3Skin::QskMaterial3Skin( const QskMaterial3Theme& palette, QObject* p
addGraphicProvider( {}, new QskMaterial3GraphicProvder() );
setupFonts();
setupGraphicFilters( palette );
Editor editor( &hintTable(), palette );
editor.setup();
@ -1064,4 +1107,19 @@ void QskMaterial3Skin::setupFonts()
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"

View File

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

View File

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

View File

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

View File

@ -147,19 +147,6 @@ QSGNode* QskCheckBoxSkinlet::updateIndicatorNode(
}
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 );
}