|
1 /**************************************************************************** |
|
2 ** |
|
3 ** Copyright (C) 2010 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 QtDeclarative 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 #include "private/qdeclarativeanimation_p.h" |
|
43 #include "private/qdeclarativeanimation_p_p.h" |
|
44 |
|
45 #include "private/qdeclarativebehavior_p.h" |
|
46 #include "private/qdeclarativestateoperations_p.h" |
|
47 #include "private/qdeclarativecontext_p.h" |
|
48 |
|
49 #include <qdeclarativepropertyvaluesource.h> |
|
50 #include <qdeclarative.h> |
|
51 #include <qdeclarativeinfo.h> |
|
52 #include <qdeclarativeexpression.h> |
|
53 #include <qdeclarativestringconverters_p.h> |
|
54 #include <qdeclarativeglobal_p.h> |
|
55 #include <qdeclarativemetatype_p.h> |
|
56 #include <qdeclarativevaluetype_p.h> |
|
57 #include <qdeclarativeproperty_p.h> |
|
58 #include <qdeclarativeengine_p.h> |
|
59 |
|
60 #include <qvariant.h> |
|
61 #include <qcolor.h> |
|
62 #include <qfile.h> |
|
63 #include <QParallelAnimationGroup> |
|
64 #include <QSequentialAnimationGroup> |
|
65 #include <QtCore/qset.h> |
|
66 #include <QtCore/qrect.h> |
|
67 #include <QtCore/qpoint.h> |
|
68 #include <QtCore/qsize.h> |
|
69 #include <QtCore/qmath.h> |
|
70 |
|
71 #include <private/qvariantanimation_p.h> |
|
72 |
|
73 QT_BEGIN_NAMESPACE |
|
74 |
|
75 /*! |
|
76 \qmlclass Animation QDeclarativeAbstractAnimation |
|
77 \since 4.7 |
|
78 \brief The Animation element is the base of all QML animations. |
|
79 |
|
80 The Animation element cannot be used directly in a QML file. It exists |
|
81 to provide a set of common properties and methods, available across all the |
|
82 other animation types that inherit from it. Attempting to use the Animation |
|
83 element directly will result in an error. |
|
84 */ |
|
85 |
|
86 /*! |
|
87 \class QDeclarativeAbstractAnimation |
|
88 \internal |
|
89 */ |
|
90 |
|
91 QDeclarativeAbstractAnimation::QDeclarativeAbstractAnimation(QObject *parent) |
|
92 : QObject(*(new QDeclarativeAbstractAnimationPrivate), parent) |
|
93 { |
|
94 } |
|
95 |
|
96 QDeclarativeAbstractAnimation::~QDeclarativeAbstractAnimation() |
|
97 { |
|
98 } |
|
99 |
|
100 QDeclarativeAbstractAnimation::QDeclarativeAbstractAnimation(QDeclarativeAbstractAnimationPrivate &dd, QObject *parent) |
|
101 : QObject(dd, parent) |
|
102 { |
|
103 } |
|
104 |
|
105 /*! |
|
106 \qmlproperty bool Animation::running |
|
107 This property holds whether the animation is currently running. |
|
108 |
|
109 The \c running property can be set to declaratively control whether or not |
|
110 an animation is running. The following example will animate a rectangle |
|
111 whenever the \l MouseArea is pressed. |
|
112 |
|
113 \code |
|
114 Rectangle { |
|
115 width: 100; height: 100 |
|
116 NumberAnimation on x { |
|
117 running: myMouse.pressed |
|
118 from: 0; to: 100 |
|
119 } |
|
120 MouseArea { id: myMouse } |
|
121 } |
|
122 \endcode |
|
123 |
|
124 Likewise, the \c running property can be read to determine if the animation |
|
125 is running. In the following example the text element will indicate whether |
|
126 or not the animation is running. |
|
127 |
|
128 \code |
|
129 NumberAnimation { id: myAnimation } |
|
130 Text { text: myAnimation.running ? "Animation is running" : "Animation is not running" } |
|
131 \endcode |
|
132 |
|
133 Animations can also be started and stopped imperatively from JavaScript |
|
134 using the \c start() and \c stop() methods. |
|
135 |
|
136 By default, animations are not running. Though, when the animations are assigned to properties, |
|
137 as property value sources using the \e on syntax, they are set to running by default. |
|
138 */ |
|
139 bool QDeclarativeAbstractAnimation::isRunning() const |
|
140 { |
|
141 Q_D(const QDeclarativeAbstractAnimation); |
|
142 return d->running; |
|
143 } |
|
144 |
|
145 //commence is called to start an animation when it is used as a |
|
146 //simple animation, and not as part of a transition |
|
147 void QDeclarativeAbstractAnimationPrivate::commence() |
|
148 { |
|
149 Q_Q(QDeclarativeAbstractAnimation); |
|
150 |
|
151 QDeclarativeStateActions actions; |
|
152 QDeclarativeProperties properties; |
|
153 q->transition(actions, properties, QDeclarativeAbstractAnimation::Forward); |
|
154 |
|
155 q->qtAnimation()->start(); |
|
156 if (q->qtAnimation()->state() != QAbstractAnimation::Running) { |
|
157 running = false; |
|
158 emit q->completed(); |
|
159 } |
|
160 } |
|
161 |
|
162 QDeclarativeProperty QDeclarativeAbstractAnimationPrivate::createProperty(QObject *obj, const QString &str, QObject *infoObj) |
|
163 { |
|
164 QDeclarativeProperty prop(obj, str, qmlContext(infoObj)); |
|
165 if (!prop.isValid()) { |
|
166 qmlInfo(infoObj) << QDeclarativeAbstractAnimation::tr("Cannot animate non-existent property \"%1\"").arg(str); |
|
167 return QDeclarativeProperty(); |
|
168 } else if (!prop.isWritable()) { |
|
169 qmlInfo(infoObj) << QDeclarativeAbstractAnimation::tr("Cannot animate read-only property \"%1\"").arg(str); |
|
170 return QDeclarativeProperty(); |
|
171 } |
|
172 return prop; |
|
173 } |
|
174 |
|
175 void QDeclarativeAbstractAnimation::setRunning(bool r) |
|
176 { |
|
177 Q_D(QDeclarativeAbstractAnimation); |
|
178 if (!d->componentComplete) { |
|
179 d->running = r; |
|
180 if (r == false) |
|
181 d->avoidPropertyValueSourceStart = true; |
|
182 else { |
|
183 QDeclarativeEnginePrivate *engPriv = QDeclarativeEnginePrivate::get(qmlEngine(this)); |
|
184 engPriv->registerFinalizedParserStatusObject(this, this->metaObject()->indexOfSlot("componentFinalized()")); |
|
185 } |
|
186 return; |
|
187 } |
|
188 |
|
189 if (d->running == r) |
|
190 return; |
|
191 |
|
192 if (d->group || d->disableUserControl) { |
|
193 qmlInfo(this) << "setRunning() cannot be used on non-root animation nodes."; |
|
194 return; |
|
195 } |
|
196 |
|
197 d->running = r; |
|
198 if (d->running) { |
|
199 if (d->alwaysRunToEnd && d->loopCount != 1 |
|
200 && qtAnimation()->state() == QAbstractAnimation::Running) { |
|
201 //we've restarted before the final loop finished; restore proper loop count |
|
202 if (d->loopCount == -1) |
|
203 qtAnimation()->setLoopCount(d->loopCount); |
|
204 else |
|
205 qtAnimation()->setLoopCount(qtAnimation()->currentLoop() + d->loopCount); |
|
206 } |
|
207 |
|
208 if (!d->connectedTimeLine) { |
|
209 QObject::connect(qtAnimation(), SIGNAL(finished()), |
|
210 this, SLOT(timelineComplete())); |
|
211 d->connectedTimeLine = true; |
|
212 } |
|
213 d->commence(); |
|
214 emit started(); |
|
215 } else { |
|
216 if (d->alwaysRunToEnd) { |
|
217 if (d->loopCount != 1) |
|
218 qtAnimation()->setLoopCount(qtAnimation()->currentLoop()+1); //finish the current loop |
|
219 } else |
|
220 qtAnimation()->stop(); |
|
221 |
|
222 emit completed(); |
|
223 } |
|
224 |
|
225 emit runningChanged(d->running); |
|
226 } |
|
227 |
|
228 /*! |
|
229 \qmlproperty bool Animation::paused |
|
230 This property holds whether the animation is currently paused. |
|
231 |
|
232 The \c paused property can be set to declaratively control whether or not |
|
233 an animation is paused. |
|
234 |
|
235 Animations can also be paused and resumed imperatively from JavaScript |
|
236 using the \c pause() and \c resume() methods. |
|
237 |
|
238 By default, animations are not paused. |
|
239 */ |
|
240 bool QDeclarativeAbstractAnimation::isPaused() const |
|
241 { |
|
242 Q_D(const QDeclarativeAbstractAnimation); |
|
243 return d->paused; |
|
244 } |
|
245 |
|
246 void QDeclarativeAbstractAnimation::setPaused(bool p) |
|
247 { |
|
248 Q_D(QDeclarativeAbstractAnimation); |
|
249 if (d->paused == p) |
|
250 return; |
|
251 |
|
252 if (d->group || d->disableUserControl) { |
|
253 qmlInfo(this) << "setPaused() cannot be used on non-root animation nodes."; |
|
254 return; |
|
255 } |
|
256 |
|
257 d->paused = p; |
|
258 if (d->paused) |
|
259 qtAnimation()->pause(); |
|
260 else |
|
261 qtAnimation()->resume(); |
|
262 |
|
263 emit pausedChanged(d->paused); |
|
264 } |
|
265 |
|
266 void QDeclarativeAbstractAnimation::classBegin() |
|
267 { |
|
268 Q_D(QDeclarativeAbstractAnimation); |
|
269 d->componentComplete = false; |
|
270 } |
|
271 |
|
272 void QDeclarativeAbstractAnimation::componentComplete() |
|
273 { |
|
274 Q_D(QDeclarativeAbstractAnimation); |
|
275 d->componentComplete = true; |
|
276 } |
|
277 |
|
278 void QDeclarativeAbstractAnimation::componentFinalized() |
|
279 { |
|
280 Q_D(QDeclarativeAbstractAnimation); |
|
281 if (d->running) { |
|
282 d->running = false; |
|
283 setRunning(true); |
|
284 } |
|
285 } |
|
286 |
|
287 /*! |
|
288 \qmlproperty bool Animation::alwaysRunToEnd |
|
289 This property holds whether the animation should run to completion when it is stopped. |
|
290 |
|
291 If this true the animation will complete its current iteration when it |
|
292 is stopped - either by setting the \c running property to false, or by |
|
293 calling the \c stop() method. The \c complete() method is not effected |
|
294 by this value. |
|
295 |
|
296 This behavior is most useful when the \c repeat property is set, as the |
|
297 animation will finish playing normally but not restart. |
|
298 |
|
299 By default, the alwaysRunToEnd property is not set. |
|
300 */ |
|
301 bool QDeclarativeAbstractAnimation::alwaysRunToEnd() const |
|
302 { |
|
303 Q_D(const QDeclarativeAbstractAnimation); |
|
304 return d->alwaysRunToEnd; |
|
305 } |
|
306 |
|
307 void QDeclarativeAbstractAnimation::setAlwaysRunToEnd(bool f) |
|
308 { |
|
309 Q_D(QDeclarativeAbstractAnimation); |
|
310 if (d->alwaysRunToEnd == f) |
|
311 return; |
|
312 |
|
313 d->alwaysRunToEnd = f; |
|
314 emit alwaysRunToEndChanged(f); |
|
315 } |
|
316 |
|
317 /*! |
|
318 \qmlproperty int Animation::loops |
|
319 This property holds the number of times the animation should play. |
|
320 |
|
321 By default, \c loops is 1: the animation will play through once and then stop. |
|
322 |
|
323 If set to Animation.Infinite, the animation will continuously repeat until it is explicitly |
|
324 stopped - either by setting the \c running property to false, or by calling |
|
325 the \c stop() method. |
|
326 |
|
327 In the following example, the rectangle will spin indefinately. |
|
328 |
|
329 \code |
|
330 Rectangle { |
|
331 width: 100; height: 100; color: "green" |
|
332 RotationAnimation on rotation { |
|
333 loops: Animation.Infinite |
|
334 from: 0 |
|
335 to: 360 |
|
336 } |
|
337 } |
|
338 \endcode |
|
339 */ |
|
340 int QDeclarativeAbstractAnimation::loops() const |
|
341 { |
|
342 Q_D(const QDeclarativeAbstractAnimation); |
|
343 return d->loopCount; |
|
344 } |
|
345 |
|
346 void QDeclarativeAbstractAnimation::setLoops(int loops) |
|
347 { |
|
348 Q_D(QDeclarativeAbstractAnimation); |
|
349 if (loops < 0) |
|
350 loops = -1; |
|
351 |
|
352 if (loops == d->loopCount) |
|
353 return; |
|
354 |
|
355 d->loopCount = loops; |
|
356 qtAnimation()->setLoopCount(loops); |
|
357 emit loopCountChanged(loops); |
|
358 } |
|
359 |
|
360 |
|
361 int QDeclarativeAbstractAnimation::currentTime() |
|
362 { |
|
363 return qtAnimation()->currentLoopTime(); |
|
364 } |
|
365 |
|
366 void QDeclarativeAbstractAnimation::setCurrentTime(int time) |
|
367 { |
|
368 qtAnimation()->setCurrentTime(time); |
|
369 } |
|
370 |
|
371 QDeclarativeAnimationGroup *QDeclarativeAbstractAnimation::group() const |
|
372 { |
|
373 Q_D(const QDeclarativeAbstractAnimation); |
|
374 return d->group; |
|
375 } |
|
376 |
|
377 void QDeclarativeAbstractAnimation::setGroup(QDeclarativeAnimationGroup *g) |
|
378 { |
|
379 Q_D(QDeclarativeAbstractAnimation); |
|
380 if (d->group == g) |
|
381 return; |
|
382 if (d->group) |
|
383 static_cast<QDeclarativeAnimationGroupPrivate *>(d->group->d_func())->animations.removeAll(this); |
|
384 |
|
385 d->group = g; |
|
386 |
|
387 if (d->group && !static_cast<QDeclarativeAnimationGroupPrivate *>(d->group->d_func())->animations.contains(this)) |
|
388 static_cast<QDeclarativeAnimationGroupPrivate *>(d->group->d_func())->animations.append(this); |
|
389 |
|
390 //if (g) //if removed from a group, then the group should no longer be the parent |
|
391 setParent(g); |
|
392 } |
|
393 |
|
394 /*! |
|
395 \qmlmethod Animation::start() |
|
396 \brief Starts the animation. |
|
397 |
|
398 If the animation is already running, calling this method has no effect. The |
|
399 \c running property will be true following a call to \c start(). |
|
400 */ |
|
401 void QDeclarativeAbstractAnimation::start() |
|
402 { |
|
403 setRunning(true); |
|
404 } |
|
405 |
|
406 /*! |
|
407 \qmlmethod Animation::pause() |
|
408 \brief Pauses the animation. |
|
409 |
|
410 If the animation is already paused, calling this method has no effect. The |
|
411 \c paused property will be true following a call to \c pause(). |
|
412 */ |
|
413 void QDeclarativeAbstractAnimation::pause() |
|
414 { |
|
415 setPaused(true); |
|
416 } |
|
417 |
|
418 /*! |
|
419 \qmlmethod Animation::resume() |
|
420 \brief Resumes a paused animation. |
|
421 |
|
422 If the animation is not paused, calling this method has no effect. The |
|
423 \c paused property will be false following a call to \c resume(). |
|
424 */ |
|
425 void QDeclarativeAbstractAnimation::resume() |
|
426 { |
|
427 setPaused(false); |
|
428 } |
|
429 |
|
430 /*! |
|
431 \qmlmethod Animation::stop() |
|
432 \brief Stops the animation. |
|
433 |
|
434 If the animation is not running, calling this method has no effect. The |
|
435 \c running property will be false following a call to \c stop(). |
|
436 |
|
437 Normally \c stop() stops the animation immediately, and the animation has |
|
438 no further influence on property values. In this example animation |
|
439 \code |
|
440 Rectangle { |
|
441 NumberAnimation on x { from: 0; to: 100; duration: 500 } |
|
442 } |
|
443 \endcode |
|
444 was stopped at time 250ms, the \c x property will have a value of 50. |
|
445 |
|
446 However, if the \c alwaysRunToEnd property is set, the animation will |
|
447 continue running until it completes and then stop. The \c running property |
|
448 will still become false immediately. |
|
449 */ |
|
450 void QDeclarativeAbstractAnimation::stop() |
|
451 { |
|
452 setRunning(false); |
|
453 } |
|
454 |
|
455 /*! |
|
456 \qmlmethod Animation::restart() |
|
457 \brief Restarts the animation. |
|
458 |
|
459 This is a convenience method, and is equivalent to calling \c stop() and |
|
460 then \c start(). |
|
461 */ |
|
462 void QDeclarativeAbstractAnimation::restart() |
|
463 { |
|
464 stop(); |
|
465 start(); |
|
466 } |
|
467 |
|
468 /*! |
|
469 \qmlmethod Animation::complete() |
|
470 \brief Stops the animation, jumping to the final property values. |
|
471 |
|
472 If the animation is not running, calling this method has no effect. The |
|
473 \c running property will be false following a call to \c complete(). |
|
474 |
|
475 Unlike \c stop(), \c complete() immediately fast-forwards the animation to |
|
476 its end. In the following example, |
|
477 \code |
|
478 Rectangle { |
|
479 NumberAnimation on x { from: 0; to: 100; duration: 500 } |
|
480 } |
|
481 \endcode |
|
482 calling \c stop() at time 250ms will result in the \c x property having |
|
483 a value of 50, while calling \c complete() will set the \c x property to |
|
484 100, exactly as though the animation had played the whole way through. |
|
485 */ |
|
486 void QDeclarativeAbstractAnimation::complete() |
|
487 { |
|
488 if (isRunning()) { |
|
489 qtAnimation()->setCurrentTime(qtAnimation()->duration()); |
|
490 } |
|
491 } |
|
492 |
|
493 void QDeclarativeAbstractAnimation::setTarget(const QDeclarativeProperty &p) |
|
494 { |
|
495 Q_D(QDeclarativeAbstractAnimation); |
|
496 d->defaultProperty = p; |
|
497 |
|
498 if (!d->avoidPropertyValueSourceStart) |
|
499 setRunning(true); |
|
500 } |
|
501 |
|
502 /* |
|
503 we rely on setTarget only being called when used as a value source |
|
504 so this function allows us to do the same thing as setTarget without |
|
505 that assumption |
|
506 */ |
|
507 void QDeclarativeAbstractAnimation::setDefaultTarget(const QDeclarativeProperty &p) |
|
508 { |
|
509 Q_D(QDeclarativeAbstractAnimation); |
|
510 d->defaultProperty = p; |
|
511 } |
|
512 |
|
513 /* |
|
514 don't allow start/stop/pause/resume to be manually invoked, |
|
515 because something else (like a Behavior) already has control |
|
516 over the animation. |
|
517 */ |
|
518 void QDeclarativeAbstractAnimation::setDisableUserControl() |
|
519 { |
|
520 Q_D(QDeclarativeAbstractAnimation); |
|
521 d->disableUserControl = true; |
|
522 } |
|
523 |
|
524 void QDeclarativeAbstractAnimation::transition(QDeclarativeStateActions &actions, |
|
525 QDeclarativeProperties &modified, |
|
526 TransitionDirection direction) |
|
527 { |
|
528 Q_UNUSED(actions); |
|
529 Q_UNUSED(modified); |
|
530 Q_UNUSED(direction); |
|
531 } |
|
532 |
|
533 void QDeclarativeAbstractAnimation::timelineComplete() |
|
534 { |
|
535 Q_D(QDeclarativeAbstractAnimation); |
|
536 setRunning(false); |
|
537 if (d->alwaysRunToEnd && d->loopCount != 1) { |
|
538 //restore the proper loopCount for the next run |
|
539 qtAnimation()->setLoopCount(d->loopCount); |
|
540 } |
|
541 } |
|
542 |
|
543 /*! |
|
544 \qmlclass PauseAnimation QDeclarativePauseAnimation |
|
545 \since 4.7 |
|
546 \inherits Animation |
|
547 \brief The PauseAnimation element provides a pause for an animation. |
|
548 |
|
549 When used in a SequentialAnimation, PauseAnimation is a step when |
|
550 nothing happens, for a specified duration. |
|
551 |
|
552 A 500ms animation sequence, with a 100ms pause between two animations: |
|
553 \code |
|
554 SequentialAnimation { |
|
555 NumberAnimation { ... duration: 200 } |
|
556 PauseAnimation { duration: 100 } |
|
557 NumberAnimation { ... duration: 200 } |
|
558 } |
|
559 \endcode |
|
560 */ |
|
561 /*! |
|
562 \internal |
|
563 \class QDeclarativePauseAnimation |
|
564 */ |
|
565 |
|
566 |
|
567 QDeclarativePauseAnimation::QDeclarativePauseAnimation(QObject *parent) |
|
568 : QDeclarativeAbstractAnimation(*(new QDeclarativePauseAnimationPrivate), parent) |
|
569 { |
|
570 Q_D(QDeclarativePauseAnimation); |
|
571 d->init(); |
|
572 } |
|
573 |
|
574 QDeclarativePauseAnimation::~QDeclarativePauseAnimation() |
|
575 { |
|
576 } |
|
577 |
|
578 void QDeclarativePauseAnimationPrivate::init() |
|
579 { |
|
580 Q_Q(QDeclarativePauseAnimation); |
|
581 pa = new QPauseAnimation; |
|
582 QDeclarative_setParent_noEvent(pa, q); |
|
583 } |
|
584 |
|
585 /*! |
|
586 \qmlproperty int PauseAnimation::duration |
|
587 This property holds the duration of the pause in milliseconds |
|
588 |
|
589 The default value is 250. |
|
590 */ |
|
591 int QDeclarativePauseAnimation::duration() const |
|
592 { |
|
593 Q_D(const QDeclarativePauseAnimation); |
|
594 return d->pa->duration(); |
|
595 } |
|
596 |
|
597 void QDeclarativePauseAnimation::setDuration(int duration) |
|
598 { |
|
599 if (duration < 0) { |
|
600 qmlInfo(this) << tr("Cannot set a duration of < 0"); |
|
601 return; |
|
602 } |
|
603 |
|
604 Q_D(QDeclarativePauseAnimation); |
|
605 if (d->pa->duration() == duration) |
|
606 return; |
|
607 d->pa->setDuration(duration); |
|
608 emit durationChanged(duration); |
|
609 } |
|
610 |
|
611 QAbstractAnimation *QDeclarativePauseAnimation::qtAnimation() |
|
612 { |
|
613 Q_D(QDeclarativePauseAnimation); |
|
614 return d->pa; |
|
615 } |
|
616 |
|
617 /*! |
|
618 \qmlclass ColorAnimation QDeclarativeColorAnimation |
|
619 \since 4.7 |
|
620 \inherits PropertyAnimation |
|
621 \brief The ColorAnimation element allows you to animate color changes. |
|
622 |
|
623 \code |
|
624 ColorAnimation { from: "white"; to: "#c0c0c0"; duration: 100 } |
|
625 \endcode |
|
626 |
|
627 When used in a transition, ColorAnimation will by default animate |
|
628 all properties of type color that are changing. If a property or properties |
|
629 are explicitly set for the animation, then those will be used instead. |
|
630 */ |
|
631 /*! |
|
632 \internal |
|
633 \class QDeclarativeColorAnimation |
|
634 */ |
|
635 |
|
636 QDeclarativeColorAnimation::QDeclarativeColorAnimation(QObject *parent) |
|
637 : QDeclarativePropertyAnimation(parent) |
|
638 { |
|
639 Q_D(QDeclarativePropertyAnimation); |
|
640 d->interpolatorType = QMetaType::QColor; |
|
641 d->interpolator = QVariantAnimationPrivate::getInterpolator(d->interpolatorType); |
|
642 d->defaultToInterpolatorType = true; |
|
643 } |
|
644 |
|
645 QDeclarativeColorAnimation::~QDeclarativeColorAnimation() |
|
646 { |
|
647 } |
|
648 |
|
649 /*! |
|
650 \qmlproperty color ColorAnimation::from |
|
651 This property holds the starting color. |
|
652 */ |
|
653 QColor QDeclarativeColorAnimation::from() const |
|
654 { |
|
655 Q_D(const QDeclarativePropertyAnimation); |
|
656 return d->from.value<QColor>(); |
|
657 } |
|
658 |
|
659 void QDeclarativeColorAnimation::setFrom(const QColor &f) |
|
660 { |
|
661 QDeclarativePropertyAnimation::setFrom(f); |
|
662 } |
|
663 |
|
664 /*! |
|
665 \qmlproperty color ColorAnimation::to |
|
666 This property holds the ending color. |
|
667 */ |
|
668 QColor QDeclarativeColorAnimation::to() const |
|
669 { |
|
670 Q_D(const QDeclarativePropertyAnimation); |
|
671 return d->to.value<QColor>(); |
|
672 } |
|
673 |
|
674 void QDeclarativeColorAnimation::setTo(const QColor &t) |
|
675 { |
|
676 QDeclarativePropertyAnimation::setTo(t); |
|
677 } |
|
678 |
|
679 |
|
680 |
|
681 /*! |
|
682 \qmlclass ScriptAction QDeclarativeScriptAction |
|
683 \since 4.7 |
|
684 \inherits Animation |
|
685 \brief The ScriptAction element allows scripts to be run during an animation. |
|
686 |
|
687 ScriptAction can be used to run script at a specific point in an animation. |
|
688 |
|
689 \qml |
|
690 SequentialAnimation { |
|
691 NumberAnimation { ... } |
|
692 ScriptAction { script: doSomething(); } |
|
693 NumberAnimation { ... } |
|
694 } |
|
695 \endqml |
|
696 |
|
697 When used as part of a Transition, you can also target a specific |
|
698 StateChangeScript to run using the \c scriptName property. |
|
699 |
|
700 \qml |
|
701 State { |
|
702 StateChangeScript { |
|
703 name: "myScript" |
|
704 script: doStateStuff(); |
|
705 } |
|
706 } |
|
707 ... |
|
708 Transition { |
|
709 SequentialAnimation { |
|
710 NumberAnimation { ... } |
|
711 ScriptAction { scriptName: "myScript" } |
|
712 NumberAnimation { ... } |
|
713 } |
|
714 } |
|
715 \endqml |
|
716 |
|
717 \sa StateChangeScript |
|
718 */ |
|
719 /*! |
|
720 \internal |
|
721 \class QDeclarativeScriptAction |
|
722 */ |
|
723 QDeclarativeScriptAction::QDeclarativeScriptAction(QObject *parent) |
|
724 :QDeclarativeAbstractAnimation(*(new QDeclarativeScriptActionPrivate), parent) |
|
725 { |
|
726 Q_D(QDeclarativeScriptAction); |
|
727 d->init(); |
|
728 } |
|
729 |
|
730 QDeclarativeScriptAction::~QDeclarativeScriptAction() |
|
731 { |
|
732 } |
|
733 |
|
734 void QDeclarativeScriptActionPrivate::init() |
|
735 { |
|
736 Q_Q(QDeclarativeScriptAction); |
|
737 rsa = new QActionAnimation(&proxy); |
|
738 QDeclarative_setParent_noEvent(rsa, q); |
|
739 } |
|
740 |
|
741 /*! |
|
742 \qmlproperty script ScriptAction::script |
|
743 This property holds the script to run. |
|
744 */ |
|
745 QDeclarativeScriptString QDeclarativeScriptAction::script() const |
|
746 { |
|
747 Q_D(const QDeclarativeScriptAction); |
|
748 return d->script; |
|
749 } |
|
750 |
|
751 void QDeclarativeScriptAction::setScript(const QDeclarativeScriptString &script) |
|
752 { |
|
753 Q_D(QDeclarativeScriptAction); |
|
754 d->script = script; |
|
755 } |
|
756 |
|
757 /*! |
|
758 \qmlproperty string ScriptAction::scriptName |
|
759 This property holds the the name of the StateChangeScript to run. |
|
760 |
|
761 This property is only valid when ScriptAction is used as part of a transition. |
|
762 If both script and scriptName are set, scriptName will be used. |
|
763 |
|
764 \note When using scriptName in a reversible transition, the script will only |
|
765 be run when the transition is being run forwards. |
|
766 */ |
|
767 QString QDeclarativeScriptAction::stateChangeScriptName() const |
|
768 { |
|
769 Q_D(const QDeclarativeScriptAction); |
|
770 return d->name; |
|
771 } |
|
772 |
|
773 void QDeclarativeScriptAction::setStateChangeScriptName(const QString &name) |
|
774 { |
|
775 Q_D(QDeclarativeScriptAction); |
|
776 d->name = name; |
|
777 } |
|
778 |
|
779 void QDeclarativeScriptActionPrivate::execute() |
|
780 { |
|
781 Q_Q(QDeclarativeScriptAction); |
|
782 if (hasRunScriptScript && reversing) |
|
783 return; |
|
784 |
|
785 QDeclarativeScriptString scriptStr = hasRunScriptScript ? runScriptScript : script; |
|
786 |
|
787 const QString &str = scriptStr.script(); |
|
788 if (!str.isEmpty()) { |
|
789 QDeclarativeExpression expr(scriptStr.context(), scriptStr.scopeObject(), str); |
|
790 QDeclarativeData *ddata = QDeclarativeData::get(q); |
|
791 if (ddata && ddata->outerContext && !ddata->outerContext->url.isEmpty()) |
|
792 expr.setSourceLocation(ddata->outerContext->url.toString(), ddata->lineNumber); |
|
793 expr.evaluate(); |
|
794 if (expr.hasError()) |
|
795 qmlInfo(q) << expr.error(); |
|
796 } |
|
797 } |
|
798 |
|
799 void QDeclarativeScriptAction::transition(QDeclarativeStateActions &actions, |
|
800 QDeclarativeProperties &modified, |
|
801 TransitionDirection direction) |
|
802 { |
|
803 Q_D(QDeclarativeScriptAction); |
|
804 Q_UNUSED(modified); |
|
805 |
|
806 d->hasRunScriptScript = false; |
|
807 d->reversing = (direction == Backward); |
|
808 for (int ii = 0; ii < actions.count(); ++ii) { |
|
809 QDeclarativeAction &action = actions[ii]; |
|
810 |
|
811 if (action.event && action.event->typeName() == QLatin1String("StateChangeScript") |
|
812 && static_cast<QDeclarativeStateChangeScript*>(action.event)->name() == d->name) { |
|
813 d->runScriptScript = static_cast<QDeclarativeStateChangeScript*>(action.event)->script(); |
|
814 d->hasRunScriptScript = true; |
|
815 action.actionDone = true; |
|
816 break; //only match one (names should be unique) |
|
817 } |
|
818 } |
|
819 } |
|
820 |
|
821 QAbstractAnimation *QDeclarativeScriptAction::qtAnimation() |
|
822 { |
|
823 Q_D(QDeclarativeScriptAction); |
|
824 return d->rsa; |
|
825 } |
|
826 |
|
827 |
|
828 |
|
829 /*! |
|
830 \qmlclass PropertyAction QDeclarativePropertyAction |
|
831 \since 4.7 |
|
832 \inherits Animation |
|
833 \brief The PropertyAction element allows immediate property changes during animation. |
|
834 |
|
835 Explicitly set \c theimage.smooth=true during a transition: |
|
836 \code |
|
837 PropertyAction { target: theimage; property: "smooth"; value: true } |
|
838 \endcode |
|
839 |
|
840 Set \c thewebview.url to the value set for the destination state: |
|
841 \code |
|
842 PropertyAction { target: thewebview; property: "url" } |
|
843 \endcode |
|
844 |
|
845 The PropertyAction is immediate - |
|
846 the target property is not animated to the selected value in any way. |
|
847 |
|
848 \sa QtDeclarative |
|
849 */ |
|
850 /*! |
|
851 \internal |
|
852 \class QDeclarativePropertyAction |
|
853 */ |
|
854 QDeclarativePropertyAction::QDeclarativePropertyAction(QObject *parent) |
|
855 : QDeclarativeAbstractAnimation(*(new QDeclarativePropertyActionPrivate), parent) |
|
856 { |
|
857 Q_D(QDeclarativePropertyAction); |
|
858 d->init(); |
|
859 } |
|
860 |
|
861 QDeclarativePropertyAction::~QDeclarativePropertyAction() |
|
862 { |
|
863 } |
|
864 |
|
865 void QDeclarativePropertyActionPrivate::init() |
|
866 { |
|
867 Q_Q(QDeclarativePropertyAction); |
|
868 spa = new QActionAnimation; |
|
869 QDeclarative_setParent_noEvent(spa, q); |
|
870 } |
|
871 |
|
872 /*! |
|
873 \qmlproperty Object PropertyAction::target |
|
874 This property holds an explicit target object to animate. |
|
875 |
|
876 The exact effect of the \c target property depends on how the animation |
|
877 is being used. Refer to the \l {QML Animation} documentation for details. |
|
878 */ |
|
879 |
|
880 QObject *QDeclarativePropertyAction::target() const |
|
881 { |
|
882 Q_D(const QDeclarativePropertyAction); |
|
883 return d->target; |
|
884 } |
|
885 |
|
886 void QDeclarativePropertyAction::setTarget(QObject *o) |
|
887 { |
|
888 Q_D(QDeclarativePropertyAction); |
|
889 if (d->target == o) |
|
890 return; |
|
891 d->target = o; |
|
892 emit targetChanged(d->target, d->propertyName); |
|
893 } |
|
894 |
|
895 QString QDeclarativePropertyAction::property() const |
|
896 { |
|
897 Q_D(const QDeclarativePropertyAction); |
|
898 return d->propertyName; |
|
899 } |
|
900 |
|
901 void QDeclarativePropertyAction::setProperty(const QString &n) |
|
902 { |
|
903 Q_D(QDeclarativePropertyAction); |
|
904 if (d->propertyName == n) |
|
905 return; |
|
906 d->propertyName = n; |
|
907 emit targetChanged(d->target, d->propertyName); |
|
908 } |
|
909 |
|
910 /*! |
|
911 \qmlproperty list<Object> PropertyAction::targets |
|
912 \qmlproperty string PropertyAction::property |
|
913 \qmlproperty string PropertyAction::properties |
|
914 \qmlproperty Object PropertyAction::target |
|
915 |
|
916 These properties are used as a set to determine which properties should be |
|
917 affected by this action. |
|
918 |
|
919 The details of how these properties are interpreted in different situations |
|
920 is covered in the \l{PropertyAnimation::properties}{corresponding} PropertyAnimation |
|
921 documentation. |
|
922 |
|
923 \sa exclude |
|
924 */ |
|
925 QString QDeclarativePropertyAction::properties() const |
|
926 { |
|
927 Q_D(const QDeclarativePropertyAction); |
|
928 return d->properties; |
|
929 } |
|
930 |
|
931 void QDeclarativePropertyAction::setProperties(const QString &p) |
|
932 { |
|
933 Q_D(QDeclarativePropertyAction); |
|
934 if (d->properties == p) |
|
935 return; |
|
936 d->properties = p; |
|
937 emit propertiesChanged(p); |
|
938 } |
|
939 |
|
940 QDeclarativeListProperty<QObject> QDeclarativePropertyAction::targets() |
|
941 { |
|
942 Q_D(QDeclarativePropertyAction); |
|
943 return QDeclarativeListProperty<QObject>(this, d->targets); |
|
944 } |
|
945 |
|
946 /*! |
|
947 \qmlproperty list<Object> PropertyAction::exclude |
|
948 This property holds the objects not to be affected by this animation. |
|
949 |
|
950 \sa targets |
|
951 */ |
|
952 QDeclarativeListProperty<QObject> QDeclarativePropertyAction::exclude() |
|
953 { |
|
954 Q_D(QDeclarativePropertyAction); |
|
955 return QDeclarativeListProperty<QObject>(this, d->exclude); |
|
956 } |
|
957 |
|
958 /*! |
|
959 \qmlproperty any PropertyAction::value |
|
960 This property holds the value to be set on the property. |
|
961 If not set, then the value defined for the end state of the transition. |
|
962 */ |
|
963 QVariant QDeclarativePropertyAction::value() const |
|
964 { |
|
965 Q_D(const QDeclarativePropertyAction); |
|
966 return d->value; |
|
967 } |
|
968 |
|
969 void QDeclarativePropertyAction::setValue(const QVariant &v) |
|
970 { |
|
971 Q_D(QDeclarativePropertyAction); |
|
972 if (d->value.isNull || d->value != v) { |
|
973 d->value = v; |
|
974 emit valueChanged(v); |
|
975 } |
|
976 } |
|
977 |
|
978 QAbstractAnimation *QDeclarativePropertyAction::qtAnimation() |
|
979 { |
|
980 Q_D(QDeclarativePropertyAction); |
|
981 return d->spa; |
|
982 } |
|
983 |
|
984 void QDeclarativePropertyAction::transition(QDeclarativeStateActions &actions, |
|
985 QDeclarativeProperties &modified, |
|
986 TransitionDirection direction) |
|
987 { |
|
988 Q_D(QDeclarativePropertyAction); |
|
989 Q_UNUSED(direction); |
|
990 |
|
991 struct QDeclarativeSetPropertyAnimationAction : public QAbstractAnimationAction |
|
992 { |
|
993 QDeclarativeStateActions actions; |
|
994 virtual void doAction() |
|
995 { |
|
996 for (int ii = 0; ii < actions.count(); ++ii) { |
|
997 const QDeclarativeAction &action = actions.at(ii); |
|
998 QDeclarativePropertyPrivate::write(action.property, action.toValue, QDeclarativePropertyPrivate::BypassInterceptor | QDeclarativePropertyPrivate::DontRemoveBinding); |
|
999 } |
|
1000 } |
|
1001 }; |
|
1002 |
|
1003 QStringList props = d->properties.isEmpty() ? QStringList() : d->properties.split(QLatin1Char(',')); |
|
1004 for (int ii = 0; ii < props.count(); ++ii) |
|
1005 props[ii] = props.at(ii).trimmed(); |
|
1006 if (!d->propertyName.isEmpty()) |
|
1007 props << d->propertyName; |
|
1008 |
|
1009 QList<QObject*> targets = d->targets; |
|
1010 if (d->target) |
|
1011 targets.append(d->target); |
|
1012 |
|
1013 bool hasSelectors = !props.isEmpty() || !targets.isEmpty() || !d->exclude.isEmpty(); |
|
1014 |
|
1015 if (d->defaultProperty.isValid() && !hasSelectors) { |
|
1016 props << d->defaultProperty.name(); |
|
1017 targets << d->defaultProperty.object(); |
|
1018 } |
|
1019 |
|
1020 QDeclarativeSetPropertyAnimationAction *data = new QDeclarativeSetPropertyAnimationAction; |
|
1021 |
|
1022 bool hasExplicit = false; |
|
1023 //an explicit animation has been specified |
|
1024 if (d->value.isValid()) { |
|
1025 for (int i = 0; i < props.count(); ++i) { |
|
1026 for (int j = 0; j < targets.count(); ++j) { |
|
1027 QDeclarativeAction myAction; |
|
1028 myAction.property = d->createProperty(targets.at(j), props.at(i), this); |
|
1029 if (myAction.property.isValid()) { |
|
1030 myAction.toValue = d->value; |
|
1031 QDeclarativePropertyAnimationPrivate::convertVariant(myAction.toValue, myAction.property.propertyType()); |
|
1032 data->actions << myAction; |
|
1033 hasExplicit = true; |
|
1034 for (int ii = 0; ii < actions.count(); ++ii) { |
|
1035 QDeclarativeAction &action = actions[ii]; |
|
1036 if (action.property.object() == myAction.property.object() && |
|
1037 myAction.property.name() == action.property.name()) { |
|
1038 modified << action.property; |
|
1039 break; //### any chance there could be multiples? |
|
1040 } |
|
1041 } |
|
1042 } |
|
1043 } |
|
1044 } |
|
1045 } |
|
1046 |
|
1047 if (!hasExplicit) |
|
1048 for (int ii = 0; ii < actions.count(); ++ii) { |
|
1049 QDeclarativeAction &action = actions[ii]; |
|
1050 |
|
1051 QObject *obj = action.property.object(); |
|
1052 QString propertyName = action.property.name(); |
|
1053 QObject *sObj = action.specifiedObject; |
|
1054 QString sPropertyName = action.specifiedProperty; |
|
1055 bool same = (obj == sObj); |
|
1056 |
|
1057 if ((targets.isEmpty() || targets.contains(obj) || (!same && targets.contains(sObj))) && |
|
1058 (!d->exclude.contains(obj)) && (same || (!d->exclude.contains(sObj))) && |
|
1059 (props.contains(propertyName) || (!same && props.contains(sPropertyName)))) { |
|
1060 QDeclarativeAction myAction = action; |
|
1061 |
|
1062 if (d->value.isValid()) |
|
1063 myAction.toValue = d->value; |
|
1064 QDeclarativePropertyAnimationPrivate::convertVariant(myAction.toValue, myAction.property.propertyType()); |
|
1065 |
|
1066 modified << action.property; |
|
1067 data->actions << myAction; |
|
1068 action.fromValue = myAction.toValue; |
|
1069 } |
|
1070 } |
|
1071 |
|
1072 if (data->actions.count()) { |
|
1073 d->spa->setAnimAction(data, QAbstractAnimation::DeleteWhenStopped); |
|
1074 } else { |
|
1075 delete data; |
|
1076 } |
|
1077 } |
|
1078 |
|
1079 /*! |
|
1080 \qmlclass NumberAnimation QDeclarativeNumberAnimation |
|
1081 \since 4.7 |
|
1082 \inherits PropertyAnimation |
|
1083 \brief The NumberAnimation element allows you to animate changes in properties of type qreal. |
|
1084 |
|
1085 Animate a set of properties over 200ms, from their values in the start state to |
|
1086 their values in the end state of the transition: |
|
1087 \code |
|
1088 NumberAnimation { properties: "x,y,scale"; duration: 200 } |
|
1089 \endcode |
|
1090 */ |
|
1091 |
|
1092 /*! |
|
1093 \internal |
|
1094 \class QDeclarativeNumberAnimation |
|
1095 */ |
|
1096 |
|
1097 QDeclarativeNumberAnimation::QDeclarativeNumberAnimation(QObject *parent) |
|
1098 : QDeclarativePropertyAnimation(parent) |
|
1099 { |
|
1100 init(); |
|
1101 } |
|
1102 |
|
1103 QDeclarativeNumberAnimation::QDeclarativeNumberAnimation(QDeclarativePropertyAnimationPrivate &dd, QObject *parent) |
|
1104 : QDeclarativePropertyAnimation(dd, parent) |
|
1105 { |
|
1106 init(); |
|
1107 } |
|
1108 |
|
1109 QDeclarativeNumberAnimation::~QDeclarativeNumberAnimation() |
|
1110 { |
|
1111 } |
|
1112 |
|
1113 void QDeclarativeNumberAnimation::init() |
|
1114 { |
|
1115 Q_D(QDeclarativePropertyAnimation); |
|
1116 d->interpolatorType = QMetaType::QReal; |
|
1117 d->interpolator = QVariantAnimationPrivate::getInterpolator(d->interpolatorType); |
|
1118 } |
|
1119 |
|
1120 /*! |
|
1121 \qmlproperty real NumberAnimation::from |
|
1122 This property holds the starting value. |
|
1123 If not set, then the value defined in the start state of the transition. |
|
1124 */ |
|
1125 qreal QDeclarativeNumberAnimation::from() const |
|
1126 { |
|
1127 Q_D(const QDeclarativePropertyAnimation); |
|
1128 return d->from.toReal(); |
|
1129 } |
|
1130 |
|
1131 void QDeclarativeNumberAnimation::setFrom(qreal f) |
|
1132 { |
|
1133 QDeclarativePropertyAnimation::setFrom(f); |
|
1134 } |
|
1135 |
|
1136 /*! |
|
1137 \qmlproperty real NumberAnimation::to |
|
1138 This property holds the ending value. |
|
1139 If not set, then the value defined in the end state of the transition or Behavior. |
|
1140 */ |
|
1141 qreal QDeclarativeNumberAnimation::to() const |
|
1142 { |
|
1143 Q_D(const QDeclarativePropertyAnimation); |
|
1144 return d->to.toReal(); |
|
1145 } |
|
1146 |
|
1147 void QDeclarativeNumberAnimation::setTo(qreal t) |
|
1148 { |
|
1149 QDeclarativePropertyAnimation::setTo(t); |
|
1150 } |
|
1151 |
|
1152 |
|
1153 |
|
1154 /*! |
|
1155 \qmlclass Vector3dAnimation QDeclarativeVector3dAnimation |
|
1156 \since 4.7 |
|
1157 \inherits PropertyAnimation |
|
1158 \brief The Vector3dAnimation element allows you to animate changes in properties of type QVector3d. |
|
1159 */ |
|
1160 |
|
1161 /*! |
|
1162 \internal |
|
1163 \class QDeclarativeVector3dAnimation |
|
1164 */ |
|
1165 |
|
1166 QDeclarativeVector3dAnimation::QDeclarativeVector3dAnimation(QObject *parent) |
|
1167 : QDeclarativePropertyAnimation(parent) |
|
1168 { |
|
1169 Q_D(QDeclarativePropertyAnimation); |
|
1170 d->interpolatorType = QMetaType::QVector3D; |
|
1171 d->interpolator = QVariantAnimationPrivate::getInterpolator(d->interpolatorType); |
|
1172 d->defaultToInterpolatorType = true; |
|
1173 } |
|
1174 |
|
1175 QDeclarativeVector3dAnimation::~QDeclarativeVector3dAnimation() |
|
1176 { |
|
1177 } |
|
1178 |
|
1179 /*! |
|
1180 \qmlproperty real Vector3dAnimation::from |
|
1181 This property holds the starting value. |
|
1182 If not set, then the value defined in the start state of the transition. |
|
1183 */ |
|
1184 QVector3D QDeclarativeVector3dAnimation::from() const |
|
1185 { |
|
1186 Q_D(const QDeclarativePropertyAnimation); |
|
1187 return d->from.value<QVector3D>(); |
|
1188 } |
|
1189 |
|
1190 void QDeclarativeVector3dAnimation::setFrom(QVector3D f) |
|
1191 { |
|
1192 QDeclarativePropertyAnimation::setFrom(f); |
|
1193 } |
|
1194 |
|
1195 /*! |
|
1196 \qmlproperty real Vector3dAnimation::to |
|
1197 This property holds the ending value. |
|
1198 If not set, then the value defined in the end state of the transition or Behavior. |
|
1199 */ |
|
1200 QVector3D QDeclarativeVector3dAnimation::to() const |
|
1201 { |
|
1202 Q_D(const QDeclarativePropertyAnimation); |
|
1203 return d->to.value<QVector3D>(); |
|
1204 } |
|
1205 |
|
1206 void QDeclarativeVector3dAnimation::setTo(QVector3D t) |
|
1207 { |
|
1208 QDeclarativePropertyAnimation::setTo(t); |
|
1209 } |
|
1210 |
|
1211 |
|
1212 |
|
1213 /*! |
|
1214 \qmlclass RotationAnimation QDeclarativeRotationAnimation |
|
1215 \since 4.7 |
|
1216 \inherits PropertyAnimation |
|
1217 \brief The RotationAnimation element allows you to animate rotations. |
|
1218 |
|
1219 RotationAnimation is a specialized PropertyAnimation that gives control |
|
1220 over the direction of rotation. By default, it will rotate in the direction |
|
1221 of the numerical change; a rotation from 0 to 240 will rotate 220 degrees |
|
1222 clockwise, while a rotation from 240 to 0 will rotate 220 degrees |
|
1223 counterclockwise. |
|
1224 |
|
1225 When used in a transition RotationAnimation will rotate all |
|
1226 properties named "rotation" or "angle". You can override this by providing |
|
1227 your own properties via \c properties or \c property. |
|
1228 |
|
1229 In the following example we use RotationAnimation to animate the rotation |
|
1230 between states via the shortest path. |
|
1231 \qml |
|
1232 states: { |
|
1233 State { name: "180"; PropertyChanges { target: myItem; rotation: 180 } } |
|
1234 State { name: "90"; PropertyChanges { target: myItem; rotation: 90 } } |
|
1235 State { name: "-90"; PropertyChanges { target: myItem; rotation: -90 } } |
|
1236 } |
|
1237 transition: Transition { |
|
1238 RotationAnimation { direction: RotationAnimation.Shortest } |
|
1239 } |
|
1240 \endqml |
|
1241 */ |
|
1242 |
|
1243 /*! |
|
1244 \internal |
|
1245 \class QDeclarativeRotationAnimation |
|
1246 */ |
|
1247 |
|
1248 QVariant _q_interpolateShortestRotation(qreal &f, qreal &t, qreal progress) |
|
1249 { |
|
1250 qreal newt = t; |
|
1251 qreal diff = t-f; |
|
1252 while(diff > 180.0){ |
|
1253 newt -= 360.0; |
|
1254 diff -= 360.0; |
|
1255 } |
|
1256 while(diff < -180.0){ |
|
1257 newt += 360.0; |
|
1258 diff += 360.0; |
|
1259 } |
|
1260 return QVariant(f + (newt - f) * progress); |
|
1261 } |
|
1262 |
|
1263 QVariant _q_interpolateClockwiseRotation(qreal &f, qreal &t, qreal progress) |
|
1264 { |
|
1265 qreal newt = t; |
|
1266 qreal diff = t-f; |
|
1267 while(diff < 0.0){ |
|
1268 newt += 360.0; |
|
1269 diff += 360.0; |
|
1270 } |
|
1271 return QVariant(f + (newt - f) * progress); |
|
1272 } |
|
1273 |
|
1274 QVariant _q_interpolateCounterclockwiseRotation(qreal &f, qreal &t, qreal progress) |
|
1275 { |
|
1276 qreal newt = t; |
|
1277 qreal diff = t-f; |
|
1278 while(diff > 0.0){ |
|
1279 newt -= 360.0; |
|
1280 diff -= 360.0; |
|
1281 } |
|
1282 return QVariant(f + (newt - f) * progress); |
|
1283 } |
|
1284 |
|
1285 QDeclarativeRotationAnimation::QDeclarativeRotationAnimation(QObject *parent) |
|
1286 : QDeclarativePropertyAnimation(*(new QDeclarativeRotationAnimationPrivate), parent) |
|
1287 { |
|
1288 Q_D(QDeclarativeRotationAnimation); |
|
1289 d->interpolatorType = QMetaType::QReal; |
|
1290 d->interpolator = QVariantAnimationPrivate::getInterpolator(d->interpolatorType); |
|
1291 d->defaultProperties = QLatin1String("rotation,angle"); |
|
1292 } |
|
1293 |
|
1294 QDeclarativeRotationAnimation::~QDeclarativeRotationAnimation() |
|
1295 { |
|
1296 } |
|
1297 |
|
1298 /*! |
|
1299 \qmlproperty real RotationAnimation::from |
|
1300 This property holds the starting value. |
|
1301 If not set, then the value defined in the start state of the transition. |
|
1302 */ |
|
1303 qreal QDeclarativeRotationAnimation::from() const |
|
1304 { |
|
1305 Q_D(const QDeclarativeRotationAnimation); |
|
1306 return d->from.toReal(); |
|
1307 } |
|
1308 |
|
1309 void QDeclarativeRotationAnimation::setFrom(qreal f) |
|
1310 { |
|
1311 QDeclarativePropertyAnimation::setFrom(f); |
|
1312 } |
|
1313 |
|
1314 /*! |
|
1315 \qmlproperty real RotationAnimation::to |
|
1316 This property holds the ending value. |
|
1317 If not set, then the value defined in the end state of the transition or Behavior. |
|
1318 */ |
|
1319 qreal QDeclarativeRotationAnimation::to() const |
|
1320 { |
|
1321 Q_D(const QDeclarativeRotationAnimation); |
|
1322 return d->to.toReal(); |
|
1323 } |
|
1324 |
|
1325 void QDeclarativeRotationAnimation::setTo(qreal t) |
|
1326 { |
|
1327 QDeclarativePropertyAnimation::setTo(t); |
|
1328 } |
|
1329 |
|
1330 /*! |
|
1331 \qmlproperty enumeration RotationAnimation::direction |
|
1332 The direction in which to rotate. |
|
1333 |
|
1334 Possible values are: |
|
1335 |
|
1336 \table |
|
1337 \row |
|
1338 \o RotationAnimation.Numerical |
|
1339 \o Rotate by linearly interpolating between the two numbers. |
|
1340 A rotation from 10 to 350 will rotate 340 degrees clockwise. |
|
1341 \row |
|
1342 \o RotationAnimation.Clockwise |
|
1343 \o Rotate clockwise between the two values |
|
1344 \row |
|
1345 \o RotationAnimation.Counterclockwise |
|
1346 \o Rotate counterclockwise between the two values |
|
1347 \row |
|
1348 \o RotationAnimation.Shortest |
|
1349 \o Rotate in the direction that produces the shortest animation path. |
|
1350 A rotation from 10 to 350 will rotate 20 degrees counterclockwise. |
|
1351 \endtable |
|
1352 |
|
1353 The default direction is RotationAnimation.Numerical. |
|
1354 */ |
|
1355 QDeclarativeRotationAnimation::RotationDirection QDeclarativeRotationAnimation::direction() const |
|
1356 { |
|
1357 Q_D(const QDeclarativeRotationAnimation); |
|
1358 return d->direction; |
|
1359 } |
|
1360 |
|
1361 void QDeclarativeRotationAnimation::setDirection(QDeclarativeRotationAnimation::RotationDirection direction) |
|
1362 { |
|
1363 Q_D(QDeclarativeRotationAnimation); |
|
1364 if (d->direction == direction) |
|
1365 return; |
|
1366 |
|
1367 d->direction = direction; |
|
1368 switch(d->direction) { |
|
1369 case Clockwise: |
|
1370 d->interpolator = reinterpret_cast<QVariantAnimation::Interpolator>(&_q_interpolateClockwiseRotation); |
|
1371 break; |
|
1372 case Counterclockwise: |
|
1373 d->interpolator = reinterpret_cast<QVariantAnimation::Interpolator>(&_q_interpolateCounterclockwiseRotation); |
|
1374 break; |
|
1375 case Shortest: |
|
1376 d->interpolator = reinterpret_cast<QVariantAnimation::Interpolator>(&_q_interpolateShortestRotation); |
|
1377 break; |
|
1378 default: |
|
1379 d->interpolator = QVariantAnimationPrivate::getInterpolator(d->interpolatorType); |
|
1380 break; |
|
1381 } |
|
1382 |
|
1383 emit directionChanged(); |
|
1384 } |
|
1385 |
|
1386 |
|
1387 |
|
1388 QDeclarativeAnimationGroup::QDeclarativeAnimationGroup(QObject *parent) |
|
1389 : QDeclarativeAbstractAnimation(*(new QDeclarativeAnimationGroupPrivate), parent) |
|
1390 { |
|
1391 } |
|
1392 |
|
1393 QDeclarativeAnimationGroup::QDeclarativeAnimationGroup(QDeclarativeAnimationGroupPrivate &dd, QObject *parent) |
|
1394 : QDeclarativeAbstractAnimation(dd, parent) |
|
1395 { |
|
1396 } |
|
1397 |
|
1398 void QDeclarativeAnimationGroupPrivate::append_animation(QDeclarativeListProperty<QDeclarativeAbstractAnimation> *list, QDeclarativeAbstractAnimation *a) |
|
1399 { |
|
1400 QDeclarativeAnimationGroup *q = qobject_cast<QDeclarativeAnimationGroup *>(list->object); |
|
1401 if (q) { |
|
1402 a->setGroup(q); |
|
1403 QDeclarative_setParent_noEvent(a->qtAnimation(), q->d_func()->ag); |
|
1404 q->d_func()->ag->addAnimation(a->qtAnimation()); |
|
1405 } |
|
1406 } |
|
1407 |
|
1408 void QDeclarativeAnimationGroupPrivate::clear_animation(QDeclarativeListProperty<QDeclarativeAbstractAnimation> *list) |
|
1409 { |
|
1410 QDeclarativeAnimationGroup *q = qobject_cast<QDeclarativeAnimationGroup *>(list->object); |
|
1411 if (q) { |
|
1412 for (int i = 0; i < q->d_func()->animations.count(); ++i) |
|
1413 q->d_func()->animations.at(i)->setGroup(0); |
|
1414 q->d_func()->animations.clear(); |
|
1415 } |
|
1416 } |
|
1417 |
|
1418 QDeclarativeAnimationGroup::~QDeclarativeAnimationGroup() |
|
1419 { |
|
1420 } |
|
1421 |
|
1422 QDeclarativeListProperty<QDeclarativeAbstractAnimation> QDeclarativeAnimationGroup::animations() |
|
1423 { |
|
1424 Q_D(QDeclarativeAnimationGroup); |
|
1425 QDeclarativeListProperty<QDeclarativeAbstractAnimation> list(this, d->animations); |
|
1426 list.append = &QDeclarativeAnimationGroupPrivate::append_animation; |
|
1427 list.clear = &QDeclarativeAnimationGroupPrivate::clear_animation; |
|
1428 return list; |
|
1429 } |
|
1430 |
|
1431 /*! |
|
1432 \qmlclass SequentialAnimation QDeclarativeSequentialAnimation |
|
1433 \since 4.7 |
|
1434 \inherits Animation |
|
1435 \brief The SequentialAnimation element allows you to run animations sequentially. |
|
1436 |
|
1437 Animations controlled in SequentialAnimation will be run one after the other. |
|
1438 |
|
1439 The following example chains two numeric animations together. The \c MyItem |
|
1440 object will animate from its current x position to 100, and then back to 0. |
|
1441 |
|
1442 \code |
|
1443 SequentialAnimation { |
|
1444 NumberAnimation { target: MyItem; property: "x"; to: 100 } |
|
1445 NumberAnimation { target: MyItem; property: "x"; to: 0 } |
|
1446 } |
|
1447 \endcode |
|
1448 |
|
1449 \sa ParallelAnimation |
|
1450 */ |
|
1451 |
|
1452 QDeclarativeSequentialAnimation::QDeclarativeSequentialAnimation(QObject *parent) : |
|
1453 QDeclarativeAnimationGroup(parent) |
|
1454 { |
|
1455 Q_D(QDeclarativeAnimationGroup); |
|
1456 d->ag = new QSequentialAnimationGroup; |
|
1457 QDeclarative_setParent_noEvent(d->ag, this); |
|
1458 } |
|
1459 |
|
1460 QDeclarativeSequentialAnimation::~QDeclarativeSequentialAnimation() |
|
1461 { |
|
1462 } |
|
1463 |
|
1464 QAbstractAnimation *QDeclarativeSequentialAnimation::qtAnimation() |
|
1465 { |
|
1466 Q_D(QDeclarativeAnimationGroup); |
|
1467 return d->ag; |
|
1468 } |
|
1469 |
|
1470 void QDeclarativeSequentialAnimation::transition(QDeclarativeStateActions &actions, |
|
1471 QDeclarativeProperties &modified, |
|
1472 TransitionDirection direction) |
|
1473 { |
|
1474 Q_D(QDeclarativeAnimationGroup); |
|
1475 |
|
1476 int inc = 1; |
|
1477 int from = 0; |
|
1478 if (direction == Backward) { |
|
1479 inc = -1; |
|
1480 from = d->animations.count() - 1; |
|
1481 } |
|
1482 |
|
1483 bool valid = d->defaultProperty.isValid(); |
|
1484 for (int ii = from; ii < d->animations.count() && ii >= 0; ii += inc) { |
|
1485 if (valid) |
|
1486 d->animations.at(ii)->setDefaultTarget(d->defaultProperty); |
|
1487 d->animations.at(ii)->transition(actions, modified, direction); |
|
1488 } |
|
1489 } |
|
1490 |
|
1491 |
|
1492 |
|
1493 /*! |
|
1494 \qmlclass ParallelAnimation QDeclarativeParallelAnimation |
|
1495 \since 4.7 |
|
1496 \inherits Animation |
|
1497 \brief The ParallelAnimation element allows you to run animations in parallel. |
|
1498 |
|
1499 Animations contained in ParallelAnimation will be run at the same time. |
|
1500 |
|
1501 The following animation demonstrates animating the \c MyItem item |
|
1502 to (100,100) by animating the x and y properties in parallel. |
|
1503 |
|
1504 \code |
|
1505 ParallelAnimation { |
|
1506 NumberAnimation { target: MyItem; property: "x"; to: 100 } |
|
1507 NumberAnimation { target: MyItem; property: "y"; to: 100 } |
|
1508 } |
|
1509 \endcode |
|
1510 |
|
1511 \sa SequentialAnimation |
|
1512 */ |
|
1513 /*! |
|
1514 \internal |
|
1515 \class QDeclarativeParallelAnimation |
|
1516 */ |
|
1517 |
|
1518 QDeclarativeParallelAnimation::QDeclarativeParallelAnimation(QObject *parent) : |
|
1519 QDeclarativeAnimationGroup(parent) |
|
1520 { |
|
1521 Q_D(QDeclarativeAnimationGroup); |
|
1522 d->ag = new QParallelAnimationGroup; |
|
1523 QDeclarative_setParent_noEvent(d->ag, this); |
|
1524 } |
|
1525 |
|
1526 QDeclarativeParallelAnimation::~QDeclarativeParallelAnimation() |
|
1527 { |
|
1528 } |
|
1529 |
|
1530 QAbstractAnimation *QDeclarativeParallelAnimation::qtAnimation() |
|
1531 { |
|
1532 Q_D(QDeclarativeAnimationGroup); |
|
1533 return d->ag; |
|
1534 } |
|
1535 |
|
1536 void QDeclarativeParallelAnimation::transition(QDeclarativeStateActions &actions, |
|
1537 QDeclarativeProperties &modified, |
|
1538 TransitionDirection direction) |
|
1539 { |
|
1540 Q_D(QDeclarativeAnimationGroup); |
|
1541 bool valid = d->defaultProperty.isValid(); |
|
1542 for (int ii = 0; ii < d->animations.count(); ++ii) { |
|
1543 if (valid) |
|
1544 d->animations.at(ii)->setDefaultTarget(d->defaultProperty); |
|
1545 d->animations.at(ii)->transition(actions, modified, direction); |
|
1546 } |
|
1547 } |
|
1548 |
|
1549 |
|
1550 |
|
1551 //convert a variant from string type to another animatable type |
|
1552 void QDeclarativePropertyAnimationPrivate::convertVariant(QVariant &variant, int type) |
|
1553 { |
|
1554 if (variant.userType() != QVariant::String) { |
|
1555 variant.convert((QVariant::Type)type); |
|
1556 return; |
|
1557 } |
|
1558 |
|
1559 switch (type) { |
|
1560 case QVariant::Rect: { |
|
1561 variant.setValue(QDeclarativeStringConverters::rectFFromString(variant.toString()).toRect()); |
|
1562 break; |
|
1563 } |
|
1564 case QVariant::RectF: { |
|
1565 variant.setValue(QDeclarativeStringConverters::rectFFromString(variant.toString())); |
|
1566 break; |
|
1567 } |
|
1568 case QVariant::Point: { |
|
1569 variant.setValue(QDeclarativeStringConverters::pointFFromString(variant.toString()).toPoint()); |
|
1570 break; |
|
1571 } |
|
1572 case QVariant::PointF: { |
|
1573 variant.setValue(QDeclarativeStringConverters::pointFFromString(variant.toString())); |
|
1574 break; |
|
1575 } |
|
1576 case QVariant::Size: { |
|
1577 variant.setValue(QDeclarativeStringConverters::sizeFFromString(variant.toString()).toSize()); |
|
1578 break; |
|
1579 } |
|
1580 case QVariant::SizeF: { |
|
1581 variant.setValue(QDeclarativeStringConverters::sizeFFromString(variant.toString())); |
|
1582 break; |
|
1583 } |
|
1584 case QVariant::Color: { |
|
1585 variant.setValue(QDeclarativeStringConverters::colorFromString(variant.toString())); |
|
1586 break; |
|
1587 } |
|
1588 case QVariant::Vector3D: { |
|
1589 variant.setValue(QDeclarativeStringConverters::vector3DFromString(variant.toString())); |
|
1590 break; |
|
1591 } |
|
1592 default: |
|
1593 if (QDeclarativeValueTypeFactory::isValueType((uint)type)) { |
|
1594 variant.convert((QVariant::Type)type); |
|
1595 } else { |
|
1596 QDeclarativeMetaType::StringConverter converter = QDeclarativeMetaType::customStringConverter(type); |
|
1597 if (converter) |
|
1598 variant = converter(variant.toString()); |
|
1599 } |
|
1600 break; |
|
1601 } |
|
1602 } |
|
1603 |
|
1604 /*! |
|
1605 \qmlclass PropertyAnimation QDeclarativePropertyAnimation |
|
1606 \since 4.7 |
|
1607 \inherits Animation |
|
1608 \brief The PropertyAnimation element allows you to animate property changes. |
|
1609 |
|
1610 PropertyAnimation provides a way to animate changes to a property's value. It can |
|
1611 be used in many different situations: |
|
1612 \list |
|
1613 \o In a Transition |
|
1614 |
|
1615 Animate any objects that have changed their x or y properties in the target state using |
|
1616 an InOutQuad easing curve: |
|
1617 \qml |
|
1618 Transition { PropertyAnimation { properties: "x,y"; easing.type: Easing.InOutQuad } } |
|
1619 \endqml |
|
1620 \o In a Behavior |
|
1621 |
|
1622 Animate all changes to a rectangle's x property. |
|
1623 \qml |
|
1624 Rectangle { |
|
1625 Behavior on x { PropertyAnimation {} } |
|
1626 } |
|
1627 \endqml |
|
1628 \o As a property value source |
|
1629 |
|
1630 Repeatedly animate the rectangle's x property. |
|
1631 \qml |
|
1632 Rectangle { |
|
1633 SequentialAnimation on x { |
|
1634 loops: Animation.Infinite |
|
1635 PropertyAnimation { to: 50 } |
|
1636 PropertyAnimation { to: 0 } |
|
1637 } |
|
1638 } |
|
1639 \endqml |
|
1640 \o In a signal handler |
|
1641 |
|
1642 Fade out \c theObject when clicked: |
|
1643 \qml |
|
1644 MouseArea { |
|
1645 anchors.fill: theObject |
|
1646 onClicked: PropertyAnimation { target: theObject; property: "opacity"; to: 0 } |
|
1647 } |
|
1648 \endqml |
|
1649 \o Standalone |
|
1650 |
|
1651 Animate \c theObject's size property over 200ms, from its current size to 20-by-20: |
|
1652 \qml |
|
1653 PropertyAnimation { target: theObject; property: "size"; to: "20x20"; duration: 200 } |
|
1654 \endqml |
|
1655 \endlist |
|
1656 |
|
1657 Depending on how the animation is used, the set of properties normally used will be |
|
1658 different. For more information see the individual property documentation, as well |
|
1659 as the \l{QML Animation} introduction. |
|
1660 */ |
|
1661 |
|
1662 QDeclarativePropertyAnimation::QDeclarativePropertyAnimation(QObject *parent) |
|
1663 : QDeclarativeAbstractAnimation(*(new QDeclarativePropertyAnimationPrivate), parent) |
|
1664 { |
|
1665 Q_D(QDeclarativePropertyAnimation); |
|
1666 d->init(); |
|
1667 } |
|
1668 |
|
1669 QDeclarativePropertyAnimation::QDeclarativePropertyAnimation(QDeclarativePropertyAnimationPrivate &dd, QObject *parent) |
|
1670 : QDeclarativeAbstractAnimation(dd, parent) |
|
1671 { |
|
1672 Q_D(QDeclarativePropertyAnimation); |
|
1673 d->init(); |
|
1674 } |
|
1675 |
|
1676 QDeclarativePropertyAnimation::~QDeclarativePropertyAnimation() |
|
1677 { |
|
1678 } |
|
1679 |
|
1680 void QDeclarativePropertyAnimationPrivate::init() |
|
1681 { |
|
1682 Q_Q(QDeclarativePropertyAnimation); |
|
1683 va = new QDeclarativeBulkValueAnimator; |
|
1684 QDeclarative_setParent_noEvent(va, q); |
|
1685 } |
|
1686 |
|
1687 /*! |
|
1688 \qmlproperty int PropertyAnimation::duration |
|
1689 This property holds the duration of the animation, in milliseconds. |
|
1690 |
|
1691 The default value is 250. |
|
1692 */ |
|
1693 int QDeclarativePropertyAnimation::duration() const |
|
1694 { |
|
1695 Q_D(const QDeclarativePropertyAnimation); |
|
1696 return d->va->duration(); |
|
1697 } |
|
1698 |
|
1699 void QDeclarativePropertyAnimation::setDuration(int duration) |
|
1700 { |
|
1701 if (duration < 0) { |
|
1702 qmlInfo(this) << tr("Cannot set a duration of < 0"); |
|
1703 return; |
|
1704 } |
|
1705 |
|
1706 Q_D(QDeclarativePropertyAnimation); |
|
1707 if (d->va->duration() == duration) |
|
1708 return; |
|
1709 d->va->setDuration(duration); |
|
1710 emit durationChanged(duration); |
|
1711 } |
|
1712 |
|
1713 /*! |
|
1714 \qmlproperty real PropertyAnimation::from |
|
1715 This property holds the starting value. |
|
1716 If not set, then the value defined in the start state of the transition. |
|
1717 */ |
|
1718 QVariant QDeclarativePropertyAnimation::from() const |
|
1719 { |
|
1720 Q_D(const QDeclarativePropertyAnimation); |
|
1721 return d->from; |
|
1722 } |
|
1723 |
|
1724 void QDeclarativePropertyAnimation::setFrom(const QVariant &f) |
|
1725 { |
|
1726 Q_D(QDeclarativePropertyAnimation); |
|
1727 if (d->fromIsDefined && f == d->from) |
|
1728 return; |
|
1729 d->from = f; |
|
1730 d->fromIsDefined = f.isValid(); |
|
1731 emit fromChanged(f); |
|
1732 } |
|
1733 |
|
1734 /*! |
|
1735 \qmlproperty real PropertyAnimation::to |
|
1736 This property holds the ending value. |
|
1737 If not set, then the value defined in the end state of the transition or Behavior. |
|
1738 */ |
|
1739 QVariant QDeclarativePropertyAnimation::to() const |
|
1740 { |
|
1741 Q_D(const QDeclarativePropertyAnimation); |
|
1742 return d->to; |
|
1743 } |
|
1744 |
|
1745 void QDeclarativePropertyAnimation::setTo(const QVariant &t) |
|
1746 { |
|
1747 Q_D(QDeclarativePropertyAnimation); |
|
1748 if (d->toIsDefined && t == d->to) |
|
1749 return; |
|
1750 d->to = t; |
|
1751 d->toIsDefined = t.isValid(); |
|
1752 emit toChanged(t); |
|
1753 } |
|
1754 |
|
1755 /*! |
|
1756 \qmlproperty enumeration PropertyAnimation::easing.type |
|
1757 \qmlproperty real PropertyAnimation::easing.amplitude |
|
1758 \qmlproperty real PropertyAnimation::easing.overshoot |
|
1759 \qmlproperty real PropertyAnimation::easing.period |
|
1760 \brief the easing curve used for the animation. |
|
1761 |
|
1762 To specify an easing curve you need to specify at least the type. For some curves you can also specify |
|
1763 amplitude, period and/or overshoot (more details provided after the table). The default easing curve is |
|
1764 Linear. |
|
1765 |
|
1766 \qml |
|
1767 PropertyAnimation { properties: "y"; easing.type: Easing.InOutElastic; easing.amplitude: 2.0; easing.period: 1.5 } |
|
1768 \endqml |
|
1769 |
|
1770 Available types are: |
|
1771 |
|
1772 \table |
|
1773 \row |
|
1774 \o \c Easing.Linear |
|
1775 \o Easing curve for a linear (t) function: velocity is constant. |
|
1776 \o \inlineimage qeasingcurve-linear.png |
|
1777 \row |
|
1778 \o \c Easing.InQuad |
|
1779 \o Easing curve for a quadratic (t^2) function: accelerating from zero velocity. |
|
1780 \o \inlineimage qeasingcurve-inquad.png |
|
1781 \row |
|
1782 \o \c Easing.OutQuad |
|
1783 \o Easing curve for a quadratic (t^2) function: decelerating to zero velocity. |
|
1784 \o \inlineimage qeasingcurve-outquad.png |
|
1785 \row |
|
1786 \o \c Easing.InOutQuad |
|
1787 \o Easing curve for a quadratic (t^2) function: acceleration until halfway, then deceleration. |
|
1788 \o \inlineimage qeasingcurve-inoutquad.png |
|
1789 \row |
|
1790 \o \c Easing.OutInQuad |
|
1791 \o Easing curve for a quadratic (t^2) function: deceleration until halfway, then acceleration. |
|
1792 \o \inlineimage qeasingcurve-outinquad.png |
|
1793 \row |
|
1794 \o \c Easing.InCubic |
|
1795 \o Easing curve for a cubic (t^3) function: accelerating from zero velocity. |
|
1796 \o \inlineimage qeasingcurve-incubic.png |
|
1797 \row |
|
1798 \o \c Easing.OutCubic |
|
1799 \o Easing curve for a cubic (t^3) function: decelerating from zero velocity. |
|
1800 \o \inlineimage qeasingcurve-outcubic.png |
|
1801 \row |
|
1802 \o \c Easing.InOutCubic |
|
1803 \o Easing curve for a cubic (t^3) function: acceleration until halfway, then deceleration. |
|
1804 \o \inlineimage qeasingcurve-inoutcubic.png |
|
1805 \row |
|
1806 \o \c Easing.OutInCubic |
|
1807 \o Easing curve for a cubic (t^3) function: deceleration until halfway, then acceleration. |
|
1808 \o \inlineimage qeasingcurve-outincubic.png |
|
1809 \row |
|
1810 \o \c Easing.InQuart |
|
1811 \o Easing curve for a quartic (t^4) function: accelerating from zero velocity. |
|
1812 \o \inlineimage qeasingcurve-inquart.png |
|
1813 \row |
|
1814 \o \c Easing.OutQuart |
|
1815 \o Easing curve for a cubic (t^4) function: decelerating from zero velocity. |
|
1816 \o \inlineimage qeasingcurve-outquart.png |
|
1817 \row |
|
1818 \o \c Easing.InOutQuart |
|
1819 \o Easing curve for a cubic (t^4) function: acceleration until halfway, then deceleration. |
|
1820 \o \inlineimage qeasingcurve-inoutquart.png |
|
1821 \row |
|
1822 \o \c Easing.OutInQuart |
|
1823 \o Easing curve for a cubic (t^4) function: deceleration until halfway, then acceleration. |
|
1824 \o \inlineimage qeasingcurve-outinquart.png |
|
1825 \row |
|
1826 \o \c Easing.InQuint |
|
1827 \o Easing curve for a quintic (t^5) function: accelerating from zero velocity. |
|
1828 \o \inlineimage qeasingcurve-inquint.png |
|
1829 \row |
|
1830 \o \c Easing.OutQuint |
|
1831 \o Easing curve for a cubic (t^5) function: decelerating from zero velocity. |
|
1832 \o \inlineimage qeasingcurve-outquint.png |
|
1833 \row |
|
1834 \o \c Easing.InOutQuint |
|
1835 \o Easing curve for a cubic (t^5) function: acceleration until halfway, then deceleration. |
|
1836 \o \inlineimage qeasingcurve-inoutquint.png |
|
1837 \row |
|
1838 \o \c Easing.OutInQuint |
|
1839 \o Easing curve for a cubic (t^5) function: deceleration until halfway, then acceleration. |
|
1840 \o \inlineimage qeasingcurve-outinquint.png |
|
1841 \row |
|
1842 \o \c Easing.InSine |
|
1843 \o Easing curve for a sinusoidal (sin(t)) function: accelerating from zero velocity. |
|
1844 \o \inlineimage qeasingcurve-insine.png |
|
1845 \row |
|
1846 \o \c Easing.OutSine |
|
1847 \o Easing curve for a sinusoidal (sin(t)) function: decelerating from zero velocity. |
|
1848 \o \inlineimage qeasingcurve-outsine.png |
|
1849 \row |
|
1850 \o \c Easing.InOutSine |
|
1851 \o Easing curve for a sinusoidal (sin(t)) function: acceleration until halfway, then deceleration. |
|
1852 \o \inlineimage qeasingcurve-inoutsine.png |
|
1853 \row |
|
1854 \o \c Easing.OutInSine |
|
1855 \o Easing curve for a sinusoidal (sin(t)) function: deceleration until halfway, then acceleration. |
|
1856 \o \inlineimage qeasingcurve-outinsine.png |
|
1857 \row |
|
1858 \o \c Easing.InExpo |
|
1859 \o Easing curve for an exponential (2^t) function: accelerating from zero velocity. |
|
1860 \o \inlineimage qeasingcurve-inexpo.png |
|
1861 \row |
|
1862 \o \c Easing.OutExpo |
|
1863 \o Easing curve for an exponential (2^t) function: decelerating from zero velocity. |
|
1864 \o \inlineimage qeasingcurve-outexpo.png |
|
1865 \row |
|
1866 \o \c Easing.InOutExpo |
|
1867 \o Easing curve for an exponential (2^t) function: acceleration until halfway, then deceleration. |
|
1868 \o \inlineimage qeasingcurve-inoutexpo.png |
|
1869 \row |
|
1870 \o \c Easing.OutInExpo |
|
1871 \o Easing curve for an exponential (2^t) function: deceleration until halfway, then acceleration. |
|
1872 \o \inlineimage qeasingcurve-outinexpo.png |
|
1873 \row |
|
1874 \o \c Easing.InCirc |
|
1875 \o Easing curve for a circular (sqrt(1-t^2)) function: accelerating from zero velocity. |
|
1876 \o \inlineimage qeasingcurve-incirc.png |
|
1877 \row |
|
1878 \o \c Easing.OutCirc |
|
1879 \o Easing curve for a circular (sqrt(1-t^2)) function: decelerating from zero velocity. |
|
1880 \o \inlineimage qeasingcurve-outcirc.png |
|
1881 \row |
|
1882 \o \c Easing.InOutCirc |
|
1883 \o Easing curve for a circular (sqrt(1-t^2)) function: acceleration until halfway, then deceleration. |
|
1884 \o \inlineimage qeasingcurve-inoutcirc.png |
|
1885 \row |
|
1886 \o \c Easing.OutInCirc |
|
1887 \o Easing curve for a circular (sqrt(1-t^2)) function: deceleration until halfway, then acceleration. |
|
1888 \o \inlineimage qeasingcurve-outincirc.png |
|
1889 \row |
|
1890 \o \c Easing.InElastic |
|
1891 \o Easing curve for an elastic (exponentially decaying sine wave) function: accelerating from zero velocity. |
|
1892 \br The peak amplitude can be set with the \e amplitude parameter, and the period of decay by the \e period parameter. |
|
1893 \o \inlineimage qeasingcurve-inelastic.png |
|
1894 \row |
|
1895 \o \c Easing.OutElastic |
|
1896 \o Easing curve for an elastic (exponentially decaying sine wave) function: decelerating from zero velocity. |
|
1897 \br The peak amplitude can be set with the \e amplitude parameter, and the period of decay by the \e period parameter. |
|
1898 \o \inlineimage qeasingcurve-outelastic.png |
|
1899 \row |
|
1900 \o \c Easing.InOutElastic |
|
1901 \o Easing curve for an elastic (exponentially decaying sine wave) function: acceleration until halfway, then deceleration. |
|
1902 \o \inlineimage qeasingcurve-inoutelastic.png |
|
1903 \row |
|
1904 \o \c Easing.OutInElastic |
|
1905 \o Easing curve for an elastic (exponentially decaying sine wave) function: deceleration until halfway, then acceleration. |
|
1906 \o \inlineimage qeasingcurve-outinelastic.png |
|
1907 \row |
|
1908 \o \c Easing.InBack |
|
1909 \o Easing curve for a back (overshooting cubic function: (s+1)*t^3 - s*t^2) easing in: accelerating from zero velocity. |
|
1910 \o \inlineimage qeasingcurve-inback.png |
|
1911 \row |
|
1912 \o \c Easing.OutBack |
|
1913 \o Easing curve for a back (overshooting cubic function: (s+1)*t^3 - s*t^2) easing out: decelerating to zero velocity. |
|
1914 \o \inlineimage qeasingcurve-outback.png |
|
1915 \row |
|
1916 \o \c Easing.InOutBack |
|
1917 \o Easing curve for a back (overshooting cubic function: (s+1)*t^3 - s*t^2) easing in/out: acceleration until halfway, then deceleration. |
|
1918 \o \inlineimage qeasingcurve-inoutback.png |
|
1919 \row |
|
1920 \o \c Easing.OutInBack |
|
1921 \o Easing curve for a back (overshooting cubic easing: (s+1)*t^3 - s*t^2) easing out/in: deceleration until halfway, then acceleration. |
|
1922 \o \inlineimage qeasingcurve-outinback.png |
|
1923 \row |
|
1924 \o \c Easing.InBounce |
|
1925 \o Easing curve for a bounce (exponentially decaying parabolic bounce) function: accelerating from zero velocity. |
|
1926 \o \inlineimage qeasingcurve-inbounce.png |
|
1927 \row |
|
1928 \o \c Easing.OutBounce |
|
1929 \o Easing curve for a bounce (exponentially decaying parabolic bounce) function: decelerating from zero velocity. |
|
1930 \o \inlineimage qeasingcurve-outbounce.png |
|
1931 \row |
|
1932 \o \c Easing.InOutBounce |
|
1933 \o Easing curve for a bounce (exponentially decaying parabolic bounce) function easing in/out: acceleration until halfway, then deceleration. |
|
1934 \o \inlineimage qeasingcurve-inoutbounce.png |
|
1935 \row |
|
1936 \o \c Easing.OutInBounce |
|
1937 \o Easing curve for a bounce (exponentially decaying parabolic bounce) function easing out/in: deceleration until halfway, then acceleration. |
|
1938 \o \inlineimage qeasingcurve-outinbounce.png |
|
1939 \endtable |
|
1940 |
|
1941 easing.amplitude is only applicable for bounce and elastic curves (curves of type |
|
1942 Easing.InBounce, Easing.OutBounce, Easing.InOutBounce, Easing.OutInBounce, Easing.InElastic, |
|
1943 Easing.OutElastic, Easing.InOutElastic or Easing.OutInElastic). |
|
1944 |
|
1945 easing.overshoot is only applicable if type is: Easing.InBack, Easing.OutBack, |
|
1946 Easing.InOutBack or Easing.OutInBack. |
|
1947 |
|
1948 easing.period is only applicable if type is: Easing.InElastic, Easing.OutElastic, |
|
1949 Easing.InOutElastic or Easing.OutInElastic. |
|
1950 |
|
1951 See the \l {declarative/animation/easing}{easing} example for a demonstration of |
|
1952 the different easing settings. |
|
1953 */ |
|
1954 QEasingCurve QDeclarativePropertyAnimation::easing() const |
|
1955 { |
|
1956 Q_D(const QDeclarativePropertyAnimation); |
|
1957 return d->easing; |
|
1958 } |
|
1959 |
|
1960 void QDeclarativePropertyAnimation::setEasing(const QEasingCurve &e) |
|
1961 { |
|
1962 Q_D(QDeclarativePropertyAnimation); |
|
1963 if (d->easing == e) |
|
1964 return; |
|
1965 |
|
1966 d->easing = e; |
|
1967 d->va->setEasingCurve(d->easing); |
|
1968 emit easingChanged(e); |
|
1969 } |
|
1970 |
|
1971 QObject *QDeclarativePropertyAnimation::target() const |
|
1972 { |
|
1973 Q_D(const QDeclarativePropertyAnimation); |
|
1974 return d->target; |
|
1975 } |
|
1976 |
|
1977 void QDeclarativePropertyAnimation::setTarget(QObject *o) |
|
1978 { |
|
1979 Q_D(QDeclarativePropertyAnimation); |
|
1980 if (d->target == o) |
|
1981 return; |
|
1982 d->target = o; |
|
1983 emit targetChanged(d->target, d->propertyName); |
|
1984 } |
|
1985 |
|
1986 QString QDeclarativePropertyAnimation::property() const |
|
1987 { |
|
1988 Q_D(const QDeclarativePropertyAnimation); |
|
1989 return d->propertyName; |
|
1990 } |
|
1991 |
|
1992 void QDeclarativePropertyAnimation::setProperty(const QString &n) |
|
1993 { |
|
1994 Q_D(QDeclarativePropertyAnimation); |
|
1995 if (d->propertyName == n) |
|
1996 return; |
|
1997 d->propertyName = n; |
|
1998 emit targetChanged(d->target, d->propertyName); |
|
1999 } |
|
2000 |
|
2001 QString QDeclarativePropertyAnimation::properties() const |
|
2002 { |
|
2003 Q_D(const QDeclarativePropertyAnimation); |
|
2004 return d->properties; |
|
2005 } |
|
2006 |
|
2007 void QDeclarativePropertyAnimation::setProperties(const QString &prop) |
|
2008 { |
|
2009 Q_D(QDeclarativePropertyAnimation); |
|
2010 if (d->properties == prop) |
|
2011 return; |
|
2012 |
|
2013 d->properties = prop; |
|
2014 emit propertiesChanged(prop); |
|
2015 } |
|
2016 |
|
2017 /*! |
|
2018 \qmlproperty string PropertyAnimation::properties |
|
2019 \qmlproperty list<Object> PropertyAnimation::targets |
|
2020 \qmlproperty string PropertyAnimation::property |
|
2021 \qmlproperty Object PropertyAnimation::target |
|
2022 |
|
2023 These properties are used as a set to determine which properties should be animated. |
|
2024 The singular and plural forms are functionally identical, e.g. |
|
2025 \qml |
|
2026 NumberAnimation { target: theItem; property: "x"; to: 500 } |
|
2027 \endqml |
|
2028 has the same meaning as |
|
2029 \qml |
|
2030 NumberAnimation { targets: theItem; properties: "x"; to: 500 } |
|
2031 \endqml |
|
2032 The singular forms are slightly optimized, so if you do have only a single target/property |
|
2033 to animate you should try to use them. |
|
2034 |
|
2035 In many cases these properties do not need to be explicitly specified -- they can be |
|
2036 inferred from the animation framework. |
|
2037 \table 80% |
|
2038 \row |
|
2039 \o Value Source / Behavior |
|
2040 \o When an animation is used as a value source or in a Behavior, the default target and property |
|
2041 name to be animated can both be inferred. |
|
2042 \qml |
|
2043 Rectangle { |
|
2044 id: theRect |
|
2045 width: 100; height: 100 |
|
2046 color: Qt.rgba(0,0,1) |
|
2047 NumberAnimation on x { to: 500; loops: Animation.Infinite } //animate theRect's x property |
|
2048 Behavior on y { NumberAnimation {} } //animate theRect's y property |
|
2049 } |
|
2050 \endqml |
|
2051 \row |
|
2052 \o Transition |
|
2053 \o When used in a transition, a property animation is assumed to match \e all targets |
|
2054 but \e no properties. In practice, that means you need to specify at least the properties |
|
2055 in order for the animation to do anything. |
|
2056 \qml |
|
2057 Rectangle { |
|
2058 id: theRect |
|
2059 width: 100; height: 100 |
|
2060 color: Qt.rgba(0,0,1) |
|
2061 Item { id: uselessItem } |
|
2062 states: State { |
|
2063 name: "state1" |
|
2064 PropertyChanges { target: theRect; x: 200; y: 200; z: 4 } |
|
2065 PropertyChanges { target: uselessItem; x: 10; y: 10; z: 2 } |
|
2066 } |
|
2067 transitions: Transition { |
|
2068 //animate both theRect's and uselessItem's x and y to their final values |
|
2069 NumberAnimation { properties: "x,y" } |
|
2070 |
|
2071 //animate theRect's z to its final value |
|
2072 NumberAnimation { target: theRect; property: "z" } |
|
2073 } |
|
2074 } |
|
2075 \endqml |
|
2076 \row |
|
2077 \o Standalone |
|
2078 \o When an animation is used standalone, both the target and property need to be |
|
2079 explicitly specified. |
|
2080 \qml |
|
2081 Rectangle { |
|
2082 id: theRect |
|
2083 width: 100; height: 100 |
|
2084 color: Qt.rgba(0,0,1) |
|
2085 //need to explicitly specify target and property |
|
2086 NumberAnimation { id: theAnim; target: theRect; property: "x" to: 500 } |
|
2087 MouseArea { |
|
2088 anchors.fill: parent |
|
2089 onClicked: theAnim.start() |
|
2090 } |
|
2091 } |
|
2092 \endqml |
|
2093 \endtable |
|
2094 |
|
2095 As seen in the above example, properties is specified as a comma-separated string of property names to animate. |
|
2096 |
|
2097 \sa exclude |
|
2098 */ |
|
2099 QDeclarativeListProperty<QObject> QDeclarativePropertyAnimation::targets() |
|
2100 { |
|
2101 Q_D(QDeclarativePropertyAnimation); |
|
2102 return QDeclarativeListProperty<QObject>(this, d->targets); |
|
2103 } |
|
2104 |
|
2105 /*! |
|
2106 \qmlproperty list<Object> PropertyAnimation::exclude |
|
2107 This property holds the items not to be affected by this animation. |
|
2108 \sa PropertyAnimation::targets |
|
2109 */ |
|
2110 QDeclarativeListProperty<QObject> QDeclarativePropertyAnimation::exclude() |
|
2111 { |
|
2112 Q_D(QDeclarativePropertyAnimation); |
|
2113 return QDeclarativeListProperty<QObject>(this, d->exclude); |
|
2114 } |
|
2115 |
|
2116 QAbstractAnimation *QDeclarativePropertyAnimation::qtAnimation() |
|
2117 { |
|
2118 Q_D(QDeclarativePropertyAnimation); |
|
2119 return d->va; |
|
2120 } |
|
2121 |
|
2122 struct PropertyUpdater : public QDeclarativeBulkValueUpdater |
|
2123 { |
|
2124 QDeclarativeStateActions actions; |
|
2125 int interpolatorType; //for Number/ColorAnimation |
|
2126 int prevInterpolatorType; //for generic |
|
2127 QVariantAnimation::Interpolator interpolator; |
|
2128 bool reverse; |
|
2129 bool fromSourced; |
|
2130 bool fromDefined; |
|
2131 bool *wasDeleted; |
|
2132 PropertyUpdater() : prevInterpolatorType(0), wasDeleted(0) {} |
|
2133 ~PropertyUpdater() { if (wasDeleted) *wasDeleted = true; } |
|
2134 void setValue(qreal v) |
|
2135 { |
|
2136 bool deleted = false; |
|
2137 wasDeleted = &deleted; |
|
2138 if (reverse) //QVariantAnimation sends us 1->0 when reversed, but we are expecting 0->1 |
|
2139 v = 1 - v; |
|
2140 for (int ii = 0; ii < actions.count(); ++ii) { |
|
2141 QDeclarativeAction &action = actions[ii]; |
|
2142 |
|
2143 if (v == 1.) |
|
2144 QDeclarativePropertyPrivate::write(action.property, action.toValue, QDeclarativePropertyPrivate::BypassInterceptor | QDeclarativePropertyPrivate::DontRemoveBinding); |
|
2145 else { |
|
2146 if (!fromSourced && !fromDefined) { |
|
2147 action.fromValue = action.property.read(); |
|
2148 if (interpolatorType) |
|
2149 QDeclarativePropertyAnimationPrivate::convertVariant(action.fromValue, interpolatorType); |
|
2150 } |
|
2151 if (!interpolatorType) { |
|
2152 int propType = action.property.propertyType(); |
|
2153 if (!prevInterpolatorType || prevInterpolatorType != propType) { |
|
2154 prevInterpolatorType = propType; |
|
2155 interpolator = QVariantAnimationPrivate::getInterpolator(prevInterpolatorType); |
|
2156 } |
|
2157 } |
|
2158 if (interpolator) |
|
2159 QDeclarativePropertyPrivate::write(action.property, interpolator(action.fromValue.constData(), action.toValue.constData(), v), QDeclarativePropertyPrivate::BypassInterceptor | QDeclarativePropertyPrivate::DontRemoveBinding); |
|
2160 } |
|
2161 if (deleted) |
|
2162 return; |
|
2163 } |
|
2164 wasDeleted = 0; |
|
2165 fromSourced = true; |
|
2166 } |
|
2167 }; |
|
2168 |
|
2169 void QDeclarativePropertyAnimation::transition(QDeclarativeStateActions &actions, |
|
2170 QDeclarativeProperties &modified, |
|
2171 TransitionDirection direction) |
|
2172 { |
|
2173 Q_D(QDeclarativePropertyAnimation); |
|
2174 |
|
2175 QStringList props = d->properties.isEmpty() ? QStringList() : d->properties.split(QLatin1Char(',')); |
|
2176 for (int ii = 0; ii < props.count(); ++ii) |
|
2177 props[ii] = props.at(ii).trimmed(); |
|
2178 if (!d->propertyName.isEmpty()) |
|
2179 props << d->propertyName; |
|
2180 |
|
2181 QList<QObject*> targets = d->targets; |
|
2182 if (d->target) |
|
2183 targets.append(d->target); |
|
2184 |
|
2185 bool hasSelectors = !props.isEmpty() || !targets.isEmpty() || !d->exclude.isEmpty(); |
|
2186 bool useType = (props.isEmpty() && d->defaultToInterpolatorType) ? true : false; |
|
2187 |
|
2188 if (d->defaultProperty.isValid() && !hasSelectors) { |
|
2189 props << d->defaultProperty.name(); |
|
2190 targets << d->defaultProperty.object(); |
|
2191 } |
|
2192 |
|
2193 if (props.isEmpty() && !d->defaultProperties.isEmpty()) { |
|
2194 props << d->defaultProperties.split(QLatin1Char(',')); |
|
2195 } |
|
2196 |
|
2197 PropertyUpdater *data = new PropertyUpdater; |
|
2198 data->interpolatorType = d->interpolatorType; |
|
2199 data->interpolator = d->interpolator; |
|
2200 data->reverse = direction == Backward ? true : false; |
|
2201 data->fromSourced = false; |
|
2202 data->fromDefined = d->fromIsDefined; |
|
2203 |
|
2204 bool hasExplicit = false; |
|
2205 //an explicit animation has been specified |
|
2206 if (d->toIsDefined) { |
|
2207 for (int i = 0; i < props.count(); ++i) { |
|
2208 for (int j = 0; j < targets.count(); ++j) { |
|
2209 QDeclarativeAction myAction; |
|
2210 myAction.property = d->createProperty(targets.at(j), props.at(i), this); |
|
2211 if (myAction.property.isValid()) { |
|
2212 if (d->fromIsDefined) { |
|
2213 myAction.fromValue = d->from; |
|
2214 d->convertVariant(myAction.fromValue, d->interpolatorType ? d->interpolatorType : myAction.property.propertyType()); |
|
2215 } |
|
2216 myAction.toValue = d->to; |
|
2217 d->convertVariant(myAction.toValue, d->interpolatorType ? d->interpolatorType : myAction.property.propertyType()); |
|
2218 data->actions << myAction; |
|
2219 hasExplicit = true; |
|
2220 for (int ii = 0; ii < actions.count(); ++ii) { |
|
2221 QDeclarativeAction &action = actions[ii]; |
|
2222 if (action.property.object() == myAction.property.object() && |
|
2223 myAction.property.name() == action.property.name()) { |
|
2224 modified << action.property; |
|
2225 break; //### any chance there could be multiples? |
|
2226 } |
|
2227 } |
|
2228 } |
|
2229 } |
|
2230 } |
|
2231 } |
|
2232 |
|
2233 if (!hasExplicit) |
|
2234 for (int ii = 0; ii < actions.count(); ++ii) { |
|
2235 QDeclarativeAction &action = actions[ii]; |
|
2236 |
|
2237 QObject *obj = action.property.object(); |
|
2238 QString propertyName = action.property.name(); |
|
2239 QObject *sObj = action.specifiedObject; |
|
2240 QString sPropertyName = action.specifiedProperty; |
|
2241 bool same = (obj == sObj); |
|
2242 |
|
2243 if ((targets.isEmpty() || targets.contains(obj) || (!same && targets.contains(sObj))) && |
|
2244 (!d->exclude.contains(obj)) && (same || (!d->exclude.contains(sObj))) && |
|
2245 (props.contains(propertyName) || (!same && props.contains(sPropertyName)) |
|
2246 || (useType && action.property.propertyType() == d->interpolatorType))) { |
|
2247 QDeclarativeAction myAction = action; |
|
2248 |
|
2249 if (d->fromIsDefined) |
|
2250 myAction.fromValue = d->from; |
|
2251 else |
|
2252 myAction.fromValue = QVariant(); |
|
2253 if (d->toIsDefined) |
|
2254 myAction.toValue = d->to; |
|
2255 |
|
2256 d->convertVariant(myAction.fromValue, d->interpolatorType ? d->interpolatorType : myAction.property.propertyType()); |
|
2257 d->convertVariant(myAction.toValue, d->interpolatorType ? d->interpolatorType : myAction.property.propertyType()); |
|
2258 |
|
2259 modified << action.property; |
|
2260 |
|
2261 data->actions << myAction; |
|
2262 action.fromValue = myAction.toValue; |
|
2263 } |
|
2264 } |
|
2265 |
|
2266 if (data->actions.count()) { |
|
2267 if (!d->rangeIsSet) { |
|
2268 d->va->setStartValue(qreal(0)); |
|
2269 d->va->setEndValue(qreal(1)); |
|
2270 d->rangeIsSet = true; |
|
2271 } |
|
2272 d->va->setAnimValue(data, QAbstractAnimation::DeleteWhenStopped); |
|
2273 d->va->setFromSourcedValue(&data->fromSourced); |
|
2274 d->actions = &data->actions; |
|
2275 } else { |
|
2276 delete data; |
|
2277 d->actions = 0; |
|
2278 } |
|
2279 } |
|
2280 |
|
2281 /*! |
|
2282 \qmlclass ParentAnimation QDeclarativeParentAnimation |
|
2283 \since 4.7 |
|
2284 \inherits Animation |
|
2285 \brief The ParentAnimation element allows you to animate parent changes. |
|
2286 |
|
2287 ParentAnimation is used in conjunction with NumberAnimation to smoothly |
|
2288 animate changing an item's parent. In the following example, |
|
2289 ParentAnimation wraps a NumberAnimation which animates from the |
|
2290 current position in the old parent to the new position in the new |
|
2291 parent. |
|
2292 |
|
2293 \qml |
|
2294 ... |
|
2295 State { |
|
2296 //reparent myItem to newParent. myItem's final location |
|
2297 //should be 10,10 in newParent. |
|
2298 ParentChange { |
|
2299 target: myItem |
|
2300 parent: newParent |
|
2301 x: 10; y: 10 |
|
2302 } |
|
2303 } |
|
2304 ... |
|
2305 Transition { |
|
2306 //smoothly reparent myItem and move into new position |
|
2307 ParentAnimation { |
|
2308 target: theItem |
|
2309 NumberAnimation { properties: "x,y" } |
|
2310 } |
|
2311 } |
|
2312 \endqml |
|
2313 |
|
2314 ParentAnimation can wrap any number of animations -- those animations will |
|
2315 be run in parallel (like those in a ParallelAnimation group). |
|
2316 |
|
2317 In some cases, such as reparenting between items with clipping, it's useful |
|
2318 to animate the parent change via another item with no clipping. |
|
2319 |
|
2320 When used in a transition, ParentAnimation will by default animate |
|
2321 all ParentChanges. |
|
2322 */ |
|
2323 |
|
2324 /*! |
|
2325 \internal |
|
2326 \class QDeclarativeParentAnimation |
|
2327 */ |
|
2328 QDeclarativeParentAnimation::QDeclarativeParentAnimation(QObject *parent) |
|
2329 : QDeclarativeAnimationGroup(*(new QDeclarativeParentAnimationPrivate), parent) |
|
2330 { |
|
2331 Q_D(QDeclarativeParentAnimation); |
|
2332 d->topLevelGroup = new QSequentialAnimationGroup; |
|
2333 QDeclarative_setParent_noEvent(d->topLevelGroup, this); |
|
2334 |
|
2335 d->startAction = new QActionAnimation; |
|
2336 QDeclarative_setParent_noEvent(d->startAction, d->topLevelGroup); |
|
2337 d->topLevelGroup->addAnimation(d->startAction); |
|
2338 |
|
2339 d->ag = new QParallelAnimationGroup; |
|
2340 QDeclarative_setParent_noEvent(d->ag, d->topLevelGroup); |
|
2341 d->topLevelGroup->addAnimation(d->ag); |
|
2342 |
|
2343 d->endAction = new QActionAnimation; |
|
2344 QDeclarative_setParent_noEvent(d->endAction, d->topLevelGroup); |
|
2345 d->topLevelGroup->addAnimation(d->endAction); |
|
2346 } |
|
2347 |
|
2348 QDeclarativeParentAnimation::~QDeclarativeParentAnimation() |
|
2349 { |
|
2350 } |
|
2351 |
|
2352 /*! |
|
2353 \qmlproperty Item ParentAnimation::target |
|
2354 The item to reparent. |
|
2355 |
|
2356 When used in a transition, if no target is specified all |
|
2357 ParentChanges will be animated by the ParentAnimation. |
|
2358 */ |
|
2359 QDeclarativeItem *QDeclarativeParentAnimation::target() const |
|
2360 { |
|
2361 Q_D(const QDeclarativeParentAnimation); |
|
2362 return d->target; |
|
2363 } |
|
2364 |
|
2365 void QDeclarativeParentAnimation::setTarget(QDeclarativeItem *target) |
|
2366 { |
|
2367 Q_D(QDeclarativeParentAnimation); |
|
2368 if (target == d->target) |
|
2369 return; |
|
2370 |
|
2371 d->target = target; |
|
2372 emit targetChanged(); |
|
2373 } |
|
2374 |
|
2375 /*! |
|
2376 \qmlproperty Item ParentAnimation::newParent |
|
2377 The new parent to animate to. |
|
2378 |
|
2379 If not set, then the parent defined in the end state of the transition. |
|
2380 */ |
|
2381 QDeclarativeItem *QDeclarativeParentAnimation::newParent() const |
|
2382 { |
|
2383 Q_D(const QDeclarativeParentAnimation); |
|
2384 return d->newParent; |
|
2385 } |
|
2386 |
|
2387 void QDeclarativeParentAnimation::setNewParent(QDeclarativeItem *newParent) |
|
2388 { |
|
2389 Q_D(QDeclarativeParentAnimation); |
|
2390 if (newParent == d->newParent) |
|
2391 return; |
|
2392 |
|
2393 d->newParent = newParent; |
|
2394 emit newParentChanged(); |
|
2395 } |
|
2396 |
|
2397 /*! |
|
2398 \qmlproperty Item ParentAnimation::via |
|
2399 The item to reparent via. This provides a way to do an unclipped animation |
|
2400 when both the old parent and new parent are clipped |
|
2401 |
|
2402 \qml |
|
2403 ParentAnimation { |
|
2404 target: myItem |
|
2405 via: topLevelItem |
|
2406 ... |
|
2407 } |
|
2408 \endqml |
|
2409 */ |
|
2410 QDeclarativeItem *QDeclarativeParentAnimation::via() const |
|
2411 { |
|
2412 Q_D(const QDeclarativeParentAnimation); |
|
2413 return d->via; |
|
2414 } |
|
2415 |
|
2416 void QDeclarativeParentAnimation::setVia(QDeclarativeItem *via) |
|
2417 { |
|
2418 Q_D(QDeclarativeParentAnimation); |
|
2419 if (via == d->via) |
|
2420 return; |
|
2421 |
|
2422 d->via = via; |
|
2423 emit viaChanged(); |
|
2424 } |
|
2425 |
|
2426 //### mirrors same-named function in QDeclarativeItem |
|
2427 QPointF QDeclarativeParentAnimationPrivate::computeTransformOrigin(QDeclarativeItem::TransformOrigin origin, qreal width, qreal height) const |
|
2428 { |
|
2429 switch(origin) { |
|
2430 default: |
|
2431 case QDeclarativeItem::TopLeft: |
|
2432 return QPointF(0, 0); |
|
2433 case QDeclarativeItem::Top: |
|
2434 return QPointF(width / 2., 0); |
|
2435 case QDeclarativeItem::TopRight: |
|
2436 return QPointF(width, 0); |
|
2437 case QDeclarativeItem::Left: |
|
2438 return QPointF(0, height / 2.); |
|
2439 case QDeclarativeItem::Center: |
|
2440 return QPointF(width / 2., height / 2.); |
|
2441 case QDeclarativeItem::Right: |
|
2442 return QPointF(width, height / 2.); |
|
2443 case QDeclarativeItem::BottomLeft: |
|
2444 return QPointF(0, height); |
|
2445 case QDeclarativeItem::Bottom: |
|
2446 return QPointF(width / 2., height); |
|
2447 case QDeclarativeItem::BottomRight: |
|
2448 return QPointF(width, height); |
|
2449 } |
|
2450 } |
|
2451 |
|
2452 void QDeclarativeParentAnimation::transition(QDeclarativeStateActions &actions, |
|
2453 QDeclarativeProperties &modified, |
|
2454 TransitionDirection direction) |
|
2455 { |
|
2456 Q_D(QDeclarativeParentAnimation); |
|
2457 |
|
2458 struct QDeclarativeParentAnimationData : public QAbstractAnimationAction |
|
2459 { |
|
2460 QDeclarativeParentAnimationData() {} |
|
2461 ~QDeclarativeParentAnimationData() { qDeleteAll(pc); } |
|
2462 |
|
2463 QDeclarativeStateActions actions; |
|
2464 //### reverse should probably apply on a per-action basis |
|
2465 bool reverse; |
|
2466 QList<QDeclarativeParentChange *> pc; |
|
2467 virtual void doAction() |
|
2468 { |
|
2469 for (int ii = 0; ii < actions.count(); ++ii) { |
|
2470 const QDeclarativeAction &action = actions.at(ii); |
|
2471 if (reverse) |
|
2472 action.event->reverse(); |
|
2473 else |
|
2474 action.event->execute(); |
|
2475 } |
|
2476 } |
|
2477 }; |
|
2478 |
|
2479 QDeclarativeParentAnimationData *data = new QDeclarativeParentAnimationData; |
|
2480 QDeclarativeParentAnimationData *viaData = new QDeclarativeParentAnimationData; |
|
2481 |
|
2482 bool hasExplicit = false; |
|
2483 if (d->target && d->newParent) { |
|
2484 data->reverse = false; |
|
2485 QDeclarativeAction myAction; |
|
2486 QDeclarativeParentChange *pc = new QDeclarativeParentChange; |
|
2487 pc->setObject(d->target); |
|
2488 pc->setParent(d->newParent); |
|
2489 myAction.event = pc; |
|
2490 data->pc << pc; |
|
2491 data->actions << myAction; |
|
2492 hasExplicit = true; |
|
2493 if (d->via) { |
|
2494 viaData->reverse = false; |
|
2495 QDeclarativeAction myVAction; |
|
2496 QDeclarativeParentChange *vpc = new QDeclarativeParentChange; |
|
2497 vpc->setObject(d->target); |
|
2498 vpc->setParent(d->via); |
|
2499 myVAction.event = vpc; |
|
2500 viaData->pc << vpc; |
|
2501 viaData->actions << myVAction; |
|
2502 } |
|
2503 //### once actions have concept of modified, |
|
2504 // loop to match appropriate ParentChanges and mark as modified |
|
2505 } |
|
2506 |
|
2507 if (!hasExplicit) |
|
2508 for (int i = 0; i < actions.size(); ++i) { |
|
2509 QDeclarativeAction &action = actions[i]; |
|
2510 if (action.event && action.event->typeName() == QLatin1String("ParentChange") |
|
2511 && (!d->target || static_cast<QDeclarativeParentChange*>(action.event)->object() == d->target)) { |
|
2512 |
|
2513 QDeclarativeParentChange *pc = static_cast<QDeclarativeParentChange*>(action.event); |
|
2514 QDeclarativeAction myAction = action; |
|
2515 data->reverse = action.reverseEvent; |
|
2516 |
|
2517 //### this logic differs from PropertyAnimation |
|
2518 // (probably a result of modified vs. done) |
|
2519 if (d->newParent) { |
|
2520 QDeclarativeParentChange *epc = new QDeclarativeParentChange; |
|
2521 epc->setObject(static_cast<QDeclarativeParentChange*>(action.event)->object()); |
|
2522 epc->setParent(d->newParent); |
|
2523 myAction.event = epc; |
|
2524 data->pc << epc; |
|
2525 data->actions << myAction; |
|
2526 pc = epc; |
|
2527 } else { |
|
2528 action.actionDone = true; |
|
2529 data->actions << myAction; |
|
2530 } |
|
2531 |
|
2532 if (d->via) { |
|
2533 viaData->reverse = false; |
|
2534 QDeclarativeAction myAction; |
|
2535 QDeclarativeParentChange *vpc = new QDeclarativeParentChange; |
|
2536 vpc->setObject(pc->object()); |
|
2537 vpc->setParent(d->via); |
|
2538 myAction.event = vpc; |
|
2539 viaData->pc << vpc; |
|
2540 viaData->actions << myAction; |
|
2541 QDeclarativeAction dummyAction; |
|
2542 QDeclarativeAction &xAction = pc->xIsSet() && i < actions.size()-1 ? actions[++i] : dummyAction; |
|
2543 QDeclarativeAction &yAction = pc->yIsSet() && i < actions.size()-1 ? actions[++i] : dummyAction; |
|
2544 QDeclarativeAction &sAction = pc->scaleIsSet() && i < actions.size()-1 ? actions[++i] : dummyAction; |
|
2545 QDeclarativeAction &rAction = pc->rotationIsSet() && i < actions.size()-1 ? actions[++i] : dummyAction; |
|
2546 QDeclarativeItem *target = pc->object(); |
|
2547 QDeclarativeItem *targetParent = action.reverseEvent ? pc->originalParent() : pc->parent(); |
|
2548 |
|
2549 //### this mirrors the logic in QDeclarativeParentChange. |
|
2550 bool ok; |
|
2551 const QTransform &transform = targetParent->itemTransform(d->via, &ok); |
|
2552 if (transform.type() >= QTransform::TxShear || !ok) { |
|
2553 qmlInfo(this) << QDeclarativeParentAnimation::tr("Unable to preserve appearance under complex transform"); |
|
2554 ok = false; |
|
2555 } |
|
2556 |
|
2557 qreal scale = 1; |
|
2558 qreal rotation = 0; |
|
2559 if (ok && transform.type() != QTransform::TxRotate) { |
|
2560 if (transform.m11() == transform.m22()) |
|
2561 scale = transform.m11(); |
|
2562 else { |
|
2563 qmlInfo(this) << QDeclarativeParentAnimation::tr("Unable to preserve appearance under non-uniform scale"); |
|
2564 ok = false; |
|
2565 } |
|
2566 } else if (ok && transform.type() == QTransform::TxRotate) { |
|
2567 if (transform.m11() == transform.m22()) |
|
2568 scale = qSqrt(transform.m11()*transform.m11() + transform.m12()*transform.m12()); |
|
2569 else { |
|
2570 qmlInfo(this) << QDeclarativeParentAnimation::tr("Unable to preserve appearance under non-uniform scale"); |
|
2571 ok = false; |
|
2572 } |
|
2573 |
|
2574 if (scale != 0) |
|
2575 rotation = atan2(transform.m12()/scale, transform.m11()/scale) * 180/M_PI; |
|
2576 else { |
|
2577 qmlInfo(this) << QDeclarativeParentAnimation::tr("Unable to preserve appearance under scale of 0"); |
|
2578 ok = false; |
|
2579 } |
|
2580 } |
|
2581 |
|
2582 const QPointF &point = transform.map(QPointF(xAction.toValue.toReal(),yAction.toValue.toReal())); |
|
2583 qreal x = point.x(); |
|
2584 qreal y = point.y(); |
|
2585 if (ok && target->transformOrigin() != QDeclarativeItem::TopLeft) { |
|
2586 qreal w = target->width(); |
|
2587 qreal h = target->height(); |
|
2588 if (pc->widthIsSet() && i < actions.size() - 1) |
|
2589 w = actions[++i].toValue.toReal(); |
|
2590 if (pc->heightIsSet() && i < actions.size() - 1) |
|
2591 h = actions[++i].toValue.toReal(); |
|
2592 const QPointF &transformOrigin |
|
2593 = d->computeTransformOrigin(target->transformOrigin(), w,h); |
|
2594 qreal tempxt = transformOrigin.x(); |
|
2595 qreal tempyt = transformOrigin.y(); |
|
2596 QTransform t; |
|
2597 t.translate(-tempxt, -tempyt); |
|
2598 t.rotate(rotation); |
|
2599 t.scale(scale, scale); |
|
2600 t.translate(tempxt, tempyt); |
|
2601 const QPointF &offset = t.map(QPointF(0,0)); |
|
2602 x += offset.x(); |
|
2603 y += offset.y(); |
|
2604 } |
|
2605 |
|
2606 if (ok) { |
|
2607 //qDebug() << x << y << rotation << scale; |
|
2608 xAction.toValue = x; |
|
2609 yAction.toValue = y; |
|
2610 sAction.toValue = sAction.toValue.toReal() * scale; |
|
2611 rAction.toValue = rAction.toValue.toReal() + rotation; |
|
2612 } |
|
2613 } |
|
2614 } |
|
2615 } |
|
2616 |
|
2617 if (data->actions.count()) { |
|
2618 if (direction == QDeclarativeAbstractAnimation::Forward) { |
|
2619 d->startAction->setAnimAction(d->via ? viaData : data, QActionAnimation::DeleteWhenStopped); |
|
2620 d->endAction->setAnimAction(d->via ? data : 0, QActionAnimation::DeleteWhenStopped); |
|
2621 } else { |
|
2622 d->endAction->setAnimAction(d->via ? viaData : data, QActionAnimation::DeleteWhenStopped); |
|
2623 d->startAction->setAnimAction(d->via ? data : 0, QActionAnimation::DeleteWhenStopped); |
|
2624 } |
|
2625 } else { |
|
2626 delete data; |
|
2627 delete viaData; |
|
2628 } |
|
2629 |
|
2630 //take care of any child animations |
|
2631 bool valid = d->defaultProperty.isValid(); |
|
2632 for (int ii = 0; ii < d->animations.count(); ++ii) { |
|
2633 if (valid) |
|
2634 d->animations.at(ii)->setDefaultTarget(d->defaultProperty); |
|
2635 d->animations.at(ii)->transition(actions, modified, direction); |
|
2636 } |
|
2637 |
|
2638 } |
|
2639 |
|
2640 QAbstractAnimation *QDeclarativeParentAnimation::qtAnimation() |
|
2641 { |
|
2642 Q_D(QDeclarativeParentAnimation); |
|
2643 return d->topLevelGroup; |
|
2644 } |
|
2645 |
|
2646 /*! |
|
2647 \qmlclass AnchorAnimation QDeclarativeAnchorAnimation |
|
2648 \since 4.7 |
|
2649 \inherits Animation |
|
2650 \brief The AnchorAnimation element allows you to animate anchor changes. |
|
2651 |
|
2652 AnchorAnimation will animated any changes specified by a state's AnchorChanges. |
|
2653 In the following snippet we animate the addition of a right anchor to our item. |
|
2654 \qml |
|
2655 Item { |
|
2656 id: myItem |
|
2657 width: 100 |
|
2658 } |
|
2659 ... |
|
2660 State { |
|
2661 AnchorChanges { |
|
2662 target: myItem |
|
2663 anchors.right: container.right |
|
2664 } |
|
2665 } |
|
2666 ... |
|
2667 Transition { |
|
2668 //smoothly reanchor myItem and move into new position |
|
2669 AnchorAnimation {} |
|
2670 } |
|
2671 \endqml |
|
2672 |
|
2673 \sa AnchorChanges |
|
2674 */ |
|
2675 |
|
2676 QDeclarativeAnchorAnimation::QDeclarativeAnchorAnimation(QObject *parent) |
|
2677 : QDeclarativeAbstractAnimation(*(new QDeclarativeAnchorAnimationPrivate), parent) |
|
2678 { |
|
2679 Q_D(QDeclarativeAnchorAnimation); |
|
2680 d->va = new QDeclarativeBulkValueAnimator; |
|
2681 QDeclarative_setParent_noEvent(d->va, this); |
|
2682 } |
|
2683 |
|
2684 QDeclarativeAnchorAnimation::~QDeclarativeAnchorAnimation() |
|
2685 { |
|
2686 } |
|
2687 |
|
2688 QAbstractAnimation *QDeclarativeAnchorAnimation::qtAnimation() |
|
2689 { |
|
2690 Q_D(QDeclarativeAnchorAnimation); |
|
2691 return d->va; |
|
2692 } |
|
2693 |
|
2694 /*! |
|
2695 \qmlproperty list<Item> AnchorAnimation::targets |
|
2696 The items to reanchor. |
|
2697 |
|
2698 If no targets are specified all AnchorChanges will be |
|
2699 animated by the AnchorAnimation. |
|
2700 */ |
|
2701 QDeclarativeListProperty<QDeclarativeItem> QDeclarativeAnchorAnimation::targets() |
|
2702 { |
|
2703 Q_D(QDeclarativeAnchorAnimation); |
|
2704 return QDeclarativeListProperty<QDeclarativeItem>(this, d->targets); |
|
2705 } |
|
2706 |
|
2707 /*! |
|
2708 \qmlproperty int AnchorAnimation::duration |
|
2709 This property holds the duration of the animation, in milliseconds. |
|
2710 |
|
2711 The default value is 250. |
|
2712 */ |
|
2713 int QDeclarativeAnchorAnimation::duration() const |
|
2714 { |
|
2715 Q_D(const QDeclarativeAnchorAnimation); |
|
2716 return d->va->duration(); |
|
2717 } |
|
2718 |
|
2719 void QDeclarativeAnchorAnimation::setDuration(int duration) |
|
2720 { |
|
2721 if (duration < 0) { |
|
2722 qmlInfo(this) << tr("Cannot set a duration of < 0"); |
|
2723 return; |
|
2724 } |
|
2725 |
|
2726 Q_D(QDeclarativeAnchorAnimation); |
|
2727 if (d->va->duration() == duration) |
|
2728 return; |
|
2729 d->va->setDuration(duration); |
|
2730 emit durationChanged(duration); |
|
2731 } |
|
2732 |
|
2733 /*! |
|
2734 \qmlproperty enumeration AnchorAnimation::easing.type |
|
2735 \qmlproperty real AnchorAnimation::easing.amplitude |
|
2736 \qmlproperty real AnchorAnimation::easing.overshoot |
|
2737 \qmlproperty real AnchorAnimation::easing.period |
|
2738 \brief the easing curve used for the animation. |
|
2739 |
|
2740 To specify an easing curve you need to specify at least the type. For some curves you can also specify |
|
2741 amplitude, period and/or overshoot. The default easing curve is |
|
2742 Linear. |
|
2743 |
|
2744 \qml |
|
2745 AnchorAnimation { easing.type: Easing.InOutQuad } |
|
2746 \endqml |
|
2747 |
|
2748 See the \l{PropertyAnimation::easing.type} documentation for information |
|
2749 about the different types of easing curves. |
|
2750 */ |
|
2751 |
|
2752 QEasingCurve QDeclarativeAnchorAnimation::easing() const |
|
2753 { |
|
2754 Q_D(const QDeclarativeAnchorAnimation); |
|
2755 return d->va->easingCurve(); |
|
2756 } |
|
2757 |
|
2758 void QDeclarativeAnchorAnimation::setEasing(const QEasingCurve &e) |
|
2759 { |
|
2760 Q_D(QDeclarativeAnchorAnimation); |
|
2761 if (d->va->easingCurve() == e) |
|
2762 return; |
|
2763 |
|
2764 d->va->setEasingCurve(e); |
|
2765 emit easingChanged(e); |
|
2766 } |
|
2767 |
|
2768 void QDeclarativeAnchorAnimation::transition(QDeclarativeStateActions &actions, |
|
2769 QDeclarativeProperties &modified, |
|
2770 TransitionDirection direction) |
|
2771 { |
|
2772 Q_UNUSED(modified); |
|
2773 Q_D(QDeclarativeAnchorAnimation); |
|
2774 PropertyUpdater *data = new PropertyUpdater; |
|
2775 data->interpolatorType = QMetaType::QReal; |
|
2776 data->interpolator = d->interpolator; |
|
2777 |
|
2778 data->reverse = direction == Backward ? true : false; |
|
2779 data->fromSourced = false; |
|
2780 data->fromDefined = false; |
|
2781 |
|
2782 for (int ii = 0; ii < actions.count(); ++ii) { |
|
2783 QDeclarativeAction &action = actions[ii]; |
|
2784 if (action.event && action.event->typeName() == QLatin1String("AnchorChanges") |
|
2785 && (d->targets.isEmpty() || d->targets.contains(static_cast<QDeclarativeAnchorChanges*>(action.event)->object()))) { |
|
2786 data->actions << static_cast<QDeclarativeAnchorChanges*>(action.event)->additionalActions(); |
|
2787 } |
|
2788 } |
|
2789 |
|
2790 if (data->actions.count()) { |
|
2791 if (!d->rangeIsSet) { |
|
2792 d->va->setStartValue(qreal(0)); |
|
2793 d->va->setEndValue(qreal(1)); |
|
2794 d->rangeIsSet = true; |
|
2795 } |
|
2796 d->va->setAnimValue(data, QAbstractAnimation::DeleteWhenStopped); |
|
2797 d->va->setFromSourcedValue(&data->fromSourced); |
|
2798 } else { |
|
2799 delete data; |
|
2800 } |
|
2801 } |
|
2802 |
|
2803 QT_END_NAMESPACE |