skin transition heavily changed
This commit is contained in:
parent
27ee0fe423
commit
e2d6823927
@ -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 )
|
||||
|
@ -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
@ -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 )
|
||||
{
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
|
Loading…
x
Reference in New Issue
Block a user