check box: Add ripple effect and style for M3

This commit is contained in:
Peter Hartmann 2023-01-06 16:25:40 +01:00 committed by uwerat
parent cd4a46cc11
commit 4352410128
10 changed files with 109 additions and 7 deletions

View File

@ -12,6 +12,9 @@
#include <QskDialogButtonBox.h> #include <QskDialogButtonBox.h>
#include <QskFocusIndicator.h> #include <QskFocusIndicator.h>
#include <QskFunctions.h> #include <QskFunctions.h>
#include <QskGraphic.h>
#include <QskGraphicIO.h>
#include <QskGraphicProvider.h>
#include <QskInputPanelBox.h> #include <QskInputPanelBox.h>
#include <QskListView.h> #include <QskListView.h>
#include <QskMenu.h> #include <QskMenu.h>
@ -23,6 +26,7 @@
#include <QskSeparator.h> #include <QskSeparator.h>
#include <QskShadowMetrics.h> #include <QskShadowMetrics.h>
#include <QskSlider.h> #include <QskSlider.h>
#include <QskStandardSymbol.h>
#include <QskSubWindow.h> #include <QskSubWindow.h>
#include <QskSwitchButton.h> #include <QskSwitchButton.h>
#include <QskSwitchButtonSkinlet.h> #include <QskSwitchButtonSkinlet.h>
@ -98,12 +102,10 @@ namespace
return value * factor; return value * factor;
} }
#if 0
inline double operator ""_dp( long double value ) inline double operator ""_dp( long double value )
{ {
return dpToPixels( value ); return dpToPixels( value );
} }
#endif
inline double operator ""_dp( unsigned long long int value ) inline double operator ""_dp( unsigned long long int value )
{ {
@ -221,11 +223,11 @@ void Editor::setupCheckBox()
{ {
using Q = QskCheckBox; using Q = QskCheckBox;
setSpacing( Q::Panel, 10_dp ); setSpacing( Q::Panel, 40_dp );
setStrutSize( Q::Box, 24_dp, 24_dp ); setStrutSize( Q::Box, 24_dp, 24_dp );
setPadding( Q::Box, 6_dp ); setPadding( Q::Box, 4_dp );
setBoxShape( Q::Box, 2_dp ); setBoxShape( Q::Box, 2_dp );
setBoxBorderMetrics( Q::Box, 2_dp ); setBoxBorderMetrics( Q::Box, 2_dp );
setBoxBorderColors( Q::Box, m_pal.onBackground ); setBoxBorderColors( Q::Box, m_pal.onBackground );
@ -242,6 +244,14 @@ void Editor::setupCheckBox()
setColor( Q::Text, m_pal.onBackground ); setColor( Q::Text, m_pal.onBackground );
setTextOptions( Q::Text, Qt::ElideMiddle, QskTextOptions::NoWrap ); setTextOptions( Q::Text, Qt::ElideMiddle, QskTextOptions::NoWrap );
setStrutSize( Q::Ripple, { 53.33_dp, 53.33_dp } );
setBoxShape( Q::Ripple, 100, Qt::RelativeSize );
setGradient( Q::Ripple, Qt::transparent );
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::Pressed, m_pal.primary12 );
} }
void Editor::setupBox() void Editor::setupBox()
@ -978,6 +988,7 @@ QskMaterial3Theme::QskMaterial3Theme(Lightness lightness,
shadow = m_palettes[ Neutral ].toned( 0 ).rgb(); shadow = m_palettes[ Neutral ].toned( 0 ).rgb();
} }
primary8 = QskRgb::toTransparentF( primary, 0.08 );
primary12 = QskRgb::toTransparentF( primary, 0.12 ); primary12 = QskRgb::toTransparentF( primary, 0.12 );
surface1 = flattenedColor( primary, background, 0.05 ); surface1 = flattenedColor( primary, background, 0.05 );
@ -986,6 +997,7 @@ QskMaterial3Theme::QskMaterial3Theme(Lightness lightness,
surface4 = flattenedColor( primary, background, 0.12 ); surface4 = flattenedColor( primary, background, 0.12 );
surface5 = flattenedColor( primary, background, 0.14 ); surface5 = flattenedColor( primary, background, 0.14 );
onSurface8 = QskRgb::toTransparentF( onSurface, 0.08 );
onSurface12 = QskRgb::toTransparentF( onSurface, 0.12 ); onSurface12 = QskRgb::toTransparentF( onSurface, 0.12 );
onSurface38 = QskRgb::toTransparentF( onSurface, 0.38 ); onSurface38 = QskRgb::toTransparentF( onSurface, 0.38 );
@ -996,9 +1008,24 @@ QskMaterial3Theme::QskMaterial3Theme(Lightness lightness,
elevationLight3 = QskShadowMetrics( -1, 11, { 0, 2 } ); elevationLight3 = QskShadowMetrics( -1, 11, { 0, 2 } );
} }
QskMaterial3GraphicProvder::QskMaterial3GraphicProvder( QObject* parent )
: Inherited( parent )
{
}
const QskGraphic* QskMaterial3GraphicProvder::loadGraphic( const QString& id ) const
{
const QString name = QString( ":/icons/qvg/%1.qvg" ).arg( id );
const QskGraphic graphic = QskGraphicIO::read( name );
return graphic.isNull() ? nullptr : new QskGraphic( graphic );
}
QskMaterial3Skin::QskMaterial3Skin( const QskMaterial3Theme& palette, QObject* parent ) QskMaterial3Skin::QskMaterial3Skin( const QskMaterial3Theme& palette, QObject* parent )
: Inherited( parent ) : Inherited( parent )
{ {
addGraphicProvider( {}, new QskMaterial3GraphicProvder() );
setupFonts(); setupFonts();
Editor editor( &hintTable(), palette ); Editor editor( &hintTable(), palette );
@ -1009,6 +1036,24 @@ QskMaterial3Skin::~QskMaterial3Skin()
{ {
} }
QskGraphic QskMaterial3Skin::symbol( int symbolType ) const
{
switch ( symbolType )
{
case QskStandardSymbol::CheckMark:
{
const auto* provider = graphicProvider( {} );
return *( provider->requestGraphic( "check_small" ) );
}
case QskStandardSymbol::CrossMark:
{
return {};
}
default:
return Inherited::symbol( symbolType );
}
}
void QskMaterial3Skin::setupFonts() void QskMaterial3Skin::setupFonts()
{ {
Inherited::setupFonts( QStringLiteral( "Roboto" ) ); Inherited::setupFonts( QStringLiteral( "Roboto" ) );

View File

@ -8,6 +8,7 @@
#include "QskMaterial3Global.h" #include "QskMaterial3Global.h"
#include <QskGraphicProvider.h>
#include <QskHctColor.h> #include <QskHctColor.h>
#include <QskSkin.h> #include <QskSkin.h>
#include <QskShadowMetrics.h> #include <QskShadowMetrics.h>
@ -39,6 +40,7 @@ class QSK_MATERIAL3_EXPORT QskMaterial3Theme
QskMaterial3Theme( Lightness, std::array< QskHctColor, NumPaletteTypes > ); QskMaterial3Theme( Lightness, std::array< QskHctColor, NumPaletteTypes > );
QRgb primary; QRgb primary;
QRgb primary8;
QRgb primary12; QRgb primary12;
QRgb onPrimary; QRgb onPrimary;
QRgb primaryContainer; QRgb primaryContainer;
@ -69,6 +71,7 @@ class QSK_MATERIAL3_EXPORT QskMaterial3Theme
QRgb surface5; QRgb surface5;
QRgb onSurface; QRgb onSurface;
QRgb onSurface8;
QRgb onSurface12; QRgb onSurface12;
QRgb onSurface38; QRgb onSurface38;
@ -92,6 +95,19 @@ class QSK_MATERIAL3_EXPORT QskMaterial3Theme
std::array< QskHctColor, NumPaletteTypes > m_palettes; std::array< QskHctColor, NumPaletteTypes > m_palettes;
}; };
class QSK_MATERIAL3_EXPORT QskMaterial3GraphicProvder : public QskGraphicProvider
{
Q_OBJECT
using Inherited = QskGraphicProvider;
public:
QskMaterial3GraphicProvder( QObject* parent = nullptr );
protected:
virtual const QskGraphic* loadGraphic( const QString& id ) const override;
};
class QSK_MATERIAL3_EXPORT QskMaterial3Skin : public QskSkin class QSK_MATERIAL3_EXPORT QskMaterial3Skin : public QskSkin
{ {
Q_OBJECT Q_OBJECT
@ -102,6 +118,8 @@ class QSK_MATERIAL3_EXPORT QskMaterial3Skin : public QskSkin
QskMaterial3Skin( const QskMaterial3Theme&, QObject* parent = nullptr ); QskMaterial3Skin( const QskMaterial3Theme&, QObject* parent = nullptr );
~QskMaterial3Skin() override; ~QskMaterial3Skin() override;
virtual QskGraphic symbol( int symbolType ) const override;
enum FontRole enum FontRole
{ {
M3BodyMedium = QskSkin::HugeFont + 1, M3BodyMedium = QskSkin::HugeFont + 1,

View File

@ -0,0 +1,5 @@
<RCC>
<qresource>
<file>icons/qvg/check_small.qvg</file>
</qresource>
</RCC>

View File

@ -0,0 +1,4 @@
<svg width="12" height="10" viewBox="0 0 12 10" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M4 9.4L0 5.4L1.4 4L4 6.6L10.6 0L12 1.4L4 9.4Z" fill="white"/>
</svg>

After

Width:  |  Height:  |  Size: 175 B

Binary file not shown.

View File

@ -16,8 +16,10 @@ SOURCES += \
QskMaterial3Skin.cpp \ QskMaterial3Skin.cpp \
QskMaterial3SkinFactory.cpp QskMaterial3SkinFactory.cpp
RESOURCES += \
icons.qrc \
OTHER_FILES += metadata.json OTHER_FILES += metadata.json
target.path = $${QSK_INSTALL_PLUGINS}/$${QSK_PLUGIN_SUBDIR} target.path = $${QSK_INSTALL_PLUGINS}/$${QSK_PLUGIN_SUBDIR}
INSTALLS = target INSTALLS = target

View File

@ -9,6 +9,7 @@ QSK_SUBCONTROL( QskCheckBox, Panel )
QSK_SUBCONTROL( QskCheckBox, Box ) QSK_SUBCONTROL( QskCheckBox, Box )
QSK_SUBCONTROL( QskCheckBox, Indicator ) QSK_SUBCONTROL( QskCheckBox, Indicator )
QSK_SUBCONTROL( QskCheckBox, Text ) QSK_SUBCONTROL( QskCheckBox, Text )
QSK_SUBCONTROL( QskCheckBox, Ripple )
class QskCheckBox::PrivateData class QskCheckBox::PrivateData
{ {

View File

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

View File

@ -15,7 +15,7 @@
QskCheckBoxSkinlet::QskCheckBoxSkinlet( QskSkin* skin ) QskCheckBoxSkinlet::QskCheckBoxSkinlet( QskSkin* skin )
: QskSkinlet( skin ) : QskSkinlet( skin )
{ {
setNodeRoles( { BoxRole, IndicatorRole, TextRole } ); setNodeRoles( { BoxRole, IndicatorRole, TextRole, RippleRole } );
} }
QskCheckBoxSkinlet::~QskCheckBoxSkinlet() QskCheckBoxSkinlet::~QskCheckBoxSkinlet()
@ -47,6 +47,11 @@ QRectF QskCheckBoxSkinlet::subControlRect( const QskSkinnable* skinnable,
return textRect( checkBox, contentsRect ); return textRect( checkBox, contentsRect );
} }
if ( subControl == QskCheckBox::Ripple )
{
return rippleRect( checkBox, contentsRect );
}
return contentsRect; return contentsRect;
} }
@ -85,6 +90,21 @@ QRectF QskCheckBoxSkinlet::boxRect(
return r; return r;
} }
QRectF QskCheckBoxSkinlet::rippleRect(
const QskCheckBox* checkBox, const QRectF& rect ) const
{
const auto rippleSize = checkBox->strutSizeHint( QskCheckBox::Ripple );
const auto boxSize = checkBox->strutSizeHint( QskCheckBox::Box );
const auto w = ( rippleSize.width() - boxSize.width() ) / 2;
const auto h = ( rippleSize.height() - boxSize.height() ) / 2;
auto r = boxRect( checkBox, rect );
r = r.marginsAdded( { w, h, w, h } );
return r;
}
QSGNode* QskCheckBoxSkinlet::updateSubNode( QSGNode* QskCheckBoxSkinlet::updateSubNode(
const QskSkinnable* skinnable, quint8 nodeRole, QSGNode* node ) const const QskSkinnable* skinnable, quint8 nodeRole, QSGNode* node ) const
{ {
@ -103,6 +123,11 @@ QSGNode* QskCheckBoxSkinlet::updateSubNode(
case TextRole: case TextRole:
return updateTextNode( checkBox, node ); return updateTextNode( checkBox, node );
case RippleRole:
{
return updateBoxNode( checkBox, node, QskCheckBox::Ripple );
}
} }
return Inherited::updateSubNode( skinnable, nodeRole, node ); return Inherited::updateSubNode( skinnable, nodeRole, node );

View File

@ -23,6 +23,7 @@ class QSK_EXPORT QskCheckBoxSkinlet : public QskSkinlet
BoxRole, BoxRole,
IndicatorRole, IndicatorRole,
TextRole, TextRole,
RippleRole,
RoleCount RoleCount
}; };
@ -43,6 +44,7 @@ class QSK_EXPORT QskCheckBoxSkinlet : public QskSkinlet
private: private:
QRectF textRect( const QskCheckBox*, const QRectF& ) const; QRectF textRect( const QskCheckBox*, const QRectF& ) const;
QRectF boxRect( const QskCheckBox*, const QRectF& ) const; QRectF boxRect( const QskCheckBox*, const QRectF& ) const;
QRectF rippleRect( const QskCheckBox*, const QRectF& ) const;
QSGNode* updateIndicatorNode( const QskCheckBox*, QSGNode* ) const; QSGNode* updateIndicatorNode( const QskCheckBox*, QSGNode* ) const;
QSGNode* updateTextNode( const QskCheckBox*, QSGNode* ) const; QSGNode* updateTextNode( const QskCheckBox*, QSGNode* ) const;