2 * Copyright (c) 2014 Samsung Electronics Co., Ltd.
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
19 #include <dali/internal/event/animation/animation-impl.h>
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>
39 using Dali::Internal::SceneGraph::UpdateManager;
40 using Dali::Internal::SceneGraph::AnimatorBase;
41 using Dali::Internal::SceneGraph::Shader;
49 static bool SHOW_VALUE = true;
50 static bool HIDE_VALUE = false;
57 return Dali::Animation::New(0.f);
60 TypeRegistration mType( typeid(Dali::Animation), typeid(Dali::BaseHandle), Create );
62 SignalConnectorType signalConnector1( mType, Dali::Animation::SIGNAL_FINISHED, &Animation::DoConnectSignal );
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 );
68 const Dali::Animation::EndAction DEFAULT_END_ACTION( Dali::Animation::Bake );
69 const Dali::Animation::EndAction DEFAULT_DISCONNECT_ACTION( Dali::Animation::BakeFinal );
74 AnimationPtr Animation::New(float durationSeconds)
76 ThreadLocalStorage& tls = ThreadLocalStorage::Get();
77 UpdateManager& updateManager = tls.GetUpdateManager();
79 AnimationPlaylist& playlist = Stage::GetCurrent()->GetAnimationPlaylist();
81 AnimationPtr animation = new Animation( updateManager, playlist, durationSeconds, DEFAULT_END_ACTION, DEFAULT_DISCONNECT_ACTION, Dali::AlphaFunctions::Linear );
83 // Second-phase construction
84 animation->Initialize();
89 Animation::Animation( UpdateManager& updateManager, AnimationPlaylist& playlist, float durationSeconds, EndAction endAction, EndAction disconnectAction, AlphaFunction defaultAlpha )
90 : mUpdateManager( updateManager ),
91 mPlaylist( playlist ),
93 mNotificationCount( 0 ),
94 mFinishedCallback( NULL ),
95 mFinishedCallbackObject( NULL ),
96 mDurationSeconds( durationSeconds ),
99 mPlayRange( Vector2(0.0f,1.0f)),
100 mEndAction( endAction ),
101 mDisconnectAction( disconnectAction ),
102 mDefaultAlpha( defaultAlpha )
106 void Animation::Initialize()
108 // Connect to the animation playlist
109 mPlaylist.AnimationCreated( *this );
116 Animation::~Animation()
118 // Guard to allow handle destruction after Core has been destroyed
119 if ( Stage::IsInstalled() )
121 // Disconnect from the animation playlist
122 mPlaylist.AnimationDestroyed( *this );
124 DestroySceneObject();
130 void Animation::CreateSceneObject()
132 DALI_ASSERT_DEBUG( mAnimation == NULL );
134 // Create a new animation, temporarily owned
135 SceneGraph::Animation* animation = SceneGraph::Animation::New( mDurationSeconds, mSpeedFactor, mPlayRange, mIsLooping, mEndAction, mDisconnectAction );
137 // Keep a const pointer to the animation.
138 mAnimation = animation;
140 // Transfer animation ownership to the update manager through a message
141 AddAnimationMessage( mUpdateManager, animation );
144 void Animation::DestroySceneObject()
146 if ( mAnimation != NULL )
148 // Remove animation using a message to the update manager
149 RemoveAnimationMessage( mUpdateManager, *mAnimation );
154 void Animation::SetDuration(float seconds)
156 // Cache for public getters
157 mDurationSeconds = seconds;
159 // mAnimation is being used in a separate thread; queue a message to set the value
160 SetDurationMessage( mUpdateManager.GetEventToUpdate(), *mAnimation, seconds );
163 float Animation::GetDuration() const
165 // This is not animatable; the cached value is up-to-date.
166 return mDurationSeconds;
169 void Animation::SetLooping(bool looping)
171 // Cache for public getters
172 mIsLooping = looping;
174 // mAnimation is being used in a separate thread; queue a message to set the value
175 SetLoopingMessage( mUpdateManager.GetEventToUpdate(), *mAnimation, looping );
178 bool Animation::IsLooping() const
180 // This is not animatable; the cached value is up-to-date.
184 void Animation::SetEndAction(EndAction action)
186 // Cache for public getters
189 // mAnimation is being used in a separate thread; queue a message to set the value
190 SetEndActionMessage( mUpdateManager.GetEventToUpdate(), *mAnimation, action );
193 Dali::Animation::EndAction Animation::GetEndAction() const
195 // This is not animatable; the cached value is up-to-date.
199 void Animation::SetDisconnectAction(EndAction action)
201 // Cache for public getters
202 mDisconnectAction = action;
204 // mAnimation is being used in a separate thread; queue a message to set the value
205 SetDisconnectActionMessage( mUpdateManager.GetEventToUpdate(), *mAnimation, action );
208 Dali::Animation::EndAction Animation::GetDisconnectAction() const
210 // This is not animatable; the cached value is up-to-date.
211 return mDisconnectAction;
214 void Animation::Play()
216 // Update the current playlist
217 mPlaylist.OnPlay( *this );
219 // mAnimation is being used in a separate thread; queue a Play message
220 PlayAnimationMessage( mUpdateManager.GetEventToUpdate(), *mAnimation );
223 void Animation::PlayFrom( float progress )
225 if( progress >= mPlayRange.x && progress <= mPlayRange.y )
227 // Update the current playlist
228 mPlaylist.OnPlay( *this );
230 // mAnimation is being used in a separate thread; queue a Play message
231 PlayAnimationFromMessage( mUpdateManager.GetEventToUpdate(), *mAnimation, progress );
235 void Animation::Pause()
237 // mAnimation is being used in a separate thread; queue a Pause message
238 PauseAnimationMessage( mUpdateManager.GetEventToUpdate(), *mAnimation );
241 void Animation::Stop()
243 // mAnimation is being used in a separate thread; queue a Stop message
244 StopAnimationMessage( mUpdateManager, *mAnimation );
247 void Animation::Clear()
249 DALI_ASSERT_DEBUG(mAnimation);
251 // Remove all the connectors
254 // Replace the old scene-object with a new one
255 DestroySceneObject();
258 // Reset the notification count, since the new scene-object has never been played
259 mNotificationCount = 0;
261 // Update the current playlist
262 mPlaylist.OnClear( *this );
265 void Animation::AnimateBy(Property& target, Property::Value& relativeValue)
267 AnimateBy(target, relativeValue, AlphaFunctions::Default, mDurationSeconds);
270 void Animation::AnimateBy(Property& target, Property::Value& relativeValue, AlphaFunction alpha)
272 AnimateBy(target, relativeValue, alpha, mDurationSeconds);
275 void Animation::AnimateBy(Property& target, Property::Value& relativeValue, TimePeriod period)
277 AnimateBy(target, relativeValue, AlphaFunctions::Default, period);
280 void Animation::AnimateBy(Property& target, Property::Value& relativeValue, AlphaFunction alpha, TimePeriod period)
282 ProxyObject& proxy = dynamic_cast<ProxyObject&>( GetImplementation(target.object) );
284 ExtendDuration( period );
286 switch ( relativeValue.GetType() )
288 case Property::BOOLEAN:
290 AddAnimatorConnector( AnimatorConnector<bool>::New( proxy,
291 target.propertyIndex,
292 target.componentIndex,
293 AnimateByBoolean(relativeValue.Get<bool>()),
299 case Property::FLOAT:
301 AddAnimatorConnector( AnimatorConnector<float>::New( proxy,
302 target.propertyIndex,
303 target.componentIndex,
304 AnimateByFloat(relativeValue.Get<float>()),
310 case Property::INTEGER:
312 AddAnimatorConnector( AnimatorConnector<int>::New( proxy,
313 target.propertyIndex,
314 target.componentIndex,
315 AnimateByInteger(relativeValue.Get<int>()),
321 case Property::VECTOR2:
323 AddAnimatorConnector( AnimatorConnector<Vector2>::New( proxy,
324 target.propertyIndex,
325 target.componentIndex,
326 AnimateByVector2(relativeValue.Get<Vector2>()),
332 case Property::VECTOR3:
334 AddAnimatorConnector( AnimatorConnector<Vector3>::New( proxy,
335 target.propertyIndex,
336 target.componentIndex,
337 AnimateByVector3(relativeValue.Get<Vector3>()),
343 case Property::VECTOR4:
345 AddAnimatorConnector( AnimatorConnector<Vector4>::New( proxy,
346 target.propertyIndex,
347 target.componentIndex,
348 AnimateByVector4(relativeValue.Get<Vector4>()),
354 case Property::ROTATION:
356 AngleAxis angleAxis = relativeValue.Get<AngleAxis>();
358 AddAnimatorConnector( AnimatorConnector<Quaternion>::New( proxy,
359 target.propertyIndex,
360 target.componentIndex,
361 RotateByAngleAxis(angleAxis.angle, angleAxis.axis),
368 DALI_ASSERT_ALWAYS( false && "Property type enumeration out of bounds" ); // should never come here
373 void Animation::AnimateTo(Property& target, Property::Value& destinationValue)
375 AnimateTo(target, destinationValue, AlphaFunctions::Default, mDurationSeconds);
378 void Animation::AnimateTo(Property& target, Property::Value& destinationValue, AlphaFunction alpha)
380 AnimateTo(target, destinationValue, alpha, mDurationSeconds);
383 void Animation::AnimateTo(Property& target, Property::Value& destinationValue, TimePeriod period)
385 AnimateTo(target, destinationValue, AlphaFunctions::Default, period);
388 void Animation::AnimateTo(Property& target, Property::Value& destinationValue, AlphaFunction alpha, TimePeriod period)
390 ProxyObject& proxy = dynamic_cast<ProxyObject&>( GetImplementation(target.object) );
392 AnimateTo( proxy, target.propertyIndex, target.componentIndex, destinationValue, alpha, period );
395 void Animation::AnimateTo(ProxyObject& targetObject, Property::Index targetPropertyIndex, int componentIndex, Property::Value& destinationValue, AlphaFunction alpha, TimePeriod period)
397 Property::Type type = targetObject.GetPropertyType(targetPropertyIndex);
398 if(componentIndex != Property::INVALID_COMPONENT_INDEX)
400 if( type == Property::VECTOR2
401 || type == Property::VECTOR3
402 || type == Property::VECTOR4 )
404 type = Property::FLOAT;
407 DALI_ASSERT_ALWAYS( type == destinationValue.GetType() && "DestinationValue does not match Target Property type" );
409 ExtendDuration( period );
411 switch (destinationValue.GetType())
413 case Property::BOOLEAN:
415 AddAnimatorConnector( AnimatorConnector<bool>::New(targetObject,
418 AnimateToBoolean(destinationValue.Get<bool>()),
424 case Property::FLOAT:
426 AddAnimatorConnector( AnimatorConnector<float>::New(targetObject,
429 AnimateToFloat(destinationValue.Get<float>()),
435 case Property::INTEGER:
437 AddAnimatorConnector( AnimatorConnector<int>::New(targetObject,
440 AnimateToInteger(destinationValue.Get<int>()),
446 case Property::VECTOR2:
448 AddAnimatorConnector( AnimatorConnector<Vector2>::New(targetObject,
451 AnimateToVector2(destinationValue.Get<Vector2>()),
457 case Property::VECTOR3:
459 if ( Dali::Actor::SIZE == targetPropertyIndex )
461 // Test whether this is actually an Actor
462 Actor* maybeActor = dynamic_cast<Actor*>( &targetObject );
465 // Notify the actor that its size is being animated
466 maybeActor->NotifySizeAnimation( *this, destinationValue.Get<Vector3>() );
470 AddAnimatorConnector( AnimatorConnector<Vector3>::New(targetObject,
473 AnimateToVector3(destinationValue.Get<Vector3>()),
479 case Property::VECTOR4:
481 AddAnimatorConnector( AnimatorConnector<Vector4>::New(targetObject,
484 AnimateToVector4(destinationValue.Get<Vector4>()),
490 case Property::ROTATION:
492 AddAnimatorConnector( AnimatorConnector<Quaternion>::New(targetObject,
495 RotateToQuaternion(destinationValue.Get<Quaternion>()),
502 DALI_ASSERT_ALWAYS( false && "Property type enumeration out of bounds" ); // should never come here
507 void Animation::AnimateBetween(Property target, const KeyFrames& keyFrames)
509 AnimateBetween(target, keyFrames, mDefaultAlpha, mDurationSeconds);
512 void Animation::AnimateBetween(Property target, const KeyFrames& keyFrames, TimePeriod period)
514 AnimateBetween(target, keyFrames, mDefaultAlpha, period);
517 void Animation::AnimateBetween(Property target, const KeyFrames& keyFrames, AlphaFunction alpha)
519 AnimateBetween(target, keyFrames, alpha, mDurationSeconds);
522 void Animation::AnimateBetween(Property target, const KeyFrames& keyFrames, AlphaFunction alpha, TimePeriod period)
524 ProxyObject& proxy = dynamic_cast<ProxyObject&>( GetImplementation(target.object) );
526 ExtendDuration( period );
528 switch(keyFrames.GetType())
530 case Dali::Property::BOOLEAN:
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),
544 case Dali::Property::FLOAT:
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),
558 case Dali::Property::INTEGER:
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),
572 case Dali::Property::VECTOR2:
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),
586 case Dali::Property::VECTOR3:
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),
600 case Dali::Property::VECTOR4:
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),
614 case Dali::Property::ROTATION:
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),
628 default: // not all property types are animateable
633 bool Animation::HasFinished()
635 bool hasFinished(false);
636 const int playCount(mAnimation->GetPlayCount());
638 // If the play count has been incremented, then another notification is required
639 if (playCount > mNotificationCount)
641 // Note that only one signal is emitted, if the animation has been played repeatedly
642 mNotificationCount = playCount;
650 Dali::Animation::AnimationSignalV2& Animation::FinishedSignal()
652 return mFinishedSignal;
655 void Animation::EmitSignalFinish()
657 if ( !mFinishedSignal.Empty() )
659 Dali::Animation handle( this );
660 mFinishedSignal.Emit( handle );
663 // This callback is used internally, to avoid the overhead of using a signal.
664 if ( mFinishedCallback )
666 mFinishedCallback( mFinishedCallbackObject );
670 bool Animation::DoConnectSignal( BaseObject* object, ConnectionTrackerInterface* tracker, const std::string& signalName, FunctorDelegate* functor )
672 bool connected( true );
673 Animation* animation = dynamic_cast<Animation*>(object);
675 if ( Dali::Animation::SIGNAL_FINISHED == signalName )
677 animation->FinishedSignal().Connect( tracker, functor );
681 // signalName does not match any signal
688 void Animation::SetFinishedCallback( FinishedCallback callback, Object* object )
690 mFinishedCallback = callback;
691 mFinishedCallbackObject = object;
694 void Animation::AddAnimatorConnector( AnimatorConnectorBase* connector )
696 DALI_ASSERT_DEBUG( NULL != connector );
698 connector->SetParent(*this);
700 mConnectors.PushBack( connector );
703 void Animation::MoveBy(Actor& actor, float x, float y, float z)
705 MoveBy(actor, Vector3(x, y, z), mDefaultAlpha, 0.0f, GetDuration());
708 void Animation::MoveBy(Actor& actor, const Vector3& displacement, AlphaFunction alpha)
710 MoveBy(actor, displacement, alpha, 0.0f, GetDuration());
713 void Animation::MoveBy(Actor& actor, const Vector3& displacement, AlphaFunction alpha, float delaySeconds, float durationSeconds)
715 ExtendDuration( TimePeriod(delaySeconds, durationSeconds) );
717 AddAnimatorConnector( AnimatorConnector<Vector3>::New( actor,
718 Dali::Actor::POSITION,
719 Property::INVALID_COMPONENT_INDEX,
720 AnimateByVector3(displacement),
722 TimePeriod(delaySeconds, durationSeconds) ) );
725 void Animation::MoveTo(Actor& actor, float x, float y, float z)
727 MoveTo(actor, Vector3(x, y, z), mDefaultAlpha, 0.0f, GetDuration());
730 void Animation::MoveTo(Actor& actor, const Vector3& position, AlphaFunction alpha)
732 MoveTo(actor, position, alpha, 0.0f, GetDuration());
735 void Animation::MoveTo(Actor& actor, const Vector3& position, AlphaFunction alpha, float delaySeconds, float durationSeconds)
737 ExtendDuration( TimePeriod(delaySeconds, durationSeconds) );
739 AddAnimatorConnector( AnimatorConnector<Vector3>::New( actor,
740 Dali::Actor::POSITION,
741 Property::INVALID_COMPONENT_INDEX,
742 AnimateToVector3(position),
744 TimePeriod(delaySeconds, durationSeconds) ) );
747 void Animation::RotateBy(Actor& actor, Radian angle, const Vector3& axis)
749 RotateBy(actor, angle, axis, mDefaultAlpha, 0.0f, GetDuration());
752 void Animation::RotateBy(Actor& actor, Radian angle, const Vector3& axis, AlphaFunction alpha)
754 RotateBy(actor, angle, axis, alpha, 0.0f, GetDuration());
757 void Animation::RotateBy(Actor& actor, Radian angle, const Vector3& axis, AlphaFunction alpha, float delaySeconds, float durationSeconds)
759 ExtendDuration( TimePeriod(delaySeconds, durationSeconds) );
761 AddAnimatorConnector( AnimatorConnector<Quaternion>::New( actor,
762 Dali::Actor::ROTATION,
763 Property::INVALID_COMPONENT_INDEX,
764 RotateByAngleAxis(angle, axis),
766 TimePeriod(delaySeconds, durationSeconds) ) );
769 void Animation::RotateTo(Actor& actor, Radian angle, const Vector3& axis)
771 Vector4 normalizedAxis(axis.x, axis.y, axis.z, 0.0f);
772 normalizedAxis.Normalize();
774 Quaternion orientation(Quaternion::FromAxisAngle(normalizedAxis, angle));
776 RotateTo(actor, orientation, mDefaultAlpha, 0.0f, GetDuration());
779 void Animation::RotateTo(Actor& actor, const Quaternion& orientation)
781 RotateTo(actor, orientation, mDefaultAlpha, 0.0f, GetDuration());
784 void Animation::RotateTo(Actor& actor, Radian angle, const Vector3& axis, AlphaFunction alpha)
786 Vector4 normalizedAxis(axis.x, axis.y, axis.z, 0.0f);
787 normalizedAxis.Normalize();
789 Quaternion orientation(Quaternion::FromAxisAngle(normalizedAxis, angle));
791 RotateTo(actor, orientation, alpha, 0.0f, GetDuration());
794 void Animation::RotateTo(Actor& actor, const Quaternion& orientation, AlphaFunction alpha)
796 RotateTo(actor, orientation, alpha, 0.0f, GetDuration());
799 void Animation::RotateTo(Actor& actor, Radian angle, const Vector3& axis, AlphaFunction alpha, float delaySeconds, float durationSeconds)
801 Vector4 normalizedAxis(axis.x, axis.y, axis.z, 0.0f);
802 normalizedAxis.Normalize();
804 Quaternion orientation(Quaternion::FromAxisAngle(normalizedAxis, angle));
806 RotateTo(actor, orientation, alpha, delaySeconds, durationSeconds);
809 void Animation::RotateTo(Actor& actor, const Quaternion& rotation, AlphaFunction alpha, float delaySeconds, float durationSeconds)
811 ExtendDuration( TimePeriod(delaySeconds, durationSeconds) );
813 AddAnimatorConnector( AnimatorConnector<Quaternion>::New( actor,
814 Dali::Actor::ROTATION,
815 Property::INVALID_COMPONENT_INDEX,
816 RotateToQuaternion(rotation),
818 TimePeriod(delaySeconds, durationSeconds) ) );
821 void Animation::ScaleBy(Actor& actor, float x, float y, float z)
823 ScaleBy(actor, Vector3(x, y, z), mDefaultAlpha, 0.0f, GetDuration());
826 void Animation::ScaleBy(Actor& actor, const Vector3& scale, AlphaFunction alpha)
828 ScaleBy(actor, scale, alpha, 0.0f, GetDuration());
831 void Animation::ScaleBy(Actor& actor, const Vector3& scale, AlphaFunction alpha, float delaySeconds, float durationSeconds)
833 ExtendDuration( TimePeriod(delaySeconds, durationSeconds) );
835 AddAnimatorConnector( AnimatorConnector<Vector3>::New( actor,
837 Property::INVALID_COMPONENT_INDEX,
838 AnimateByVector3(scale),
840 TimePeriod(delaySeconds, durationSeconds) ) );
843 void Animation::ScaleTo(Actor& actor, float x, float y, float z)
845 ScaleTo(actor, Vector3(x, y, z), mDefaultAlpha, 0.0f, GetDuration());
848 void Animation::ScaleTo(Actor& actor, const Vector3& scale, AlphaFunction alpha)
850 ScaleTo(actor, scale, alpha, 0.0f, GetDuration());
853 void Animation::ScaleTo(Actor& actor, const Vector3& scale, AlphaFunction alpha, float delaySeconds, float durationSeconds)
855 ExtendDuration( TimePeriod(delaySeconds, durationSeconds) );
857 AddAnimatorConnector( AnimatorConnector<Vector3>::New( actor,
859 Property::INVALID_COMPONENT_INDEX,
860 AnimateToVector3(scale),
862 TimePeriod(delaySeconds, durationSeconds) ) );
865 void Animation::Show(Actor& actor, float delaySeconds)
867 ExtendDuration( TimePeriod(delaySeconds, 0) );
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*/) ) );
877 void Animation::Hide(Actor& actor, float delaySeconds)
879 ExtendDuration( TimePeriod(delaySeconds, 0) );
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*/) ) );
889 void Animation::OpacityBy(Actor& actor, float opacity)
891 OpacityBy(actor, opacity, mDefaultAlpha, 0.0f, GetDuration());
894 void Animation::OpacityBy(Actor& actor, float opacity, AlphaFunction alpha)
896 OpacityBy(actor, opacity, alpha, 0.0f, GetDuration());
899 void Animation::OpacityBy(Actor& actor, float opacity, AlphaFunction alpha, float delaySeconds, float durationSeconds)
901 ExtendDuration( TimePeriod(delaySeconds, durationSeconds) );
903 AddAnimatorConnector( AnimatorConnector<Vector4>::New( actor,
905 Property::INVALID_COMPONENT_INDEX,
906 AnimateByOpacity(opacity),
908 TimePeriod(delaySeconds, durationSeconds) ) );
911 void Animation::OpacityTo(Actor& actor, float opacity)
913 OpacityTo(actor, opacity, mDefaultAlpha, 0.0f, GetDuration());
916 void Animation::OpacityTo(Actor& actor, float opacity, AlphaFunction alpha)
918 OpacityTo(actor, opacity, alpha, 0.0f, GetDuration());
921 void Animation::OpacityTo(Actor& actor, float opacity, AlphaFunction alpha, float delaySeconds, float durationSeconds)
923 ExtendDuration( TimePeriod(delaySeconds, durationSeconds) );
925 AddAnimatorConnector( AnimatorConnector<Vector4>::New( actor,
927 Property::INVALID_COMPONENT_INDEX,
928 AnimateToOpacity(opacity),
930 TimePeriod(delaySeconds, durationSeconds) ) );
933 void Animation::ColorBy(Actor& actor, const Vector4& color)
935 ColorBy(actor, color, mDefaultAlpha, 0.0f, GetDuration());
938 void Animation::ColorBy(Actor& actor, const Vector4& color, AlphaFunction alpha)
940 ColorBy(actor, color, alpha, 0.0f, GetDuration());
943 void Animation::ColorBy(Actor& actor, const Vector4& color, AlphaFunction alpha, float delaySeconds, float durationSeconds)
945 ExtendDuration( TimePeriod(delaySeconds, durationSeconds) );
947 AddAnimatorConnector( AnimatorConnector<Vector4>::New( actor,
949 Property::INVALID_COMPONENT_INDEX,
950 AnimateByVector4(color),
952 TimePeriod(delaySeconds, durationSeconds) ) );
955 void Animation::ColorTo(Actor& actor, const Vector4& color)
957 ColorTo(actor, color, mDefaultAlpha, 0.0f, GetDuration());
960 void Animation::ColorTo(Actor& actor, const Vector4& color, AlphaFunction alpha)
962 ColorTo(actor, color, alpha, 0.0f, GetDuration());
965 void Animation::ColorTo(Actor& actor, const Vector4& color, AlphaFunction alpha, float delaySeconds, float durationSeconds)
967 ExtendDuration( TimePeriod(delaySeconds, durationSeconds) );
969 AddAnimatorConnector( AnimatorConnector<Vector4>::New( actor,
971 Property::INVALID_COMPONENT_INDEX,
972 AnimateToVector4(color),
974 TimePeriod(delaySeconds, durationSeconds) ) );
977 void Animation::Resize(Actor& actor, float width, float height)
979 Resize(actor, width, height, mDefaultAlpha, 0.0f, GetDuration());
982 void Animation::Resize(Actor& actor, float width, float height, AlphaFunction alpha)
984 Resize(actor, width, height, alpha, 0.0f, GetDuration());
987 void Animation::Resize(Actor& actor, float width, float height, AlphaFunction alpha, float delaySeconds, float durationSeconds)
989 Vector3 targetSize( width, height, min(width, height) );
991 ExtendDuration( TimePeriod(delaySeconds, durationSeconds) );
993 // Notify the actor impl that its size is being animated
994 actor.NotifySizeAnimation( *this, targetSize );
996 AddAnimatorConnector( AnimatorConnector<Vector3>::New( actor,
998 Property::INVALID_COMPONENT_INDEX,
999 AnimateToVector3(targetSize),
1001 TimePeriod(delaySeconds, durationSeconds) ) );
1004 void Animation::Resize(Actor& actor, const Vector3& size)
1006 Resize(actor, size, mDefaultAlpha, 0.0f, GetDuration());
1009 void Animation::Resize(Actor& actor, const Vector3& size, AlphaFunction alpha)
1011 Resize(actor, size, alpha, 0.0f, GetDuration());
1014 void Animation::Resize(Actor& actor, const Vector3& size, AlphaFunction alpha, float delaySeconds, float durationSeconds)
1016 ExtendDuration( TimePeriod(delaySeconds, durationSeconds) );
1018 // Notify the actor impl that its size is being animated
1019 actor.NotifySizeAnimation( *this, size );
1021 AddAnimatorConnector( AnimatorConnector<Vector3>::New( actor,
1023 Property::INVALID_COMPONENT_INDEX,
1024 AnimateToVector3(size),
1026 TimePeriod(delaySeconds, durationSeconds) ) );
1029 bool Animation::DoAction(BaseObject* object, const std::string& actionName, const std::vector<Property::Value>& attributes)
1032 Animation* animation = dynamic_cast<Animation*>(object);
1036 if(Dali::Animation::ACTION_PLAY == actionName)
1038 if(attributes.size() > 0)
1040 animation->SetDuration(attributes[0].Get<float>());
1046 else if(Dali::Animation::ACTION_STOP == actionName)
1051 else if(Dali::Animation::ACTION_PAUSE == actionName)
1061 void Animation::SetCurrentProgress(float progress)
1063 if( mAnimation && progress >= mPlayRange.x && progress <= mPlayRange.y )
1065 // mAnimation is being used in a separate thread; queue a message to set the current progress
1066 SetCurrentProgressMessage( mUpdateManager.GetEventToUpdate(), *mAnimation, progress );
1070 float Animation::GetCurrentProgress()
1074 return mAnimation->GetCurrentProgress();
1080 void Animation::ExtendDuration( const TimePeriod& timePeriod )
1082 float duration = timePeriod.delaySeconds + timePeriod.durationSeconds;
1084 if( duration > mDurationSeconds )
1086 SetDuration( duration );
1090 void Animation::SetSpeedFactor( float factor )
1094 mSpeedFactor = factor;
1095 SetSpeedFactorMessage( mUpdateManager.GetEventToUpdate(), *mAnimation, factor );
1099 float Animation::GetSpeedFactor() const
1101 return mSpeedFactor;
1104 void Animation::SetPlayRange( const Vector2& range)
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 )
1109 Vector2 orderedRange( range );
1110 //If the range is not in order swap values
1111 if( range.x > range.y )
1113 orderedRange = Vector2(range.y, range.x);
1116 // Cache for public getters
1117 mPlayRange = orderedRange;
1119 // mAnimation is being used in a separate thread; queue a message to set play range
1120 SetPlayRangeMessage( mUpdateManager.GetEventToUpdate(), *mAnimation, orderedRange );
1124 Vector2 Animation::GetPlayRange() const
1130 } // namespace Internal