better seperation between state animators and those for skin changes

This commit is contained in:
Uwe Rathmann 2022-09-09 10:25:46 +02:00
parent 50ec41868d
commit 47df732f4a
2 changed files with 85 additions and 90 deletions

View File

@ -737,7 +737,8 @@ QskColorFilter QskSkinnable::effectiveGraphicFilter(
aspect.setSection( QskAspect::Body ); aspect.setSection( QskAspect::Body );
aspect.setPlacement( QskAspect::NoPlacement ); aspect.setPlacement( QskAspect::NoPlacement );
const auto v = animatedValue( aspect, nullptr ); const auto v = animatedHint( aspect, nullptr );
if ( v.canConvert< QskColorFilter >() ) if ( v.canConvert< QskColorFilter >() )
return v.value< QskColorFilter >(); return v.value< QskColorFilter >();
@ -866,22 +867,33 @@ QVariant QskSkinnable::effectiveSkinHint(
{ {
aspect.setSubControl( effectiveSubcontrol( aspect.subControl() ) ); aspect.setSubControl( effectiveSubcontrol( aspect.subControl() ) );
if ( !( aspect.isAnimator() || aspect.hasStates() ) )
{
const auto v = animatedHint( aspect, status );
if ( v.isValid() )
return v;
}
if ( aspect.section() == QskAspect::Body ) if ( aspect.section() == QskAspect::Body )
aspect.setSection( section() ); aspect.setSection( section() );
if ( aspect.placement() == QskAspect::NoPlacement ) if ( aspect.placement() == QskAspect::NoPlacement )
aspect.setPlacement( effectivePlacement() ); aspect.setPlacement( effectivePlacement() );
if ( aspect.isAnimator() )
return storedHint( aspect, status );
const auto v = animatedValue( aspect, status );
if ( v.isValid() )
return v;
if ( !aspect.hasStates() ) if ( !aspect.hasStates() )
aspect.setStates( skinStates() ); aspect.setStates( skinStates() );
if ( !aspect.isAnimator() && QskSkinTransition::isRunning() )
{
/*
The skin has changed and the hints are interpolated
between the old and the new one over time
*/
const auto v = interpolatedHint( aspect, status );
if ( v.isValid() )
return v;
}
return storedHint( aspect, status ); return storedHint( aspect, status );
} }
@ -919,12 +931,12 @@ bool QskSkinnable::moveSkinHint( QskAspect aspect, const QVariant& value )
return moveSkinHint( aspect, effectiveSkinHint( aspect ), value ); return moveSkinHint( aspect, effectiveSkinHint( aspect ), value );
} }
QVariant QskSkinnable::animatedValue( QVariant QskSkinnable::animatedHint(
QskAspect aspect, QskSkinHintStatus* status ) const QskAspect aspect, QskSkinHintStatus* status ) const
{ {
QVariant v; QVariant v;
if ( !m_data->animators.isEmpty() && !aspect.hasStates() ) if ( !m_data->animators.isEmpty() )
{ {
/* /*
The local animators were invented to be stateless The local animators were invented to be stateless
@ -932,53 +944,29 @@ QVariant QskSkinnable::animatedValue(
But that might change ... But that might change ...
*/ */
auto a = aspect;
Q_FOREVER
{
v = m_data->animators.currentValue( aspect ); v = m_data->animators.currentValue( aspect );
if ( !v.isValid() )
{
if ( aspect.placement() )
{
// clear the placement bits and restart
aspect = a;
aspect.setPlacement( QskAspect::NoPlacement );
continue;
}
} }
if ( aspect.section() != QskAspect::Body ) if ( status && v.isValid() )
{ {
// try to resolve from QskAspect::Body status->source = QskSkinHintStatus::Animator;
status->aspect = aspect;
a.setSection( QskAspect::Body );
aspect = a;
continue;
} }
break; return v;
}
} }
if ( !v.isValid() ) QVariant QskSkinnable::interpolatedHint(
QskAspect aspect, QskSkinHintStatus* status ) const
{ {
if ( QskSkinTransition::isRunning() && if ( !QskSkinTransition::isRunning() || m_data->hintTable.hasHint( aspect ) )
!m_data->hintTable.hasHint( aspect ) ) return QVariant();
{
/*
Next we check for values from the skin. Those
animators are usually from global skin/color changes
and are state aware
*/
if ( const auto control = owningControl() ) const auto control = owningControl();
{ if ( control == nullptr )
if ( !aspect.hasStates() ) return QVariant();
aspect.setStates( skinStates() );
QVariant v;
auto a = aspect; auto a = aspect;
@ -1004,9 +992,9 @@ QVariant QskSkinnable::animatedValue(
} }
} }
if ( aspect.section() != QskAspect::Body ) if ( a.section() != QskAspect::Body )
{ {
// try to resolve from QskAspect::Body // try to resolve with the default section
a.setSection( QskAspect::Body ); a.setSection( QskAspect::Body );
aspect = a; aspect = a;
@ -1016,9 +1004,6 @@ QVariant QskSkinnable::animatedValue(
break; break;
} }
}
}
}
if ( status && v.isValid() ) if ( status && v.isValid() )
{ {
@ -1264,9 +1249,15 @@ void QskSkinnable::startHintTransition( QskAspect aspect,
v2.setValue( skin->graphicFilter( v2.toInt() ) ); v2.setValue( skin->graphicFilter( v2.toInt() ) );
} }
/*
We do not need the extra bits that would slow down resolving
the effective aspect in animatedHint.
*/
aspect.clearStates(); aspect.clearStates();
aspect.setSection( QskAspect::Body );
aspect.setPlacement( QskAspect::NoPlacement );
aspect.setAnimator( false ); aspect.setAnimator( false );
aspect.setPlacement( effectivePlacement() );
#if DEBUG_ANIMATOR #if DEBUG_ANIMATOR
qDebug() << aspect << animationHint.duration; qDebug() << aspect << animationHint.duration;
@ -1333,13 +1324,16 @@ void QskSkinnable::setSkinStates( QskAspect::States newStates )
if ( control->window() && isTransitionAccepted( QskAspect() ) ) if ( control->window() && isTransitionAccepted( QskAspect() ) )
{ {
const auto placement = effectivePlacement(); QskAspect aspect;
aspect.setPlacement( effectivePlacement() );
aspect.setSection( section() );
const auto primitiveCount = QskAspect::primitiveCount(); const auto primitiveCount = QskAspect::primitiveCount();
const auto subControls = control->subControls(); const auto subControls = control->subControls();
for ( const auto subControl : subControls ) for ( const auto subControl : subControls )
{ {
auto aspect = subControl | placement; aspect.setSubControl( subControl );
const auto& skinTable = skin->hintTable(); const auto& skinTable = skin->hintTable();

View File

@ -261,7 +261,8 @@ class QSK_EXPORT QskSkinnable
void startHintTransition( QskAspect, void startHintTransition( QskAspect,
QskAnimationHint, const QVariant& from, const QVariant& to ); QskAnimationHint, const QVariant& from, const QVariant& to );
QVariant animatedValue( QskAspect, QskSkinHintStatus* ) const; QVariant animatedHint( QskAspect, QskSkinHintStatus* ) const;
QVariant interpolatedHint( QskAspect, QskSkinHintStatus* ) const;
const QVariant& storedHint( QskAspect, QskSkinHintStatus* = nullptr ) const; const QVariant& storedHint( QskAspect, QskSkinHintStatus* = nullptr ) const;
class PrivateData; class PrivateData;