startHintTransitions added to be able to start transitions withot

changing the state
This commit is contained in:
Uwe Rathmann 2022-09-09 11:29:47 +02:00
parent 47df732f4a
commit 996e849fc5
2 changed files with 80 additions and 57 deletions

View File

@ -1302,91 +1302,113 @@ void QskSkinnable::setSkinStates( QskAspect::States newStates )
auto control = owningControl(); auto control = owningControl();
#if DEBUG_STATE #if DEBUG_STATE
qDebug() << control->className() << ":" const auto className = control ? control->className() : "QskSkinnable";
qDebug() << className << ":"
<< skinStateAsPrintable( m_data->skinState ) << "->" << skinStateAsPrintable( m_data->skinState ) << "->"
<< skinStateAsPrintable( newState ); << skinStateAsPrintable( newState );
#endif #endif
const auto skin = effectiveSkin(); if ( control && control->window() )
if ( skin )
{ {
const auto mask = skin->hintTable().states() | m_data->hintTable.states(); const bool needUpdate = startHintTransitions( m_data->skinStates, newStates );
if ( needUpdate )
if ( ( newStates & mask ) == ( m_data->skinStates & mask ) )
{ {
// the modified bits are not handled by the skin if ( control->flags() & QQuickItem::ItemHasContents )
control->update();
m_data->skinStates = newStates;
return;
} }
} }
if ( control->window() && isTransitionAccepted( QskAspect() ) ) m_data->skinStates = newStates;
}
bool QskSkinnable::startHintTransitions(
QskAspect::States oldStates, QskAspect::States newStates )
{
const auto skin = effectiveSkin();
auto control = owningControl();
if ( skin == nullptr || control == nullptr || control->window() == nullptr )
return false;
const auto mask = m_data->hintTable.states() | skin->hintTable().states();
if ( ( newStates & mask ) == ( oldStates & mask ) )
{ {
QskAspect aspect; /*
aspect.setPlacement( effectivePlacement() ); When there are no aspects for the changed state bits we know
aspect.setSection( section() ); that there won't be any animated transitions
*/
return false;
}
const auto primitiveCount = QskAspect::primitiveCount(); if ( !isTransitionAccepted( QskAspect() ) )
{
// the control does not like any animated transition at the moment
return false;
}
const auto subControls = control->subControls(); bool started = false; // at least one transition has been started
for ( const auto subControl : subControls )
QskAspect aspect;
aspect.setPlacement( effectivePlacement() );
aspect.setSection( section() );
const auto primitiveCount = QskAspect::primitiveCount();
const auto subControls = control->subControls();
for ( const auto subControl : subControls )
{
aspect.setSubControl( subControl );
const auto& skinTable = skin->hintTable();
for ( uint i = 0; i < QskAspect::typeCount; i++ )
{ {
aspect.setSubControl( subControl ); const auto type = static_cast< QskAspect::Type >( i );
const auto& skinTable = skin->hintTable(); const auto hint = effectiveAnimation( type, subControl, newStates );
for ( uint i = 0; i < QskAspect::typeCount; i++ ) if ( hint.duration > 0 )
{ {
const auto type = static_cast< QskAspect::Type >( i ); /*
Starting an animator for all primitives,
that differ between the states
*/
const auto hint = effectiveAnimation( type, subControl, newStates ); for ( uint i = 0; i < primitiveCount; i++ )
if ( hint.duration > 0 )
{ {
/* const auto primitive = static_cast< QskAspect::Primitive >( i );
Starting an animator for all primitives, aspect.setPrimitive( type, primitive );
that differ between the states
*/
for ( uint i = 0; i < primitiveCount; i++ ) const auto a1 = aspect | m_data->skinStates;
const auto a2 = aspect | newStates;
bool doTransition = true;
if ( m_data->hintTable.states() == QskAspect::NoState )
{ {
const auto primitive = static_cast< QskAspect::Primitive >( i ); /*
aspect.setPrimitive( type, primitive ); In case we have no state aware aspects in the local
table we can avoid starting animators for aspects,
that are finally resolved from the same hint in
the skin table.
*/
doTransition = !skinTable.isResolutionMatching( a1, a2 );
}
const auto a1 = aspect | m_data->skinStates; if ( doTransition )
const auto a2 = aspect | newStates; {
startHintTransition( aspect, hint,
storedHint( a1 ), storedHint( a2 ) );
bool doTransition = true; started = true;
if ( m_data->hintTable.states() == QskAspect::NoState )
{
/*
In case we have no state aware aspects in the local
table we can avoid starting animators for aspects,
that are finally resolved from the same hint in
the skin table.
*/
doTransition = !skinTable.isResolutionMatching( a1, a2 );
}
if ( doTransition )
{
startHintTransition( aspect, hint,
storedHint( a1 ), storedHint( a2 ) );
}
} }
} }
} }
} }
} }
m_data->skinStates = newStates; return started;
if ( control->flags() & QQuickItem::ItemHasContents )
control->update();
} }
QskSkin* QskSkinnable::effectiveSkin() const QskSkin* QskSkinnable::effectiveSkin() const

View File

@ -258,6 +258,7 @@ class QSK_EXPORT QskSkinnable
private: private:
Q_DISABLE_COPY( QskSkinnable ) Q_DISABLE_COPY( QskSkinnable )
bool startHintTransitions( QskAspect::States, QskAspect::States );
void startHintTransition( QskAspect, void startHintTransition( QskAspect,
QskAnimationHint, const QVariant& from, const QVariant& to ); QskAnimationHint, const QVariant& from, const QVariant& to );