[dali_1.0.17] Merge branch 'tizen'
[platform/core/uifw/dali-core.git] / dali / internal / event / animation / animation-impl.cpp
1 /*
2  * Copyright (c) 2014 Samsung Electronics Co., Ltd.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  *
16  */
17
18 // CLASS HEADER
19 #include <dali/internal/event/animation/animation-impl.h>
20
21 // INTERNAL INCLUDES
22 #include <dali/public-api/animation/alpha-functions.h>
23 #include <dali/public-api/animation/time-period.h>
24 #include <dali/public-api/common/dali-common.h>
25 #include <dali/public-api/object/type-registry.h>
26 #include <dali/public-api/math/vector2.h>
27 #include <dali/public-api/math/radian.h>
28 #include <dali/internal/event/actors/actor-impl.h>
29 #include <dali/internal/event/common/stage-impl.h>
30 #include <dali/internal/event/animation/animator-connector.h>
31 #include <dali/internal/event/animation/animation-playlist.h>
32 #include <dali/internal/event/common/notification-manager.h>
33 #include <dali/internal/update/manager/update-manager.h>
34 #include <dali/internal/event/effects/shader-effect-impl.h>
35 #include <dali/internal/event/common/thread-local-storage.h>
36
37 using Dali::Internal::SceneGraph::UpdateManager;
38 using Dali::Internal::SceneGraph::AnimatorBase;
39 using Dali::Internal::SceneGraph::Shader;
40
41 namespace Dali
42 {
43
44 namespace Internal
45 {
46
47 static bool SHOW_VALUE = true;
48 static bool HIDE_VALUE = false;
49
50 namespace
51 {
52
53 BaseHandle Create()
54 {
55   return Dali::Animation::New(0.f);
56 }
57
58 TypeRegistration mType( typeid(Dali::Animation), typeid(Dali::BaseHandle), Create );
59
60 SignalConnectorType signalConnector1( mType, Dali::Animation::SIGNAL_FINISHED, &Animation::DoConnectSignal );
61
62 TypeAction action1( mType, Dali::Animation::ACTION_PLAY, &Animation::DoAction );
63 TypeAction action2( mType, Dali::Animation::ACTION_STOP, &Animation::DoAction );
64 TypeAction action3( mType, Dali::Animation::ACTION_PAUSE, &Animation::DoAction );
65
66 const Dali::Animation::EndAction DEFAULT_END_ACTION( Dali::Animation::Bake );
67 const Dali::Animation::EndAction DEFAULT_DISCONNECT_ACTION( Dali::Animation::BakeFinal );
68
69 } // anon namespace
70
71
72 AnimationPtr Animation::New(float durationSeconds)
73 {
74   ThreadLocalStorage& tls = ThreadLocalStorage::Get();
75   UpdateManager& updateManager = tls.GetUpdateManager();
76
77   AnimationPlaylist& playlist = Stage::GetCurrent()->GetAnimationPlaylist();
78
79   AnimationPtr animation = new Animation( updateManager, playlist, durationSeconds, DEFAULT_END_ACTION, DEFAULT_DISCONNECT_ACTION, Dali::AlphaFunctions::Linear );
80
81   // Second-phase construction
82   animation->Initialize();
83
84   return animation;
85 }
86
87 Animation::Animation( UpdateManager& updateManager, AnimationPlaylist& playlist, float durationSeconds, EndAction endAction, EndAction disconnectAction, AlphaFunction defaultAlpha )
88 : mUpdateManager( updateManager ),
89   mPlaylist( playlist ),
90   mAnimation( NULL ),
91   mNotificationCount( 0 ),
92   mFinishedCallback( NULL ),
93   mFinishedCallbackObject( NULL ),
94   mDurationSeconds( durationSeconds ),
95   mSpeedFactor(1.0f),
96   mIsLooping( false ),
97   mPlayRange( Vector2(0.0f,1.0f)),
98   mEndAction( endAction ),
99   mDisconnectAction( disconnectAction ),
100   mDefaultAlpha( defaultAlpha )
101 {
102 }
103
104 void Animation::Initialize()
105 {
106   // Connect to the animation playlist
107   mPlaylist.AnimationCreated( *this );
108
109   CreateSceneObject();
110
111   RegisterObject();
112 }
113
114 Animation::~Animation()
115 {
116   // Guard to allow handle destruction after Core has been destroyed
117   if ( Stage::IsInstalled() )
118   {
119     // Disconnect from the animation playlist
120     mPlaylist.AnimationDestroyed( *this );
121
122     DestroySceneObject();
123
124     UnregisterObject();
125   }
126 }
127
128 void Animation::CreateSceneObject()
129 {
130   DALI_ASSERT_DEBUG( mAnimation == NULL );
131
132   // Create a new animation, temporarily owned
133   SceneGraph::Animation* animation = SceneGraph::Animation::New( mDurationSeconds, mSpeedFactor, mPlayRange, mIsLooping, mEndAction, mDisconnectAction );
134
135   // Keep a const pointer to the animation.
136   mAnimation = animation;
137
138   // Transfer animation ownership to the update manager through a message
139   AddAnimationMessage( mUpdateManager, animation );
140 }
141
142 void Animation::DestroySceneObject()
143 {
144   if ( mAnimation != NULL )
145   {
146     // Remove animation using a message to the update manager
147     RemoveAnimationMessage( mUpdateManager, *mAnimation );
148     mAnimation = NULL;
149   }
150 }
151
152 void Animation::SetDuration(float seconds)
153 {
154   // Cache for public getters
155   mDurationSeconds = seconds;
156
157   // mAnimation is being used in a separate thread; queue a message to set the value
158   SetDurationMessage( mUpdateManager.GetEventToUpdate(), *mAnimation, seconds );
159 }
160
161 float Animation::GetDuration() const
162 {
163   // This is not animatable; the cached value is up-to-date.
164   return mDurationSeconds;
165 }
166
167 void Animation::SetLooping(bool looping)
168 {
169   // Cache for public getters
170   mIsLooping = looping;
171
172   // mAnimation is being used in a separate thread; queue a message to set the value
173   SetLoopingMessage( mUpdateManager.GetEventToUpdate(), *mAnimation, looping );
174 }
175
176 bool Animation::IsLooping() const
177 {
178   // This is not animatable; the cached value is up-to-date.
179   return mIsLooping;
180 }
181
182 void Animation::SetEndAction(EndAction action)
183 {
184   // Cache for public getters
185   mEndAction = action;
186
187   // mAnimation is being used in a separate thread; queue a message to set the value
188   SetEndActionMessage( mUpdateManager.GetEventToUpdate(), *mAnimation, action );
189 }
190
191 Dali::Animation::EndAction Animation::GetEndAction() const
192 {
193   // This is not animatable; the cached value is up-to-date.
194   return mEndAction;
195 }
196
197 void Animation::SetDisconnectAction(EndAction action)
198 {
199   // Cache for public getters
200   mDisconnectAction = action;
201
202   // mAnimation is being used in a separate thread; queue a message to set the value
203   SetDisconnectActionMessage( mUpdateManager.GetEventToUpdate(), *mAnimation, action );
204 }
205
206 Dali::Animation::EndAction Animation::GetDisconnectAction() const
207 {
208   // This is not animatable; the cached value is up-to-date.
209   return mDisconnectAction;
210 }
211
212 void Animation::Play()
213 {
214   // Update the current playlist
215   mPlaylist.OnPlay( *this );
216
217   // mAnimation is being used in a separate thread; queue a Play message
218   PlayAnimationMessage( mUpdateManager.GetEventToUpdate(), *mAnimation );
219 }
220
221 void Animation::PlayFrom( float progress )
222 {
223   if( progress >= mPlayRange.x && progress <= mPlayRange.y )
224   {
225     // Update the current playlist
226     mPlaylist.OnPlay( *this );
227
228     // mAnimation is being used in a separate thread; queue a Play message
229     PlayAnimationFromMessage( mUpdateManager.GetEventToUpdate(), *mAnimation, progress );
230   }
231 }
232
233 void Animation::Pause()
234 {
235   // mAnimation is being used in a separate thread; queue a Pause message
236   PauseAnimationMessage( mUpdateManager.GetEventToUpdate(), *mAnimation );
237 }
238
239 void Animation::Stop()
240 {
241   // mAnimation is being used in a separate thread; queue a Stop message
242   StopAnimationMessage( mUpdateManager, *mAnimation );
243 }
244
245 void Animation::Clear()
246 {
247   DALI_ASSERT_DEBUG(mAnimation);
248
249   // Remove all the connectors
250   mConnectors.Clear();
251
252   // Replace the old scene-object with a new one
253   DestroySceneObject();
254   CreateSceneObject();
255
256   // Reset the notification count, since the new scene-object has never been played
257   mNotificationCount = 0;
258
259   // Update the current playlist
260   mPlaylist.OnClear( *this );
261 }
262
263 void Animation::AnimateBy(Property& target, Property::Value& relativeValue)
264 {
265   AnimateBy(target, relativeValue, AlphaFunctions::Default, mDurationSeconds);
266 }
267
268 void Animation::AnimateBy(Property& target, Property::Value& relativeValue, AlphaFunction alpha)
269 {
270   AnimateBy(target, relativeValue, alpha, mDurationSeconds);
271 }
272
273 void Animation::AnimateBy(Property& target, Property::Value& relativeValue, TimePeriod period)
274 {
275   AnimateBy(target, relativeValue, AlphaFunctions::Default, period);
276 }
277
278 void Animation::AnimateBy(Property& target, Property::Value& relativeValue, AlphaFunction alpha, TimePeriod period)
279 {
280   ProxyObject& proxy = dynamic_cast<ProxyObject&>( GetImplementation(target.object) );
281
282   ExtendDuration( period );
283
284   switch ( relativeValue.GetType() )
285   {
286     case Property::BOOLEAN:
287     {
288       AddAnimatorConnector( AnimatorConnector<bool>::New( proxy,
289                                                           target.propertyIndex,
290                                                           target.componentIndex,
291                                                           AnimateByBoolean(relativeValue.Get<bool>()),
292                                                           alpha,
293                                                           period ) );
294       break;
295     }
296
297     case Property::FLOAT:
298     {
299       AddAnimatorConnector( AnimatorConnector<float>::New( proxy,
300                                                            target.propertyIndex,
301                                                            target.componentIndex,
302                                                            AnimateByFloat(relativeValue.Get<float>()),
303                                                            alpha,
304                                                            period ) );
305       break;
306     }
307
308     case Property::INTEGER:
309     {
310       AddAnimatorConnector( AnimatorConnector<int>::New( proxy,
311                                                          target.propertyIndex,
312                                                          target.componentIndex,
313                                                          AnimateByInteger(relativeValue.Get<int>()),
314                                                          alpha,
315                                                          period ) );
316       break;
317     }
318
319     case Property::VECTOR2:
320     {
321       AddAnimatorConnector( AnimatorConnector<Vector2>::New( proxy,
322                                                              target.propertyIndex,
323                                                              target.componentIndex,
324                                                              AnimateByVector2(relativeValue.Get<Vector2>()),
325                                                              alpha,
326                                                              period ) );
327       break;
328     }
329
330     case Property::VECTOR3:
331     {
332       AddAnimatorConnector( AnimatorConnector<Vector3>::New( proxy,
333                                                              target.propertyIndex,
334                                                              target.componentIndex,
335                                                              AnimateByVector3(relativeValue.Get<Vector3>()),
336                                                              alpha,
337                                                              period ) );
338       break;
339     }
340
341     case Property::VECTOR4:
342     {
343       AddAnimatorConnector( AnimatorConnector<Vector4>::New( proxy,
344                                                              target.propertyIndex,
345                                                              target.componentIndex,
346                                                              AnimateByVector4(relativeValue.Get<Vector4>()),
347                                                              alpha,
348                                                              period ) );
349       break;
350     }
351
352     case Property::ROTATION:
353     {
354       AngleAxis angleAxis = relativeValue.Get<AngleAxis>();
355
356       AddAnimatorConnector( AnimatorConnector<Quaternion>::New( proxy,
357                                                                 target.propertyIndex,
358                                                                 target.componentIndex,
359                                                                 RotateByAngleAxis(angleAxis.angle, angleAxis.axis),
360                                                                 alpha,
361                                                                 period ) );
362       break;
363     }
364
365     default:
366       DALI_ASSERT_ALWAYS( false && "Property type enumeration out of bounds" ); // should never come here
367       break;
368   }
369 }
370
371 void Animation::AnimateTo(Property& target, Property::Value& destinationValue)
372 {
373   AnimateTo(target, destinationValue, AlphaFunctions::Default, mDurationSeconds);
374 }
375
376 void Animation::AnimateTo(Property& target, Property::Value& destinationValue, AlphaFunction alpha)
377 {
378   AnimateTo(target, destinationValue, alpha, mDurationSeconds);
379 }
380
381 void Animation::AnimateTo(Property& target, Property::Value& destinationValue, TimePeriod period)
382 {
383   AnimateTo(target, destinationValue, AlphaFunctions::Default, period);
384 }
385
386 void Animation::AnimateTo(Property& target, Property::Value& destinationValue, AlphaFunction alpha, TimePeriod period)
387 {
388   ProxyObject& proxy = dynamic_cast<ProxyObject&>( GetImplementation(target.object) );
389
390   AnimateTo( proxy, target.propertyIndex, target.componentIndex, destinationValue, alpha, period );
391 }
392
393 void Animation::AnimateTo(ProxyObject& targetObject, Property::Index targetPropertyIndex, int componentIndex, Property::Value& destinationValue, AlphaFunction alpha, TimePeriod period)
394 {
395   Property::Type type = targetObject.GetPropertyType(targetPropertyIndex);
396   if(componentIndex != Property::INVALID_COMPONENT_INDEX)
397   {
398     if( type == Property::VECTOR2
399         || type == Property::VECTOR3
400         || type == Property::VECTOR4 )
401     {
402       type = Property::FLOAT;
403     }
404   }
405   DALI_ASSERT_ALWAYS( type == destinationValue.GetType() && "DestinationValue does not match Target Property type" );
406
407   ExtendDuration( period );
408
409   switch (destinationValue.GetType())
410   {
411     case Property::BOOLEAN:
412     {
413       AddAnimatorConnector( AnimatorConnector<bool>::New(targetObject,
414                                                          targetPropertyIndex,
415                                                          componentIndex,
416                                                          AnimateToBoolean(destinationValue.Get<bool>()),
417                                                          alpha,
418                                                          period) );
419       break;
420     }
421
422     case Property::FLOAT:
423     {
424       AddAnimatorConnector( AnimatorConnector<float>::New(targetObject,
425                                                           targetPropertyIndex,
426                                                           componentIndex,
427                                                           AnimateToFloat(destinationValue.Get<float>()),
428                                                           alpha,
429                                                           period) );
430       break;
431     }
432
433     case Property::INTEGER:
434     {
435       AddAnimatorConnector( AnimatorConnector<int>::New(targetObject,
436                                                         targetPropertyIndex,
437                                                         componentIndex,
438                                                         AnimateToInteger(destinationValue.Get<int>()),
439                                                         alpha,
440                                                         period) );
441       break;
442     }
443
444     case Property::VECTOR2:
445     {
446       AddAnimatorConnector( AnimatorConnector<Vector2>::New(targetObject,
447                                                             targetPropertyIndex,
448                                                             componentIndex,
449                                                             AnimateToVector2(destinationValue.Get<Vector2>()),
450                                                             alpha,
451                                                             period) );
452       break;
453     }
454
455     case Property::VECTOR3:
456     {
457       if ( Dali::Actor::SIZE == targetPropertyIndex )
458       {
459         // Test whether this is actually an Actor
460         Actor* maybeActor = dynamic_cast<Actor*>( &targetObject );
461         if ( maybeActor )
462         {
463           // Notify the actor that its size is being animated
464           maybeActor->NotifySizeAnimation( *this, destinationValue.Get<Vector3>() );
465         }
466       }
467
468       AddAnimatorConnector( AnimatorConnector<Vector3>::New(targetObject,
469                                                             targetPropertyIndex,
470                                                             componentIndex,
471                                                             AnimateToVector3(destinationValue.Get<Vector3>()),
472                                                             alpha,
473                                                             period) );
474       break;
475     }
476
477     case Property::VECTOR4:
478     {
479       AddAnimatorConnector( AnimatorConnector<Vector4>::New(targetObject,
480                                                             targetPropertyIndex,
481                                                             componentIndex,
482                                                             AnimateToVector4(destinationValue.Get<Vector4>()),
483                                                             alpha,
484                                                             period) );
485       break;
486     }
487
488     case Property::ROTATION:
489     {
490       AddAnimatorConnector( AnimatorConnector<Quaternion>::New(targetObject,
491                                                                targetPropertyIndex,
492                                                                componentIndex,
493                                                                RotateToQuaternion(destinationValue.Get<Quaternion>()),
494                                                                alpha,
495                                                                period) );
496       break;
497     }
498
499     default:
500       DALI_ASSERT_ALWAYS( false && "Property type enumeration out of bounds" ); // should never come here
501       break;
502   }
503 }
504
505 void Animation::AnimateBetween(Property target, const KeyFrames& keyFrames)
506 {
507   AnimateBetween(target, keyFrames, mDefaultAlpha, mDurationSeconds);
508 }
509
510 void Animation::AnimateBetween(Property target, const KeyFrames& keyFrames, TimePeriod period)
511 {
512   AnimateBetween(target, keyFrames, mDefaultAlpha, period);
513 }
514
515 void Animation::AnimateBetween(Property target, const KeyFrames& keyFrames, AlphaFunction alpha)
516 {
517   AnimateBetween(target, keyFrames, alpha, mDurationSeconds);
518 }
519
520 void Animation::AnimateBetween(Property target, const KeyFrames& keyFrames, AlphaFunction alpha, TimePeriod period)
521 {
522   ProxyObject& proxy = dynamic_cast<ProxyObject&>( GetImplementation(target.object) );
523
524   ExtendDuration( period );
525
526   switch(keyFrames.GetType())
527   {
528     case Dali::Property::BOOLEAN:
529     {
530       const KeyFrameBoolean* kf;
531       GetSpecialization(keyFrames, kf);
532       KeyFrameBooleanPtr kfCopy = KeyFrameBoolean::Clone(*kf);
533       AddAnimatorConnector( AnimatorConnector<bool>::New( proxy,
534                                                           target.propertyIndex,
535                                                           target.componentIndex,
536                                                           KeyFrameBooleanFunctor(kfCopy),
537                                                           alpha,
538                                                           period ) );
539       break;
540     }
541
542     case Dali::Property::FLOAT:
543     {
544       const KeyFrameNumber* kf;
545       GetSpecialization(keyFrames, kf);
546       KeyFrameNumberPtr kfCopy = KeyFrameNumber::Clone(*kf);
547       AddAnimatorConnector( AnimatorConnector<float>::New( proxy,
548                                                            target.propertyIndex,
549                                                            target.componentIndex,
550                                                            KeyFrameNumberFunctor(kfCopy),
551                                                            alpha,
552                                                            period ) );
553       break;
554     }
555
556     case Dali::Property::INTEGER:
557     {
558       const KeyFrameInteger* kf;
559       GetSpecialization(keyFrames, kf);
560       KeyFrameIntegerPtr kfCopy = KeyFrameInteger::Clone(*kf);
561       AddAnimatorConnector( AnimatorConnector<int>::New( proxy,
562                                                          target.propertyIndex,
563                                                          target.componentIndex,
564                                                          KeyFrameIntegerFunctor(kfCopy),
565                                                          alpha,
566                                                          period ) );
567       break;
568     }
569
570     case Dali::Property::VECTOR2:
571     {
572       const KeyFrameVector2* kf;
573       GetSpecialization(keyFrames, kf);
574       KeyFrameVector2Ptr kfCopy = KeyFrameVector2::Clone(*kf);
575       AddAnimatorConnector( AnimatorConnector<Vector2>::New( proxy,
576                                                              target.propertyIndex,
577                                                              target.componentIndex,
578                                                              KeyFrameVector2Functor(kfCopy),
579                                                              alpha,
580                                                              period ) );
581       break;
582     }
583
584     case Dali::Property::VECTOR3:
585     {
586       const KeyFrameVector3* kf;
587       GetSpecialization(keyFrames, kf);
588       KeyFrameVector3Ptr kfCopy = KeyFrameVector3::Clone(*kf);
589       AddAnimatorConnector( AnimatorConnector<Vector3>::New( proxy,
590                                                              target.propertyIndex,
591                                                              target.componentIndex,
592                                                              KeyFrameVector3Functor(kfCopy),
593                                                              alpha,
594                                                              period ) );
595       break;
596     }
597
598     case Dali::Property::VECTOR4:
599     {
600       const KeyFrameVector4* kf;
601       GetSpecialization(keyFrames, kf);
602       KeyFrameVector4Ptr kfCopy = KeyFrameVector4::Clone(*kf);
603       AddAnimatorConnector( AnimatorConnector<Vector4>::New( proxy,
604                                                              target.propertyIndex,
605                                                              target.componentIndex,
606                                                              KeyFrameVector4Functor(kfCopy),
607                                                              alpha,
608                                                              period ) );
609       break;
610     }
611
612     case Dali::Property::ROTATION:
613     {
614       const KeyFrameQuaternion* kf;
615       GetSpecialization(keyFrames, kf);
616       KeyFrameQuaternionPtr kfCopy = KeyFrameQuaternion::Clone(*kf);
617       AddAnimatorConnector( AnimatorConnector<Quaternion>::New( proxy,
618                                                                 target.propertyIndex,
619                                                                 target.componentIndex,
620                                                                 KeyFrameQuaternionFunctor(kfCopy),
621                                                                 alpha,
622                                                                 period ) );
623       break;
624     }
625
626     default: // not all property types are animateable
627       break;
628   }
629 }
630
631 bool Animation::HasFinished()
632 {
633   bool hasFinished(false);
634   const int playCount(mAnimation->GetPlayCount());
635
636   // If the play count has been incremented, then another notification is required
637   if (playCount > mNotificationCount)
638   {
639     // Note that only one signal is emitted, if the animation has been played repeatedly
640     mNotificationCount = playCount;
641
642     hasFinished = true;
643   }
644
645   return hasFinished;
646 }
647
648 Dali::Animation::AnimationSignalV2& Animation::FinishedSignal()
649 {
650   return mFinishedSignal;
651 }
652
653 void Animation::EmitSignalFinish()
654 {
655   if ( !mFinishedSignal.Empty() )
656   {
657     Dali::Animation handle( this );
658     mFinishedSignal.Emit( handle );
659   }
660
661   // This callback is used internally, to avoid the overhead of using a signal.
662   if ( mFinishedCallback )
663   {
664     mFinishedCallback( mFinishedCallbackObject );
665   }
666 }
667
668 bool Animation::DoConnectSignal( BaseObject* object, ConnectionTrackerInterface* tracker, const std::string& signalName, FunctorDelegate* functor )
669 {
670   bool connected( true );
671   Animation* animation = dynamic_cast<Animation*>(object);
672
673   if ( Dali::Animation::SIGNAL_FINISHED == signalName )
674   {
675     animation->FinishedSignal().Connect( tracker, functor );
676   }
677   else
678   {
679     // signalName does not match any signal
680     connected = false;
681   }
682
683   return connected;
684 }
685
686 void Animation::SetFinishedCallback( FinishedCallback callback, Object* object )
687 {
688   mFinishedCallback = callback;
689   mFinishedCallbackObject = object;
690 }
691
692 void Animation::AddAnimatorConnector( AnimatorConnectorBase* connector )
693 {
694   DALI_ASSERT_DEBUG( NULL != connector );
695
696   connector->SetParent(*this);
697
698   mConnectors.PushBack( connector );
699 }
700
701 void Animation::MoveBy(Actor& actor, float x, float y, float z)
702 {
703   MoveBy(actor, Vector3(x, y, z), mDefaultAlpha, 0.0f, GetDuration());
704 }
705
706 void Animation::MoveBy(Actor& actor, const Vector3& displacement, AlphaFunction alpha)
707 {
708   MoveBy(actor, displacement, alpha, 0.0f, GetDuration());
709 }
710
711 void Animation::MoveBy(Actor& actor, const Vector3& displacement, AlphaFunction alpha, float delaySeconds, float durationSeconds)
712 {
713   ExtendDuration( TimePeriod(delaySeconds, durationSeconds) );
714
715   AddAnimatorConnector( AnimatorConnector<Vector3>::New( actor,
716                                                          Dali::Actor::POSITION,
717                                                          Property::INVALID_COMPONENT_INDEX,
718                                                          AnimateByVector3(displacement),
719                                                          alpha,
720                                                          TimePeriod(delaySeconds, durationSeconds) ) );
721 }
722
723 void Animation::MoveTo(Actor& actor, float x, float y, float z)
724 {
725   MoveTo(actor, Vector3(x, y, z), mDefaultAlpha, 0.0f, GetDuration());
726 }
727
728 void Animation::MoveTo(Actor& actor, const Vector3& position, AlphaFunction alpha)
729 {
730   MoveTo(actor, position, alpha, 0.0f, GetDuration());
731 }
732
733 void Animation::MoveTo(Actor& actor, const Vector3& position, AlphaFunction alpha,  float delaySeconds, float durationSeconds)
734 {
735   ExtendDuration( TimePeriod(delaySeconds, durationSeconds) );
736
737   AddAnimatorConnector( AnimatorConnector<Vector3>::New( actor,
738                                                          Dali::Actor::POSITION,
739                                                          Property::INVALID_COMPONENT_INDEX,
740                                                          AnimateToVector3(position),
741                                                          alpha,
742                                                          TimePeriod(delaySeconds, durationSeconds) ) );
743 }
744
745 void Animation::RotateBy(Actor& actor, Radian angle, const Vector3& axis)
746 {
747   RotateBy(actor, angle, axis, mDefaultAlpha, 0.0f, GetDuration());
748 }
749
750 void Animation::RotateBy(Actor& actor, Radian angle, const Vector3& axis, AlphaFunction alpha)
751 {
752   RotateBy(actor, angle, axis, alpha, 0.0f, GetDuration());
753 }
754
755 void Animation::RotateBy(Actor& actor, Radian angle, const Vector3& axis, AlphaFunction alpha, float delaySeconds, float durationSeconds)
756 {
757   ExtendDuration( TimePeriod(delaySeconds, durationSeconds) );
758
759   AddAnimatorConnector( AnimatorConnector<Quaternion>::New( actor,
760                                                             Dali::Actor::ROTATION,
761                                                             Property::INVALID_COMPONENT_INDEX,
762                                                             RotateByAngleAxis(angle, axis),
763                                                             alpha,
764                                                             TimePeriod(delaySeconds, durationSeconds) ) );
765 }
766
767 void Animation::RotateTo(Actor& actor, Radian angle, const Vector3& axis)
768 {
769   Vector4 normalizedAxis(axis.x, axis.y, axis.z, 0.0f);
770   normalizedAxis.Normalize();
771
772   Quaternion orientation(Quaternion::FromAxisAngle(normalizedAxis, angle));
773
774   RotateTo(actor, orientation, mDefaultAlpha, 0.0f, GetDuration());
775 }
776
777 void Animation::RotateTo(Actor& actor, const Quaternion& orientation)
778 {
779   RotateTo(actor, orientation, mDefaultAlpha, 0.0f, GetDuration());
780 }
781
782 void Animation::RotateTo(Actor& actor, Radian angle, const Vector3& axis, AlphaFunction alpha)
783 {
784   Vector4 normalizedAxis(axis.x, axis.y, axis.z, 0.0f);
785   normalizedAxis.Normalize();
786
787   Quaternion orientation(Quaternion::FromAxisAngle(normalizedAxis, angle));
788
789   RotateTo(actor, orientation, alpha, 0.0f, GetDuration());
790 }
791
792 void Animation::RotateTo(Actor& actor, const Quaternion& orientation, AlphaFunction alpha)
793 {
794   RotateTo(actor, orientation, alpha, 0.0f, GetDuration());
795 }
796
797 void Animation::RotateTo(Actor& actor, Radian angle, const Vector3& axis, AlphaFunction alpha, float delaySeconds, float durationSeconds)
798 {
799   Vector4 normalizedAxis(axis.x, axis.y, axis.z, 0.0f);
800   normalizedAxis.Normalize();
801
802   Quaternion orientation(Quaternion::FromAxisAngle(normalizedAxis, angle));
803
804   RotateTo(actor, orientation, alpha, delaySeconds, durationSeconds);
805 }
806
807 void Animation::RotateTo(Actor& actor, const Quaternion& rotation, AlphaFunction alpha, float delaySeconds, float durationSeconds)
808 {
809   ExtendDuration( TimePeriod(delaySeconds, durationSeconds) );
810
811   AddAnimatorConnector( AnimatorConnector<Quaternion>::New( actor,
812                                                             Dali::Actor::ROTATION,
813                                                             Property::INVALID_COMPONENT_INDEX,
814                                                             RotateToQuaternion(rotation),
815                                                             alpha,
816                                                             TimePeriod(delaySeconds, durationSeconds) ) );
817 }
818
819 void Animation::ScaleBy(Actor& actor, float x, float y, float z)
820 {
821   ScaleBy(actor, Vector3(x, y, z), mDefaultAlpha, 0.0f, GetDuration());
822 }
823
824 void Animation::ScaleBy(Actor& actor, const Vector3& scale, AlphaFunction alpha)
825 {
826   ScaleBy(actor, scale, alpha, 0.0f, GetDuration());
827 }
828
829 void Animation::ScaleBy(Actor& actor, const Vector3& scale, AlphaFunction alpha, float delaySeconds, float durationSeconds)
830 {
831   ExtendDuration( TimePeriod(delaySeconds, durationSeconds) );
832
833   AddAnimatorConnector( AnimatorConnector<Vector3>::New( actor,
834                                                          Dali::Actor::SCALE,
835                                                          Property::INVALID_COMPONENT_INDEX,
836                                                          AnimateByVector3(scale),
837                                                          alpha,
838                                                          TimePeriod(delaySeconds, durationSeconds) ) );
839 }
840
841 void Animation::ScaleTo(Actor& actor, float x, float y, float z)
842 {
843   ScaleTo(actor, Vector3(x, y, z), mDefaultAlpha, 0.0f, GetDuration());
844 }
845
846 void Animation::ScaleTo(Actor& actor, const Vector3& scale, AlphaFunction alpha)
847 {
848   ScaleTo(actor, scale, alpha, 0.0f, GetDuration());
849 }
850
851 void Animation::ScaleTo(Actor& actor, const Vector3& scale, AlphaFunction alpha, float delaySeconds, float durationSeconds)
852 {
853   ExtendDuration( TimePeriod(delaySeconds, durationSeconds) );
854
855   AddAnimatorConnector( AnimatorConnector<Vector3>::New( actor,
856                                                          Dali::Actor::SCALE,
857                                                          Property::INVALID_COMPONENT_INDEX,
858                                                          AnimateToVector3(scale),
859                                                          alpha,
860                                                          TimePeriod(delaySeconds, durationSeconds) ) );
861 }
862
863 void Animation::Show(Actor& actor, float delaySeconds)
864 {
865   ExtendDuration( TimePeriod(delaySeconds, 0) );
866
867   AddAnimatorConnector( AnimatorConnector<bool>::New( actor,
868                                                       Dali::Actor::VISIBLE,
869                                                       Property::INVALID_COMPONENT_INDEX,
870                                                       AnimateToBoolean(SHOW_VALUE),
871                                                       AlphaFunctions::Default,
872                                                       TimePeriod(delaySeconds, 0.0f/*immediate*/) ) );
873 }
874
875 void Animation::Hide(Actor& actor, float delaySeconds)
876 {
877   ExtendDuration( TimePeriod(delaySeconds, 0) );
878
879   AddAnimatorConnector( AnimatorConnector<bool>::New( actor,
880                                                       Dali::Actor::VISIBLE,
881                                                       Property::INVALID_COMPONENT_INDEX,
882                                                       AnimateToBoolean(HIDE_VALUE),
883                                                       AlphaFunctions::Default,
884                                                       TimePeriod(delaySeconds, 0.0f/*immediate*/) ) );
885 }
886
887 void Animation::OpacityBy(Actor& actor, float opacity)
888 {
889   OpacityBy(actor, opacity, mDefaultAlpha, 0.0f, GetDuration());
890 }
891
892 void Animation::OpacityBy(Actor& actor, float opacity, AlphaFunction alpha)
893 {
894   OpacityBy(actor, opacity, alpha, 0.0f, GetDuration());
895 }
896
897 void Animation::OpacityBy(Actor& actor, float opacity, AlphaFunction alpha, float delaySeconds, float durationSeconds)
898 {
899   ExtendDuration( TimePeriod(delaySeconds, durationSeconds) );
900
901   AddAnimatorConnector( AnimatorConnector<Vector4>::New( actor,
902                                                          Dali::Actor::COLOR,
903                                                          Property::INVALID_COMPONENT_INDEX,
904                                                          AnimateByOpacity(opacity),
905                                                          alpha,
906                                                          TimePeriod(delaySeconds, durationSeconds) ) );
907 }
908
909 void Animation::OpacityTo(Actor& actor, float opacity)
910 {
911   OpacityTo(actor, opacity, mDefaultAlpha, 0.0f, GetDuration());
912 }
913
914 void Animation::OpacityTo(Actor& actor, float opacity, AlphaFunction alpha)
915 {
916   OpacityTo(actor, opacity, alpha, 0.0f, GetDuration());
917 }
918
919 void Animation::OpacityTo(Actor& actor, float opacity, AlphaFunction alpha, float delaySeconds, float durationSeconds)
920 {
921   ExtendDuration( TimePeriod(delaySeconds, durationSeconds) );
922
923   AddAnimatorConnector( AnimatorConnector<Vector4>::New( actor,
924                                                          Dali::Actor::COLOR,
925                                                          Property::INVALID_COMPONENT_INDEX,
926                                                          AnimateToOpacity(opacity),
927                                                          alpha,
928                                                          TimePeriod(delaySeconds, durationSeconds) ) );
929 }
930
931 void Animation::ColorBy(Actor& actor, const Vector4& color)
932 {
933   ColorBy(actor, color, mDefaultAlpha, 0.0f, GetDuration());
934 }
935
936 void Animation::ColorBy(Actor& actor, const Vector4& color, AlphaFunction alpha)
937 {
938   ColorBy(actor, color, alpha, 0.0f, GetDuration());
939 }
940
941 void Animation::ColorBy(Actor& actor, const Vector4& color, AlphaFunction alpha, float delaySeconds, float durationSeconds)
942 {
943   ExtendDuration( TimePeriod(delaySeconds, durationSeconds) );
944
945   AddAnimatorConnector( AnimatorConnector<Vector4>::New( actor,
946                                                          Dali::Actor::COLOR,
947                                                          Property::INVALID_COMPONENT_INDEX,
948                                                          AnimateByVector4(color),
949                                                          alpha,
950                                                          TimePeriod(delaySeconds, durationSeconds) ) );
951 }
952
953 void Animation::ColorTo(Actor& actor, const Vector4& color)
954 {
955   ColorTo(actor, color, mDefaultAlpha, 0.0f, GetDuration());
956 }
957
958 void Animation::ColorTo(Actor& actor, const Vector4& color, AlphaFunction alpha)
959 {
960   ColorTo(actor, color, alpha, 0.0f, GetDuration());
961 }
962
963 void Animation::ColorTo(Actor& actor, const Vector4& color, AlphaFunction alpha, float delaySeconds, float durationSeconds)
964 {
965   ExtendDuration( TimePeriod(delaySeconds, durationSeconds) );
966
967   AddAnimatorConnector( AnimatorConnector<Vector4>::New( actor,
968                                                          Dali::Actor::COLOR,
969                                                          Property::INVALID_COMPONENT_INDEX,
970                                                          AnimateToVector4(color),
971                                                          alpha,
972                                                          TimePeriod(delaySeconds, durationSeconds) ) );
973 }
974
975 void Animation::Resize(Actor& actor, float width, float height)
976 {
977   Resize(actor, width, height, mDefaultAlpha, 0.0f, GetDuration());
978 }
979
980 void Animation::Resize(Actor& actor, float width, float height, AlphaFunction alpha)
981 {
982   Resize(actor, width, height, alpha, 0.0f, GetDuration());
983 }
984
985 void Animation::Resize(Actor& actor, float width, float height, AlphaFunction alpha, float delaySeconds, float durationSeconds)
986 {
987   Vector3 targetSize( width, height, std::min(width, height) );
988
989   ExtendDuration( TimePeriod(delaySeconds, durationSeconds) );
990
991   // Notify the actor impl that its size is being animated
992   actor.NotifySizeAnimation( *this, targetSize );
993
994   AddAnimatorConnector( AnimatorConnector<Vector3>::New( actor,
995                                                          Dali::Actor::SIZE,
996                                                          Property::INVALID_COMPONENT_INDEX,
997                                                          AnimateToVector3(targetSize),
998                                                          alpha,
999                                                          TimePeriod(delaySeconds, durationSeconds) ) );
1000 }
1001
1002 void Animation::Resize(Actor& actor, const Vector3& size)
1003 {
1004   Resize(actor, size, mDefaultAlpha, 0.0f, GetDuration());
1005 }
1006
1007 void Animation::Resize(Actor& actor, const Vector3& size, AlphaFunction alpha)
1008 {
1009   Resize(actor, size, alpha, 0.0f, GetDuration());
1010 }
1011
1012 void Animation::Resize(Actor& actor, const Vector3& size, AlphaFunction alpha, float delaySeconds, float durationSeconds)
1013 {
1014   ExtendDuration( TimePeriod(delaySeconds, durationSeconds) );
1015
1016   // Notify the actor impl that its size is being animated
1017   actor.NotifySizeAnimation( *this, size );
1018
1019   AddAnimatorConnector( AnimatorConnector<Vector3>::New( actor,
1020                                                          Dali::Actor::SIZE,
1021                                                          Property::INVALID_COMPONENT_INDEX,
1022                                                          AnimateToVector3(size),
1023                                                          alpha,
1024                                                          TimePeriod(delaySeconds, durationSeconds) ) );
1025 }
1026
1027 bool Animation::DoAction(BaseObject* object, const std::string& actionName, const std::vector<Property::Value>& attributes)
1028 {
1029   bool done = false;
1030   Animation* animation = dynamic_cast<Animation*>(object);
1031
1032   if( animation )
1033   {
1034     if(Dali::Animation::ACTION_PLAY == actionName)
1035     {
1036       if(attributes.size() > 0)
1037       {
1038         animation->SetDuration(attributes[0].Get<float>());
1039       }
1040
1041       animation->Play();
1042       done = true;
1043     }
1044     else if(Dali::Animation::ACTION_STOP == actionName)
1045     {
1046       animation->Stop();
1047       done = true;
1048     }
1049     else if(Dali::Animation::ACTION_PAUSE == actionName)
1050     {
1051       animation->Pause();
1052       done = true;
1053     }
1054   }
1055
1056   return done;
1057 }
1058
1059 void Animation::SetCurrentProgress(float progress)
1060 {
1061   if( mAnimation && progress >= mPlayRange.x && progress <= mPlayRange.y )
1062   {
1063     // mAnimation is being used in a separate thread; queue a message to set the current progress
1064     SetCurrentProgressMessage( mUpdateManager.GetEventToUpdate(), *mAnimation, progress );
1065   }
1066 }
1067
1068 float Animation::GetCurrentProgress()
1069 {
1070   if( mAnimation )
1071   {
1072     return mAnimation->GetCurrentProgress();
1073   }
1074
1075   return 0.0f;
1076 }
1077
1078 void Animation::ExtendDuration( const TimePeriod& timePeriod )
1079 {
1080   float duration = timePeriod.delaySeconds + timePeriod.durationSeconds;
1081
1082   if( duration > mDurationSeconds )
1083   {
1084     SetDuration( duration );
1085   }
1086 }
1087
1088 void Animation::SetSpeedFactor( float factor )
1089 {
1090   if( mAnimation )
1091   {
1092     mSpeedFactor = factor;
1093     SetSpeedFactorMessage( mUpdateManager.GetEventToUpdate(), *mAnimation, factor );
1094   }
1095 }
1096
1097 float Animation::GetSpeedFactor() const
1098 {
1099   return mSpeedFactor;
1100 }
1101
1102 void Animation::SetPlayRange( const Vector2& range)
1103 {
1104   //Make sure the range specified is between 0.0 and 1.0
1105   if( range.x >= 0.0f && range.x <= 1.0f && range.y >= 0.0f && range.y <= 1.0f )
1106   {
1107     Vector2 orderedRange( range );
1108     //If the range is not in order swap values
1109     if( range.x > range.y )
1110     {
1111       orderedRange = Vector2(range.y, range.x);
1112     }
1113
1114     // Cache for public getters
1115     mPlayRange = orderedRange;
1116
1117     // mAnimation is being used in a separate thread; queue a message to set play range
1118     SetPlayRangeMessage( mUpdateManager.GetEventToUpdate(), *mAnimation, orderedRange );
1119   }
1120 }
1121
1122 Vector2 Animation::GetPlayRange() const
1123 {
1124   return mPlayRange;
1125 }
1126
1127
1128 } // namespace Internal
1129
1130 } // namespace Dali