diff --git a/skins/material3/QskMaterial3Skin.cpp b/skins/material3/QskMaterial3Skin.cpp index c6ad860f..f593b841 100644 --- a/skins/material3/QskMaterial3Skin.cpp +++ b/skins/material3/QskMaterial3Skin.cpp @@ -9,10 +9,13 @@ #include #include +#include #include #include #include #include +#include +#include #include #include #include @@ -24,6 +27,7 @@ #include #include #include +#include #include #include #include @@ -44,6 +48,9 @@ #include #include +#include +#include + static const int qskDuration = 150; namespace @@ -90,6 +97,28 @@ namespace const QskMaterial3Theme& m_pal; }; + class Material3GraphicProvider final : public QskGraphicProvider + { + protected: + const QskGraphic* loadGraphic( const QString& id ) const override + { + static QString scope = QStringLiteral( ":/icons/" ); + const QString file = scope + id + QStringLiteral( "_24px.svg" ); + + QskGraphic graphic; + QSvgRenderer renderer; + + if ( renderer.load( file ) ) + { + QPainter painter( &graphic ); + renderer.render( &painter ); + painter.end(); + } + + return graphic.isNull() ? nullptr : new QskGraphic( graphic ); + } + }; + QFont createFont( int pixelSize, qreal tracking, QFont::Weight weight ) { QFont font( "Roboto" ); @@ -165,6 +194,7 @@ void Editor::setupControl() void Editor::setupCheckBox() { using Q = QskCheckBox; + using M3 = QskMaterial3Skin; setSpacing( Q::Panel, 10 ); @@ -174,16 +204,17 @@ void Editor::setupCheckBox() setBoxShape( Q::Box, 2 ); setBoxBorderMetrics( Q::Box, 2 ); setBoxBorderColors( Q::Box, m_pal.onBackground ); + setBoxBorderColors( Q::Box | Q::Disabled, stateLayerColor( m_pal.onBackground, m_pal.disabledContentOpacity ) ); 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 ); + setGradient( Q::Box | Q::Disabled, stateLayerColor( m_pal.surfaceVariant, m_pal.disabledContainerOpacity ) ); + setGradient( Q::Box | Q::Checked | Q::Disabled, stateLayerColor( m_pal.onSurface, m_pal.disabledContainerOpacity ) ); - 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, M3::GraphicRoleBackground ); + setGraphicRole( Q::Indicator | Q::Checked, M3::GraphicRoleOnPrimary ); + setGraphicRole( Q::Indicator | Q::Checked | Q::Disabled, M3::GraphicRoleOnSurfaceDisabled ); setColor( Q::Text, m_pal.onBackground ); } @@ -840,8 +871,8 @@ QskMaterial3Theme::QskMaterial3Theme( Lightness lightness ) { } -QskMaterial3Theme::QskMaterial3Theme(Lightness lightness, - std::array palettes ) +QskMaterial3Theme::QskMaterial3Theme( Lightness lightness, + std::array palettes ) : m_palettes( palettes ) { if ( lightness == Light ) @@ -931,7 +962,9 @@ QskMaterial3Theme::QskMaterial3Theme(Lightness lightness, QskMaterial3Skin::QskMaterial3Skin( const QskMaterial3Theme& palette, QObject* parent ) : Inherited( parent ) { + setupGraphicFilters( palette ); setupFonts(); + addGraphicProvider( "material3", new Material3GraphicProvider ); Editor editor( &hintTable(), palette ); editor.setup(); @@ -941,6 +974,41 @@ QskMaterial3Skin::~QskMaterial3Skin() { } +QskGraphic QskMaterial3Skin::symbol( int symbolType ) const +{ + switch( symbolType ) + { + case QskStandardSymbol::Cancel: + return Qsk::loadGraphic( "image://material3/cancel" ); + case QskStandardSymbol::Critical: + return Qsk::loadGraphic( "image://material3/error" ); + case QskStandardSymbol::CheckMark: + return Qsk::loadGraphic( "image://material3/check" ); + case QskStandardSymbol::CrossMark: + return {}; // not existant in Material + default: + return Inherited::symbol( symbolType ); + } +} + +void QskMaterial3Skin::setupGraphicFilters( const QskMaterial3Theme& palette ) +{ + QRgb defaultColor( 0xff1f1f1f ); + + QskColorFilter backgroundFilter; + backgroundFilter.addColorSubstitution( defaultColor, palette.background ); + QskSkin::setGraphicFilter( GraphicRoleBackground, backgroundFilter ); + + QskColorFilter onPrimaryFilter; + onPrimaryFilter.addColorSubstitution( defaultColor, palette.onPrimary ); + QskSkin::setGraphicFilter( GraphicRoleOnPrimary, onPrimaryFilter ); + + QskColorFilter disabledFilter; + QColor onSurfaceDisabledColor = stateLayerColor( palette.onSurface, palette.disabledContentOpacity ); + disabledFilter.addColorSubstitution( defaultColor, onSurfaceDisabledColor.rgba() ); + QskSkin::setGraphicFilter( GraphicRoleOnSurfaceDisabled, disabledFilter ); +} + void QskMaterial3Skin::setupFonts() { Inherited::setupFonts( QStringLiteral( "Roboto" ) ); diff --git a/skins/material3/QskMaterial3Skin.h b/skins/material3/QskMaterial3Skin.h index 646cef4b..94b1f635 100644 --- a/skins/material3/QskMaterial3Skin.h +++ b/skins/material3/QskMaterial3Skin.h @@ -81,6 +81,8 @@ class QSK_MATERIAL3_EXPORT QskMaterial3Theme const qreal focusOpacity = 0.12; const qreal pressedOpacity = 0.12; const qreal draggedOpacity = 0.16; + const qreal disabledContainerOpacity = 0.12; + const qreal disabledContentOpacity = 0.38; private: std::array< QskHctColor, NumPaletteTypes > m_palettes; @@ -96,6 +98,15 @@ class QSK_MATERIAL3_EXPORT QskMaterial3Skin : public QskSkin QskMaterial3Skin( const QskMaterial3Theme&, QObject* parent = nullptr ); ~QskMaterial3Skin() override; + virtual QskGraphic symbol( int symbolType ) const override; + + enum GraphicRole + { + GraphicRoleBackground, + GraphicRoleOnPrimary, + GraphicRoleOnSurfaceDisabled, + }; + enum FontRole { M3BodyMedium = QskSkin::HugeFont + 1, @@ -105,6 +116,7 @@ class QSK_MATERIAL3_EXPORT QskMaterial3Skin : public QskSkin }; private: + void setupGraphicFilters( const QskMaterial3Theme& ); void setupFonts(); }; diff --git a/skins/material3/icons.qrc b/skins/material3/icons.qrc new file mode 100644 index 00000000..51a26761 --- /dev/null +++ b/skins/material3/icons.qrc @@ -0,0 +1,7 @@ + + + icons/cancel_24px.svg + icons/check_24px.svg + icons/error_24px.svg + + diff --git a/skins/material3/icons/cancel_24px.svg b/skins/material3/icons/cancel_24px.svg new file mode 100644 index 00000000..076c0a73 --- /dev/null +++ b/skins/material3/icons/cancel_24px.svg @@ -0,0 +1,4 @@ + + + + diff --git a/skins/material3/icons/check_24px.svg b/skins/material3/icons/check_24px.svg new file mode 100644 index 00000000..88bfdda9 --- /dev/null +++ b/skins/material3/icons/check_24px.svg @@ -0,0 +1,4 @@ + + + + diff --git a/skins/material3/icons/error_24px.svg b/skins/material3/icons/error_24px.svg new file mode 100644 index 00000000..de16d5ee --- /dev/null +++ b/skins/material3/icons/error_24px.svg @@ -0,0 +1,4 @@ + + + + diff --git a/skins/material3/material3.pro b/skins/material3/material3.pro index 97317b2d..a4a2aa68 100644 --- a/skins/material3/material3.pro +++ b/skins/material3/material3.pro @@ -4,6 +4,8 @@ CONFIG += qskinny TEMPLATE = lib QSK_PLUGIN_SUBDIR = skins +QT += svg + TARGET = $$qskPluginTarget(material3skin) DEFINES += QSK_MATERIAL3_MAKEDLL @@ -21,3 +23,5 @@ OTHER_FILES += metadata.json target.path = $${QSK_INSTALL_PLUGINS}/$${QSK_PLUGIN_SUBDIR} INSTALLS = target +RESOURCES += \ + icons.qrc