Qt 4.8
qdeclarativesmoothedanimation.cpp
Go to the documentation of this file.
1 /****************************************************************************
2 **
3 ** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
4 ** Contact: http://www.qt-project.org/legal
5 **
6 ** This file is part of the QtDeclarative module of the Qt Toolkit.
7 **
8 ** $QT_BEGIN_LICENSE:LGPL$
9 ** Commercial License Usage
10 ** Licensees holding valid commercial Qt licenses may use this file in
11 ** accordance with the commercial license agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and Digia. For licensing terms and
14 ** conditions see http://qt.digia.com/licensing. For further information
15 ** use the contact form at http://qt.digia.com/contact-us.
16 **
17 ** GNU Lesser General Public License Usage
18 ** Alternatively, this file may be used under the terms of the GNU Lesser
19 ** General Public License version 2.1 as published by the Free Software
20 ** Foundation and appearing in the file LICENSE.LGPL included in the
21 ** packaging of this file. Please review the following information to
22 ** ensure the GNU Lesser General Public License version 2.1 requirements
23 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
24 **
25 ** In addition, as a special exception, Digia gives you certain additional
26 ** rights. These rights are described in the Digia Qt LGPL Exception
27 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
28 **
29 ** GNU General Public License Usage
30 ** Alternatively, this file may be used under the terms of the GNU
31 ** General Public License version 3.0 as published by the Free Software
32 ** Foundation and appearing in the file LICENSE.GPL included in the
33 ** packaging of this file. Please review the following information to
34 ** ensure the GNU General Public License version 3.0 requirements will be
35 ** met: http://www.gnu.org/copyleft/gpl.html.
36 **
37 **
38 ** $QT_END_LICENSE$
39 **
40 ****************************************************************************/
41 
42 #include "private/qdeclarativesmoothedanimation_p.h"
43 #include "private/qdeclarativesmoothedanimation_p_p.h"
44 
45 #include "private/qdeclarativeanimation_p_p.h"
46 
47 #include <qdeclarativeproperty.h>
48 #include "private/qdeclarativeproperty_p.h"
49 
50 #include "private/qdeclarativeglobal_p.h"
51 
52 #include <QtCore/qdebug.h>
53 
54 #include <QtCore/qmath.h>
55 
56 #define DELAY_STOP_TIMER_INTERVAL 32
57 
59 
61  : QAbstractAnimation(parent), to(0), velocity(200), userDuration(-1), maximumEasingTime(-1),
62  reversingMode(QDeclarativeSmoothedAnimation::Eased), initialVelocity(0),
63  trackVelocity(0), initialValue(0), invert(false), finalDuration(-1), lastTime(0)
64 {
67  connect(&delayedStopTimer, SIGNAL(timeout()), this, SLOT(stop()));
68 }
69 
71 {
74  start();
75  else
76  init();
77 }
78 
80 {
81  if (newState == QAbstractAnimation::Running)
82  init();
83 }
84 
86 {
89 }
90 
92 {
93  return -1;
94 }
95 
97 {
98  s = to - initialValue;
100 
101  s = (invert? qreal(-1.0): qreal(1.0)) * s;
102 
103  if (userDuration > 0 && velocity > 0) {
104  tf = s / velocity;
105  if (tf > (userDuration / qreal(1000.))) tf = (userDuration / qreal(1000.));
106  } else if (userDuration > 0) {
107  tf = userDuration / qreal(1000.);
108  } else if (velocity > 0) {
109  tf = s / velocity;
110  } else {
111  return false;
112  }
113 
114  finalDuration = ceil(tf * qreal(1000.0));
115 
116  if (maximumEasingTime == 0) {
117  a = 0;
118  d = 0;
119  tp = 0;
120  td = tf;
121  vp = velocity;
122  sp = 0;
123  sd = s;
124  } else if (maximumEasingTime != -1 && tf > (maximumEasingTime / qreal(1000.))) {
125  qreal met = maximumEasingTime / qreal(1000.);
126  td = tf - met;
127 
128  qreal c1 = td;
129  qreal c2 = (tf - td) * vi - tf * velocity;
130  qreal c3 = qreal(-0.5) * (tf - td) * vi * vi;
131 
132  qreal vp1 = (-c2 + qSqrt(c2 * c2 - 4 * c1 * c3)) / (qreal(2.) * c1);
133 
134  vp = vp1;
135  a = vp / met;
136  d = a;
137  tp = (vp - vi) / a;
138  sp = vi * tp + qreal(0.5) * a * tp * tp;
139  sd = sp + (td - tp) * vp;
140  } else {
141  qreal c1 = qreal(0.25) * tf * tf;
142  qreal c2 = qreal(0.5) * vi * tf - s;
143  qreal c3 = qreal(-0.25) * vi * vi;
144 
145  qreal a1 = (-c2 + qSqrt(c2 * c2 - 4 * c1 * c3)) / (qreal(2.) * c1);
146 
147  qreal tp1 = qreal(0.5) * tf - qreal(0.5) * vi / a1;
148  qreal vp1 = a1 * tp1 + vi;
149 
150  qreal sp1 = qreal(0.5) * a1 * tp1 * tp1 + vi * tp1;
151 
152  a = a1;
153  d = a1;
154  tp = tp1;
155  td = tp1;
156  vp = vp1;
157  sp = sp1;
158  sd = sp1;
159  }
160  return true;
161 }
162 
164 {
165  qreal value;
166  if (time_seconds < tp) {
167  trackVelocity = vi + time_seconds * a;
168  value = qreal(0.5) * a * time_seconds * time_seconds + vi * time_seconds;
169  } else if (time_seconds < td) {
170  time_seconds -= tp;
171  trackVelocity = vp;
172  value = sp + time_seconds * vp;
173  } else if (time_seconds < tf) {
174  time_seconds -= td;
175  trackVelocity = vp - time_seconds * a;
176  value = sd - qreal(0.5) * d * time_seconds * time_seconds + vp * time_seconds;
177  } else {
178  trackVelocity = 0;
179  value = s;
180  delayedStop();
181  }
182 
183  // to normalize 's' between [0..1], divide 'value' by 's'
184  return value;
185 }
186 
188 {
189  qreal time_seconds = qreal(t - lastTime) / qreal(1000.);
190 
191  qreal value = easeFollow(time_seconds);
192  value *= (invert? qreal(-1.0): qreal(1.0));
196 }
197 
199 {
200  if (velocity == 0) {
201  stop();
202  return;
203  }
204 
207 
209  lastTime = this->currentTime();
210 
211  if (to == initialValue) {
212  stop();
213  return;
214  }
215 
216  bool hasReversed = trackVelocity != qreal(0.) &&
217  ((!invert) == ((initialValue - to) > 0));
218 
219  if (hasReversed) {
220  switch (reversingMode) {
221  default:
224  break;
229  trackVelocity = 0;
230  stop();
231  return;
233  initialVelocity = 0;
234  break;
235  }
236  }
237 
239 
240  invert = (to < initialValue);
241 
242  if (!recalc()) {
246  stop();
247  return;
248  }
249 }
250 
303 {
304 }
305 
307 {
308 }
309 
311  : wrapperGroup(new QParallelAnimationGroup), anim(new QSmoothedAnimation)
312 {
316 }
317 
319 {
320  foreach(QSmoothedAnimation* ease, activeAnimations.values()){
323  ease->velocity = anim->velocity;
324  ease->userDuration = anim->userDuration;
325  ease->init();
326  }
327 }
328 
330 {
332  return d->wrapperGroup;
333 }
334 
336  QDeclarativeProperties &modified,
338 {
340  QDeclarativeNumberAnimation::transition(actions, modified, direction);
341 
342  if (!d->actions)
343  return;
344 
346  for (int i = 0; i < d->actions->size(); i++) {
347  QSmoothedAnimation *ease;
348  bool needsRestart;
349  if (!d->activeAnimations.contains((*d->actions)[i].property)) {
350  ease = new QSmoothedAnimation();
351  d->wrapperGroup->addAnimation(ease);
352  d->activeAnimations.insert((*d->actions)[i].property, ease);
353  needsRestart = false;
354  } else {
355  ease = d->activeAnimations.value((*d->actions)[i].property);
356  needsRestart = true;
357  }
358  ease->target = (*d->actions)[i].property;
359  ease->to = (*d->actions)[i].toValue.toReal();
360 
361  // copying public members from main value holder animation
362  ease->maximumEasingTime = d->anim->maximumEasingTime;
363  ease->reversingMode = d->anim->reversingMode;
364  ease->velocity = d->anim->velocity;
365  ease->userDuration = d->anim->userDuration;
366 
367  ease->initialVelocity = ease->trackVelocity;
368 
369  if (needsRestart)
370  ease->init();
371  anims.insert(ease);
372  }
373 
374  for (int i = d->wrapperGroup->animationCount() - 1; i >= 0 ; --i) {
375  if (!anims.contains(d->wrapperGroup->animationAt(i))) {
376  QSmoothedAnimation *ease = static_cast<QSmoothedAnimation*>(d->wrapperGroup->animationAt(i));
377  d->activeAnimations.remove(ease->target);
378  d->wrapperGroup->takeAnimation(i);
379  delete ease;
380  }
381  }
382 }
383 
401 {
403  return (QDeclarativeSmoothedAnimation::ReversingMode) d->anim->reversingMode;
404 }
405 
407 {
409  if (d->anim->reversingMode == m)
410  return;
411 
412  d->anim->reversingMode = m;
413  emit reversingModeChanged();
414  d->updateRunningAnimations();
415 }
416 
431 {
433  return d->anim->userDuration;
434 }
435 
437 {
439  if (duration != -1)
441  if(duration == d->anim->userDuration)
442  return;
443  d->anim->userDuration = duration;
444  d->updateRunningAnimations();
445 }
446 
448 {
450  return d->anim->velocity;
451 }
452 
469 {
471  if (d->anim->velocity == v)
472  return;
473 
474  d->anim->velocity = v;
475  emit velocityChanged();
476  d->updateRunningAnimations();
477 }
478 
493 {
495  return d->anim->maximumEasingTime;
496 }
497 
499 {
501  if(v == d->anim->maximumEasingTime)
502  return;
503  d->anim->maximumEasingTime = v;
504  emit maximumEasingTimeChanged();
505  d->updateRunningAnimations();
506 }
507 
double d
Definition: qnumeric_p.h:62
void setSingleShot(bool singleShot)
Definition: qtimer.h:108
virtual void transition(QDeclarativeStateActions &actions, QDeclarativeProperties &modified, TransitionDirection direction)
virtual void updateCurrentTime(int)
This pure virtual function is called every time the animation&#39;s currentTime changes.
double qreal
Definition: qglobal.h:1193
#define QT_END_NAMESPACE
This macro expands to.
Definition: qglobal.h:90
State
This enum describes the state of the animation.
ReversingMode reversingMode() const
State state() const
#define SLOT(a)
Definition: qobjectdefs.h:226
virtual void transition(QDeclarativeStateActions &actions, QDeclarativeProperties &modified, TransitionDirection direction)
void start(QAbstractAnimation::DeletionPolicy policy=KeepWhenStopped)
Starts the animation.
The QObject class is the base class of all Qt objects.
Definition: qobject.h:111
#define Q_D(Class)
Definition: qglobal.h:2482
void stop()
Stops the animation.
#define Q_Q(Class)
Definition: qglobal.h:2483
int currentTime() const
#define SIGNAL(a)
Definition: qobjectdefs.h:227
QDeclarativeSmoothedAnimation::ReversingMode reversingMode
#define QT_BEGIN_NAMESPACE
This macro expands to.
Definition: qglobal.h:89
bool contains(const T &value) const
Definition: qset.h:91
static bool connect(const QObject *sender, const char *signal, const QObject *receiver, const char *member, Qt::ConnectionType=Qt::AutoConnection)
Creates a connection of the given type from the signal in the sender object to the method in the rece...
Definition: qobject.cpp:2580
#define emit
Definition: qobjectdefs.h:76
const_iterator insert(const T &value)
Definition: qset.h:179
bool isActive() const
Returns true if the timer is running (pending); otherwise returns false.
Definition: qtimer.h:69
The QAbstractAnimation class is the base of all animations.
#define ceil(x)
void setInterval(int msec)
Definition: qtimer.cpp:419
virtual void updateState(QAbstractAnimation::State, QAbstractAnimation::State)
This virtual function is called by QAbstractAnimation when the state of the animation is changed from...
The QParallelAnimationGroup class provides a parallel group of animations.
void QDeclarative_setParent_noEvent(QObject *object, QObject *parent)
Makes the object a child of parent.
QList< T > values() const
Returns a list containing all the values in the hash, in an arbitrary order.
Definition: qhash.h:693
QObject * parent() const
Returns a pointer to the parent object.
Definition: qobject.h:273
const char * property
Definition: qwizard.cpp:138
QHash< QDeclarativeProperty, QSmoothedAnimation * > activeAnimations
#define DELAY_STOP_TIMER_INTERVAL
void stop()
Stops the timer.
Definition: qtimer.cpp:284
void start(int msec)
Starts or restarts the timer with a timeout interval of msec milliseconds.
Definition: qtimer.cpp:249
qreal qSqrt(qreal v)
Definition: qmath.h:205
qreal toReal(bool *ok=0) const
Returns the variant as a qreal if the variant has type() Double , QMetaType::Float ...
Definition: qvariant.cpp:2740
QVariant read() const
Returns the property value.
static bool write(QObject *, const QDeclarativePropertyCache::Data &, const QVariant &, QDeclarativeContextData *, WriteFlags flags=0)
Qt::LayoutDirection direction