From 13d6719a5f6d49bd1254fa053f2906462f65695c Mon Sep 17 00:00:00 2001 From: Uwe Rathmann Date: Tue, 22 Aug 2017 20:50:55 +0200 Subject: [PATCH] QskSkinHintTable introduced to share more code between accessing local and global hints --- src/controls/QskSkin.cpp | 101 ++++--------------- src/controls/QskSkin.h | 11 ++- src/controls/QskSkinHintTable.cpp | 137 ++++++++++++++++++++++++++ src/controls/QskSkinHintTable.h | 131 +++++++++++++++++++++++++ src/controls/QskSkinTransition.cpp | 5 +- src/controls/QskSkinnable.cpp | 151 +++++++++-------------------- src/controls/QskSkinnable.h | 8 +- src/src.pro | 2 + 8 files changed, 348 insertions(+), 198 deletions(-) create mode 100644 src/controls/QskSkinHintTable.cpp create mode 100644 src/controls/QskSkinHintTable.h diff --git a/src/controls/QskSkin.cpp b/src/controls/QskSkin.cpp index f5da57b0..e82bbc72 100644 --- a/src/controls/QskSkin.cpp +++ b/src/controls/QskSkin.cpp @@ -12,6 +12,7 @@ #include "QskSetup.h" #include "QskAnimationHint.h" #include "QskStandardSymbol.h" +#include "QskSkinHintTable.h" #include "QskFocusIndicator.h" @@ -105,15 +106,15 @@ class QskSkin::PrivateData { public: PrivateData( QskSkin* skin ): - skin( skin ) + skin( skin ), + hintTable( true ) { } QskSkin* skin; std::unordered_map< const QMetaObject*, SkinletData > skinletMap; - std::unordered_map< QskAspect::Aspect, QVariant > skinHints; - std::unordered_map< int, std::set< QskAspect::Aspect > > animatorAspects; + QskSkinHintTable hintTable; std::unordered_map< int, QFont > fonts; std::unordered_map< int, QskColorFilter > graphicFilters; @@ -170,98 +171,38 @@ void QskSkin::setColor( QskAspect::Aspect aspect, const QColor& color ) QColor QskSkin::color( QskAspect::Aspect aspect ) const { - return skinHint( aspect | QskAspect::Color ).value(); + return m_data->hintTable.color( aspect ); } void QskSkin::setMetric( QskAspect::Aspect aspect, qreal metric ) { - setSkinHint( aspect | QskAspect::Metric, metric ); + m_data->hintTable.setMetric( aspect, metric ); } qreal QskSkin::metric( QskAspect::Aspect aspect ) const { - return skinHint( aspect | QskAspect::Metric ).toReal(); + return m_data->hintTable.metric( aspect ); } void QskSkin::setAnimation( QskAspect::Aspect aspect, QskAnimationHint animation ) { - aspect.setAnimator( true ); - setSkinHint( aspect, QVariant::fromValue( animation ) ); + m_data->hintTable.setAnimation( aspect, animation ); } QskAnimationHint QskSkin::animation( QskAspect::Aspect aspect ) const { - aspect.setAnimator( true ); - return skinHint( aspect ).value< QskAnimationHint >(); + return m_data->hintTable.animation( aspect ); } void QskSkin::setSkinHint( QskAspect::Aspect aspect, const QVariant& skinHint ) { - // For edges/corners, add all the implied assignments - if ( aspect.isBoxPrimitive() ) - { - if ( aspect.boxPrimitive() == QskAspect::Radius ) - { - setSkinHint( aspect | QskAspect::RadiusX, skinHint ); - setSkinHint( aspect | QskAspect::RadiusY, skinHint ); - return; - } - - const auto edges = aspect.edge(); - - const auto bitcount = qPopulationCount( static_cast( edges ) ); - if ( !bitcount || bitcount > 1 ) - { - using namespace QskAspect; - - auto aspectEdges = aspect; - aspectEdges.clearEdge(); - - if ( !bitcount || edges & TopEdge ) - setSkinHint( aspectEdges | TopEdge, skinHint ); - - if ( !bitcount || ( edges & LeftEdge ) ) - setSkinHint( aspectEdges | LeftEdge, skinHint ); - - if ( !bitcount || ( edges & RightEdge ) ) - setSkinHint( aspectEdges | RightEdge, skinHint ); - - if ( !bitcount || ( edges & BottomEdge ) ) - setSkinHint( aspectEdges | BottomEdge, skinHint ); - } - - if ( bitcount > 1 ) // Allows 0 to imply AllEdges - return; - } - - auto it = m_data->skinHints.find( aspect ); - if ( it == m_data->skinHints.end() ) - { - m_data->skinHints.emplace( aspect, skinHint ); - } - else if ( it->second != skinHint ) - { - it->second = skinHint; - } - - if ( aspect.isAnimator() ) - m_data->animatorAspects[ aspect.subControl() ].insert( aspect ); -} - -void QskSkin::removeSkinHint( QskAspect::Aspect aspect ) -{ - m_data->skinHints.erase( aspect ); + m_data->hintTable.setSkinHint( aspect, skinHint ); } const QVariant& QskSkin::skinHint( QskAspect::Aspect aspect ) const { - auto it = m_data->skinHints.find( aspect ); - if ( it != m_data->skinHints.cend() ) - return it->second; - - static QVariant invalidHint; - return invalidHint; + return m_data->hintTable.skinHint( aspect ); } void QskSkin::declareSkinlet( const QMetaObject* metaObject, @@ -351,9 +292,14 @@ QskColorFilter QskSkin::graphicFilter( int graphicRole ) const return QskColorFilter(); } -const std::unordered_map< QskAspect::Aspect, QVariant >& QskSkin::skinHints() const +const QskSkinHintTable& QskSkin::hintTable() const { - return m_data->skinHints; + return m_data->hintTable; +} + +QskSkinHintTable& QskSkin::skinHintTable() +{ + return m_data->hintTable; } const std::unordered_map< int, QFont >& QskSkin::fonts() const @@ -366,17 +312,6 @@ const std::unordered_map< int, QskColorFilter >& QskSkin::graphicFilters() const return m_data->graphicFilters; } -const std::set< QskAspect::Aspect >& QskSkin::animatorAspects( - QskAspect::Subcontrol subControl ) const -{ - auto it = m_data->animatorAspects.find( subControl ); - if ( it != m_data->animatorAspects.cend() ) - return it->second; - - static std::set< QskAspect::Aspect > dummyAspects; - return dummyAspects; -} - QskGraphic QskSkin::symbol( int symbolType ) const { // should this one be somehow related to the platform icons ??? diff --git a/src/controls/QskSkin.h b/src/controls/QskSkin.h index 6f918b12..95b94a94 100644 --- a/src/controls/QskSkin.h +++ b/src/controls/QskSkin.h @@ -13,7 +13,6 @@ #include #include -#include #include #include @@ -26,6 +25,7 @@ class QskGraphic; class QskGraphicProvider; class QskAnimationHint; +class QskSkinHintTable; class QVariant; @@ -69,8 +69,6 @@ public: QskAnimationHint animation( QskAspect::Aspect ) const; void setSkinHint( QskAspect::Aspect, const QVariant& hint ); - void removeSkinHint( QskAspect::Aspect ); - const QVariant& skinHint( QskAspect::Aspect ) const; void setGraphicFilter( int graphicRole, const QskColorFilter& ); @@ -94,11 +92,14 @@ public: QskSkinlet* skinlet( const QskSkinnable* ); - const std::set< QskAspect::Aspect >& animatorAspects( QskAspect::Subcontrol ) const; - const std::unordered_map< QskAspect::Aspect, QVariant >& skinHints() const; + const QskSkinHintTable& hintTable() const; + const std::unordered_map< int, QFont >& fonts() const; const std::unordered_map< int, QskColorFilter >& graphicFilters() const; +protected: + QskSkinHintTable& skinHintTable(); + private: void declareSkinlet( const QMetaObject* controlMetaObject, const QMetaObject* skinMetaObject ); diff --git a/src/controls/QskSkinHintTable.cpp b/src/controls/QskSkinHintTable.cpp new file mode 100644 index 00000000..c52755af --- /dev/null +++ b/src/controls/QskSkinHintTable.cpp @@ -0,0 +1,137 @@ +/****************************************************************************** + * QSkinny - Copyright (C) 2016 Uwe Rathmann + * This file may be used under the terms of the QSkinny License, Version 1.0 + *****************************************************************************/ + +#include "QskSkinHintTable.h" + +QskSkinHintTable::QskSkinHintTable( bool extraAnimatorLookup ): + m_hints( nullptr ), + m_animatorAspects( nullptr ) +{ + if ( extraAnimatorLookup ) + m_animatorAspects = new std::unordered_map< int, std::set< QskAspect::Aspect > >(); +} + +QskSkinHintTable::~QskSkinHintTable() +{ + delete m_hints; + delete m_animatorAspects; +} + +const std::set< QskAspect::Aspect >& QskSkinHintTable::animatorAspects( + QskAspect::Subcontrol subControl ) const +{ + if ( m_animatorAspects ) + { + auto it = m_animatorAspects->find( subControl ); + if ( it != m_animatorAspects->cend() ) + return it->second; + } + + static std::set< QskAspect::Aspect > dummyAspects; + return dummyAspects; +} + +const std::unordered_map< QskAspect::Aspect, QVariant >& QskSkinHintTable::hints() const +{ + if ( m_hints ) + return *m_hints; + + static std::unordered_map< QskAspect::Aspect, QVariant > dummyHints; + return dummyHints; +} + +void QskSkinHintTable::setSkinHint( QskAspect::Aspect aspect, const QVariant& skinHint ) +{ + // For edges/corners, add all the implied assignments + if ( aspect.isBoxPrimitive() ) + { + if ( aspect.boxPrimitive() == QskAspect::Radius ) + { + setSkinHint( aspect | QskAspect::RadiusX, skinHint ); + setSkinHint( aspect | QskAspect::RadiusY, skinHint ); + return; + } + + const auto edges = aspect.edge(); + + const auto bitcount = qPopulationCount( static_cast< quint8 >( edges ) ); + if ( !bitcount || bitcount > 1 ) + { + using namespace QskAspect; + + auto aspectEdges = aspect; + aspectEdges.clearEdge(); + + if ( !bitcount || edges & TopEdge ) + setSkinHint( aspectEdges | TopEdge, skinHint ); + + if ( !bitcount || ( edges & LeftEdge ) ) + setSkinHint( aspectEdges | LeftEdge, skinHint ); + + if ( !bitcount || ( edges & RightEdge ) ) + setSkinHint( aspectEdges | RightEdge, skinHint ); + + if ( !bitcount || ( edges & BottomEdge ) ) + setSkinHint( aspectEdges | BottomEdge, skinHint ); + } + + if ( bitcount > 1 ) // Allows 0 to imply AllEdges + return; + } + + if ( m_hints == nullptr ) + m_hints = new std::remove_pointer< decltype( m_hints ) >::type; + + auto it = m_hints->find( aspect ); + if ( it == m_hints->end() ) + { + m_hints->emplace( aspect, skinHint ); + } + else if ( it->second != skinHint ) + { + it->second = skinHint; + } + + if ( m_animatorAspects && aspect.isAnimator() ) + ( *m_animatorAspects )[ aspect.subControl() ].insert( aspect ); +} + +void QskSkinHintTable::removeSkinHint( QskAspect::Aspect aspect ) +{ + if ( m_hints == nullptr ) + return; + + m_hints->erase( aspect ); + if ( m_hints->empty() ) + { + delete m_hints; + m_hints = nullptr; + } + + if ( m_animatorAspects && aspect.isAnimator() ) + { + auto it = m_animatorAspects->find( aspect.subControl() ); + if ( it != m_animatorAspects->end() ) + { + auto& aspects = it->second; + aspects.erase( aspect ); + if ( aspects.empty() ) + m_animatorAspects->erase( it ); + } + } +} + +const QVariant& QskSkinHintTable::skinHint( QskAspect::Aspect aspect ) const +{ + if ( m_hints ) + { + auto it = m_hints->find( aspect ); + if ( it != m_hints->cend() ) + return it->second; + } + + static QVariant invalidHint; + return invalidHint; +} diff --git a/src/controls/QskSkinHintTable.h b/src/controls/QskSkinHintTable.h new file mode 100644 index 00000000..3b98261b --- /dev/null +++ b/src/controls/QskSkinHintTable.h @@ -0,0 +1,131 @@ +/****************************************************************************** + * QSkinny - Copyright (C) 2016 Uwe Rathmann + * This file may be used under the terms of the QSkinny License, Version 1.0 + *****************************************************************************/ + +#ifndef QSK_SKIN_HINT_TABLE_H +#define QSK_SKIN_HINT_TABLE_H + +#include "QskGlobal.h" +#include "QskAspect.h" +#include "QskAnimationHint.h" + +#include +#include + +#include +#include + +class QSK_EXPORT QskSkinHintTable +{ +public: + QskSkinHintTable( bool extraAnimatorLookup ); + ~QskSkinHintTable(); + + void setColor( QskAspect::Aspect, Qt::GlobalColor ); + void setColor( QskAspect::Aspect, QRgb ); + + void setColor( QskAspect::Aspect, const QColor& ); + QColor color( QskAspect::Aspect aspect ) const; + + void setMetric( QskAspect::Aspect, qreal metric ); + qreal metric( QskAspect::Aspect ) const; + + void setAnimation( QskAspect::Aspect, QskAnimationHint animation ); + QskAnimationHint animation( QskAspect::Aspect ) const; + + void setGraphicRole( QskAspect::Aspect, int role ); + void setFontRole( QskAspect::Aspect, int role ); + void setFlagHint( QskAspect::Aspect, int flag ); + + bool hasAnimatorLookup() const; + + void setSkinHint( QskAspect::Aspect, const QVariant& ); + const QVariant& skinHint( QskAspect::Aspect ) const; + void removeSkinHint( QskAspect::Aspect ); + + bool hasHint( QskAspect::Aspect ) const; + + const std::set< QskAspect::Aspect >& animatorAspects( QskAspect::Subcontrol ) const; + const std::unordered_map< QskAspect::Aspect, QVariant >& hints() const; + +private: + std::unordered_map< QskAspect::Aspect, QVariant >* m_hints; + std::unordered_map< int, std::set< QskAspect::Aspect > >* m_animatorAspects; +}; + +inline bool QskSkinHintTable::hasAnimatorLookup() const +{ + return m_animatorAspects != nullptr; +} + +inline bool QskSkinHintTable::hasHint( QskAspect::Aspect aspect ) const +{ + if ( m_hints ) + return m_hints->find( aspect ) != m_hints->cend(); + + return false; +} + +inline void QskSkinHintTable::setColor( + QskAspect::Aspect aspect, const QColor& color ) +{ + setSkinHint( aspect | QskAspect::Color, color ); +} + +inline void QskSkinHintTable::setColor( + QskAspect::Aspect aspect, Qt::GlobalColor color ) +{ + setSkinHint( aspect | QskAspect::Color, QColor( color ) ); +} + +inline void QskSkinHintTable::setColor( + QskAspect::Aspect aspect, QRgb rgb ) +{ + setSkinHint( aspect | QskAspect::Color, QColor::fromRgba( rgb ) ); +} + +inline QColor QskSkinHintTable::color( QskAspect::Aspect aspect ) const +{ + return skinHint( aspect | QskAspect::Color ).value(); +} + +inline void QskSkinHintTable::setMetric( QskAspect::Aspect aspect, qreal metric ) +{ + setSkinHint( aspect | QskAspect::Metric, metric ); +} + +inline qreal QskSkinHintTable::metric( QskAspect::Aspect aspect ) const +{ + return skinHint( aspect | QskAspect::Metric ).toReal(); +} + +inline void QskSkinHintTable::setAnimation( + QskAspect::Aspect aspect, QskAnimationHint animation ) +{ + aspect.setAnimator( true ); + setSkinHint( aspect, QVariant::fromValue( animation ) ); +} + +inline QskAnimationHint QskSkinHintTable::animation( QskAspect::Aspect aspect ) const +{ + aspect.setAnimator( true ); + return skinHint( aspect ).value< QskAnimationHint >(); +} + +inline void QskSkinHintTable::setGraphicRole( QskAspect::Aspect aspect, int role ) +{ + setSkinHint( aspect | QskAspect::GraphicRole, role ); +} + +inline void QskSkinHintTable::setFontRole( QskAspect::Aspect aspect, int role ) +{ + setSkinHint( aspect | QskAspect::FontRole, role ); +} + +inline void QskSkinHintTable::setFlagHint( QskAspect::Aspect aspect, int flag ) +{ + setSkinHint( aspect, QVariant( flag ) ); +} + +#endif diff --git a/src/controls/QskSkinTransition.cpp b/src/controls/QskSkinTransition.cpp index db0328c7..d2c83ea4 100644 --- a/src/controls/QskSkinTransition.cpp +++ b/src/controls/QskSkinTransition.cpp @@ -1,6 +1,7 @@ #include "QskSkinTransition.h" #include "QskControl.h" #include "QskSkin.h" +#include "QskSkinHintTable.h" #include "QskColorFilter.h" #include "QskHintAnimator.h" @@ -421,14 +422,14 @@ void QskSkinTransition::process() // copy out all hints before updating the skin // - would be good to have Copy on Write here - const auto oldMap = m_skins[0]->skinHints(); + const auto oldMap = m_skins[0]->hintTable().hints(); const auto oldFilters = m_skins[0]->graphicFilters(); // apply the changes updateSkin( m_skins[0], m_skins[1] ); candidates = qskAnimatorCandidates( m_mask, oldMap, oldFilters, - m_skins[1]->skinHints(), m_skins[1]->graphicFilters() ); + m_skins[1]->hintTable().hints(), m_skins[1]->graphicFilters() ); } if ( !candidates.isEmpty() ) diff --git a/src/controls/QskSkinnable.cpp b/src/controls/QskSkinnable.cpp index 2471c45e..fed4ae62 100644 --- a/src/controls/QskSkinnable.cpp +++ b/src/controls/QskSkinnable.cpp @@ -8,6 +8,7 @@ #include "QskAspect.h" #include "QskSetup.h" #include "QskSkin.h" +#include "QskSkinHintTable.h" #include "QskSkinlet.h" #include "QskAnimationHint.h" #include "QskHintAnimator.h" @@ -121,7 +122,7 @@ class QskSkinnable::PrivateData { public: PrivateData(): - skinHints( nullptr ), + hintTable( false ), skinlet( nullptr ), skinState( QskAspect::NoState ), hasLocalSkinlet( false ) @@ -132,11 +133,9 @@ public: { if ( skinlet && skinlet->isOwnedBySkinnable() ) delete skinlet; - - delete skinHints; } - std::unordered_map< QskAspect::Aspect, QVariant >* skinHints; + QskSkinHintTable hintTable; QskHintAnimatorTable animators; @@ -207,9 +206,19 @@ const QskSkinlet* QskSkinnable::effectiveSkinlet() const return m_data->skinlet; } +QskSkinHintTable &QskSkinnable::hintTable() +{ + return m_data->hintTable; +} + +const QskSkinHintTable &QskSkinnable::hintTable() const +{ + return m_data->hintTable; +} + void QskSkinnable::setFlagHint( QskAspect::Aspect aspect, int flag ) { - setSkinHint( aspect, QVariant( flag ) ); + m_data->hintTable.setSkinHint( aspect, QVariant( flag ) ); } int QskSkinnable::flagHint( QskAspect::Aspect aspect ) const @@ -219,12 +228,17 @@ int QskSkinnable::flagHint( QskAspect::Aspect aspect ) const void QskSkinnable::setColor( QskAspect::Aspect aspect, const QColor& color ) { - setSkinHint( aspect | QskAspect::Color, color ); + m_data->hintTable.setColor( aspect, color ); } void QskSkinnable::setColor( QskAspect::Aspect aspect, Qt::GlobalColor color ) { - setSkinHint( aspect | QskAspect::Color, QColor( color ) ); + m_data->hintTable.setColor( aspect, color ); +} + +void QskSkinnable::setColor( QskAspect::Aspect aspect, QRgb rgb ) +{ + m_data->hintTable.setColor( aspect, rgb ); } QColor QskSkinnable::color( QskAspect::Aspect aspect, QskSkinHintStatus* status ) const @@ -232,14 +246,9 @@ QColor QskSkinnable::color( QskAspect::Aspect aspect, QskSkinHintStatus* status return effectiveHint( aspect | QskAspect::Color, status ).value< QColor >(); } -void QskSkinnable::setColor( QskAspect::Aspect aspect, QRgb rgb ) -{ - setSkinHint( aspect | QskAspect::Color, QColor::fromRgba( rgb ) ); -} - void QskSkinnable::setMetric( QskAspect::Aspect aspect, qreal metric ) { - setSkinHint( aspect | QskAspect::Metric, metric ); + m_data->hintTable.setMetric( aspect, metric ); } qreal QskSkinnable::metric( QskAspect::Aspect aspect, QskSkinHintStatus* status ) const @@ -263,11 +272,7 @@ QMarginsF QskSkinnable::edgeMetrics( QskAspect::Subcontrol subControl, void QskSkinnable::setFontRole( QskAspect::Aspect aspect, int role ) { - setSkinHint( aspect | QskAspect::FontRole, role ); -#if 1 - if ( QskControl* control = owningControl() ) - control->resetImplicitSize(); -#endif + m_data->hintTable.setFontRole( aspect, role ); } int QskSkinnable::fontRole( QskAspect::Aspect aspect ) const @@ -282,7 +287,7 @@ QFont QskSkinnable::effectiveFont( QskAspect::Aspect aspect ) const void QskSkinnable::setGraphicRole( QskAspect::Aspect aspect, int role ) { - setSkinHint( aspect | QskAspect::GraphicRole, role ); + m_data->hintTable.setGraphicRole( aspect, role ); } int QskSkinnable::graphicRole( QskAspect::Aspect aspect ) const @@ -322,8 +327,7 @@ QskColorFilter QskSkinnable::effectiveGraphicFilter( void QskSkinnable::setAnimation( QskAspect::Aspect aspect, QskAnimationHint animation ) { - aspect.setAnimator( true ); - setSkinHint( aspect, QVariant::fromValue( animation ) ); + m_data->hintTable.setAnimation( aspect, animation ); } QskAnimationHint QskSkinnable::animation( @@ -333,60 +337,6 @@ QskAnimationHint QskSkinnable::animation( return effectiveHint( aspect, status ).value< QskAnimationHint >(); } -void QskSkinnable::setSkinHint( QskAspect::Aspect aspect, const QVariant& skinHint ) -{ - // For edges/corners, add all the implied assignments - if ( aspect.isBoxPrimitive() ) - { - // Special case for Radius, which is actually two primitives - if ( aspect.boxPrimitive() == QskAspect::Radius ) - { - setSkinHint( aspect | QskAspect::RadiusX, skinHint ); - setSkinHint( aspect | QskAspect::RadiusY, skinHint ); - return; - } - - const auto edges = aspect.edge(); - - const auto bitcount = qPopulationCount( static_cast< quint8 >( edges ) ); - if ( !bitcount || bitcount > 1 ) - { - using namespace QskAspect; - - auto aspectEdges = aspect; - aspectEdges.clearEdge(); - - if ( !bitcount || edges & TopEdge ) - setSkinHint( aspectEdges | TopEdge, skinHint ); - - if ( !bitcount || ( edges & LeftEdge ) ) - setSkinHint( aspectEdges | LeftEdge, skinHint ); - - if ( !bitcount || ( edges & RightEdge ) ) - setSkinHint( aspectEdges | RightEdge, skinHint ); - - if ( !bitcount || ( edges & BottomEdge ) ) - setSkinHint( aspectEdges | BottomEdge, skinHint ); - } - - if ( bitcount > 1 ) // Allows 0 to imply AllEdges - return; - } - - if ( m_data->skinHints == nullptr ) - m_data->skinHints = new std::remove_pointer< decltype( m_data->skinHints ) >::type; - - auto it = m_data->skinHints->find( aspect ); - if ( it == m_data->skinHints->end() ) - { - m_data->skinHints->emplace( aspect, skinHint ); - } - else if ( it->second != skinHint ) - { - it->second = skinHint; - } -} - QVariant QskSkinnable::effectiveHint( QskAspect::Aspect aspect, QskSkinHintStatus* status ) const { @@ -463,18 +413,16 @@ QVariant QskSkinnable::animatedValue( return v; } -void QskSkinnable::removeSkinHint( QskAspect::Aspect aspect ) -{ - if ( m_data->skinHints ) - m_data->skinHints->erase( aspect ); -} - const QVariant& QskSkinnable::storedHint( QskAspect::Aspect aspect, QskSkinHintStatus* status ) const { - const auto skin = effectiveSkin(); - return qskResolvedHint( aspect, m_data->skinHints, - skin ? &skin->skinHints() : nullptr, status ); + const auto& localHints = m_data->hintTable.hints(); + const QskSkin* skin = effectiveSkin(); + + return qskResolvedHint( aspect, + !localHints.empty() ? &localHints : nullptr, + skin ? &skin->hintTable().hints() : nullptr, + status ); } QskAspect::State QskSkinnable::skinState() const @@ -746,44 +694,39 @@ void QskSkinnable::setSkinStateFlag( QskAspect::State state, bool on ) QskControl* control = owningControl(); if ( control->window() && control->isInitiallyPainted() ) { - const auto localHints = m_data->skinHints; - - if ( localHints ) + for ( const auto entry : m_data->hintTable.hints() ) { - for ( const auto entry : *localHints ) + const auto aspect = entry.first; + if ( aspect.isAnimator() ) { - const auto aspect = entry.first; - if ( aspect.isAnimator() ) - { - if ( !aspect.state() || aspect.state() == newState ) - startTransition( aspect, m_data->skinState, newState ); - } + if ( !aspect.state() || aspect.state() == newState ) + startTransition( aspect, m_data->skinState, newState ); } } - const auto skin = effectiveSkin(); + const QskSkin* skin = effectiveSkin(); auto subControls = control->subControls(); #if 1 subControls += QskAspect::Control; #endif + const auto& hintTable = skin->hintTable(); + for ( const auto subControl : subControls ) { - const auto& animatorAspects = skin->animatorAspects( subControl ); + const auto& animatorAspects = hintTable.animatorAspects( subControl ); for ( QskAspect::Aspect aspect : animatorAspects ) { - if ( localHints && ( localHints->find( aspect ) != localHints->end() ) ) + // ignore animators from the skin, when we have others + // specifically defined for the skinnable + + if ( !m_data->hintTable.hasHint( aspect ) ) { - // ignore animators from the skin, when we have others - // specifically defined for the skinnable - - continue; + if ( !aspect.state() || aspect.state() == newState ) + startTransition( aspect, m_data->skinState, newState ); } - - if ( !aspect.state() || aspect.state() == newState ) - startTransition( aspect, m_data->skinState, newState ); } } } diff --git a/src/controls/QskSkinnable.h b/src/controls/QskSkinnable.h index 7bba6127..5b6b43fa 100644 --- a/src/controls/QskSkinnable.h +++ b/src/controls/QskSkinnable.h @@ -30,6 +30,7 @@ class QskColorFilter; class QskSkin; class QskSkinlet; +class QskSkinHintTable; class QSK_EXPORT QskSkinHintStatus { @@ -95,8 +96,6 @@ public: void setAnimation( QskAspect::Aspect, QskAnimationHint ); QskAnimationHint animation( QskAspect::Aspect, QskSkinHintStatus* = nullptr ) const; - void removeSkinHint( QskAspect::Aspect ); - QVariant effectiveHint( QskAspect::Aspect, QskSkinHintStatus* = nullptr ) const; QskSkinHintStatus hintStatus( QskAspect::Aspect ) const; @@ -134,9 +133,10 @@ protected: void setSkinStateFlag( QskAspect::State, bool = true ); virtual void updateNode( QSGNode* ); -private: - void setSkinHint( QskAspect::Aspect, const QVariant& ); + QskSkinHintTable &hintTable(); + const QskSkinHintTable &hintTable() const; +private: void startTransition( QskAspect::Aspect, QskAspect::State, QskAspect::State ); QVariant animatedValue( QskAspect::Aspect, QskSkinHintStatus* ) const; const QVariant& storedHint( QskAspect::Aspect, QskSkinHintStatus* = nullptr ) const; diff --git a/src/src.pro b/src/src.pro index cb361882..0bf07493 100644 --- a/src/src.pro +++ b/src/src.pro @@ -157,6 +157,7 @@ HEADERS += \ controls/QskSimpleListBox.h \ controls/QskSkinFactory.h \ controls/QskSkin.h \ + controls/QskSkinHintTable.h \ controls/QskAnimationHint.h \ controls/QskSkinlet.h \ controls/QskSkinnable.h \ @@ -220,6 +221,7 @@ SOURCES += \ controls/QskShortcut.cpp \ controls/QskSimpleListBox.cpp \ controls/QskSkin.cpp \ + controls/QskSkinHintTable.cpp \ controls/QskSkinFactory.cpp \ controls/QskSkinlet.cpp \ controls/QskSkinnable.cpp \