diff --git a/src/controls/QskSkin.cpp b/src/controls/QskSkin.cpp index f99dc41a..85215d98 100644 --- a/src/controls/QskSkin.cpp +++ b/src/controls/QskSkin.cpp @@ -128,7 +128,6 @@ class QskSkin::PrivateData std::unordered_map< const QMetaObject*, SkinletData > skinletMap; QskSkinHintTable hintTable; - QskAspect::States stateMask = QskAspect::AllStates; std::unordered_map< int, QFont > fonts; std::unordered_map< int, QskColorFilter > graphicFilters; @@ -345,22 +344,6 @@ const int* QskSkin::dialogButtonLayout( Qt::Orientation orientation ) const return QPlatformDialogHelper::buttonLayout( orientation, policy ); } -void QskSkin::setStateMask( QskAspect::States mask ) -{ - for ( auto state : { QskControl::Disabled, QskControl::Hovered, QskControl::Focused } ) - { - if ( mask & state ) - m_data->stateMask |= state; - else - m_data->stateMask &= ~state; - } -} - -QskAspect::States QskSkin::stateMask() const -{ - return m_data->stateMask; -} - QskSkinlet* QskSkin::skinlet( const QMetaObject* metaObject ) { while ( metaObject ) diff --git a/src/controls/QskSkin.h b/src/controls/QskSkin.h index adeb2c54..723b0115 100644 --- a/src/controls/QskSkin.h +++ b/src/controls/QskSkin.h @@ -77,9 +77,6 @@ class QSK_EXPORT QskSkin : public QObject virtual const int* dialogButtonLayout( Qt::Orientation ) const; virtual QString dialogButtonText( int button ) const; - void setStateMask( QskAspect::States ); - QskAspect::States stateMask() const; - QskSkinlet* skinlet( const QMetaObject* ); const QskSkinHintTable& hintTable() const; diff --git a/src/controls/QskSkinHintTable.cpp b/src/controls/QskSkinHintTable.cpp index 9bac96f0..d43a4434 100644 --- a/src/controls/QskSkinHintTable.cpp +++ b/src/controls/QskSkinHintTable.cpp @@ -67,7 +67,7 @@ QskSkinHintTable::QskSkinHintTable() QskSkinHintTable::QskSkinHintTable( const QskSkinHintTable& other ) : m_hints( nullptr ) , m_animatorCount( other.m_animatorCount ) - , m_statefulCount( other.m_statefulCount ) + , m_states( other.m_states ) { if ( other.m_hints ) m_hints = new HintMap( *( other.m_hints ) ); @@ -81,7 +81,7 @@ QskSkinHintTable::~QskSkinHintTable() QskSkinHintTable& QskSkinHintTable::operator=( const QskSkinHintTable& other ) { m_animatorCount = other.m_animatorCount; - m_statefulCount = other.m_statefulCount; + m_states = other.m_states; if ( other.m_hints ) { @@ -126,11 +126,7 @@ bool QskSkinHintTable::setHint( QskAspect aspect, const QVariant& skinHint ) QSK_ASSERT_COUNTER( m_animatorCount ); } - if ( aspect.hasStates() ) - { - m_statefulCount++; - QSK_ASSERT_COUNTER( m_statefulCount ); - } + m_states |= aspect.states(); return true; } @@ -158,8 +154,7 @@ bool QskSkinHintTable::removeHint( QskAspect aspect ) if ( aspect.isAnimator() ) m_animatorCount--; - if ( aspect.hasStates() ) - m_statefulCount--; + // how to clear m_states ? TODO ... if ( m_hints->empty() ) { @@ -184,8 +179,7 @@ QVariant QskSkinHintTable::takeHint( QskAspect aspect ) if ( aspect.isAnimator() ) m_animatorCount--; - if ( aspect.hasStates() ) - m_statefulCount--; + // how to clear m_states ? TODO ... if ( m_hints->empty() ) { @@ -206,14 +200,14 @@ void QskSkinHintTable::clear() m_hints = nullptr; m_animatorCount = 0; - m_statefulCount = 0; + m_states = QskAspect::NoState; } const QVariant* QskSkinHintTable::resolvedHint( QskAspect aspect, QskAspect* resolvedAspect ) const { if ( m_hints != nullptr ) - return qskResolvedHint( aspect, *m_hints, resolvedAspect ); + return qskResolvedHint( aspect & m_states, *m_hints, resolvedAspect ); return nullptr; } @@ -223,7 +217,7 @@ QskAspect QskSkinHintTable::resolvedAspect( QskAspect aspect ) const QskAspect a; if ( m_hints != nullptr ) - qskResolvedHint( aspect, *m_hints, &a ); + qskResolvedHint( aspect & m_states, *m_hints, &a ); return a; } @@ -233,6 +227,8 @@ QskAspect QskSkinHintTable::resolvedAnimator( { if ( m_hints && m_animatorCount > 0 ) { + aspect &= m_states; + Q_FOREVER { auto it = m_hints->find( aspect ); @@ -268,15 +264,16 @@ bool QskSkinHintTable::setAnimation( bool QskSkinHintTable::isResolutionMatching( QskAspect aspect1, QskAspect aspect2 ) const { + // remove states we do not have early + aspect1 &= m_states; + aspect2 &= m_states; + if ( aspect1 == aspect2 ) return true; if ( aspect1.trunk() != aspect2.trunk() ) return false; - if ( !hasStates() ) - return false; - const auto a1 = aspect1; const auto a2 = aspect2; diff --git a/src/controls/QskSkinHintTable.h b/src/controls/QskSkinHintTable.h index c1e6a647..ac246376 100644 --- a/src/controls/QskSkinHintTable.h +++ b/src/controls/QskSkinHintTable.h @@ -40,9 +40,10 @@ class QSK_EXPORT QskSkinHintTable const std::unordered_map< QskAspect, QVariant >& hints() const; bool hasAnimators() const; - bool hasStates() const; bool hasHints() const; + QskAspect::States states() const; + void clear(); const QVariant* resolvedHint( QskAspect, @@ -62,7 +63,7 @@ class QSK_EXPORT QskSkinHintTable HintMap* m_hints = nullptr; unsigned short m_animatorCount = 0; - unsigned short m_statefulCount = 0; + QskAspect::States m_states; }; inline bool QskSkinHintTable::hasHints() const @@ -70,9 +71,9 @@ inline bool QskSkinHintTable::hasHints() const return m_hints != nullptr; } -inline bool QskSkinHintTable::hasStates() const +inline QskAspect::States QskSkinHintTable::states() const { - return m_statefulCount > 0; + return m_states; } inline bool QskSkinHintTable::hasAnimators() const diff --git a/src/controls/QskSkinnable.cpp b/src/controls/QskSkinnable.cpp index 1268fcde..fba33948 100644 --- a/src/controls/QskSkinnable.cpp +++ b/src/controls/QskSkinnable.cpp @@ -940,23 +940,12 @@ const QVariant& QskSkinnable::storedHint( { const auto skin = effectiveSkin(); - // clearing all state bits not being handled from the skin - aspect.clearStates( ~skin->stateMask() ); - QskAspect resolvedAspect; const auto& localTable = m_data->hintTable; if ( localTable.hasHints() ) { - auto a = aspect; - - if ( !localTable.hasStates() ) - { - // we don't need to clear the state bits stepwise - a.clearStates(); - } - - if ( const QVariant* value = localTable.resolvedHint( a, &resolvedAspect ) ) + if ( const auto value = localTable.resolvedHint( aspect, &resolvedAspect ) ) { if ( status ) { @@ -972,10 +961,7 @@ const QVariant& QskSkinnable::storedHint( const auto& skinTable = skin->hintTable(); if ( skinTable.hasHints() ) { - auto a = aspect; - - const QVariant* value = skinTable.resolvedHint( a, &resolvedAspect ); - if ( value ) + if ( const auto value = skinTable.resolvedHint( aspect, &resolvedAspect ) ) { if ( status ) { @@ -993,8 +979,7 @@ const QVariant& QskSkinnable::storedHint( aspect.setSubControl( QskAspect::Control ); aspect.clearStates(); - value = skinTable.resolvedHint( aspect, &resolvedAspect ); - if ( value ) + if ( const auto value = skinTable.resolvedHint( aspect, &resolvedAspect ) ) { if ( status ) { @@ -1257,7 +1242,8 @@ void QskSkinnable::setSkinStates( QskAspect::States newStates ) if ( skin ) { - const auto mask = skin->stateMask(); + const auto mask = skin->hintTable().states() | m_data->hintTable.states(); + if ( ( newStates & mask ) == ( m_data->skinStates & mask ) ) { // the modified bits are not handled by the skin @@ -1297,24 +1283,13 @@ void QskSkinnable::setSkinStates( QskAspect::States newStates ) const auto primitive = static_cast< QskAspect::Primitive >( i ); aspect.setPrimitive( type, primitive ); - auto a1 = aspect | m_data->skinStates; - auto a2 = aspect | newStates; + const auto a1 = aspect | m_data->skinStates; + const auto a2 = aspect | newStates; bool doTransition = true; - if ( !m_data->hintTable.hasStates() ) - { - /* - The hints are found by stripping the state bits one by - one until a lookup into the hint table is successful. - So for deciding whether two aspects lead to the same hint - we can stop as soon as the aspects have the same state bits. - This way we can reduce the number of lookups significantly - for skinnables with many state bits. - - */ + if ( m_data->hintTable.states() == QskAspect::NoState ) doTransition = !skinTable.isResolutionMatching( a1, a2 ); - } if ( doTransition ) {