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