ganeswidgets/src/hgspring.cpp
changeset 0 89c329efa980
child 2 49c70dcc3f17
equal deleted inserted replaced
-1:000000000000 0:89c329efa980
       
     1 /*
       
     2 * Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 *
       
    14 * Description:
       
    15 *
       
    16 */
       
    17 
       
    18 #include "HgSpring.h"
       
    19 #include <qtimer>
       
    20 #include "trace.h"
       
    21 
       
    22 const int KTimeDelta(10);
       
    23 const qreal KTimeDeltaF(0.01f);
       
    24 //const qreal KVelocitySnap(0.05f);
       
    25 const qreal KPositionSnap(0.01f);
       
    26 const int KTimerInterval(10);
       
    27 
       
    28 HgSpring::HgSpring() :
       
    29 mStartPos(QPointF(0,0)),
       
    30 mPos(QPointF(0,0)),
       
    31 mEndPos(QPointF(0,0)),
       
    32 mVelocity(QPointF(0,0)),
       
    33 mK(30.1),
       
    34 mDamping(10.1),
       
    35 mAccumulator(0.0),
       
    36 mDoNotUpdate(false)
       
    37 {
       
    38     mTimer = new QTimer(this);
       
    39 
       
    40     QObject::connect( mTimer, SIGNAL( timeout() ), this, SLOT( update() ) );
       
    41 
       
    42 }
       
    43 
       
    44 HgSpring::~HgSpring()
       
    45 {
       
    46 
       
    47 }
       
    48 
       
    49 void HgSpring::setK(qreal k)
       
    50 {
       
    51     mK = k;
       
    52 }
       
    53 
       
    54 void HgSpring::setDamping(qreal damping)
       
    55 {
       
    56     mDamping = damping;
       
    57 }
       
    58 
       
    59 void HgSpring::animateToPos(const QPointF& pos)
       
    60 {
       
    61     mStartPos = mPos;
       
    62     mEndPos = pos;
       
    63 
       
    64     emit started();
       
    65 
       
    66     if (!mTimer->isActive())
       
    67     {
       
    68         mTimer->start(KTimerInterval);
       
    69         mPrevTime.start();
       
    70     }
       
    71 }
       
    72 
       
    73 void HgSpring::gotoPos(const QPointF& pos)
       
    74 {
       
    75     if (mTimer->isActive())
       
    76     {
       
    77         mTimer->stop();
       
    78     }
       
    79 
       
    80     mPos = pos;
       
    81     mEndPos = pos;
       
    82 }
       
    83 
       
    84 void HgSpring::cancel()
       
    85 {
       
    86     if (mTimer->isActive())
       
    87         mTimer->stop();
       
    88 }
       
    89 
       
    90 const QPointF& HgSpring::startPos() const
       
    91 {
       
    92     return mStartPos;
       
    93 }
       
    94 
       
    95 const QPointF& HgSpring::pos() const
       
    96 {
       
    97     return mPos;
       
    98 }
       
    99 
       
   100 const QPointF& HgSpring::endPos() const
       
   101 {
       
   102     return mEndPos;
       
   103 }
       
   104 
       
   105 const QPointF& HgSpring::velocity() const
       
   106 {
       
   107 return mVelocity;
       
   108 }
       
   109 
       
   110 
       
   111 void HgSpring::update()
       
   112 {
       
   113     int deltaTime = mPrevTime.elapsed();
       
   114 
       
   115     mPrevTime.start();
       
   116 
       
   117     mAccumulator += deltaTime;
       
   118 
       
   119     bool stopped = false;
       
   120     while (mAccumulator >= KTimeDelta)
       
   121     {
       
   122         QPointF delta = mEndPos - mPos;
       
   123         QPointF force = delta * mK - mVelocity * mDamping;
       
   124         mVelocity += force * KTimeDeltaF;
       
   125         mPos += mVelocity * KTimeDeltaF;
       
   126         if ( (qAbs(mPos.x() - mEndPos.x()) < KPositionSnap &&
       
   127               qAbs(mPos.y() - mEndPos.y()) < KPositionSnap) )
       
   128         {
       
   129             mPos = mEndPos;
       
   130             mAccumulator = 0;
       
   131             mVelocity = QPointF(0,0);
       
   132             mTimer->stop();
       
   133             stopped = true;
       
   134             break;
       
   135         }
       
   136 
       
   137         mAccumulator -= KTimeDelta;
       
   138     }
       
   139 
       
   140     if (!mDoNotUpdate)
       
   141         emit updated();
       
   142     
       
   143     if (stopped)
       
   144         emit ended();
       
   145 
       
   146 }
       
   147 
       
   148 bool HgSpring::isActive() const
       
   149 {
       
   150     return mTimer->isActive();
       
   151 }
       
   152 
       
   153 bool HgSpring::updatePositionIfNeeded()
       
   154 {
       
   155     if (isActive() && mPrevTime.elapsed() > KTimeDelta) {
       
   156         mDoNotUpdate = true;
       
   157         update();
       
   158         mDoNotUpdate = false;
       
   159         mTimer->stop();
       
   160         mTimer->start(KTimerInterval);
       
   161         return true;
       
   162     }
       
   163     return false;
       
   164 }
       
   165 
       
   166 
       
   167