src/corelib/tools/qeasingcurve.cpp
changeset 0 1918ee327afb
child 4 3b1da2848fc7
equal deleted inserted replaced
-1:000000000000 0:1918ee327afb
       
     1 /****************************************************************************
       
     2 **
       
     3 ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
       
     4 ** All rights reserved.
       
     5 ** Contact: Nokia Corporation (qt-info@nokia.com)
       
     6 **
       
     7 ** This file is part of the QtCore module of the Qt Toolkit.
       
     8 **
       
     9 ** $QT_BEGIN_LICENSE:LGPL$
       
    10 ** No Commercial Usage
       
    11 ** This file contains pre-release code and may not be distributed.
       
    12 ** You may use this file in accordance with the terms and conditions
       
    13 ** contained in the Technology Preview License Agreement accompanying
       
    14 ** this package.
       
    15 **
       
    16 ** GNU Lesser General Public License Usage
       
    17 ** Alternatively, this file may be used under the terms of the GNU Lesser
       
    18 ** General Public License version 2.1 as published by the Free Software
       
    19 ** Foundation and appearing in the file LICENSE.LGPL included in the
       
    20 ** packaging of this file.  Please review the following information to
       
    21 ** ensure the GNU Lesser General Public License version 2.1 requirements
       
    22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
       
    23 **
       
    24 ** In addition, as a special exception, Nokia gives you certain additional
       
    25 ** rights.  These rights are described in the Nokia Qt LGPL Exception
       
    26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
       
    27 **
       
    28 ** If you have questions regarding the use of this file, please contact
       
    29 ** Nokia at qt-info@nokia.com.
       
    30 **
       
    31 **
       
    32 **
       
    33 **
       
    34 **
       
    35 **
       
    36 **
       
    37 **
       
    38 ** $QT_END_LICENSE$
       
    39 **
       
    40 ****************************************************************************/
       
    41 
       
    42 /*
       
    43 
       
    44 | *property* | *Used for type* |
       
    45 | period     | QEasingCurve::{In,Out,InOut,OutIn}Elastic |
       
    46 | amplitude  | QEasingCurve::{In,Out,InOut,OutIn}Bounce, QEasingCurve::{In,Out,InOut,OutIn}Elastic |
       
    47 | overshoot  | QEasingCurve::{In,Out,InOut,OutIn}Back   |
       
    48 
       
    49 */
       
    50 
       
    51 
       
    52 
       
    53 
       
    54 /*!
       
    55     \class QEasingCurve
       
    56     \since 4.6
       
    57     \ingroup animation
       
    58     \brief The QEasingCurve class provides easing curves for controlling animation.
       
    59 
       
    60     Easing curves describe a function that controls how the speed of the interpolation
       
    61     between 0 and 1 should be. Easing curves allow transitions from
       
    62     one value to another to appear more natural than a simple constant speed would allow.
       
    63     The QEasingCurve class is usually used in conjunction with the QVariantAnimation and
       
    64     QPropertyAnimation classes but can be used on its own. It is usually used to accelerate
       
    65     the interpolation from zero velocity (ease in) or decelerate to zero velocity (ease out).
       
    66     Ease in and ease out can also be combined in the same easing curve.
       
    67 
       
    68     To calculate the speed of the interpolation, the easing curve provides the function
       
    69     valueForProgress(), where the \a progress argument specifies the progress of the
       
    70     interpolation: 0 is the start value of the interpolation, 1 is the end value of the
       
    71     interpolation. The returned value is the effective progress of the interpolation.
       
    72     If the returned value is the same as the input value for all input values the easing
       
    73     curve is a linear curve. This is the default behaviour.
       
    74 
       
    75     For example,
       
    76     \code
       
    77     QEasingCurve easing(QEasingCurve::InOutQuad);
       
    78 
       
    79     for(qreal t = 0.0; t < 1.0; t+=0.1)
       
    80         qWarning() << "Effective progress" << t << " is
       
    81                    << easing.valueForProgress(t);
       
    82     \endcode
       
    83     will print the effective progress of the interpolation between 0 and 1.
       
    84 
       
    85     When using a QPropertyAnimation, the associated easing curve will be used to control the
       
    86     progress of the interpolation between startValue and endValue:
       
    87     \code
       
    88     QPropertyAnimation animation;
       
    89     animation.setStartValue(0);
       
    90     animation.setEndValue(1000);
       
    91     animation.setDuration(1000);
       
    92     animation.setEasingCurve(QEasingCurve::InOutQuad);
       
    93     \endcode
       
    94  */
       
    95 
       
    96 /*!
       
    97     \enum QEasingCurve::Type
       
    98 
       
    99     The type of easing curve.
       
   100 
       
   101     \value Linear       \inlineimage qeasingcurve-linear.png
       
   102                         \br
       
   103                         Easing curve for a linear (t) function:
       
   104                         velocity is constant.
       
   105     \value InQuad       \inlineimage qeasingcurve-inquad.png
       
   106                         \br
       
   107                         Easing curve for a quadratic (t^2) function:
       
   108                         accelerating from zero velocity.
       
   109     \value OutQuad      \inlineimage qeasingcurve-outquad.png
       
   110                         \br
       
   111                         Easing curve for a quadratic (t^2) function:
       
   112                         decelerating to zero velocity.
       
   113     \value InOutQuad    \inlineimage qeasingcurve-inoutquad.png
       
   114                         \br
       
   115                         Easing curve for a quadratic (t^2) function:
       
   116                         acceleration until halfway, then deceleration.
       
   117     \value OutInQuad    \inlineimage qeasingcurve-outinquad.png
       
   118                         \br
       
   119                         Easing curve for a quadratic (t^2) function:
       
   120                         deceleration until halfway, then acceleration.
       
   121     \value InCubic      \inlineimage qeasingcurve-incubic.png
       
   122                         \br
       
   123                         Easing curve for a cubic (t^3) function:
       
   124                         accelerating from zero velocity.
       
   125     \value OutCubic     \inlineimage qeasingcurve-outcubic.png
       
   126                         \br
       
   127                         Easing curve for a cubic (t^3) function:
       
   128                         decelerating from zero velocity.
       
   129     \value InOutCubic   \inlineimage qeasingcurve-inoutcubic.png
       
   130                         \br
       
   131                         Easing curve for a cubic (t^3) function:
       
   132                         acceleration until halfway, then deceleration.
       
   133     \value OutInCubic   \inlineimage qeasingcurve-outincubic.png
       
   134                         \br
       
   135                         Easing curve for a cubic (t^3) function:
       
   136                         deceleration until halfway, then acceleration.
       
   137     \value InQuart      \inlineimage qeasingcurve-inquart.png
       
   138                         \br
       
   139                         Easing curve for a quartic (t^4) function:
       
   140                         accelerating from zero velocity.
       
   141     \value OutQuart     \inlineimage qeasingcurve-outquart.png
       
   142                         \br
       
   143                         Easing curve for a cubic (t^4) function:
       
   144                         decelerating from zero velocity.
       
   145     \value InOutQuart   \inlineimage qeasingcurve-inoutquart.png
       
   146                         \br
       
   147                         Easing curve for a cubic (t^4) function:
       
   148                         acceleration until halfway, then deceleration.
       
   149     \value OutInQuart   \inlineimage qeasingcurve-outinquart.png
       
   150                         \br
       
   151                         Easing curve for a cubic (t^4) function:
       
   152                         deceleration until halfway, then acceleration.
       
   153     \value InQuint      \inlineimage qeasingcurve-inquint.png
       
   154                         \br
       
   155                         Easing curve for a quintic (t^5) easing
       
   156                         in: accelerating from zero velocity.
       
   157     \value OutQuint     \inlineimage qeasingcurve-outquint.png
       
   158                         \br
       
   159                         Easing curve for a cubic (t^5) function:
       
   160                         decelerating from zero velocity.
       
   161     \value InOutQuint   \inlineimage qeasingcurve-inoutquint.png
       
   162                         \br
       
   163                         Easing curve for a cubic (t^5) function:
       
   164                         acceleration until halfway, then deceleration.
       
   165     \value OutInQuint   \inlineimage qeasingcurve-outinquint.png
       
   166                         \br
       
   167                         Easing curve for a cubic (t^5) function:
       
   168                         deceleration until halfway, then acceleration.
       
   169     \value InSine       \inlineimage qeasingcurve-insine.png
       
   170                         \br
       
   171                         Easing curve for a sinusoidal (sin(t)) function:
       
   172                         accelerating from zero velocity.
       
   173     \value OutSine      \inlineimage qeasingcurve-outsine.png
       
   174                         \br
       
   175                         Easing curve for a sinusoidal (sin(t)) function:
       
   176                         decelerating from zero velocity.
       
   177     \value InOutSine    \inlineimage qeasingcurve-inoutsine.png
       
   178                         \br
       
   179                         Easing curve for a sinusoidal (sin(t)) function:
       
   180                         acceleration until halfway, then deceleration.
       
   181     \value OutInSine    \inlineimage qeasingcurve-outinsine.png
       
   182                         \br
       
   183                         Easing curve for a sinusoidal (sin(t)) function:
       
   184                         deceleration until halfway, then acceleration.
       
   185     \value InExpo       \inlineimage qeasingcurve-inexpo.png
       
   186                         \br
       
   187                         Easing curve for an exponential (2^t) function:
       
   188                         accelerating from zero velocity.
       
   189     \value OutExpo      \inlineimage qeasingcurve-outexpo.png
       
   190                         \br
       
   191                         Easing curve for an exponential (2^t) function:
       
   192                         decelerating from zero velocity.
       
   193     \value InOutExpo    \inlineimage qeasingcurve-inoutexpo.png
       
   194                         \br
       
   195                         Easing curve for an exponential (2^t) function:
       
   196                         acceleration until halfway, then deceleration.
       
   197     \value OutInExpo    \inlineimage qeasingcurve-outinexpo.png
       
   198                         \br
       
   199                         Easing curve for an exponential (2^t) function:
       
   200                         deceleration until halfway, then acceleration.
       
   201     \value InCirc       \inlineimage qeasingcurve-incirc.png
       
   202                         \br
       
   203                         Easing curve for a circular (sqrt(1-t^2)) function:
       
   204                         accelerating from zero velocity.
       
   205     \value OutCirc      \inlineimage qeasingcurve-outcirc.png
       
   206                         \br
       
   207                         Easing curve for a circular (sqrt(1-t^2)) function:
       
   208                         decelerating from zero velocity.
       
   209     \value InOutCirc    \inlineimage qeasingcurve-inoutcirc.png
       
   210                         \br
       
   211                         Easing curve for a circular (sqrt(1-t^2)) function:
       
   212                         acceleration until halfway, then deceleration.
       
   213     \value OutInCirc    \inlineimage qeasingcurve-outincirc.png
       
   214                         \br
       
   215                         Easing curve for a circular (sqrt(1-t^2)) function:
       
   216                         deceleration until halfway, then acceleration.
       
   217     \value InElastic    \inlineimage qeasingcurve-inelastic.png
       
   218                         \br
       
   219                         Easing curve for an elastic
       
   220                         (exponentially decaying sine wave) function:
       
   221                         accelerating from zero velocity.  The peak amplitude
       
   222                         can be set with the \e amplitude parameter, and the
       
   223                         period of decay by the \e period parameter.
       
   224     \value OutElastic   \inlineimage qeasingcurve-outelastic.png
       
   225                         \br
       
   226                         Easing curve for an elastic
       
   227                         (exponentially decaying sine wave) function:
       
   228                         decelerating from zero velocity.  The peak amplitude
       
   229                         can be set with the \e amplitude parameter, and the
       
   230                         period of decay by the \e period parameter.
       
   231     \value InOutElastic \inlineimage qeasingcurve-inoutelastic.png
       
   232                         \br
       
   233                         Easing curve for an elastic
       
   234                         (exponentially decaying sine wave) function:
       
   235                         acceleration until halfway, then deceleration.
       
   236     \value OutInElastic \inlineimage qeasingcurve-outinelastic.png
       
   237                         \br
       
   238                         Easing curve for an elastic
       
   239                         (exponentially decaying sine wave) function:
       
   240                         deceleration until halfway, then acceleration.
       
   241     \value InBack       \inlineimage qeasingcurve-inback.png
       
   242                         \br
       
   243                         Easing curve for a back (overshooting
       
   244                         cubic function: (s+1)*t^3 - s*t^2) easing in:
       
   245                         accelerating from zero velocity.
       
   246     \value OutBack      \inlineimage qeasingcurve-outback.png
       
   247                         \br
       
   248                         Easing curve for a back (overshooting
       
   249                         cubic function: (s+1)*t^3 - s*t^2) easing out:
       
   250                         decelerating to zero velocity.
       
   251     \value InOutBack    \inlineimage qeasingcurve-inoutback.png
       
   252                         \br
       
   253                         Easing curve for a back (overshooting
       
   254                         cubic function: (s+1)*t^3 - s*t^2) easing in/out:
       
   255                         acceleration until halfway, then deceleration.
       
   256     \value OutInBack    \inlineimage qeasingcurve-outinback.png
       
   257                         \br
       
   258                         Easing curve for a back (overshooting
       
   259                         cubic easing: (s+1)*t^3 - s*t^2) easing out/in:
       
   260                         deceleration until halfway, then acceleration.
       
   261     \value InBounce     \inlineimage qeasingcurve-inbounce.png
       
   262                         \br
       
   263                         Easing curve for a bounce (exponentially
       
   264                         decaying parabolic bounce) function: accelerating
       
   265                         from zero velocity.
       
   266     \value OutBounce    \inlineimage qeasingcurve-outbounce.png
       
   267                         \br
       
   268                         Easing curve for a bounce (exponentially
       
   269                         decaying parabolic bounce) function: decelerating
       
   270                         from zero velocity.
       
   271     \value InOutBounce  \inlineimage qeasingcurve-inoutbounce.png
       
   272                         \br
       
   273                         Easing curve for a bounce (exponentially
       
   274                         decaying parabolic bounce) function easing in/out:
       
   275                         acceleration until halfway, then deceleration.
       
   276     \value OutInBounce  \inlineimage qeasingcurve-outinbounce.png
       
   277                         \br
       
   278                         Easing curve for a bounce (exponentially
       
   279                         decaying parabolic bounce) function easing out/in:
       
   280                         deceleration until halfway, then acceleration.
       
   281     \omitvalue InCurve
       
   282     \omitvalue OutCurve
       
   283     \omitvalue SineCurve
       
   284     \omitvalue CosineCurve
       
   285     \value Custom       This is returned if the user specified a custom curve type with
       
   286                         setCustomType(). Note that you cannot call setType() with this value,
       
   287                         but type() can return it.
       
   288     \omitvalue NCurveTypes
       
   289 */
       
   290 
       
   291 /*!
       
   292     \typedef QEasingCurve::EasingFunction
       
   293 
       
   294     This is a typedef for a pointer to a function with the following
       
   295     signature:
       
   296 
       
   297     \snippet doc/src/snippets/code/src_corelib_tools_qeasingcurve.cpp 0
       
   298 */
       
   299 
       
   300 #include "qeasingcurve.h"
       
   301 
       
   302 #ifndef QT_NO_DEBUG_STREAM
       
   303 #include <QtCore/qdebug.h>
       
   304 #include <QtCore/qstring.h>
       
   305 #endif
       
   306 
       
   307 QT_BEGIN_NAMESPACE
       
   308 
       
   309 static bool isConfigFunction(QEasingCurve::Type type)
       
   310 {
       
   311     return type >= QEasingCurve::InElastic
       
   312             && type <= QEasingCurve::OutInBounce;
       
   313 }
       
   314 
       
   315 class QEasingCurveFunction
       
   316 {
       
   317 public:
       
   318     enum Type { In, Out, InOut, OutIn };
       
   319 
       
   320     QEasingCurveFunction(QEasingCurveFunction::Type type = In, qreal period = 0.3, qreal amplitude = 1.0,
       
   321         qreal overshoot = 1.70158f)
       
   322         : _t(type), _p(period), _a(amplitude), _o(overshoot)
       
   323     { }
       
   324     virtual ~QEasingCurveFunction() {}
       
   325     virtual qreal value(qreal t);
       
   326     virtual QEasingCurveFunction *copy() const;
       
   327     bool operator==(const QEasingCurveFunction& other);
       
   328 
       
   329     Type _t;
       
   330     qreal _p;
       
   331     qreal _a;
       
   332     qreal _o;
       
   333 };
       
   334 
       
   335 qreal QEasingCurveFunction::value(qreal t)
       
   336 {
       
   337     return t;
       
   338 }
       
   339 
       
   340 QEasingCurveFunction *QEasingCurveFunction::copy() const
       
   341 {
       
   342     return new QEasingCurveFunction(_t, _p, _a, _o);
       
   343 }
       
   344 
       
   345 bool QEasingCurveFunction::operator==(const QEasingCurveFunction& other)
       
   346 {
       
   347     return _t == other._t &&
       
   348            _p == other._p &&
       
   349            _a == other._a &&
       
   350            _o == other._o;
       
   351 }
       
   352 
       
   353 QT_BEGIN_INCLUDE_NAMESPACE
       
   354 #include "../../3rdparty/easing/easing.cpp"
       
   355 QT_END_INCLUDE_NAMESPACE
       
   356 
       
   357 class QEasingCurvePrivate
       
   358 {
       
   359 public:
       
   360     QEasingCurvePrivate()
       
   361         : type(QEasingCurve::Linear),
       
   362           config(0),
       
   363           func(&easeNone)
       
   364     { }
       
   365     ~QEasingCurvePrivate() { delete config; }
       
   366     void setType_helper(QEasingCurve::Type);
       
   367 
       
   368     QEasingCurve::Type type;
       
   369     QEasingCurveFunction *config;
       
   370     QEasingCurve::EasingFunction func;
       
   371 };
       
   372 
       
   373 struct ElasticEase : public QEasingCurveFunction
       
   374 {
       
   375     ElasticEase(Type type)
       
   376         : QEasingCurveFunction(type, qreal(0.3), qreal(1.0))
       
   377     { }
       
   378 
       
   379     QEasingCurveFunction *copy() const
       
   380     {
       
   381         ElasticEase *rv = new ElasticEase(_t);
       
   382         rv->_p = _p;
       
   383         rv->_a = _a;
       
   384         return rv;
       
   385     }
       
   386 
       
   387     qreal value(qreal t)
       
   388     {
       
   389         qreal p = (_p < 0) ? 0.3f : _p;
       
   390         qreal a = (_a < 0) ? 1.0f : _a;
       
   391         switch(_t) {
       
   392         case In:
       
   393             return easeInElastic(t, a, p);
       
   394         case Out:
       
   395             return easeOutElastic(t, a, p);
       
   396         case InOut:
       
   397             return easeInOutElastic(t, a, p);
       
   398         case OutIn:
       
   399             return easeOutInElastic(t, a, p);
       
   400         default:
       
   401             return t;
       
   402         }
       
   403     }
       
   404 };
       
   405 
       
   406 struct BounceEase : public QEasingCurveFunction
       
   407 {
       
   408     BounceEase(Type type)
       
   409         : QEasingCurveFunction(type, 0.3f, 1.0f)
       
   410     { }
       
   411 
       
   412     QEasingCurveFunction *copy() const
       
   413     {
       
   414         BounceEase *rv = new BounceEase(_t);
       
   415         rv->_a = _a;
       
   416         return rv;
       
   417     }
       
   418 
       
   419     qreal value(qreal t)
       
   420     {
       
   421         qreal a = (_a < 0) ? 1.0f : _a;
       
   422         switch(_t) {
       
   423         case In:
       
   424             return easeInBounce(t, a);
       
   425         case Out:
       
   426             return easeOutBounce(t, a);
       
   427         case InOut:
       
   428             return easeInOutBounce(t, a);
       
   429         case OutIn:
       
   430             return easeOutInBounce(t, a);
       
   431         default:
       
   432             return t;
       
   433         }
       
   434     }
       
   435 };
       
   436 
       
   437 struct BackEase : public QEasingCurveFunction
       
   438 {
       
   439     BackEase(Type type)
       
   440         : QEasingCurveFunction(type, 0.3f, 1.0f, 1.70158f)
       
   441     { }
       
   442 
       
   443     QEasingCurveFunction *copy() const
       
   444     {
       
   445         BackEase *rv = new BackEase(_t);
       
   446         rv->_o = _o;
       
   447         return rv;
       
   448     }
       
   449 
       
   450     qreal value(qreal t)
       
   451     {
       
   452         qreal o = (_o < 0) ? 1.70158f : _o;
       
   453         switch(_t) {
       
   454         case In:
       
   455             return easeInBack(t, o);
       
   456         case Out:
       
   457             return easeOutBack(t, o);
       
   458         case InOut:
       
   459             return easeInOutBack(t, o);
       
   460         case OutIn:
       
   461             return easeOutInBack(t, o);
       
   462         default:
       
   463             return t;
       
   464         }
       
   465     }
       
   466 };
       
   467 
       
   468 static QEasingCurve::EasingFunction curveToFunc(QEasingCurve::Type curve)
       
   469 {
       
   470     switch(curve) {
       
   471     case QEasingCurve::Linear:
       
   472         return &easeNone;
       
   473     case QEasingCurve::InQuad:
       
   474         return &easeInQuad;
       
   475     case QEasingCurve::OutQuad:
       
   476         return &easeOutQuad;
       
   477     case QEasingCurve::InOutQuad:
       
   478         return &easeInOutQuad;
       
   479     case QEasingCurve::OutInQuad:
       
   480         return &easeOutInQuad;
       
   481     case QEasingCurve::InCubic:
       
   482         return &easeInCubic;
       
   483     case QEasingCurve::OutCubic:
       
   484         return &easeOutCubic;
       
   485     case QEasingCurve::InOutCubic:
       
   486         return &easeInOutCubic;
       
   487     case QEasingCurve::OutInCubic:
       
   488         return &easeOutInCubic;
       
   489     case QEasingCurve::InQuart:
       
   490         return &easeInQuart;
       
   491     case QEasingCurve::OutQuart:
       
   492         return &easeOutQuart;
       
   493     case QEasingCurve::InOutQuart:
       
   494         return &easeInOutQuart;
       
   495     case QEasingCurve::OutInQuart:
       
   496         return &easeOutInQuart;
       
   497     case QEasingCurve::InQuint:
       
   498         return &easeInQuint;
       
   499     case QEasingCurve::OutQuint:
       
   500         return &easeOutQuint;
       
   501     case QEasingCurve::InOutQuint:
       
   502         return &easeInOutQuint;
       
   503     case QEasingCurve::OutInQuint:
       
   504         return &easeOutInQuint;
       
   505     case QEasingCurve::InSine:
       
   506         return &easeInSine;
       
   507     case QEasingCurve::OutSine:
       
   508         return &easeOutSine;
       
   509     case QEasingCurve::InOutSine:
       
   510         return &easeInOutSine;
       
   511     case QEasingCurve::OutInSine:
       
   512         return &easeOutInSine;
       
   513     case QEasingCurve::InExpo:
       
   514         return &easeInExpo;
       
   515     case QEasingCurve::OutExpo:
       
   516         return &easeOutExpo;
       
   517     case QEasingCurve::InOutExpo:
       
   518         return &easeInOutExpo;
       
   519     case QEasingCurve::OutInExpo:
       
   520         return &easeOutInExpo;
       
   521     case QEasingCurve::InCirc:
       
   522         return &easeInCirc;
       
   523     case QEasingCurve::OutCirc:
       
   524         return &easeOutCirc;
       
   525     case QEasingCurve::InOutCirc:
       
   526         return &easeInOutCirc;
       
   527     case QEasingCurve::OutInCirc:
       
   528         return &easeOutInCirc;
       
   529     // Internal for, compatibility with QTimeLine only ??
       
   530     case QEasingCurve::InCurve:
       
   531         return &easeInCurve;
       
   532     case QEasingCurve::OutCurve:
       
   533         return &easeOutCurve;
       
   534     case QEasingCurve::SineCurve:
       
   535         return &easeSineCurve;
       
   536     case QEasingCurve::CosineCurve:
       
   537         return &easeCosineCurve;
       
   538     default:
       
   539         return 0;
       
   540     };
       
   541 }
       
   542 
       
   543 static QEasingCurveFunction *curveToFunctionObject(QEasingCurve::Type type)
       
   544 {
       
   545     QEasingCurveFunction *curveFunc = 0;
       
   546     switch(type) {
       
   547     case QEasingCurve::InElastic:
       
   548         curveFunc = new ElasticEase(ElasticEase::In);
       
   549         break;
       
   550     case QEasingCurve::OutElastic:
       
   551         curveFunc = new ElasticEase(ElasticEase::Out);
       
   552         break;
       
   553     case QEasingCurve::InOutElastic:
       
   554         curveFunc = new ElasticEase(ElasticEase::InOut);
       
   555         break;
       
   556     case QEasingCurve::OutInElastic:
       
   557         curveFunc = new ElasticEase(ElasticEase::OutIn);
       
   558         break;
       
   559     case QEasingCurve::OutBounce:
       
   560         curveFunc = new BounceEase(BounceEase::Out);
       
   561         break;
       
   562     case QEasingCurve::InBounce:
       
   563         curveFunc = new BounceEase(BounceEase::In);
       
   564         break;
       
   565     case QEasingCurve::OutInBounce:
       
   566         curveFunc = new BounceEase(BounceEase::OutIn);
       
   567         break;
       
   568     case QEasingCurve::InOutBounce:
       
   569         curveFunc = new BounceEase(BounceEase::InOut);
       
   570         break;
       
   571     case QEasingCurve::InBack:
       
   572         curveFunc = new BackEase(BackEase::In);
       
   573         break;
       
   574     case QEasingCurve::OutBack:
       
   575         curveFunc = new BackEase(BackEase::Out);
       
   576         break;
       
   577     case QEasingCurve::InOutBack:
       
   578         curveFunc = new BackEase(BackEase::InOut);
       
   579         break;
       
   580     case QEasingCurve::OutInBack:
       
   581         curveFunc = new BackEase(BackEase::OutIn);
       
   582         break;
       
   583     default:
       
   584         curveFunc = new QEasingCurveFunction(QEasingCurveFunction::In, 0.3f, 1.0f, 1.70158f);     // ###
       
   585     }
       
   586 
       
   587     return curveFunc;
       
   588 }
       
   589 
       
   590 /*!
       
   591     Constructs an easing curve of the given \a type.
       
   592  */
       
   593 QEasingCurve::QEasingCurve(Type type)
       
   594     : d_ptr(new QEasingCurvePrivate)
       
   595 {
       
   596     setType(type);
       
   597 }
       
   598 
       
   599 /*!
       
   600     Construct a copy of \a other.
       
   601  */
       
   602 QEasingCurve::QEasingCurve(const QEasingCurve &other)
       
   603 : d_ptr(new QEasingCurvePrivate)
       
   604 {
       
   605     // ### non-atomic, requires malloc on shallow copy
       
   606     *d_ptr = *other.d_ptr;
       
   607     if(other.d_ptr->config)
       
   608         d_ptr->config = other.d_ptr->config->copy();
       
   609 }
       
   610 
       
   611 /*!
       
   612     Destructor.
       
   613  */
       
   614 
       
   615 QEasingCurve::~QEasingCurve()
       
   616 {
       
   617     delete d_ptr;
       
   618 }
       
   619 
       
   620 /*!
       
   621     Copy \a other.
       
   622  */
       
   623 QEasingCurve &QEasingCurve::operator=(const QEasingCurve &other)
       
   624 {
       
   625     // ### non-atomic, requires malloc on shallow copy
       
   626     if (d_ptr->config) {
       
   627         delete d_ptr->config;
       
   628         d_ptr->config = 0;
       
   629     }
       
   630 
       
   631     *d_ptr = *other.d_ptr;
       
   632     if(other.d_ptr->config)
       
   633         d_ptr->config = other.d_ptr->config->copy();
       
   634 
       
   635     return *this;
       
   636 }
       
   637 
       
   638 /*!
       
   639     Compare this easing curve with \a other and returns true if they are
       
   640     equal. It will also compare the properties of a curve.
       
   641  */
       
   642 bool QEasingCurve::operator==(const QEasingCurve &other) const
       
   643 {
       
   644     bool res = d_ptr->func == other.d_ptr->func
       
   645             && d_ptr->type == other.d_ptr->type;
       
   646     if (res && d_ptr->config && other.d_ptr->config) {
       
   647         // catch the config content
       
   648         res = d_ptr->config->operator==(*(other.d_ptr->config));
       
   649     }
       
   650     return res;
       
   651 }
       
   652 
       
   653 /*!
       
   654     \fn bool QEasingCurve::operator!=(const QEasingCurve &other) const
       
   655     Compare this easing curve with \a other and returns true if they are not equal.
       
   656     It will also compare the properties of a curve.
       
   657 
       
   658     \sa operator==()
       
   659 */
       
   660 
       
   661 /*!
       
   662     Returns the amplitude. This is not applicable for all curve types.
       
   663     It is only applicable for bounce and elastic curves (curves of type()
       
   664     QEasingCurve::InBounce, QEasingCurve::OutBounce, QEasingCurve::InOutBounce,
       
   665     QEasingCurve::OutInBounce, QEasingCurve::InElastic, QEasingCurve::OutElastic,
       
   666     QEasingCurve::InOutElastic or QEasingCurve::OutInElastic).
       
   667  */
       
   668 qreal QEasingCurve::amplitude() const
       
   669 {
       
   670     return d_ptr->config ? d_ptr->config->_a : 1.0;
       
   671 }
       
   672 
       
   673 /*!
       
   674     Sets the amplitude to \a amplitude.
       
   675 
       
   676     This will set the amplitude of the bounce or the amplitude of the
       
   677     elastic "spring" effect. The higher the number, the higher the amplitude.
       
   678     \sa amplitude()
       
   679 */
       
   680 void QEasingCurve::setAmplitude(qreal amplitude)
       
   681 {
       
   682     if (!d_ptr->config)
       
   683         d_ptr->config = curveToFunctionObject(d_ptr->type);
       
   684     d_ptr->config->_a = amplitude;
       
   685 }
       
   686 
       
   687 /*!
       
   688     Returns the period. This is not applicable for all curve types.
       
   689     It is only applicable if type() is QEasingCurve::InElastic, QEasingCurve::OutElastic,
       
   690     QEasingCurve::InOutElastic or QEasingCurve::OutInElastic.
       
   691  */
       
   692 qreal QEasingCurve::period() const
       
   693 {
       
   694     return d_ptr->config ? d_ptr->config->_p : 0.3;
       
   695 }
       
   696 
       
   697 /*!
       
   698     Sets the period to \a period.
       
   699     Setting a small period value will give a high frequency of the curve. A
       
   700     large period will give it a small frequency.
       
   701 
       
   702     \sa period()
       
   703 */
       
   704 void QEasingCurve::setPeriod(qreal period)
       
   705 {
       
   706     if (!d_ptr->config)
       
   707         d_ptr->config = curveToFunctionObject(d_ptr->type);
       
   708     d_ptr->config->_p = period;
       
   709 }
       
   710 
       
   711 /*!
       
   712     Returns the overshoot. This is not applicable for all curve types.
       
   713     It is only applicable if type() is QEasingCurve::InBack, QEasingCurve::OutBack,
       
   714     QEasingCurve::InOutBack or QEasingCurve::OutInBack.
       
   715  */
       
   716 qreal QEasingCurve::overshoot() const
       
   717 {
       
   718     return d_ptr->config ? d_ptr->config->_o : 1.70158f;
       
   719 }
       
   720 
       
   721 /*!
       
   722     Sets the overshoot to \a overshoot.
       
   723 
       
   724     0 produces no overshoot, and the default value of 1.70158 produces an overshoot of 10 percent.
       
   725 
       
   726     \sa overshoot()
       
   727 */
       
   728 void QEasingCurve::setOvershoot(qreal overshoot)
       
   729 {
       
   730     if (!d_ptr->config)
       
   731         d_ptr->config = curveToFunctionObject(d_ptr->type);
       
   732     d_ptr->config->_o = overshoot;
       
   733 }
       
   734 
       
   735 /*!
       
   736     Returns the type of the easing curve.
       
   737 */
       
   738 QEasingCurve::Type QEasingCurve::type() const
       
   739 {
       
   740     return d_ptr->type;
       
   741 }
       
   742 
       
   743 void QEasingCurvePrivate::setType_helper(QEasingCurve::Type newType)
       
   744 {
       
   745     qreal amp = -1.0;
       
   746     qreal period = -1.0;
       
   747     qreal overshoot = -1.0;
       
   748 
       
   749     if (config) {
       
   750         amp = config->_a;
       
   751         period = config->_p;
       
   752         overshoot = config->_o;
       
   753         delete config;
       
   754         config = 0;
       
   755     }
       
   756 
       
   757     if (isConfigFunction(newType) || (amp != -1.0) || (period != -1.0) || (overshoot != -1.0)) {
       
   758         config = curveToFunctionObject(newType);
       
   759         if (amp != -1.0)
       
   760             config->_a = amp;
       
   761         if (period != -1.0)
       
   762             config->_p = period;
       
   763         if (overshoot != -1.0)
       
   764             config->_o = overshoot;
       
   765         func = 0;
       
   766     } else if (newType != QEasingCurve::Custom) {
       
   767         func = curveToFunc(newType);
       
   768     }
       
   769     Q_ASSERT((func == 0) == (config != 0));
       
   770     type = newType;
       
   771 }
       
   772 
       
   773 /*!
       
   774     Sets the type of the easing curve to \a type.
       
   775 */
       
   776 void QEasingCurve::setType(Type type)
       
   777 {
       
   778     if (d_ptr->type == type)
       
   779         return;
       
   780     if (type < Linear || type >= NCurveTypes - 1) {
       
   781         qWarning("QEasingCurve: Invalid curve type %d", type);
       
   782         return;
       
   783     }
       
   784 
       
   785     d_ptr->setType_helper(type);
       
   786 }
       
   787 
       
   788 /*!
       
   789     Sets a custom easing curve that is defined by the user in the function \a func.
       
   790     The signature of the function is qreal myEasingFunction(qreal progress),
       
   791     where \e progress and the return value is considered to be normalized between 0 and 1.
       
   792     (In some cases the return value can be outside that range)
       
   793     After calling this function type() will return QEasingCurve::Custom.
       
   794     \a func cannot be zero.
       
   795 
       
   796     \sa customType()
       
   797     \sa valueForProgress()
       
   798 */
       
   799 void QEasingCurve::setCustomType(EasingFunction func)
       
   800 {
       
   801     if (!func) {
       
   802         qWarning("Function pointer must not be null");
       
   803         return;
       
   804     }
       
   805     d_ptr->func = func;
       
   806     d_ptr->setType_helper(Custom);
       
   807 }
       
   808 
       
   809 /*!
       
   810     Returns the function pointer to the custom easing curve.
       
   811     If type() does not return QEasingCurve::Custom, this function
       
   812     will return 0.
       
   813 */
       
   814 QEasingCurve::EasingFunction QEasingCurve::customType() const
       
   815 {
       
   816     return d_ptr->type == Custom ? d_ptr->func : 0;
       
   817 }
       
   818 
       
   819 /*!
       
   820     Return the effective progress for the easing curve at \a progress.
       
   821     While  \a progress must be between 0 and 1, the returned effective progress
       
   822     can be outside those bounds. For instance, QEasingCurve::InBack will
       
   823     return negative values in the beginning of the function.
       
   824  */
       
   825 qreal QEasingCurve::valueForProgress(qreal progress) const
       
   826 {
       
   827     progress = qBound<qreal>(0, progress, 1);
       
   828     if (d_ptr->func)
       
   829         return d_ptr->func(progress);
       
   830     else if (d_ptr->config)
       
   831         return d_ptr->config->value(progress);
       
   832     else
       
   833         return progress;
       
   834 }
       
   835 
       
   836 #ifndef QT_NO_DEBUG_STREAM
       
   837 QDebug operator<<(QDebug debug, const QEasingCurve &item)
       
   838 {
       
   839     debug << "type:" << item.d_ptr->type
       
   840           << "func:" << item.d_ptr->func;
       
   841     if (item.d_ptr->config) {
       
   842         debug << QString::fromAscii("period:%1").arg(item.d_ptr->config->_p, 0, 'f', 20)
       
   843               << QString::fromAscii("amp:%1").arg(item.d_ptr->config->_a, 0, 'f', 20)
       
   844               << QString::fromAscii("overshoot:%1").arg(item.d_ptr->config->_o, 0, 'f', 20);
       
   845     }
       
   846     return debug;
       
   847 }
       
   848 #endif
       
   849 
       
   850 QT_END_NAMESPACE