handling of selection states for sampled subcontrols added

This commit is contained in:
Uwe Rathmann 2024-02-01 17:07:50 +01:00
parent 330df7308a
commit 0f9c86d63b

View File

@ -20,6 +20,37 @@
#include <vector>
#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() )