qskinny/src/controls/QskVariantAnimator.cpp

120 lines
3.4 KiB
C++
Raw Normal View History

2017-07-21 18:21:34 +02:00
/******************************************************************************
* QSkinny - Copyright (C) 2016 Uwe Rathmann
* This file may be used under the terms of the QSkinny License, Version 1.0
*****************************************************************************/
#include "QskVariantAnimator.h"
#include "QskBoxBorderColors.h"
2018-08-03 08:15:28 +02:00
#include "QskBoxBorderMetrics.h"
#include "QskBoxShapeMetrics.h"
#include "QskColorFilter.h"
#include "QskGradient.h"
2018-08-03 08:15:28 +02:00
#include "QskMargins.h"
2020-08-09 11:06:48 +02:00
#include "QskIntervalF.h"
2017-10-20 20:26:39 +02:00
#include "QskTextColors.h"
2017-07-21 18:21:34 +02:00
// Even if we don't use the standard Qt animation system we
// use its registry of interpolators: why adding our own ...
2018-07-19 14:10:48 +02:00
#include <qvariantanimation.h>
QSK_QT_PRIVATE_BEGIN
2017-07-21 18:21:34 +02:00
#include <private/qvariantanimation_p.h>
2018-07-19 14:10:48 +02:00
QSK_QT_PRIVATE_END
2017-07-21 18:21:34 +02:00
#if 1
static void qskRegisterInterpolator()
{
2018-08-03 08:15:28 +02:00
qRegisterAnimationInterpolator< QskColorFilter >( QskColorFilter::interpolate );
2020-08-09 11:06:48 +02:00
qRegisterAnimationInterpolator< QskIntervalF >( QskIntervalF::interpolate );
2018-08-03 08:15:28 +02:00
qRegisterAnimationInterpolator< QskMargins >( QskMargins::interpolate );
qRegisterAnimationInterpolator< QskGradient >( QskGradient::interpolate );
qRegisterAnimationInterpolator< QskBoxShapeMetrics >( QskBoxShapeMetrics::interpolate );
qRegisterAnimationInterpolator< QskBoxBorderMetrics >( QskBoxBorderMetrics::interpolate );
qRegisterAnimationInterpolator< QskBoxBorderColors >( QskBoxBorderColors::interpolate );
qRegisterAnimationInterpolator< QskTextColors >( QskTextColors::interpolate );
2017-07-21 18:21:34 +02:00
}
Q_CONSTRUCTOR_FUNCTION( qskRegisterInterpolator )
#endif
2018-08-03 08:15:28 +02:00
#if defined( Q_CC_CLANG )
#if __has_feature( address_sanitizer )
#define QSK_DECL_INSANE __attribute__( ( no_sanitize( "undefined" ) ) )
2017-12-07 11:54:06 +01:00
#endif
#endif
2017-12-07 12:59:05 +01:00
#if !defined( QSK_DECL_INSANE )
#define QSK_DECL_INSANE
#endif
2018-08-03 08:15:28 +02:00
QSK_DECL_INSANE static inline QVariant qskInterpolate(
void ( *interpolator )(), const QVariant& from, const QVariant& to, qreal progress )
2017-07-21 18:21:34 +02:00
{
2017-12-07 11:54:06 +01:00
#if 1
/*
how to get rid of the reported runtime error from the clang sanitizer,
when calling F( const T&, ... ) as G( const void* ... ); TODO ...
*/
#endif
2017-07-21 18:21:34 +02:00
auto f = reinterpret_cast< QVariantAnimation::Interpolator >( interpolator );
return f( from.constData(), to.constData(), progress );
}
2018-08-03 08:15:28 +02:00
QskVariantAnimator::QskVariantAnimator()
: m_interpolator( nullptr )
2017-07-21 18:21:34 +02:00
{
}
QskVariantAnimator::~QskVariantAnimator()
{
}
void QskVariantAnimator::setStartValue( const QVariant& value )
{
m_startValue = value;
}
void QskVariantAnimator::setEndValue( const QVariant& value )
{
m_endValue = value;
}
void QskVariantAnimator::setCurrentValue( const QVariant& value )
{
m_currentValue = value;
}
void QskVariantAnimator::setup()
{
m_interpolator = nullptr;
const auto type = m_startValue.userType();
if ( type == m_endValue.userType() )
{
// all what has been registered by qRegisterAnimationInterpolator
2018-08-03 08:15:28 +02:00
m_interpolator = reinterpret_cast< void ( * )() >(
QVariantAnimationPrivate::getInterpolator( type ) );
2017-07-21 18:21:34 +02:00
}
m_currentValue = m_interpolator ? m_startValue : m_endValue;
}
void QskVariantAnimator::advance( qreal progress )
{
if ( m_interpolator )
{
2017-12-22 14:15:24 +01:00
if ( qFuzzyCompare( progress, 1.0 ) )
progress = 1.0;
2017-07-21 18:21:34 +02:00
m_currentValue = qskInterpolate( m_interpolator,
m_startValue, m_endValue, progress );
}
}
void QskVariantAnimator::done()
{
m_interpolator = nullptr;
}