diff --git a/src/controls/QskSkinTransition.cpp b/src/controls/QskSkinTransition.cpp index 0d9f4718..76c5c7e3 100644 --- a/src/controls/QskSkinTransition.cpp +++ b/src/controls/QskSkinTransition.cpp @@ -20,6 +20,37 @@ #include +#if 1 + +/* + We need to find a way how to retrieve the extra states that are provided + by QskSkinlet::sampleStates from the control in a generic way. For the moment we + return a hardcoded list of states that we know because we know. TODO ... + */ +#include "QskMenu.h" +#include "QskRadioBox.h" +#include "QskSegmentedBar.h" +#include "QskListView.h" + +static QskAspect::State qskSelectedSampleState( const QskControl* control ) +{ + if ( qobject_cast< const QskMenu* >( control ) ) + return QskMenu::Selected; + + if ( qobject_cast< const QskRadioBox* >( control ) ) + return QskRadioBox::Selected; + + if ( qobject_cast< const QskSegmentedBar* >( control ) ) + return QskSegmentedBar::Selected; + + if ( qobject_cast< const QskListView* >( control ) ) + return QskListView::Selected; + + return QskAspect::NoState; +} + +#endif + static bool qskHasHintTable( const QskSkin* skin, const QskSkinHintTable& hintTable ) { return skin->hintTable().hints().isSharedWith( hintTable.hints() ); @@ -145,8 +176,8 @@ namespace bool isControlAffected( const QskControl*, const QVector< QskAspect::Subcontrol >&, QskAspect ) const; - void addHints( const QskControl*, - const QskAnimationHint&, const QSet< QskAspect >& candidates, + void addHint( const QskControl*, + const QskAnimationHint&, QskAspect, const QskSkinHintTable&, const QskSkinHintTable& ); void storeAnimator( const QskControl*, const QskAspect, @@ -293,22 +324,42 @@ void WindowAnimator::addItemAspects( QQuickItem* item, const QskAnimationHint& animatorHint, const QSet< QskAspect >& candidates, const QskSkinHintTable& table1, const QskSkinHintTable& table2 ) { - if ( !item->isVisible() ) - return; - - if ( auto control = qskControlCast( item ) ) + if ( auto control = qskControlCast( ( const QQuickItem* )item ) ) { - if ( control->isInitiallyPainted() && + if ( control->isVisible() && control->isInitiallyPainted() && qskHasHintTable( control->effectiveSkin(), table2 ) ) { - addHints( control, animatorHint, candidates, table1, table2 ); + const auto subControls = control->subControls(); + + const auto& localTable = control->hintTable(); + + for ( auto aspect : candidates ) + { + if ( isControlAffected( control, subControls, aspect ) ) + { + aspect.setVariation( control->effectiveVariation() ); + aspect.setStates( control->skinStates() ); + aspect.setSection( control->section() ); + + if ( !localTable.resolvedHint( aspect ) ) + addHint( control, animatorHint, aspect, table1, table2 ); + + if ( auto state = qskSelectedSampleState( control ) ) + { + aspect.addStates( state ); + if ( !localTable.resolvedHint( aspect ) ) + addHint( control, animatorHint, aspect, table1, table2 ); + } + } + } + #if 1 /* As it is hard to identify which controls depend on the animated graphic filters we schedule an initial update and let the controls do the rest: see QskSkinnable::effectiveGraphicFilter */ - control->update(); + item->update(); #endif } } @@ -336,78 +387,59 @@ void WindowAnimator::update() } } -void WindowAnimator::addHints( const QskControl* control, - const QskAnimationHint& animatorHint, const QSet< QskAspect >& candidates, +void WindowAnimator::addHint( const QskControl* control, + const QskAnimationHint& animatorHint, QskAspect aspect, const QskSkinHintTable& table1, const QskSkinHintTable& table2 ) { - const auto subControls = control->subControls(); + QskAspect r1, r2; - const auto& localTable = control->hintTable(); + const auto v1 = table1.resolvedHint( aspect, &r1 ); + const auto v2 = table2.resolvedHint( aspect, &r2 ); - for ( auto aspect : candidates ) + if ( v1 && v2 ) { - if ( !isControlAffected( control, subControls, aspect ) ) - continue; + if ( r1.section() == r2.section() ) + aspect.setSection( r2.section() ); - aspect.setVariation( control->effectiveVariation() ); - aspect.setStates( control->skinStates() ); + if ( r1.variation() == r2.variation() ) + aspect.setVariation( r2.variation() ); - if ( localTable.resolvedHint( aspect ) ) + if ( r1.states() == r2.states() ) + aspect.setStates( r2.states() ); + + bool accecptIdentity = false; + if ( aspect != aspect.trunk() ) { - // value is not from the skin - ignored - continue; + /* + We might need an animator even if the values do not differ + to prevent effectiveSkinHint to find its value from + another animator that might have been started with + less extra bits. + */ + accecptIdentity = true; } - QskAspect r1, r2; - - const auto v1 = table1.resolvedHint( aspect, &r1 ); - const auto v2 = table2.resolvedHint( aspect, &r2 ); - - if ( v1 && v2 ) + if ( QskVariantAnimator::maybeInterpolate( *v1, *v2, accecptIdentity ) ) { - if ( r1.section() == r2.section() ) - aspect.setSection( r2.section() ); - - if ( r1.variation() == r2.variation() ) - aspect.setVariation( r2.variation() ); - - if ( r1.states() == r2.states() ) - aspect.setStates( r2.states() ); - - bool accecptIdentity = false; - if ( aspect != aspect.trunk() ) - { - /* - We might need an animator even if the values do not differ - to prevent effectiveSkinHint to find its value from - another animator that might have been started with - less extra bits. - */ - accecptIdentity = true; - } - - if ( QskVariantAnimator::maybeInterpolate( *v1, *v2, accecptIdentity ) ) - { - storeAnimator( control, aspect, *v1, *v2, animatorHint ); - storeUpdateInfo( control, aspect ); - } - } - else if ( v1 ) - { - aspect.setVariation( r1.variation() ); - aspect.setStates( r1.states() ); - - storeAnimator( control, aspect, *v1, QVariant(), animatorHint ); + storeAnimator( control, aspect, *v1, *v2, animatorHint ); storeUpdateInfo( control, aspect ); } - else if ( v2 ) - { - aspect.setVariation( r1.variation() ); - aspect.setStates( r1.states() ); + } + else if ( v1 ) + { + aspect.setVariation( r1.variation() ); + aspect.setStates( r1.states() ); - storeAnimator( control, aspect, QVariant(), *v2, animatorHint ); - storeUpdateInfo( control, aspect ); - } + storeAnimator( control, aspect, *v1, QVariant(), animatorHint ); + storeUpdateInfo( control, aspect ); + } + else if ( v2 ) + { + aspect.setVariation( r1.variation() ); + aspect.setStates( r1.states() ); + + storeAnimator( control, aspect, QVariant(), *v2, animatorHint ); + storeUpdateInfo( control, aspect ); } } @@ -445,7 +477,8 @@ inline bool WindowAnimator::isControlAffected( const QskControl* control, return true; } -inline void WindowAnimator::storeAnimator( const QskControl* control, const QskAspect aspect, +inline void WindowAnimator::storeAnimator( + const QskControl* control, const QskAspect aspect, const QVariant& value1, const QVariant& value2, QskAnimationHint hint ) { if ( m_animatorMap.find( aspect ) == m_animatorMap.cend() )