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>
37 using Dali::Internal::SceneGraph::UpdateManager;
38 using Dali::Internal::SceneGraph::AnimatorBase;
39 using Dali::Internal::SceneGraph::Shader;
47 static bool SHOW_VALUE = true;
48 static bool HIDE_VALUE = false;
55 return Dali::Animation::New(0.f);
58 TypeRegistration mType( typeid(Dali::Animation), typeid(Dali::BaseHandle), Create );
60 SignalConnectorType signalConnector1( mType, Dali::Animation::SIGNAL_FINISHED, &Animation::DoConnectSignal );
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 );
66 const Dali::Animation::EndAction DEFAULT_END_ACTION( Dali::Animation::Bake );
67 const Dali::Animation::EndAction DEFAULT_DISCONNECT_ACTION( Dali::Animation::BakeFinal );
72 AnimationPtr Animation::New(float durationSeconds)
74 ThreadLocalStorage& tls = ThreadLocalStorage::Get();
75 UpdateManager& updateManager = tls.GetUpdateManager();
77 AnimationPlaylist& playlist = Stage::GetCurrent()->GetAnimationPlaylist();
79 AnimationPtr animation = new Animation( updateManager, playlist, durationSeconds, DEFAULT_END_ACTION, DEFAULT_DISCONNECT_ACTION, Dali::AlphaFunctions::Linear );
81 // Second-phase construction
82 animation->Initialize();
87 Animation::Animation( UpdateManager& updateManager, AnimationPlaylist& playlist, float durationSeconds, EndAction endAction, EndAction disconnectAction, AlphaFunction defaultAlpha )
88 : mUpdateManager( updateManager ),
89 mPlaylist( playlist ),
91 mNotificationCount( 0 ),
92 mFinishedCallback( NULL ),
93 mFinishedCallbackObject( NULL ),
94 mDurationSeconds( durationSeconds ),
97 mPlayRange( Vector2(0.0f,1.0f)),
98 mEndAction( endAction ),
99 mDisconnectAction( disconnectAction ),
100 mDefaultAlpha( defaultAlpha )
104 void Animation::Initialize()
106 // Connect to the animation playlist
107 mPlaylist.AnimationCreated( *this );
114 Animation::~Animation()
116 // Guard to allow handle destruction after Core has been destroyed
117 if ( Stage::IsInstalled() )
119 // Disconnect from the animation playlist
120 mPlaylist.AnimationDestroyed( *this );
122 DestroySceneObject();
128 void Animation::CreateSceneObject()
130 DALI_ASSERT_DEBUG( mAnimation == NULL );
132 // Create a new animation, temporarily owned
133 SceneGraph::Animation* animation = SceneGraph::Animation::New( mDurationSeconds, mSpeedFactor, mPlayRange, mIsLooping, mEndAction, mDisconnectAction );
135 // Keep a const pointer to the animation.
136 mAnimation = animation;
138 // Transfer animation ownership to the update manager through a message
139 AddAnimationMessage( mUpdateManager, animation );
142 void Animation::DestroySceneObject()
144 if ( mAnimation != NULL )
146 // Remove animation using a message to the update manager
147 RemoveAnimationMessage( mUpdateManager, *mAnimation );
152 void Animation::SetDuration(float seconds)
154 // Cache for public getters
155 mDurationSeconds = seconds;
157 // mAnimation is being used in a separate thread; queue a message to set the value
158 SetDurationMessage( mUpdateManager.GetEventToUpdate(), *mAnimation, seconds );
161 float Animation::GetDuration() const
163 // This is not animatable; the cached value is up-to-date.
164 return mDurationSeconds;
167 void Animation::SetLooping(bool looping)
169 // Cache for public getters
170 mIsLooping = looping;
172 // mAnimation is being used in a separate thread; queue a message to set the value
173 SetLoopingMessage( mUpdateManager.GetEventToUpdate(), *mAnimation, looping );
176 bool Animation::IsLooping() const
178 // This is not animatable; the cached value is up-to-date.
182 void Animation::SetEndAction(EndAction action)
184 // Cache for public getters
187 // mAnimation is being used in a separate thread; queue a message to set the value
188 SetEndActionMessage( mUpdateManager.GetEventToUpdate(), *mAnimation, action );
191 Dali::Animation::EndAction Animation::GetEndAction() const
193 // This is not animatable; the cached value is up-to-date.
197 void Animation::SetDisconnectAction(EndAction action)
199 // Cache for public getters
200 mDisconnectAction = action;
202 // mAnimation is being used in a separate thread; queue a message to set the value
203 SetDisconnectActionMessage( mUpdateManager.GetEventToUpdate(), *mAnimation, action );
206 Dali::Animation::EndAction Animation::GetDisconnectAction() const
208 // This is not animatable; the cached value is up-to-date.
209 return mDisconnectAction;
212 void Animation::Play()
214 // Update the current playlist
215 mPlaylist.OnPlay( *this );
217 // mAnimation is being used in a separate thread; queue a Play message
218 PlayAnimationMessage( mUpdateManager.GetEventToUpdate(), *mAnimation );
221 void Animation::PlayFrom( float progress )
223 if( progress >= mPlayRange.x && progress <= mPlayRange.y )
225 // Update the current playlist
226 mPlaylist.OnPlay( *this );
228 // mAnimation is being used in a separate thread; queue a Play message
229 PlayAnimationFromMessage( mUpdateManager.GetEventToUpdate(), *mAnimation, progress );
233 void Animation::Pause()
235 // mAnimation is being used in a separate thread; queue a Pause message
236 PauseAnimationMessage( mUpdateManager.GetEventToUpdate(), *mAnimation );
239 void Animation::Stop()
241 // mAnimation is being used in a separate thread; queue a Stop message
242 StopAnimationMessage( mUpdateManager, *mAnimation );
245 void Animation::Clear()
247 DALI_ASSERT_DEBUG(mAnimation);
249 // Remove all the connectors
252 // Replace the old scene-object with a new one
253 DestroySceneObject();
256 // Reset the notification count, since the new scene-object has never been played
257 mNotificationCount = 0;
259 // Update the current playlist
260 mPlaylist.OnClear( *this );
263 void Animation::AnimateBy(Property& target, Property::Value& relativeValue)
265 AnimateBy(target, relativeValue, AlphaFunctions::Default, mDurationSeconds);
268 void Animation::AnimateBy(Property& target, Property::Value& relativeValue, AlphaFunction alpha)
270 AnimateBy(target, relativeValue, alpha, mDurationSeconds);
273 void Animation::AnimateBy(Property& target, Property::Value& relativeValue, TimePeriod period)
275 AnimateBy(target, relativeValue, AlphaFunctions::Default, period);
278 void Animation::AnimateBy(Property& target, Property::Value& relativeValue, AlphaFunction alpha, TimePeriod period)
280 ProxyObject& proxy = dynamic_cast<ProxyObject&>( GetImplementation(target.object) );
282 ExtendDuration( period );
284 switch ( relativeValue.GetType() )
286 case Property::BOOLEAN:
288 AddAnimatorConnector( AnimatorConnector<bool>::New( proxy,
289 target.propertyIndex,
290 target.componentIndex,
291 AnimateByBoolean(relativeValue.Get<bool>()),
297 case Property::FLOAT:
299 AddAnimatorConnector( AnimatorConnector<float>::New( proxy,
300 target.propertyIndex,
301 target.componentIndex,
302 AnimateByFloat(relativeValue.Get<float>()),
308 case Property::INTEGER:
310 AddAnimatorConnector( AnimatorConnector<int>::New( proxy,
311 target.propertyIndex,
312 target.componentIndex,
313 AnimateByInteger(relativeValue.Get<int>()),
319 case Property::VECTOR2:
321 AddAnimatorConnector( AnimatorConnector<Vector2>::New( proxy,
322 target.propertyIndex,
323 target.componentIndex,
324 AnimateByVector2(relativeValue.Get<Vector2>()),
330 case Property::VECTOR3:
332 AddAnimatorConnector( AnimatorConnector<Vector3>::New( proxy,
333 target.propertyIndex,
334 target.componentIndex,
335 AnimateByVector3(relativeValue.Get<Vector3>()),
341 case Property::VECTOR4:
343 AddAnimatorConnector( AnimatorConnector<Vector4>::New( proxy,
344 target.propertyIndex,
345 target.componentIndex,
346 AnimateByVector4(relativeValue.Get<Vector4>()),
352 case Property::ROTATION:
354 AngleAxis angleAxis = relativeValue.Get<AngleAxis>();
356 AddAnimatorConnector( AnimatorConnector<Quaternion>::New( proxy,
357 target.propertyIndex,
358 target.componentIndex,
359 RotateByAngleAxis(angleAxis.angle, angleAxis.axis),
366 DALI_ASSERT_ALWAYS( false && "Property type enumeration out of bounds" ); // should never come here
371 void Animation::AnimateTo(Property& target, Property::Value& destinationValue)
373 AnimateTo(target, destinationValue, AlphaFunctions::Default, mDurationSeconds);
376 void Animation::AnimateTo(Property& target, Property::Value& destinationValue, AlphaFunction alpha)
378 AnimateTo(target, destinationValue, alpha, mDurationSeconds);
381 void Animation::AnimateTo(Property& target, Property::Value& destinationValue, TimePeriod period)
383 AnimateTo(target, destinationValue, AlphaFunctions::Default, period);
386 void Animation::AnimateTo(Property& target, Property::Value& destinationValue, AlphaFunction alpha, TimePeriod period)
388 ProxyObject& proxy = dynamic_cast<ProxyObject&>( GetImplementation(target.object) );
390 AnimateTo( proxy, target.propertyIndex, target.componentIndex, destinationValue, alpha, period );
393 void Animation::AnimateTo(ProxyObject& targetObject, Property::Index targetPropertyIndex, int componentIndex, Property::Value& destinationValue, AlphaFunction alpha, TimePeriod period)
395 Property::Type type = targetObject.GetPropertyType(targetPropertyIndex);
396 if(componentIndex != Property::INVALID_COMPONENT_INDEX)
398 if( type == Property::VECTOR2
399 || type == Property::VECTOR3
400 || type == Property::VECTOR4 )
402 type = Property::FLOAT;
405 DALI_ASSERT_ALWAYS( type == destinationValue.GetType() && "DestinationValue does not match Target Property type" );
407 ExtendDuration( period );
409 switch (destinationValue.GetType())
411 case Property::BOOLEAN:
413 AddAnimatorConnector( AnimatorConnector<bool>::New(targetObject,
416 AnimateToBoolean(destinationValue.Get<bool>()),
422 case Property::FLOAT:
424 AddAnimatorConnector( AnimatorConnector<float>::New(targetObject,
427 AnimateToFloat(destinationValue.Get<float>()),
433 case Property::INTEGER:
435 AddAnimatorConnector( AnimatorConnector<int>::New(targetObject,
438 AnimateToInteger(destinationValue.Get<int>()),
444 case Property::VECTOR2:
446 AddAnimatorConnector( AnimatorConnector<Vector2>::New(targetObject,
449 AnimateToVector2(destinationValue.Get<Vector2>()),
455 case Property::VECTOR3:
457 if ( Dali::Actor::SIZE == targetPropertyIndex )
459 // Test whether this is actually an Actor
460 Actor* maybeActor = dynamic_cast<Actor*>( &targetObject );
463 // Notify the actor that its size is being animated
464 maybeActor->NotifySizeAnimation( *this, destinationValue.Get<Vector3>() );
468 AddAnimatorConnector( AnimatorConnector<Vector3>::New(targetObject,
471 AnimateToVector3(destinationValue.Get<Vector3>()),
477 case Property::VECTOR4:
479 AddAnimatorConnector( AnimatorConnector<Vector4>::New(targetObject,
482 AnimateToVector4(destinationValue.Get<Vector4>()),
488 case Property::ROTATION:
490 AddAnimatorConnector( AnimatorConnector<Quaternion>::New(targetObject,
493 RotateToQuaternion(destinationValue.Get<Quaternion>()),
500 DALI_ASSERT_ALWAYS( false && "Property type enumeration out of bounds" ); // should never come here
505 void Animation::AnimateBetween(Property target, const KeyFrames& keyFrames)
507 AnimateBetween(target, keyFrames, mDefaultAlpha, mDurationSeconds);
510 void Animation::AnimateBetween(Property target, const KeyFrames& keyFrames, TimePeriod period)
512 AnimateBetween(target, keyFrames, mDefaultAlpha, period);
515 void Animation::AnimateBetween(Property target, const KeyFrames& keyFrames, AlphaFunction alpha)
517 AnimateBetween(target, keyFrames, alpha, mDurationSeconds);
520 void Animation::AnimateBetween(Property target, const KeyFrames& keyFrames, AlphaFunction alpha, TimePeriod period)
522 ProxyObject& proxy = dynamic_cast<ProxyObject&>( GetImplementation(target.object) );
524 ExtendDuration( period );
526 switch(keyFrames.GetType())
528 case Dali::Property::BOOLEAN:
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),
542 case Dali::Property::FLOAT:
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),
556 case Dali::Property::INTEGER:
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),
570 case Dali::Property::VECTOR2:
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),
584 case Dali::Property::VECTOR3:
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),
598 case Dali::Property::VECTOR4:
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),
612 case Dali::Property::ROTATION:
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),
626 default: // not all property types are animateable
631 bool Animation::HasFinished()
633 bool hasFinished(false);
634 const int playCount(mAnimation->GetPlayCount());
636 // If the play count has been incremented, then another notification is required
637 if (playCount > mNotificationCount)
639 // Note that only one signal is emitted, if the animation has been played repeatedly
640 mNotificationCount = playCount;
648 Dali::Animation::AnimationSignalV2& Animation::FinishedSignal()
650 return mFinishedSignal;
653 void Animation::EmitSignalFinish()
655 if ( !mFinishedSignal.Empty() )
657 Dali::Animation handle( this );
658 mFinishedSignal.Emit( handle );
661 // This callback is used internally, to avoid the overhead of using a signal.
662 if ( mFinishedCallback )
664 mFinishedCallback( mFinishedCallbackObject );
668 bool Animation::DoConnectSignal( BaseObject* object, ConnectionTrackerInterface* tracker, const std::string& signalName, FunctorDelegate* functor )
670 bool connected( true );
671 Animation* animation = dynamic_cast<Animation*>(object);
673 if ( Dali::Animation::SIGNAL_FINISHED == signalName )
675 animation->FinishedSignal().Connect( tracker, functor );
679 // signalName does not match any signal
686 void Animation::SetFinishedCallback( FinishedCallback callback, Object* object )
688 mFinishedCallback = callback;
689 mFinishedCallbackObject = object;
692 void Animation::AddAnimatorConnector( AnimatorConnectorBase* connector )
694 DALI_ASSERT_DEBUG( NULL != connector );
696 connector->SetParent(*this);
698 mConnectors.PushBack( connector );
701 void Animation::MoveBy(Actor& actor, float x, float y, float z)
703 MoveBy(actor, Vector3(x, y, z), mDefaultAlpha, 0.0f, GetDuration());
706 void Animation::MoveBy(Actor& actor, const Vector3& displacement, AlphaFunction alpha)
708 MoveBy(actor, displacement, alpha, 0.0f, GetDuration());
711 void Animation::MoveBy(Actor& actor, const Vector3& displacement, AlphaFunction alpha, float delaySeconds, float durationSeconds)
713 ExtendDuration( TimePeriod(delaySeconds, durationSeconds) );
715 AddAnimatorConnector( AnimatorConnector<Vector3>::New( actor,
716 Dali::Actor::POSITION,
717 Property::INVALID_COMPONENT_INDEX,
718 AnimateByVector3(displacement),
720 TimePeriod(delaySeconds, durationSeconds) ) );
723 void Animation::MoveTo(Actor& actor, float x, float y, float z)
725 MoveTo(actor, Vector3(x, y, z), mDefaultAlpha, 0.0f, GetDuration());
728 void Animation::MoveTo(Actor& actor, const Vector3& position, AlphaFunction alpha)
730 MoveTo(actor, position, alpha, 0.0f, GetDuration());
733 void Animation::MoveTo(Actor& actor, const Vector3& position, AlphaFunction alpha, float delaySeconds, float durationSeconds)
735 ExtendDuration( TimePeriod(delaySeconds, durationSeconds) );
737 AddAnimatorConnector( AnimatorConnector<Vector3>::New( actor,
738 Dali::Actor::POSITION,
739 Property::INVALID_COMPONENT_INDEX,
740 AnimateToVector3(position),
742 TimePeriod(delaySeconds, durationSeconds) ) );
745 void Animation::RotateBy(Actor& actor, Radian angle, const Vector3& axis)
747 RotateBy(actor, angle, axis, mDefaultAlpha, 0.0f, GetDuration());
750 void Animation::RotateBy(Actor& actor, Radian angle, const Vector3& axis, AlphaFunction alpha)
752 RotateBy(actor, angle, axis, alpha, 0.0f, GetDuration());
755 void Animation::RotateBy(Actor& actor, Radian angle, const Vector3& axis, AlphaFunction alpha, float delaySeconds, float durationSeconds)
757 ExtendDuration( TimePeriod(delaySeconds, durationSeconds) );
759 AddAnimatorConnector( AnimatorConnector<Quaternion>::New( actor,
760 Dali::Actor::ROTATION,
761 Property::INVALID_COMPONENT_INDEX,
762 RotateByAngleAxis(angle, axis),
764 TimePeriod(delaySeconds, durationSeconds) ) );
767 void Animation::RotateTo(Actor& actor, Radian angle, const Vector3& axis)
769 Vector4 normalizedAxis(axis.x, axis.y, axis.z, 0.0f);
770 normalizedAxis.Normalize();
772 Quaternion orientation(Quaternion::FromAxisAngle(normalizedAxis, angle));
774 RotateTo(actor, orientation, mDefaultAlpha, 0.0f, GetDuration());
777 void Animation::RotateTo(Actor& actor, const Quaternion& orientation)
779 RotateTo(actor, orientation, mDefaultAlpha, 0.0f, GetDuration());
782 void Animation::RotateTo(Actor& actor, Radian angle, const Vector3& axis, AlphaFunction alpha)
784 Vector4 normalizedAxis(axis.x, axis.y, axis.z, 0.0f);
785 normalizedAxis.Normalize();
787 Quaternion orientation(Quaternion::FromAxisAngle(normalizedAxis, angle));
789 RotateTo(actor, orientation, alpha, 0.0f, GetDuration());
792 void Animation::RotateTo(Actor& actor, const Quaternion& orientation, AlphaFunction alpha)
794 RotateTo(actor, orientation, alpha, 0.0f, GetDuration());
797 void Animation::RotateTo(Actor& actor, Radian angle, const Vector3& axis, AlphaFunction alpha, float delaySeconds, float durationSeconds)
799 Vector4 normalizedAxis(axis.x, axis.y, axis.z, 0.0f);
800 normalizedAxis.Normalize();
802 Quaternion orientation(Quaternion::FromAxisAngle(normalizedAxis, angle));
804 RotateTo(actor, orientation, alpha, delaySeconds, durationSeconds);
807 void Animation::RotateTo(Actor& actor, const Quaternion& rotation, AlphaFunction alpha, float delaySeconds, float durationSeconds)
809 ExtendDuration( TimePeriod(delaySeconds, durationSeconds) );
811 AddAnimatorConnector( AnimatorConnector<Quaternion>::New( actor,
812 Dali::Actor::ROTATION,
813 Property::INVALID_COMPONENT_INDEX,
814 RotateToQuaternion(rotation),
816 TimePeriod(delaySeconds, durationSeconds) ) );
819 void Animation::ScaleBy(Actor& actor, float x, float y, float z)
821 ScaleBy(actor, Vector3(x, y, z), mDefaultAlpha, 0.0f, GetDuration());
824 void Animation::ScaleBy(Actor& actor, const Vector3& scale, AlphaFunction alpha)
826 ScaleBy(actor, scale, alpha, 0.0f, GetDuration());
829 void Animation::ScaleBy(Actor& actor, const Vector3& scale, AlphaFunction alpha, float delaySeconds, float durationSeconds)
831 ExtendDuration( TimePeriod(delaySeconds, durationSeconds) );
833 AddAnimatorConnector( AnimatorConnector<Vector3>::New( actor,
835 Property::INVALID_COMPONENT_INDEX,
836 AnimateByVector3(scale),
838 TimePeriod(delaySeconds, durationSeconds) ) );
841 void Animation::ScaleTo(Actor& actor, float x, float y, float z)
843 ScaleTo(actor, Vector3(x, y, z), mDefaultAlpha, 0.0f, GetDuration());
846 void Animation::ScaleTo(Actor& actor, const Vector3& scale, AlphaFunction alpha)
848 ScaleTo(actor, scale, alpha, 0.0f, GetDuration());
851 void Animation::ScaleTo(Actor& actor, const Vector3& scale, AlphaFunction alpha, float delaySeconds, float durationSeconds)
853 ExtendDuration( TimePeriod(delaySeconds, durationSeconds) );
855 AddAnimatorConnector( AnimatorConnector<Vector3>::New( actor,
857 Property::INVALID_COMPONENT_INDEX,
858 AnimateToVector3(scale),
860 TimePeriod(delaySeconds, durationSeconds) ) );
863 void Animation::Show(Actor& actor, float delaySeconds)
865 ExtendDuration( TimePeriod(delaySeconds, 0) );
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*/) ) );
875 void Animation::Hide(Actor& actor, float delaySeconds)
877 ExtendDuration( TimePeriod(delaySeconds, 0) );
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*/) ) );
887 void Animation::OpacityBy(Actor& actor, float opacity)
889 OpacityBy(actor, opacity, mDefaultAlpha, 0.0f, GetDuration());
892 void Animation::OpacityBy(Actor& actor, float opacity, AlphaFunction alpha)
894 OpacityBy(actor, opacity, alpha, 0.0f, GetDuration());
897 void Animation::OpacityBy(Actor& actor, float opacity, AlphaFunction alpha, float delaySeconds, float durationSeconds)
899 ExtendDuration( TimePeriod(delaySeconds, durationSeconds) );
901 AddAnimatorConnector( AnimatorConnector<Vector4>::New( actor,
903 Property::INVALID_COMPONENT_INDEX,
904 AnimateByOpacity(opacity),
906 TimePeriod(delaySeconds, durationSeconds) ) );
909 void Animation::OpacityTo(Actor& actor, float opacity)
911 OpacityTo(actor, opacity, mDefaultAlpha, 0.0f, GetDuration());
914 void Animation::OpacityTo(Actor& actor, float opacity, AlphaFunction alpha)
916 OpacityTo(actor, opacity, alpha, 0.0f, GetDuration());
919 void Animation::OpacityTo(Actor& actor, float opacity, AlphaFunction alpha, float delaySeconds, float durationSeconds)
921 ExtendDuration( TimePeriod(delaySeconds, durationSeconds) );
923 AddAnimatorConnector( AnimatorConnector<Vector4>::New( actor,
925 Property::INVALID_COMPONENT_INDEX,
926 AnimateToOpacity(opacity),
928 TimePeriod(delaySeconds, durationSeconds) ) );
931 void Animation::ColorBy(Actor& actor, const Vector4& color)
933 ColorBy(actor, color, mDefaultAlpha, 0.0f, GetDuration());
936 void Animation::ColorBy(Actor& actor, const Vector4& color, AlphaFunction alpha)
938 ColorBy(actor, color, alpha, 0.0f, GetDuration());
941 void Animation::ColorBy(Actor& actor, const Vector4& color, AlphaFunction alpha, float delaySeconds, float durationSeconds)
943 ExtendDuration( TimePeriod(delaySeconds, durationSeconds) );
945 AddAnimatorConnector( AnimatorConnector<Vector4>::New( actor,
947 Property::INVALID_COMPONENT_INDEX,
948 AnimateByVector4(color),
950 TimePeriod(delaySeconds, durationSeconds) ) );
953 void Animation::ColorTo(Actor& actor, const Vector4& color)
955 ColorTo(actor, color, mDefaultAlpha, 0.0f, GetDuration());
958 void Animation::ColorTo(Actor& actor, const Vector4& color, AlphaFunction alpha)
960 ColorTo(actor, color, alpha, 0.0f, GetDuration());
963 void Animation::ColorTo(Actor& actor, const Vector4& color, AlphaFunction alpha, float delaySeconds, float durationSeconds)
965 ExtendDuration( TimePeriod(delaySeconds, durationSeconds) );
967 AddAnimatorConnector( AnimatorConnector<Vector4>::New( actor,
969 Property::INVALID_COMPONENT_INDEX,
970 AnimateToVector4(color),
972 TimePeriod(delaySeconds, durationSeconds) ) );
975 void Animation::Resize(Actor& actor, float width, float height)
977 Resize(actor, width, height, mDefaultAlpha, 0.0f, GetDuration());
980 void Animation::Resize(Actor& actor, float width, float height, AlphaFunction alpha)
982 Resize(actor, width, height, alpha, 0.0f, GetDuration());
985 void Animation::Resize(Actor& actor, float width, float height, AlphaFunction alpha, float delaySeconds, float durationSeconds)
987 Vector3 targetSize( width, height, std::min(width, height) );
989 ExtendDuration( TimePeriod(delaySeconds, durationSeconds) );
991 // Notify the actor impl that its size is being animated
992 actor.NotifySizeAnimation( *this, targetSize );
994 AddAnimatorConnector( AnimatorConnector<Vector3>::New( actor,
996 Property::INVALID_COMPONENT_INDEX,
997 AnimateToVector3(targetSize),
999 TimePeriod(delaySeconds, durationSeconds) ) );
1002 void Animation::Resize(Actor& actor, const Vector3& size)
1004 Resize(actor, size, mDefaultAlpha, 0.0f, GetDuration());
1007 void Animation::Resize(Actor& actor, const Vector3& size, AlphaFunction alpha)
1009 Resize(actor, size, alpha, 0.0f, GetDuration());
1012 void Animation::Resize(Actor& actor, const Vector3& size, AlphaFunction alpha, float delaySeconds, float durationSeconds)
1014 ExtendDuration( TimePeriod(delaySeconds, durationSeconds) );
1016 // Notify the actor impl that its size is being animated
1017 actor.NotifySizeAnimation( *this, size );
1019 AddAnimatorConnector( AnimatorConnector<Vector3>::New( actor,
1021 Property::INVALID_COMPONENT_INDEX,
1022 AnimateToVector3(size),
1024 TimePeriod(delaySeconds, durationSeconds) ) );
1027 bool Animation::DoAction(BaseObject* object, const std::string& actionName, const std::vector<Property::Value>& attributes)
1030 Animation* animation = dynamic_cast<Animation*>(object);
1034 if(Dali::Animation::ACTION_PLAY == actionName)
1036 if(attributes.size() > 0)
1038 animation->SetDuration(attributes[0].Get<float>());
1044 else if(Dali::Animation::ACTION_STOP == actionName)
1049 else if(Dali::Animation::ACTION_PAUSE == actionName)
1059 void Animation::SetCurrentProgress(float progress)
1061 if( mAnimation && progress >= mPlayRange.x && progress <= mPlayRange.y )
1063 // mAnimation is being used in a separate thread; queue a message to set the current progress
1064 SetCurrentProgressMessage( mUpdateManager.GetEventToUpdate(), *mAnimation, progress );
1068 float Animation::GetCurrentProgress()
1072 return mAnimation->GetCurrentProgress();
1078 void Animation::ExtendDuration( const TimePeriod& timePeriod )
1080 float duration = timePeriod.delaySeconds + timePeriod.durationSeconds;
1082 if( duration > mDurationSeconds )
1084 SetDuration( duration );
1088 void Animation::SetSpeedFactor( float factor )
1092 mSpeedFactor = factor;
1093 SetSpeedFactorMessage( mUpdateManager.GetEventToUpdate(), *mAnimation, factor );
1097 float Animation::GetSpeedFactor() const
1099 return mSpeedFactor;
1102 void Animation::SetPlayRange( const Vector2& range)
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 )
1107 Vector2 orderedRange( range );
1108 //If the range is not in order swap values
1109 if( range.x > range.y )
1111 orderedRange = Vector2(range.y, range.x);
1114 // Cache for public getters
1115 mPlayRange = orderedRange;
1117 // mAnimation is being used in a separate thread; queue a message to set play range
1118 SetPlayRangeMessage( mUpdateManager.GetEventToUpdate(), *mAnimation, orderedRange );
1122 Vector2 Animation::GetPlayRange() const
1128 } // namespace Internal