diff --git a/src/controls/QskSkinTransition.cpp b/src/controls/QskSkinTransition.cpp index 131440ec..0d9f4718 100644 --- a/src/controls/QskSkinTransition.cpp +++ b/src/controls/QskSkinTransition.cpp @@ -365,14 +365,29 @@ void WindowAnimator::addHints( const QskControl* control, if ( v1 && v2 ) { - if ( QskVariantAnimator::maybeInterpolate( *v1, *v2 ) ) + 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() ) { - if ( r1.variation() == r2.variation() ) - aspect.setVariation( r2.variation() ); - - if ( r1.states() == r2.states() ) - aspect.setStates( r2.states() ); + /* + 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 ); } diff --git a/src/controls/QskSkinnable.cpp b/src/controls/QskSkinnable.cpp index cf73ea7c..0ca14bdc 100644 --- a/src/controls/QskSkinnable.cpp +++ b/src/controls/QskSkinnable.cpp @@ -1316,7 +1316,7 @@ void QskSkinnable::startHintTransition( QskAspect aspect, int index, if ( control->window() == nullptr || !isTransitionAccepted( aspect ) ) return; - if ( !QskVariantAnimator::maybeInterpolate( from, to ) ) + if ( !QskVariantAnimator::maybeInterpolate( from, to, false ) ) return; auto v1 = from; diff --git a/src/controls/QskVariantAnimator.cpp b/src/controls/QskVariantAnimator.cpp index 7518cc9a..1b2b986a 100644 --- a/src/controls/QskVariantAnimator.cpp +++ b/src/controls/QskVariantAnimator.cpp @@ -210,30 +210,46 @@ void QskVariantAnimator::done() } bool QskVariantAnimator::maybeInterpolate( - const QVariant& value1, const QVariant& value2 ) + const QVariant& value1, const QVariant& value2, bool acceptIdentity ) { if ( !value1.isValid() && !value2.isValid() ) return false; - const auto type1 = qskMetaType( value1 ); - const auto type2 = qskMetaType( value2 ); - - if ( !value1.isValid() ) - return value2 != qskDefaultVariant( type2 ); - - if ( !value2.isValid() ) - return value1 != qskDefaultVariant( type1 ); - - if ( type1 != type2 ) + if ( acceptIdentity ) { - if ( value1.canConvert( type2 ) ) - return value2 != qskConvertedVariant( value1, type2 ); + if ( value1.isValid() && value2.isValid() ) + { + const auto type1 = qskMetaType( value1 ); + const auto type2 = qskMetaType( value2 ); - if ( value2.canConvert( type1 ) ) - return value1 != qskConvertedVariant( value2, type1 ); + if ( type1 != type2 ) + return value1.canConvert( type2 ) || value2.canConvert( type1 ); + } - return false; + return true; } + else + { + const auto type1 = qskMetaType( value1 ); + const auto type2 = qskMetaType( value2 ); - return value1 != value2; + if ( !value1.isValid() ) + return value2 != qskDefaultVariant( type2 ); + + if ( !value2.isValid() ) + return value1 != qskDefaultVariant( type1 ); + + if ( type1 != type2 ) + { + if ( value1.canConvert( type2 ) ) + return value2 != qskConvertedVariant( value1, type2 ); + + if ( value2.canConvert( type1 ) ) + return value1 != qskConvertedVariant( value2, type1 ); + + return false; + } + + return value1 != value2; + } } diff --git a/src/controls/QskVariantAnimator.h b/src/controls/QskVariantAnimator.h index 0f86e78a..5f233f63 100644 --- a/src/controls/QskVariantAnimator.h +++ b/src/controls/QskVariantAnimator.h @@ -24,7 +24,9 @@ class QSK_EXPORT QskVariantAnimator : public QskAnimator void setEndValue( const QVariant& ); QVariant endValue() const; - static bool maybeInterpolate( const QVariant&, const QVariant& ); + static bool maybeInterpolate( + const QVariant&, const QVariant&, bool acceptIdentity ); + static bool convertValues( QVariant&, QVariant& ); protected: