skin transition heavily changed

This commit is contained in:
Uwe Rathmann 2022-03-31 18:09:03 +02:00
parent 27ee0fe423
commit e2d6823927
6 changed files with 590 additions and 572 deletions

View File

@ -64,41 +64,11 @@ QskSkinHintTable::QskSkinHintTable()
{
}
QskSkinHintTable::QskSkinHintTable( const QskSkinHintTable& other )
: m_hints( nullptr )
, m_animatorCount( other.m_animatorCount )
, m_states( other.m_states )
{
if ( other.m_hints )
m_hints = new HintMap( *( other.m_hints ) );
}
QskSkinHintTable::~QskSkinHintTable()
{
delete m_hints;
}
QskSkinHintTable& QskSkinHintTable::operator=( const QskSkinHintTable& other )
{
m_animatorCount = other.m_animatorCount;
m_states = other.m_states;
if ( other.m_hints )
{
if ( m_hints == nullptr )
m_hints = new HintMap();
*m_hints = *other.m_hints;
}
else
{
delete m_hints;
m_hints = nullptr;
}
return *this;
}
const std::unordered_map< QskAspect, QVariant >& QskSkinHintTable::hints() const
{
if ( m_hints )

View File

@ -17,12 +17,8 @@ class QSK_EXPORT QskSkinHintTable
{
public:
QskSkinHintTable();
QskSkinHintTable( const QskSkinHintTable& other );
~QskSkinHintTable();
QskSkinHintTable& operator=( const QskSkinHintTable& );
bool setAnimation( QskAspect, QskAnimationHint );
QskAnimationHint animation( QskAspect ) const;
@ -57,6 +53,8 @@ class QSK_EXPORT QskSkinHintTable
bool isResolutionMatching( QskAspect, QskAspect ) const;
private:
Q_DISABLE_COPY( QskSkinHintTable )
static const QVariant invalidHint;
typedef std::unordered_map< QskAspect, QVariant > HintMap;

File diff suppressed because it is too large Load Diff

View File

@ -38,16 +38,6 @@ static inline bool qskIsControl( const QskSkinnable* skinnable )
return skinnable->metaObject()->inherits( &QskControl::staticMetaObject );
}
static inline QVariant qskTypedNullValue( const QVariant& value )
{
#if QT_VERSION >= QT_VERSION_CHECK( 6, 0, 0 )
return QVariant( value.metaType() );
#else
return QVariant( value.userType(), nullptr );
#endif
}
static inline bool qskSetFlag( QskSkinnable* skinnable,
const QskAspect aspect, int flag )
{
@ -1155,27 +1145,11 @@ void QskSkinnable::startHintTransition( QskAspect aspect,
if ( control->window() == nullptr || !isTransitionAccepted( aspect ) )
return;
/*
We might be invalid for one of the values, when an aspect
has not been defined for all states ( f.e. metrics are expected
to fallback to 0.0 ). In this case we create a default one.
*/
auto v1 = from;
auto v2 = to;
if ( !v1.isValid() )
{
v1 = qskTypedNullValue( v2 );
}
else if ( !v2.isValid() )
{
v2 = qskTypedNullValue( v1 );
}
else if ( v1.userType() != v2.userType() )
{
if ( !QskVariantAnimator::convertValues( v1, v2 ) )
return;
}
if ( aspect.flagPrimitive() == QskAspect::GraphicRole )
{

View File

@ -76,6 +76,31 @@ QSK_DECL_INSANE static inline QVariant qskInterpolate(
return f( from.constData(), to.constData(), progress );
}
#if QT_VERSION < QT_VERSION_CHECK( 6, 0, 0 )
using QskMetaType = int;
static inline QskMetaType qskMetaType( const QVariant& v ) { return v.userType(); }
#else
using QskMetaType = QMetaType;
static inline QskMetaType qskMetaType( const QVariant& v ) { return v.metaType(); }
#endif
static inline QVariant qskDefaultVariant( QskMetaType type )
{
return QVariant( type, nullptr );
}
static inline QVariant qskConvertedVariant( const QVariant& from, QskMetaType type )
{
auto v = from;
v.convert( type );
return v;
}
QskVariantAnimator::QskVariantAnimator()
: m_interpolator( nullptr )
{
@ -100,35 +125,60 @@ void QskVariantAnimator::setCurrentValue( const QVariant& value )
m_currentValue = value;
}
bool QskVariantAnimator::convertValues( QVariant& v1, QVariant& v2 )
{
if ( !v1.isValid() && !v2.isValid() )
return false;
const auto type1 = qskMetaType( v1 );
const auto type2 = qskMetaType( v2 );
if ( !v1.isValid() )
{
v1 = qskDefaultVariant( type2 );
return true;
}
if ( !v2.isValid() )
{
v2 = qskDefaultVariant( type1 );
return true;
}
if ( type1 != type2 )
{
if ( v1.canConvert( type2 ) )
{
v1.convert( type2 );
return true;
}
if ( v2.canConvert( type1 ) )
{
v2.convert( type1 );
return true;
}
return false;
}
return true;
}
void QskVariantAnimator::setup()
{
m_interpolator = nullptr;
if ( m_startValue.userType() != m_endValue.userType() )
if ( convertValues( m_startValue, m_endValue ) )
{
/*
Convert one value so that the types are matching.
As a side effect startValue()/endValue() won't return what had
been set setStartValue()/setEndValue() !
*/
if ( m_startValue.canConvert( m_endValue.userType() ) )
if ( m_startValue != m_endValue )
{
m_startValue.convert( m_endValue.userType() );
}
else if ( m_endValue.canConvert( m_startValue.userType() ) )
{
m_endValue.convert( m_startValue.userType() );
}
}
const auto id = m_startValue.userType();
const auto type = m_startValue.userType();
if ( type == m_endValue.userType() )
{
// all what has been registered by qRegisterAnimationInterpolator
m_interpolator = reinterpret_cast< void ( * )() >(
QVariantAnimationPrivate::getInterpolator( type ) );
// all what has been registered by qRegisterAnimationInterpolator
m_interpolator = reinterpret_cast< void ( * )() >(
QVariantAnimationPrivate::getInterpolator( id ) );
}
}
m_currentValue = m_interpolator ? m_startValue : m_endValue;
@ -150,3 +200,32 @@ void QskVariantAnimator::done()
{
m_interpolator = nullptr;
}
bool QskVariantAnimator::maybeInterpolate(
const QVariant& value1, const QVariant& value2 )
{
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 ( value1.canConvert( type2 ) )
return value2 != qskConvertedVariant( value1, type2 );
if ( value2.canConvert( type1 ) )
return value1 != qskConvertedVariant( value2, type1 );
return false;
}
return value1 != value2;
}

View File

@ -24,6 +24,9 @@ class QSK_EXPORT QskVariantAnimator : public QskAnimator
void setEndValue( const QVariant& );
QVariant endValue() const;
static bool maybeInterpolate( const QVariant&, const QVariant& );
static bool convertValues( QVariant&, QVariant& );
protected:
void setup() override;
void advance( qreal value ) override;