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() QskSkinHintTable::~QskSkinHintTable()
{ {
delete m_hints; 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 const std::unordered_map< QskAspect, QVariant >& QskSkinHintTable::hints() const
{ {
if ( m_hints ) if ( m_hints )

View File

@ -17,12 +17,8 @@ class QSK_EXPORT QskSkinHintTable
{ {
public: public:
QskSkinHintTable(); QskSkinHintTable();
QskSkinHintTable( const QskSkinHintTable& other );
~QskSkinHintTable(); ~QskSkinHintTable();
QskSkinHintTable& operator=( const QskSkinHintTable& );
bool setAnimation( QskAspect, QskAnimationHint ); bool setAnimation( QskAspect, QskAnimationHint );
QskAnimationHint animation( QskAspect ) const; QskAnimationHint animation( QskAspect ) const;
@ -57,6 +53,8 @@ class QSK_EXPORT QskSkinHintTable
bool isResolutionMatching( QskAspect, QskAspect ) const; bool isResolutionMatching( QskAspect, QskAspect ) const;
private: private:
Q_DISABLE_COPY( QskSkinHintTable )
static const QVariant invalidHint; static const QVariant invalidHint;
typedef std::unordered_map< QskAspect, QVariant > HintMap; 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 ); 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, static inline bool qskSetFlag( QskSkinnable* skinnable,
const QskAspect aspect, int flag ) const QskAspect aspect, int flag )
{ {
@ -1155,27 +1145,11 @@ void QskSkinnable::startHintTransition( QskAspect aspect,
if ( control->window() == nullptr || !isTransitionAccepted( aspect ) ) if ( control->window() == nullptr || !isTransitionAccepted( aspect ) )
return; 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 v1 = from;
auto v2 = to; auto v2 = to;
if ( !v1.isValid() ) if ( !QskVariantAnimator::convertValues( v1, v2 ) )
{
v1 = qskTypedNullValue( v2 );
}
else if ( !v2.isValid() )
{
v2 = qskTypedNullValue( v1 );
}
else if ( v1.userType() != v2.userType() )
{
return; return;
}
if ( aspect.flagPrimitive() == QskAspect::GraphicRole ) 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 ); 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() QskVariantAnimator::QskVariantAnimator()
: m_interpolator( nullptr ) : m_interpolator( nullptr )
{ {
@ -100,35 +125,60 @@ void QskVariantAnimator::setCurrentValue( const QVariant& value )
m_currentValue = 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() void QskVariantAnimator::setup()
{ {
m_interpolator = nullptr; m_interpolator = nullptr;
if ( m_startValue.userType() != m_endValue.userType() ) if ( convertValues( m_startValue, m_endValue ) )
{ {
/* if ( 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() ) )
{ {
m_startValue.convert( m_endValue.userType() ); const auto id = m_startValue.userType();
}
else if ( m_endValue.canConvert( m_startValue.userType() ) )
{
m_endValue.convert( m_startValue.userType() );
}
}
const auto type = m_startValue.userType(); // all what has been registered by qRegisterAnimationInterpolator
if ( type == m_endValue.userType() ) m_interpolator = reinterpret_cast< void ( * )() >(
{ QVariantAnimationPrivate::getInterpolator( id ) );
// all what has been registered by qRegisterAnimationInterpolator }
m_interpolator = reinterpret_cast< void ( * )() >(
QVariantAnimationPrivate::getInterpolator( type ) );
} }
m_currentValue = m_interpolator ? m_startValue : m_endValue; m_currentValue = m_interpolator ? m_startValue : m_endValue;
@ -150,3 +200,32 @@ void QskVariantAnimator::done()
{ {
m_interpolator = nullptr; 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& ); void setEndValue( const QVariant& );
QVariant endValue() const; QVariant endValue() const;
static bool maybeInterpolate( const QVariant&, const QVariant& );
static bool convertValues( QVariant&, QVariant& );
protected: protected:
void setup() override; void setup() override;
void advance( qreal value ) override; void advance( qreal value ) override;