Qt 4.8
qparallelanimationgroup.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 QtCore 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 
76 //#define QANIMATION_DEBUG
77 
78 #ifndef QT_NO_ANIMATION
79 
81 
88 {
89 }
90 
95  QObject *parent)
96  : QAnimationGroup(dd, parent)
97 {
98 }
99 
104 {
105 }
106 
111 {
113  int ret = 0;
114 
115  for (int i = 0; i < d->animations.size(); ++i) {
116  QAbstractAnimation *animation = d->animations.at(i);
117  const int currentDuration = animation->totalDuration();
118  if (currentDuration == -1)
119  return -1; // Undetermined length
120 
121  ret = qMax(ret, currentDuration);
122  }
123 
124  return ret;
125 }
126 
131 {
133  if (d->animations.isEmpty())
134  return;
135 
136  if (d->currentLoop > d->lastLoop) {
137  // simulate completion of the loop
138  int dura = duration();
139  if (dura > 0) {
140  for (int i = 0; i < d->animations.size(); ++i) {
141  QAbstractAnimation *animation = d->animations.at(i);
142  if (animation->state() != QAbstractAnimation::Stopped)
143  d->animations.at(i)->setCurrentTime(dura); // will stop
144  }
145  }
146  } else if (d->currentLoop < d->lastLoop) {
147  // simulate completion of the loop seeking backwards
148  for (int i = 0; i < d->animations.size(); ++i) {
149  QAbstractAnimation *animation = d->animations.at(i);
150  //we need to make sure the animation is in the right state
151  //and then rewind it
152  d->applyGroupState(animation);
153  animation->setCurrentTime(0);
154  animation->stop();
155  }
156  }
157 
158 #ifdef QANIMATION_DEBUG
159  qDebug("QParallellAnimationGroup %5d: setCurrentTime(%d), loop:%d, last:%d, timeFwd:%d, lastcurrent:%d, %d",
160  __LINE__, d->currentTime, d->currentLoop, d->lastLoop, timeFwd, d->lastCurrentTime, state());
161 #endif
162  // finally move into the actual time of the current loop
163  for (int i = 0; i < d->animations.size(); ++i) {
164  QAbstractAnimation *animation = d->animations.at(i);
165  const int dura = animation->totalDuration();
166  //if the loopcount is bigger we should always start all animations
167  if (d->currentLoop > d->lastLoop
168  //if we're at the end of the animation, we need to start it if it wasn't already started in this loop
169  //this happens in Backward direction where not all animations are started at the same time
170  || d->shouldAnimationStart(animation, d->lastCurrentTime > dura /*startIfAtEnd*/)) {
171  d->applyGroupState(animation);
172  }
173 
174  if (animation->state() == state()) {
175  animation->setCurrentTime(currentTime);
176  if (dura > 0 && currentTime > dura)
177  animation->stop();
178  }
179  }
180  d->lastLoop = d->currentLoop;
181  d->lastCurrentTime = currentTime;
182 }
183 
188  QAbstractAnimation::State oldState)
189 {
191  QAnimationGroup::updateState(newState, oldState);
192 
193  switch (newState) {
194  case Stopped:
195  for (int i = 0; i < d->animations.size(); ++i)
196  d->animations.at(i)->stop();
197  d->disconnectUncontrolledAnimations();
198  break;
199  case Paused:
200  for (int i = 0; i < d->animations.size(); ++i)
201  if (d->animations.at(i)->state() == Running)
202  d->animations.at(i)->pause();
203  break;
204  case Running:
205  d->connectUncontrolledAnimations();
206  for (int i = 0; i < d->animations.size(); ++i) {
207  QAbstractAnimation *animation = d->animations.at(i);
208  if (oldState == Stopped)
209  animation->stop();
210  animation->setDirection(d->direction);
211  if (d->shouldAnimationStart(animation, oldState == Stopped))
212  animation->start();
213  }
214  break;
215  }
216 }
217 
219 {
221 
222  QAbstractAnimation *animation = qobject_cast<QAbstractAnimation *>(q->sender());
223  Q_ASSERT(animation);
224 
225  int uncontrolledRunningCount = 0;
226  if (animation->duration() == -1 || animation->loopCount() < 0) {
227  QHash<QAbstractAnimation *, int>::iterator it = uncontrolledFinishTime.begin();
228  while (it != uncontrolledFinishTime.end()) {
229  if (it.key() == animation) {
230  *it = animation->currentTime();
231  }
232  if (it.value() == -1)
233  ++uncontrolledRunningCount;
234  ++it;
235  }
236  }
237 
238  if (uncontrolledRunningCount > 0)
239  return;
240 
241  int maxDuration = 0;
242  for (int i = 0; i < animations.size(); ++i)
243  maxDuration = qMax(maxDuration, animations.at(i)->totalDuration());
244 
245  if (currentTime >= maxDuration)
246  q->stop();
247 }
248 
250 {
251  QHash<QAbstractAnimation *, int>::iterator it = uncontrolledFinishTime.begin();
252  while (it != uncontrolledFinishTime.end()) {
253  disconnectUncontrolledAnimation(it.key());
254  ++it;
255  }
256 
257  uncontrolledFinishTime.clear();
258 }
259 
261 {
262  for (int i = 0; i < animations.size(); ++i) {
263  QAbstractAnimation *animation = animations.at(i);
264  if (animation->duration() == -1 || animation->loopCount() < 0) {
265  uncontrolledFinishTime[animation] = -1;
266  connectUncontrolledAnimation(animation);
267  }
268  }
269 }
270 
272 {
273  const int dura = animation->totalDuration();
274  if (dura == -1)
275  return !isUncontrolledAnimationFinished(animation);
276  if (startIfAtEnd)
277  return currentTime <= dura;
279  return currentTime < dura;
280  else //direction == QAbstractAnimation::Backward
281  return currentTime && currentTime <= dura;
282 }
283 
285 {
286  switch (state)
287  {
289  animation->start();
290  break;
292  animation->pause();
293  break;
295  default:
296  break;
297  }
298 }
299 
300 
302 {
303  return uncontrolledFinishTime.value(anim, -1) >= 0;
304 }
305 
307 {
309  disconnectUncontrolledAnimation(anim);
310  uncontrolledFinishTime.remove(anim);
311 }
312 
317 {
319  //we need to update the direction of the current animation
320  if (state() != Stopped) {
321  for (int i = 0; i < d->animations.size(); ++i) {
322  QAbstractAnimation *animation = d->animations.at(i);
323  animation->setDirection(direction);
324  }
325  } else {
326  if (direction == Forward) {
327  d->lastLoop = 0;
328  d->lastCurrentTime = 0;
329  } else {
330  // Looping backwards with loopCount == -1 does not really work well...
331  d->lastLoop = (d->loopCount == -1 ? 0 : d->loopCount - 1);
332  d->lastCurrentTime = duration();
333  }
334  }
335 }
336 
341 {
342  return QAnimationGroup::event(event);
343 }
344 
346 
347 #include "moc_qparallelanimationgroup.cpp"
348 
349 #endif //QT_NO_ANIMATION
double d
Definition: qnumeric_p.h:62
#define QT_END_NAMESPACE
This macro expands to.
Definition: qglobal.h:90
int totalDuration() const
Returns the total and effective duration of the animation, including the loop count.
State
This enum describes the state of the animation.
void animationRemoved(int index, QAbstractAnimation *)
#define it(className, varName)
State state() const
void start(QAbstractAnimation::DeletionPolicy policy=KeepWhenStopped)
Starts the animation.
bool event(QEvent *event)
Reimplemented Function
T * qobject_cast(QObject *object)
Definition: qobject.h:375
The QHash class is a template class that provides a hash-table-based dictionary.
Definition: qdatastream.h:66
#define Q_ASSERT(cond)
Definition: qglobal.h:1823
The QObject class is the base class of all Qt objects.
Definition: qobject.h:111
#define Q_D(Class)
Definition: qglobal.h:2482
State state
state of the animation.
const T value(const Key &key) const
Returns the value associated with the key.
Definition: qhash.h:606
void updateDirection(QAbstractAnimation::Direction direction)
Reimplemented Function
void stop()
Stops the animation.
Q_DECL_CONSTEXPR const T & qMax(const T &a, const T &b)
Definition: qglobal.h:1217
void updateState(QAbstractAnimation::State newState, QAbstractAnimation::State oldState)
Reimplemented Function
#define Q_Q(Class)
Definition: qglobal.h:2483
int currentTime() const
Q_CORE_EXPORT void qDebug(const char *,...)
#define QT_BEGIN_NAMESPACE
This macro expands to.
Definition: qglobal.h:89
Direction
This enum describes the direction of the animation when in Running state.
void setDirection(Direction direction)
bool shouldAnimationStart(QAbstractAnimation *animation, bool startIfAtEnd) const
The QAbstractAnimation class is the base of all animations.
void updateCurrentTime(int currentTime)
Reimplemented Function
int loopCount
the loop count of the animation
void applyGroupState(QAbstractAnimation *animation)
bool event(QEvent *event)
Reimplemented Function
The QParallelAnimationGroup class provides a parallel group of animations.
virtual void animationRemoved(int, QAbstractAnimation *)
iterator end()
Returns an STL-style iterator pointing to the imaginary item after the last item in the hash...
Definition: qhash.h:467
const Key key(const T &value) const
Returns the first key mapped to value.
Definition: qhash.h:674
QObject * parent() const
Returns a pointer to the parent object.
Definition: qobject.h:273
int currentTime
the current time and progress of the animation
virtual void updateState(QAbstractAnimation::State newState, QAbstractAnimation::State oldState)
This virtual function is called by QAbstractAnimation when the state of the animation is changed from...
void pause()
Pauses the animation.
quint16 index
bool isUncontrolledAnimationFinished(QAbstractAnimation *anim) const
Direction direction() const
The QAnimationGroup class is an abstract base class for groups of animations.
The QEvent class is the base class of all event classes.
Definition: qcoreevent.h:56
void setCurrentTime(int msecs)
int duration() const
Reimplemented Function
QParallelAnimationGroup(QObject *parent=0)
Constructs a QParallelAnimationGroup.
int duration
the duration of the animation.
~QParallelAnimationGroup()
Destroys the animation group.