6#include "QskVariantAnimator.h"
7#include "QskArcMetrics.h"
8#include "QskBoxBorderColors.h"
9#include "QskBoxBorderMetrics.h"
10#include "QskBoxShapeMetrics.h"
11#include "QskShadowMetrics.h"
12#include "QskStippleMetrics.h"
13#include "QskGraduationMetrics.h"
14#include "QskColorFilter.h"
15#include "QskGradient.h"
16#include "QskMargins.h"
17#include "QskIntervalF.h"
18#include "QskTextColors.h"
23#include <qvariantanimation.h>
27#if QT_VERSION >= QT_VERSION_CHECK( 6, 2, 0 )
30 #include <private/qabstractanimation_p.h>
35#include <private/qvariantanimation_p.h>
40static void qskRegisterInterpolator()
42 qRegisterAnimationInterpolator< QskColorFilter >( QskColorFilter::interpolate );
43 qRegisterAnimationInterpolator< QskIntervalF >( QskIntervalF::interpolate );
44 qRegisterAnimationInterpolator< QskMargins >( QskMargins::interpolate );
45 qRegisterAnimationInterpolator< QskGradient >( QskGradient::interpolate );
46 qRegisterAnimationInterpolator< QskBoxShapeMetrics >( QskBoxShapeMetrics::interpolate );
47 qRegisterAnimationInterpolator< QskBoxBorderMetrics >( QskBoxBorderMetrics::interpolate );
48 qRegisterAnimationInterpolator< QskBoxBorderColors >( QskBoxBorderColors::interpolate );
49 qRegisterAnimationInterpolator< QskTextColors >( QskTextColors::interpolate );
50 qRegisterAnimationInterpolator< QskShadowMetrics >( QskShadowMetrics::interpolate );
51 qRegisterAnimationInterpolator< QskStippleMetrics >( QskStippleMetrics::interpolate );
52 qRegisterAnimationInterpolator< QskArcMetrics >( QskArcMetrics::interpolate );
53 qRegisterAnimationInterpolator< QskGraduationMetrics >( QskGraduationMetrics::interpolate );
56Q_CONSTRUCTOR_FUNCTION( qskRegisterInterpolator )
59#if defined( Q_CC_CLANG )
60 #if __has_feature( address_sanitizer )
61 #define QSK_DECL_INSANE __attribute__( ( no_sanitize( "undefined" ) ) )
65#if !defined( QSK_DECL_INSANE )
66 #define QSK_DECL_INSANE
69QSK_DECL_INSANE
static inline QVariant qskInterpolate(
70 void ( *interpolator )(),
const QVariant& from,
const QVariant& to, qreal progress )
79 auto f =
reinterpret_cast< QVariantAnimation::Interpolator
>( interpolator );
80 return f( from.constData(), to.constData(), progress );
83#if QT_VERSION < QT_VERSION_CHECK( 6, 0, 0 )
85using QskMetaType = int;
86static inline QskMetaType qskMetaType(
const QVariant& v ) {
return v.userType(); }
90using QskMetaType = QMetaType;
91static inline QskMetaType qskMetaType(
const QVariant& v ) {
return v.metaType(); }
95static inline QVariant qskDefaultVariant( QskMetaType type )
97 return QVariant( type,
nullptr );
100static inline QVariant qskConvertedVariant(
const QVariant& from, QskMetaType type )
108QskVariantAnimator::QskVariantAnimator()
109 : m_interpolator( nullptr )
113QskVariantAnimator::~QskVariantAnimator()
117void QskVariantAnimator::setStartValue(
const QVariant& value )
120 m_startValue = value;
123void QskVariantAnimator::setEndValue(
const QVariant& value )
129void QskVariantAnimator::setCurrentValue(
const QVariant& value )
131 m_currentValue = value;
134bool QskVariantAnimator::convertValues( QVariant& v1, QVariant& v2 )
136 if ( !v1.isValid() && !v2.isValid() )
139 const auto type1 = qskMetaType( v1 );
140 const auto type2 = qskMetaType( v2 );
144 v1 = qskDefaultVariant( type2 );
150 v2 = qskDefaultVariant( type1 );
154 if ( type1 != type2 )
156 if ( v1.canConvert( type2 ) )
162 if ( v2.canConvert( type1 ) )
174void QskVariantAnimator::setup()
176 m_interpolator =
nullptr;
178 if ( convertValues( m_startValue, m_endValue ) )
180 if ( m_startValue != m_endValue )
182 const auto id = m_startValue.userType();
185 m_interpolator =
reinterpret_cast< void ( * )()
>(
186 QVariantAnimationPrivate::getInterpolator(
id ) );
190 m_currentValue = m_interpolator ? m_startValue : m_endValue;
193void QskVariantAnimator::advance( qreal progress )
195 if ( m_interpolator )
197 if ( qFuzzyCompare( progress, 1.0 ) )
200 Q_ASSERT( qskMetaType( m_startValue ) == qskMetaType( m_endValue ) );
202 m_currentValue = qskInterpolate( m_interpolator,
203 m_startValue, m_endValue, progress );
207void QskVariantAnimator::done()
209 m_interpolator =
nullptr;
212bool QskVariantAnimator::maybeInterpolate(
213 const QVariant& value1,
const QVariant& value2,
bool acceptIdentity )
215 if ( !value1.isValid() && !value2.isValid() )
218 if ( acceptIdentity )
220 if ( value1.isValid() && value2.isValid() )
222 const auto type1 = qskMetaType( value1 );
223 const auto type2 = qskMetaType( value2 );
225 if ( type1 != type2 )
226 return value1.canConvert( type2 ) || value2.canConvert( type1 );
233 const auto type1 = qskMetaType( value1 );
234 const auto type2 = qskMetaType( value2 );
236 if ( !value1.isValid() )
237 return value2 != qskDefaultVariant( type2 );
239 if ( !value2.isValid() )
240 return value1 != qskDefaultVariant( type1 );
242 if ( type1 != type2 )
244 if ( value1.canConvert( type2 ) )
245 return value2 != qskConvertedVariant( value1, type2 );
247 if ( value2.canConvert( type1 ) )
248 return value1 != qskConvertedVariant( value2, type1 );
253 return value1 != value2;