diff --git a/skins/material3/QskMaterial3Skin.cpp b/skins/material3/QskMaterial3Skin.cpp index 651c0ac2..b9516e03 100644 --- a/skins/material3/QskMaterial3Skin.cpp +++ b/skins/material3/QskMaterial3Skin.cpp @@ -119,8 +119,10 @@ namespace class Editor : private QskSkinHintTableEditor { public: - Editor( QskSkinHintTable* table, const QskMaterial3Theme& palette ) + Editor( const QskSkin* skin, QskSkinHintTable* table, + const QskMaterial3Theme& palette ) : QskSkinHintTableEditor( table ) + , m_skin( skin ) , m_pal( palette ) { } @@ -128,6 +130,8 @@ namespace void setup(); private: + QskGraphic symbol( int type ) const { return m_skin->symbol( type ); } + void setupBox(); void setupCheckBox(); void setupComboBox(); @@ -155,6 +159,7 @@ namespace void setupTextInput(); void setupTextLabel(); + const QskSkin* m_skin; const QskMaterial3Theme& m_pal; }; @@ -248,6 +253,13 @@ void Editor::setupCheckBox() setGraphicRole( Q::Indicator | Q::Error, QskMaterial3Skin::GraphicRoleOnError ); + for ( auto state : { QskAspect::NoState, Q::Disabled } ) + { + const auto aspect = Q::Indicator | Q::Checked | state; + setSymbol( aspect, symbol( QskStandardSymbol::CheckMark ) ); + setSymbol( aspect | Q::Error, symbol( QskStandardSymbol::CheckMark ) ); + } + setStrutSize( Q::Ripple, 40_dp, 40_dp ); setBoxShape( Q::Ripple, 100, Qt::RelativeSize ); setGradient( Q::Ripple, Qt::transparent ); @@ -333,6 +345,12 @@ void Editor::setupComboBox() setColor( Q::Text | Q::Disabled, m_pal.onSurface38 ); setGraphicRole( Q::OpenMenuGraphic, QskMaterial3Skin::GraphicRoleOnSurface38 ); + + setSymbol( Q::OpenMenuGraphic, + symbol( QskStandardSymbol::TriangleDown ) ); + + setSymbol( Q::OpenMenuGraphic | Q::PopupOpen, + symbol( QskStandardSymbol::TriangleUp ) ); } void Editor::setupBox() @@ -903,6 +921,9 @@ void Editor::setupSpinBox() setGradient( Q::UpPanel | Q::Increasing, focusColor ); } + setSymbol( Q::UpIndicator, symbol( QskStandardSymbol::TriangleUp ) ); + setSymbol( Q::DownIndicator, symbol( QskStandardSymbol::TriangleDown ) ); + for( const auto subControl : { Q::DownIndicator, Q::UpIndicator } ) { setAlignment( subControl, Qt::AlignCenter ); @@ -1346,7 +1367,7 @@ QskMaterial3Skin::QskMaterial3Skin( const QskMaterial3Theme& palette, QObject* p setupFonts(); setupGraphicFilters( palette ); - Editor editor( &hintTable(), palette ); + Editor editor( this, &hintTable(), palette ); editor.setup(); } @@ -1356,24 +1377,19 @@ QskMaterial3Skin::~QskMaterial3Skin() QskGraphic QskMaterial3Skin::symbol( int symbolType ) const { - const auto* provider = graphicProvider( {} ); + const auto provider = graphicProvider( {} ); switch ( symbolType ) { case QskStandardSymbol::CheckMark: return *( provider->requestGraphic( "check_small" ) ); - case QskStandardSymbol::CrossMark: - return {}; - case QskStandardSymbol::SegmentedBarCheckMark: return *( provider->requestGraphic( "segmented-button-check" ) ); - case QskStandardSymbol::ComboBoxSymbolPopupClosed: case QskStandardSymbol::TriangleDown: return *( provider->requestGraphic( "combo-box-arrow-closed" ) ); - case QskStandardSymbol::ComboBoxSymbolPopupOpen: case QskStandardSymbol::TriangleUp: return *( provider->requestGraphic( "combo-box-arrow-open" ) ); diff --git a/skins/squiek/QskSquiekSkin.cpp b/skins/squiek/QskSquiekSkin.cpp index 73c6ed75..4e574fff 100644 --- a/skins/squiek/QskSquiekSkin.cpp +++ b/skins/squiek/QskSquiekSkin.cpp @@ -45,6 +45,8 @@ #include #include #include +#include +#include static const int qskDuration = 200; @@ -323,8 +325,12 @@ void Editor::setupCheckBox() setGradient( Q::Box | Q::Disabled, m_pal.lighter110 ); setBoxBorderColors( Q::Box, m_pal.theme ); - setColor( Q::Indicator, m_pal.darker200 ); - setColor( Q::Indicator | Q::Checked, m_pal.lighter135 ); + for ( auto state : { A::NoState, Q::Disabled } ) + { + const auto aspect = Q::Indicator | Q::Checked | state; + setSymbol( aspect, + QskStandardSymbol::graphic( QskStandardSymbol::CheckMark ) ); + } setTextOptions( Q::Text, Qt::ElideMiddle, QskTextOptions::NoWrap ); @@ -1060,6 +1066,12 @@ void Editor::setupSpinBox() setAnimation( subControl | A::Color, 100 ); } + setSymbol( Q::UpIndicator, + QskStandardSymbol::graphic( QskStandardSymbol::TriangleUp ) ); + + setSymbol( Q::DownIndicator, + QskStandardSymbol::graphic( QskStandardSymbol::TriangleDown ) ); + for ( auto subControl : { Q::UpIndicator, Q::DownIndicator } ) { setGraphicRole( subControl | Q::Disabled, DisabledColor ); diff --git a/src/common/QskAspect.h b/src/common/QskAspect.h index 03bb7828..707a1959 100644 --- a/src/common/QskAspect.h +++ b/src/common/QskAspect.h @@ -54,6 +54,8 @@ class QSK_EXPORT QskAspect GraphicRole, FontRole, + Symbol, + TextColor, StyleColor, LinkColor, diff --git a/src/controls/QskCheckBoxSkinlet.cpp b/src/controls/QskCheckBoxSkinlet.cpp index d7fa07f4..171b3c06 100644 --- a/src/controls/QskCheckBoxSkinlet.cpp +++ b/src/controls/QskCheckBoxSkinlet.cpp @@ -7,10 +7,6 @@ #include "QskCheckBox.h" #include "QskTextOptions.h" #include "QskFunctions.h" -#include "QskGraphic.h" -#include "QskStandardSymbol.h" -#include "QskColorFilter.h" -#include "QskSkin.h" QskCheckBoxSkinlet::QskCheckBoxSkinlet( QskSkin* skin ) : QskSkinlet( skin ) @@ -25,32 +21,27 @@ QskCheckBoxSkinlet::~QskCheckBoxSkinlet() QRectF QskCheckBoxSkinlet::subControlRect( const QskSkinnable* skinnable, const QRectF& contentsRect, QskAspect::Subcontrol subControl ) const { + using Q = QskCheckBox; + const auto checkBox = static_cast< const QskCheckBox* >( skinnable ); - if ( subControl == QskCheckBox::Panel ) - { + if ( subControl == Q::Panel ) return contentsRect; - } - else if ( subControl == QskCheckBox::Box ) - { + + if ( subControl == Q::Box ) return boxRect( checkBox, contentsRect ); - } - else if ( subControl == QskCheckBox::Indicator ) - { - const auto boxRect = subControlRect( skinnable, contentsRect, QskCheckBox::Box ); - return skinnable->innerBox( QskCheckBox::Box, boxRect ); - return skinnable->innerBox( QskCheckBox::Box, contentsRect ); - } - else if ( subControl == QskCheckBox::Text ) + if ( subControl == Q::Indicator ) { + const auto boxRect = subControlRect( skinnable, contentsRect, Q::Box ); + return skinnable->innerBox( Q::Box, boxRect ); + } + + if ( subControl == Q::Text ) return textRect( checkBox, contentsRect ); - } - if ( subControl == QskCheckBox::Ripple ) - { + if ( subControl == Q::Ripple ) return rippleRect( checkBox, contentsRect ); - } return contentsRect; } @@ -58,11 +49,13 @@ QRectF QskCheckBoxSkinlet::subControlRect( const QskSkinnable* skinnable, QRectF QskCheckBoxSkinlet::textRect( const QskCheckBox* checkBox, const QRectF& contentsRect ) const { - const auto boxRect = subControlRect( checkBox, contentsRect, QskCheckBox::Box ); - const qreal spacing = checkBox->spacingHint( QskCheckBox::Panel ); + using Q = QskCheckBox; - auto r = subControlRect( checkBox, contentsRect, QskCheckBox::Panel ); - r = checkBox->innerBox( QskCheckBox::Panel, r ); + const auto boxRect = subControlRect( checkBox, contentsRect, Q::Box ); + const qreal spacing = checkBox->spacingHint( Q::Panel ); + + auto r = subControlRect( checkBox, contentsRect, Q::Panel ); + r = checkBox->innerBox( Q::Panel, r ); if ( checkBox->layoutMirroring() ) r.setRight( boxRect.left() - spacing ); @@ -108,58 +101,42 @@ QRectF QskCheckBoxSkinlet::rippleRect( QSGNode* QskCheckBoxSkinlet::updateSubNode( const QskSkinnable* skinnable, quint8 nodeRole, QSGNode* node ) const { + using Q = QskCheckBox; + auto checkBox = static_cast< const QskCheckBox* >( skinnable ); switch( nodeRole ) { case PanelRole: - return updateBoxNode( skinnable, node, QskCheckBox::Panel ); + return updateBoxNode( skinnable, node, Q::Panel ); case BoxRole: - return updateBoxNode( skinnable, node, QskCheckBox::Box ); + return updateBoxNode( skinnable, node, Q::Box ); case IndicatorRole: - return updateIndicatorNode( checkBox, node ); + return updateSymbolNode( checkBox, node, Q::Indicator ); case TextRole: return updateTextNode( checkBox, node ); case RippleRole: - { - return updateBoxNode( checkBox, node, QskCheckBox::Ripple ); - } + return updateBoxNode( checkBox, node, Q::Ripple ); } return Inherited::updateSubNode( skinnable, nodeRole, node ); } -QSGNode* QskCheckBoxSkinlet::updateIndicatorNode( - const QskCheckBox* checkBox, QSGNode* node ) const -{ - auto symbol = QskStandardSymbol::CheckMark; - if ( !checkBox->isChecked() ) - { -#if 0 - symbol = QskStandardSymbol::NoSymbol; -#else - symbol = QskStandardSymbol::CrossMark; -#endif - } - - auto graphic = checkBox->effectiveSkin()->symbol( symbol ); - return updateGraphicNode( checkBox, node, graphic, QskCheckBox::Indicator ); -} - QSGNode* QskCheckBoxSkinlet::updateTextNode( const QskCheckBox* checkBox, QSGNode* node ) const { using Q = QskCheckBox; const auto rect = checkBox->subControlRect( Q::Text ); - const auto alignH = checkBox->layoutMirroring() ? Qt::AlignRight : Qt::AlignLeft; + const auto alignH = checkBox->layoutMirroring() + ? Qt::AlignRight : Qt::AlignLeft; - return QskSkinlet::updateTextNode( checkBox, node, rect, alignH | Qt::AlignVCenter, - checkBox->text(), QskCheckBox::Text ); + return QskSkinlet::updateTextNode( checkBox, node, + rect, alignH | Qt::AlignVCenter, checkBox->text(), Q::Text ); } QSizeF QskCheckBoxSkinlet::sizeHint( const QskSkinnable* skinnable, diff --git a/src/controls/QskCheckBoxSkinlet.h b/src/controls/QskCheckBoxSkinlet.h index 19ddee11..bc529e1b 100644 --- a/src/controls/QskCheckBoxSkinlet.h +++ b/src/controls/QskCheckBoxSkinlet.h @@ -46,7 +46,6 @@ class QSK_EXPORT QskCheckBoxSkinlet : public QskSkinlet QRectF boxRect( const QskCheckBox*, const QRectF& ) const; QRectF rippleRect( const QskCheckBox*, const QRectF& ) const; - QSGNode* updateIndicatorNode( const QskCheckBox*, QSGNode* ) const; QSGNode* updateTextNode( const QskCheckBox*, QSGNode* ) const; }; diff --git a/src/controls/QskComboBoxSkinlet.cpp b/src/controls/QskComboBoxSkinlet.cpp index 3b353969..7b192e84 100644 --- a/src/controls/QskComboBoxSkinlet.cpp +++ b/src/controls/QskComboBoxSkinlet.cpp @@ -7,9 +7,7 @@ #include "QskComboBox.h" #include "QskGraphic.h" -#include "QskSkin.h" #include "QskSGNode.h" -#include "QskStandardSymbol.h" #include "QskSubcontrolLayoutEngine.h" namespace @@ -116,29 +114,16 @@ QSGNode* QskComboBoxSkinlet::updateSubNode( switch ( nodeRole ) { case PanelRole: - { return updateBoxNode( box, node, Q::Panel ); - } case GraphicRole: - { return updateGraphicNode( box, node, box->graphic(), Q::Graphic ); - } case TextRole: - { return updateTextNode( box, node ); - } case OpenMenuGraphicRole: - { - const auto symbol = box->isPopupOpen() - ? QskStandardSymbol::ComboBoxSymbolPopupOpen - : QskStandardSymbol::ComboBoxSymbolPopupClosed; - - const auto graphic = box->effectiveSkin()->symbol( symbol ); - return updateGraphicNode( box, node, graphic, Q::OpenMenuGraphic ); - } + return updateSymbolNode( box, node, Q::OpenMenuGraphic ); } return Inherited::updateSubNode( skinnable, nodeRole, node ); diff --git a/src/controls/QskSkinHintTableEditor.cpp b/src/controls/QskSkinHintTableEditor.cpp index 0895fd01..63fea4d9 100644 --- a/src/controls/QskSkinHintTableEditor.cpp +++ b/src/controls/QskSkinHintTableEditor.cpp @@ -12,6 +12,7 @@ #include "QskBoxBorderMetrics.h" #include "QskBoxBorderColors.h" #include "QskShadowMetrics.h" +#include "QskGraphic.h" namespace { @@ -124,6 +125,11 @@ namespace { return aspect | QskAspect::Option; } + + inline QskAspect aspectSymbol( QskAspect aspect ) + { + return aspect | QskAspect::Symbol; + } } QskSkinHintTableEditor::QskSkinHintTableEditor( QskSkinHintTable* table ) @@ -600,7 +606,7 @@ void QskSkinHintTableEditor::setTextOptions( QskAspect aspect, } void QskSkinHintTableEditor::setTextOptions( QskAspect aspect, - const QskTextOptions& textOptions, QskStateCombination combination ) + const QskTextOptions& textOptions, QskStateCombination combination ) { setHint( aspectOption( aspect ), textOptions, combination ); } @@ -615,3 +621,20 @@ QskTextOptions QskSkinHintTableEditor::textOptions( QskAspect aspect ) const { return hint< QskTextOptions >( aspectOption( aspect ) ); } + +void QskSkinHintTableEditor::setSymbol( QskAspect aspect, + const QskGraphic& symbol, QskStateCombination combination ) +{ + setHint( aspectSymbol( aspect ), symbol, combination ); +} + +bool QskSkinHintTableEditor::removeSymbol( + QskAspect aspect, QskStateCombination combination ) +{ + return removeHint( aspectSymbol( aspect ), combination ); +} + +QskGraphic QskSkinHintTableEditor::symbol( QskAspect aspect ) const +{ + return hint< QskGraphic >( aspectSymbol( aspect ) ); +} diff --git a/src/controls/QskSkinHintTableEditor.h b/src/controls/QskSkinHintTableEditor.h index 2372474a..336d59e1 100644 --- a/src/controls/QskSkinHintTableEditor.h +++ b/src/controls/QskSkinHintTableEditor.h @@ -22,6 +22,7 @@ class QskBoxShapeMetrics; class QskBoxBorderMetrics; class QskBoxBorderColors; class QskShadowMetrics; +class QskGraphic; class QSK_EXPORT QskSkinHintTableEditor { @@ -275,6 +276,14 @@ class QSK_EXPORT QskSkinHintTableEditor bool removeTextOptions( QskAspect, QskStateCombination = QskStateCombination() ); QskTextOptions textOptions( QskAspect ) const; + // symbol + + void setSymbol( QskAspect, + const QskGraphic&, QskStateCombination = QskStateCombination() ); + + bool removeSymbol( QskAspect, QskStateCombination = QskStateCombination() ); + QskGraphic symbol( QskAspect ) const; + private: QskSkinHintTable* m_table = nullptr; }; diff --git a/src/controls/QskSkinlet.cpp b/src/controls/QskSkinlet.cpp index e672931d..d3446d94 100644 --- a/src/controls/QskSkinlet.cpp +++ b/src/controls/QskSkinlet.cpp @@ -632,14 +632,22 @@ QSGNode* QskSkinlet::updateTextNode( rect, alignment, text, subControl ); } +QSGNode* QskSkinlet::updateSymbolNode( + const QskSkinnable* skinnable, QSGNode* node, + QskAspect::Subcontrol subControl ) const +{ + return updateGraphicNode( skinnable, node, + skinnable->symbolHint( subControl ), subControl ); +} + QSGNode* QskSkinlet::updateGraphicNode( const QskSkinnable* skinnable, QSGNode* node, - const QskGraphic& graphic, QskAspect::Subcontrol subcontrol, + const QskGraphic& graphic, QskAspect::Subcontrol subControl, Qt::Orientations mirrored ) const { - const auto rect = qskSubControlRect( this, skinnable, subcontrol ); - const auto alignment = skinnable->alignmentHint( subcontrol, Qt::AlignCenter ); - const auto colorFilter = skinnable->effectiveGraphicFilter( subcontrol ); + const auto rect = qskSubControlRect( this, skinnable, subControl ); + const auto alignment = skinnable->alignmentHint( subControl, Qt::AlignCenter ); + const auto colorFilter = skinnable->effectiveGraphicFilter( subControl ); return updateGraphicNode( skinnable, node, graphic, colorFilter, rect, alignment, mirrored ); diff --git a/src/controls/QskSkinlet.h b/src/controls/QskSkinlet.h index 79fa7554..7414b5a8 100644 --- a/src/controls/QskSkinlet.h +++ b/src/controls/QskSkinlet.h @@ -159,6 +159,9 @@ class QSK_EXPORT QskSkinlet QSGNode* updateTextNode( const QskSkinnable*, QSGNode*, const QString&, QskAspect::Subcontrol ) const; + QSGNode* updateSymbolNode( const QskSkinnable*, QSGNode*, + QskAspect::Subcontrol ) const; + QSGNode* updateGraphicNode( const QskSkinnable*, QSGNode*, const QskGraphic&, QskAspect::Subcontrol, Qt::Orientations mirrored = Qt::Orientations() ) const; diff --git a/src/controls/QskSkinnable.cpp b/src/controls/QskSkinnable.cpp index 748e492a..89e25b0d 100644 --- a/src/controls/QskSkinnable.cpp +++ b/src/controls/QskSkinnable.cpp @@ -26,6 +26,7 @@ #include "QskBoxHints.h" #include "QskGradient.h" #include "QskTextOptions.h" +#include "QskGraphic.h" #include #include @@ -650,7 +651,7 @@ qreal QskSkinnable::spacingHint( bool QskSkinnable::setTextOptionsHint( const QskAspect aspect, const QskTextOptions& options ) { - return setSkinHint( aspect | QskAspect::NoType | QskAspect::Option, + return setSkinHint( aspect | QskAspect::Option, QVariant::fromValue( options ) ); } @@ -663,7 +664,7 @@ QskTextOptions QskSkinnable::textOptionsHint( const QskAspect aspect, QskSkinHintStatus* status ) const { return effectiveSkinHint( - aspect | QskAspect::NoType | QskAspect::Option, status ).value< QskTextOptions >(); + aspect | QskAspect::Option, status ).value< QskTextOptions >(); } bool QskSkinnable::setFontRoleHint( const QskAspect aspect, int role ) @@ -709,6 +710,26 @@ int QskSkinnable::graphicRoleHint( return qskFlag( this, aspect | QskAspect::GraphicRole, status ); } +bool QskSkinnable::setSymbolHint( + const QskAspect aspect, const QskGraphic& symbol ) +{ + return setSkinHint( aspect | QskAspect::Symbol, + QVariant::fromValue( symbol ) ); +} + +bool QskSkinnable::resetSymbolHint( const QskAspect aspect ) +{ + return resetSkinHint( aspect | QskAspect::Symbol ); +} + +QskGraphic QskSkinnable::symbolHint( + const QskAspect aspect, QskSkinHintStatus* status ) const +{ + return effectiveSkinHint( + aspect | QskAspect::Symbol, status ).value< QskGraphic >(); +} + + QskColorFilter QskSkinnable::effectiveGraphicFilter( const QskAspect::Subcontrol subControl ) const { diff --git a/src/controls/QskSkinnable.h b/src/controls/QskSkinnable.h index 62568d5f..55345a27 100644 --- a/src/controls/QskSkinnable.h +++ b/src/controls/QskSkinnable.h @@ -32,6 +32,7 @@ class QskShadowMetrics; class QskTextOptions; class QskBoxHints; class QskGradient; +class QskGraphic; class QskSkin; class QskSkinlet; @@ -246,6 +247,10 @@ class QSK_EXPORT QskSkinnable bool resetGraphicRoleHint( QskAspect ); int graphicRoleHint( QskAspect, QskSkinHintStatus* = nullptr ) const; + bool setSymbolHint( const QskAspect, const QskGraphic& ); + bool resetSymbolHint( const QskAspect ); + QskGraphic symbolHint( const QskAspect, QskSkinHintStatus* = nullptr ) const; + const QskSkinHintTable& hintTable() const; bool startHintTransitions( QskAspect::States, QskAspect::States, int index = -1 ); diff --git a/src/controls/QskSpinBoxSkinlet.cpp b/src/controls/QskSpinBoxSkinlet.cpp index 20a7dcc0..4f1ac1dc 100644 --- a/src/controls/QskSpinBoxSkinlet.cpp +++ b/src/controls/QskSpinBoxSkinlet.cpp @@ -6,10 +6,7 @@ #include "QskSpinBoxSkinlet.h" #include "QskSpinBox.h" #include "QskFunctions.h" -#include "QskSkin.h" #include "QskSkinStateChanger.h" -#include "QskStandardSymbol.h" -#include "QskGraphic.h" #include @@ -95,19 +92,13 @@ QSGNode* QskSpinBoxSkinlet::updateSubNode( case UpIndicator: { stateChanger.setStates( qskButtonStates( skinnable, Q::UpIndicator ) ); - - const auto skin = skinnable->effectiveSkin(); - return updateGraphicNode( skinnable, node, - skin->symbol( QskStandardSymbol::TriangleUp ), Q::UpIndicator ); + return updateSymbolNode( skinnable, node, Q::UpIndicator ); } case DownIndicator: { stateChanger.setStates( qskButtonStates( skinnable, Q::DownIndicator ) ); - - const auto skin = skinnable->effectiveSkin(); - return updateGraphicNode( skinnable, node, - skin->symbol( QskStandardSymbol::TriangleDown ), Q::DownIndicator ); + return updateSymbolNode( skinnable, node, Q::DownIndicator ); } case TextPanel: diff --git a/src/graphic/QskStandardSymbol.cpp b/src/graphic/QskStandardSymbol.cpp index c8b62938..c551f82b 100644 --- a/src/graphic/QskStandardSymbol.cpp +++ b/src/graphic/QskStandardSymbol.cpp @@ -342,8 +342,6 @@ QskGraphic QskStandardSymbol::graphic( Type symbolType ) } case QskStandardSymbol::NoSymbol: case QskStandardSymbol::SymbolTypeCount: - case QskStandardSymbol::ComboBoxSymbolPopupClosed: - case QskStandardSymbol::ComboBoxSymbolPopupOpen: { break; } diff --git a/src/graphic/QskStandardSymbol.h b/src/graphic/QskStandardSymbol.h index 22bbc992..7efb7717 100644 --- a/src/graphic/QskStandardSymbol.h +++ b/src/graphic/QskStandardSymbol.h @@ -31,8 +31,6 @@ namespace QskStandardSymbol CrossMark, SegmentedBarCheckMark, - ComboBoxSymbolPopupClosed, - ComboBoxSymbolPopupOpen, Bullet,