tracking states of the aspects in a QskSkinHintTable
This commit is contained in:
parent
a38a4a101e
commit
1eae47aefa
@ -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 )
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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
|
||||
|
@ -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 )
|
||||
{
|
||||
|
Loading…
x
Reference in New Issue
Block a user