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"
19#include "QskInternalMacros.h"
24#include <qvariantanimation.h>
28#if QT_VERSION >= QT_VERSION_CHECK( 6, 2, 0 )
31 #include <private/qabstractanimation_p.h>
36#include <private/qvariantanimation_p.h>
41static void qskRegisterInterpolator()
43 qRegisterAnimationInterpolator< QskColorFilter >( QskColorFilter::interpolate );
44 qRegisterAnimationInterpolator< QskIntervalF >( QskIntervalF::interpolate );
45 qRegisterAnimationInterpolator< QskMargins >( QskMargins::interpolate );
46 qRegisterAnimationInterpolator< QskGradient >( QskGradient::interpolate );
47 qRegisterAnimationInterpolator< QskBoxShapeMetrics >( QskBoxShapeMetrics::interpolate );
48 qRegisterAnimationInterpolator< QskBoxBorderMetrics >( QskBoxBorderMetrics::interpolate );
49 qRegisterAnimationInterpolator< QskBoxBorderColors >( QskBoxBorderColors::interpolate );
50 qRegisterAnimationInterpolator< QskTextColors >( QskTextColors::interpolate );
51 qRegisterAnimationInterpolator< QskShadowMetrics >( QskShadowMetrics::interpolate );
52 qRegisterAnimationInterpolator< QskStippleMetrics >( QskStippleMetrics::interpolate );
53 qRegisterAnimationInterpolator< QskArcMetrics >( QskArcMetrics::interpolate );
54 qRegisterAnimationInterpolator< QskGraduationMetrics >( QskGraduationMetrics::interpolate );
57Q_CONSTRUCTOR_FUNCTION( qskRegisterInterpolator )
60#if defined( Q_CC_CLANG )
61 #if __has_feature( address_sanitizer )
62 #define QSK_DECL_INSANE __attribute__( ( no_sanitize( "undefined" ) ) )
66#if !defined( QSK_DECL_INSANE )
67 #define QSK_DECL_INSANE
70QSK_DECL_INSANE
static inline QVariant qskInterpolate(
71 void ( *interpolator )(),
const QVariant& from,
const QVariant& to, qreal progress )
80 auto f =
reinterpret_cast< QVariantAnimation::Interpolator
>( interpolator );
81 return f( from.constData(), to.constData(), progress );
84#if QT_VERSION < QT_VERSION_CHECK( 6, 0, 0 )
86using QskMetaType = int;
87static inline QskMetaType qskMetaType(
const QVariant& v ) {
return v.userType(); }
91using QskMetaType = QMetaType;
92static inline QskMetaType qskMetaType(
const QVariant& v ) {
return v.metaType(); }
96static inline QVariant qskDefaultVariant( QskMetaType type )
98 return QVariant( type,
nullptr );
101static inline QVariant qskConvertedVariant(
const QVariant& from, QskMetaType type )
109QskVariantAnimator::QskVariantAnimator()
110 : m_interpolator( nullptr )
114QskVariantAnimator::~QskVariantAnimator()
118void QskVariantAnimator::setStartValue(
const QVariant& value )
121 m_startValue = value;
124void QskVariantAnimator::setEndValue(
const QVariant& value )
130void QskVariantAnimator::setCurrentValue(
const QVariant& value )
132 m_currentValue = value;
135bool QskVariantAnimator::convertValues( QVariant& v1, QVariant& v2 )
137 if ( !v1.isValid() && !v2.isValid() )
140 const auto type1 = qskMetaType( v1 );
141 const auto type2 = qskMetaType( v2 );
145 v1 = qskDefaultVariant( type2 );
151 v2 = qskDefaultVariant( type1 );
155 if ( type1 != type2 )
157 if ( v1.canConvert( type2 ) )
163 if ( v2.canConvert( type1 ) )
175void QskVariantAnimator::setup()
177 m_interpolator =
nullptr;
179 if ( convertValues( m_startValue, m_endValue ) )
181 if ( m_startValue != m_endValue )
183 const auto id = m_startValue.userType();
186 m_interpolator =
reinterpret_cast< void ( * )()
>(
187 QVariantAnimationPrivate::getInterpolator(
id ) );
191 m_currentValue = m_interpolator ? m_startValue : m_endValue;
194void QskVariantAnimator::advance( qreal progress )
196 if ( m_interpolator )
198 if ( qFuzzyCompare( progress, 1.0 ) )
201 Q_ASSERT( qskMetaType( m_startValue ) == qskMetaType( m_endValue ) );
203 m_currentValue = qskInterpolate( m_interpolator,
204 m_startValue, m_endValue, progress );
208void QskVariantAnimator::done()
210 m_interpolator =
nullptr;
213bool QskVariantAnimator::maybeInterpolate(
214 const QVariant& value1,
const QVariant& value2,
bool acceptIdentity )
216 if ( !value1.isValid() && !value2.isValid() )
219 if ( acceptIdentity )
221 if ( value1.isValid() && value2.isValid() )
223 const auto type1 = qskMetaType( value1 );
224 const auto type2 = qskMetaType( value2 );
226 if ( type1 != type2 )
227 return value1.canConvert( type2 ) || value2.canConvert( type1 );
234 const auto type1 = qskMetaType( value1 );
235 const auto type2 = qskMetaType( value2 );
237 if ( !value1.isValid() )
238 return value2 != qskDefaultVariant( type2 );
240 if ( !value2.isValid() )
241 return value1 != qskDefaultVariant( type1 );
243 if ( type1 != type2 )
245 if ( value1.canConvert( type2 ) )
246 return value2 != qskConvertedVariant( value1, type2 );
248 if ( value2.canConvert( type1 ) )
249 return value1 != qskConvertedVariant( value2, type1 );
254 return value1 != value2;