2 * Copyright (c) 2016 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>
20 #include <dali/public-api/object/property-map.h>
25 #include <dali/public-api/actors/actor.h>
26 #include <dali/public-api/animation/alpha-function.h>
27 #include <dali/public-api/animation/time-period.h>
28 #include <dali/public-api/common/dali-common.h>
29 #include <dali/public-api/object/type-registry.h>
30 #include <dali/public-api/math/vector2.h>
31 #include <dali/public-api/math/radian.h>
32 #include <dali/internal/event/actors/actor-impl.h>
33 #include <dali/internal/event/animation/animation-playlist.h>
34 #include <dali/internal/event/animation/animator-connector.h>
35 #include <dali/internal/event/common/notification-manager.h>
36 #include <dali/internal/event/common/property-helper.h>
37 #include <dali/internal/event/common/stage-impl.h>
38 #include <dali/internal/event/common/thread-local-storage.h>
39 #include <dali/internal/update/manager/update-manager.h>
41 using Dali::Internal::SceneGraph::UpdateManager;
42 using Dali::Internal::SceneGraph::AnimatorBase;
43 using Dali::Internal::SceneGraph::Shader;
51 static bool SHOW_VALUE = true;
52 static bool HIDE_VALUE = false;
59 const char* const SIGNAL_FINISHED = "finished";
63 const char* const ACTION_PLAY = "play";
64 const char* const ACTION_STOP = "stop";
65 const char* const ACTION_PAUSE = "pause";
69 return Dali::Animation::New(0.f);
72 TypeRegistration mType( typeid( Dali::Animation ), typeid( Dali::BaseHandle ), Create );
74 SignalConnectorType signalConnector1( mType, SIGNAL_FINISHED, &Animation::DoConnectSignal );
76 TypeAction action1( mType, ACTION_PLAY, &Animation::DoAction );
77 TypeAction action2( mType, ACTION_STOP, &Animation::DoAction );
78 TypeAction action3( mType, ACTION_PAUSE, &Animation::DoAction );
80 const Dali::Animation::EndAction DEFAULT_END_ACTION( Dali::Animation::Bake );
81 const Dali::Animation::EndAction DEFAULT_DISCONNECT_ACTION( Dali::Animation::BakeFinal );
82 const Dali::Animation::Interpolation DEFAULT_INTERPOLATION( Dali::Animation::Linear );
83 const Dali::AlphaFunction DEFAULT_ALPHA_FUNCTION( Dali::AlphaFunction::DEFAULT );
88 AnimationPtr Animation::New(float durationSeconds)
90 Stage* stage = Stage::GetCurrent();
94 AnimationPlaylist& playlist = stage->GetAnimationPlaylist();
96 if( durationSeconds < 0.0f )
98 DALI_LOG_WARNING("duration should be greater than 0.0f.\n");
99 durationSeconds = 0.0f;
102 AnimationPtr animation = new Animation( *stage, playlist, durationSeconds, DEFAULT_END_ACTION, DEFAULT_DISCONNECT_ACTION, DEFAULT_ALPHA_FUNCTION );
104 // Second-phase construction
105 animation->Initialize();
115 Animation::Animation( EventThreadServices& eventThreadServices, AnimationPlaylist& playlist, float durationSeconds, EndAction endAction, EndAction disconnectAction, AlphaFunction defaultAlpha )
116 : mEventThreadServices( eventThreadServices ),
117 mPlaylist( playlist ),
119 mNotificationCount( 0 ),
120 mFinishedCallback( NULL ),
121 mFinishedCallbackObject( NULL ),
122 mDurationSeconds( durationSeconds ),
126 mPlayRange( Vector2(0.0f,1.0f)),
127 mEndAction( endAction ),
128 mDisconnectAction( disconnectAction ),
129 mDefaultAlpha( defaultAlpha ),
130 mState(Dali::Animation::STOPPED)
134 void Animation::Initialize()
136 // Connect to the animation playlist
137 mPlaylist.AnimationCreated( *this );
144 Animation::~Animation()
146 // Guard to allow handle destruction after Core has been destroyed
147 if ( Stage::IsInstalled() )
149 // Disconnect from the animation playlist
150 mPlaylist.AnimationDestroyed( *this );
152 DestroySceneObject();
158 void Animation::CreateSceneObject()
160 DALI_ASSERT_DEBUG( mAnimation == NULL );
162 // Create a new animation, temporarily owned
163 SceneGraph::Animation* animation = SceneGraph::Animation::New( mDurationSeconds, mSpeedFactor, mPlayRange, mLoopCount, mEndAction, mDisconnectAction );
165 // Keep a const pointer to the animation.
166 mAnimation = animation;
168 // Transfer animation ownership to the update manager through a message
169 AddAnimationMessage( mEventThreadServices.GetUpdateManager(), animation );
172 void Animation::DestroySceneObject()
174 if ( mAnimation != NULL )
176 // Remove animation using a message to the update manager
177 RemoveAnimationMessage( mEventThreadServices.GetUpdateManager(), *mAnimation );
182 void Animation::SetDuration(float seconds)
186 DALI_LOG_WARNING("duration should be greater than 0.0f.\n");
190 // Cache for public getters
191 mDurationSeconds = seconds;
193 // mAnimation is being used in a separate thread; queue a message to set the value
194 SetDurationMessage( mEventThreadServices, *mAnimation, seconds );
197 float Animation::GetDuration() const
199 // This is not animatable; the cached value is up-to-date.
200 return mDurationSeconds;
203 void Animation::SetLooping(bool on)
205 SetLoopCount( on ? 0 : 1 );
208 void Animation::SetLoopCount(int count)
210 // Cache for public getters
213 // mAnimation is being used in a separate thread; queue a message to set the value
214 SetLoopingMessage( mEventThreadServices, *mAnimation, mLoopCount );
217 int Animation::GetLoopCount()
222 int Animation::GetCurrentLoop()
227 bool Animation::IsLooping() const
229 return mLoopCount != 1;
232 void Animation::SetEndAction(EndAction action)
234 // Cache for public getters
237 // mAnimation is being used in a separate thread; queue a message to set the value
238 SetEndActionMessage( mEventThreadServices, *mAnimation, action );
241 Dali::Animation::EndAction Animation::GetEndAction() const
243 // This is not animatable; the cached value is up-to-date.
247 void Animation::SetDisconnectAction(EndAction action)
249 // Cache for public getters
250 mDisconnectAction = action;
252 // mAnimation is being used in a separate thread; queue a message to set the value
253 SetDisconnectActionMessage( mEventThreadServices, *mAnimation, action );
256 Dali::Animation::EndAction Animation::GetDisconnectAction() const
258 // This is not animatable; the cached value is up-to-date.
259 return mDisconnectAction;
262 void Animation::Play()
264 // Update the current playlist
265 mPlaylist.OnPlay( *this );
267 mState = Dali::Animation::PLAYING;
269 // mAnimation is being used in a separate thread; queue a Play message
270 PlayAnimationMessage( mEventThreadServices, *mAnimation );
273 void Animation::PlayFrom( float progress )
275 if( progress >= mPlayRange.x && progress <= mPlayRange.y )
277 // Update the current playlist
278 mPlaylist.OnPlay( *this );
280 mState = Dali::Animation::PLAYING;
282 // mAnimation is being used in a separate thread; queue a Play message
283 PlayAnimationFromMessage( mEventThreadServices, *mAnimation, progress );
287 void Animation::Pause()
289 mState = Dali::Animation::PAUSED;
291 // mAnimation is being used in a separate thread; queue a Pause message
292 PauseAnimationMessage( mEventThreadServices, *mAnimation );
295 Dali::Animation::State Animation::GetState() const
300 void Animation::Stop()
302 mState = Dali::Animation::STOPPED;
304 // mAnimation is being used in a separate thread; queue a Stop message
305 StopAnimationMessage( mEventThreadServices.GetUpdateManager(), *mAnimation );
308 void Animation::Clear()
310 DALI_ASSERT_DEBUG(mAnimation);
312 // Remove all the connectors
315 // Replace the old scene-object with a new one
316 DestroySceneObject();
319 // Reset the notification count, since the new scene-object has never been played
320 mNotificationCount = 0;
322 // Update the current playlist
323 mPlaylist.OnClear( *this );
326 void Animation::AnimateBy(Property& target, Property::Value& relativeValue)
328 AnimateBy(target, relativeValue, mDefaultAlpha, TimePeriod(mDurationSeconds));
331 void Animation::AnimateBy(Property& target, Property::Value& relativeValue, AlphaFunction alpha)
333 AnimateBy(target, relativeValue, alpha, TimePeriod(mDurationSeconds));
336 void Animation::AnimateBy(Property& target, Property::Value& relativeValue, TimePeriod period)
338 AnimateBy(target, relativeValue, mDefaultAlpha, period);
341 void Animation::AnimateBy(Property& target, Property::Value& relativeValue, AlphaFunction alpha, TimePeriod period)
343 Object& object = GetImplementation( target.object );
344 const Property::Type targetType = object.GetPropertyType( target.propertyIndex );
345 const Property::Type destinationType = relativeValue.GetType();
346 DALI_ASSERT_ALWAYS( targetType == destinationType && "Animated value and Property type don't match" );
348 ExtendDuration( period );
350 switch ( targetType )
352 case Property::BOOLEAN:
354 AddAnimatorConnector( AnimatorConnector<bool>::New( object,
355 target.propertyIndex,
356 target.componentIndex,
357 new AnimateByBoolean(relativeValue.Get<bool>()),
363 case Property::INTEGER:
365 AddAnimatorConnector( AnimatorConnector<int>::New( object,
366 target.propertyIndex,
367 target.componentIndex,
368 new AnimateByInteger(relativeValue.Get<int>()),
374 case Property::FLOAT:
376 AddAnimatorConnector( AnimatorConnector<float>::New( object,
377 target.propertyIndex,
378 target.componentIndex,
379 new AnimateByFloat(relativeValue.Get<float>()),
385 case Property::VECTOR2:
387 AddAnimatorConnector( AnimatorConnector<Vector2>::New( object,
388 target.propertyIndex,
389 target.componentIndex,
390 new AnimateByVector2(relativeValue.Get<Vector2>()),
396 case Property::VECTOR3:
398 AddAnimatorConnector( AnimatorConnector<Vector3>::New( object,
399 target.propertyIndex,
400 target.componentIndex,
401 new AnimateByVector3(relativeValue.Get<Vector3>()),
407 case Property::VECTOR4:
409 AddAnimatorConnector( AnimatorConnector<Vector4>::New( object,
410 target.propertyIndex,
411 target.componentIndex,
412 new AnimateByVector4(relativeValue.Get<Vector4>()),
418 case Property::ROTATION:
420 AngleAxis angleAxis = relativeValue.Get<AngleAxis>();
422 AddAnimatorConnector( AnimatorConnector<Quaternion>::New( object,
423 target.propertyIndex,
424 target.componentIndex,
425 new RotateByAngleAxis(angleAxis.angle, angleAxis.axis),
433 // non animatable types handled already
438 void Animation::AnimateTo(Property& target, Property::Value& destinationValue)
440 AnimateTo(target, destinationValue, mDefaultAlpha, TimePeriod(mDurationSeconds));
443 void Animation::AnimateTo(Property& target, Property::Value& destinationValue, AlphaFunction alpha)
445 AnimateTo(target, destinationValue, alpha, TimePeriod(mDurationSeconds));
448 void Animation::AnimateTo(Property& target, Property::Value& destinationValue, TimePeriod period)
450 AnimateTo(target, destinationValue, mDefaultAlpha, period);
453 void Animation::AnimateTo(Property& target, Property::Value& destinationValue, AlphaFunction alpha, TimePeriod period)
455 Object& object = GetImplementation(target.object);
457 AnimateTo( object, target.propertyIndex, target.componentIndex, destinationValue, alpha, period );
460 void Animation::AnimateTo(Object& targetObject, Property::Index targetPropertyIndex, int componentIndex, Property::Value& destinationValue, AlphaFunction alpha, TimePeriod period)
462 Property::Type targetType = targetObject.GetPropertyType(targetPropertyIndex);
463 if( componentIndex != Property::INVALID_COMPONENT_INDEX )
465 if( ( targetType == Property::VECTOR2 ) ||
466 ( targetType == Property::VECTOR3 ) ||
467 ( targetType == Property::VECTOR4 ) )
469 targetType = Property::FLOAT;
472 const Property::Type destinationType = destinationValue.GetType();
473 DALI_ASSERT_ALWAYS( targetType == destinationType && "Animated value and Property type don't match" );
475 ExtendDuration( period );
477 switch ( destinationType )
479 case Property::BOOLEAN:
481 AddAnimatorConnector( AnimatorConnector<bool>::New( targetObject,
484 new AnimateToBoolean( destinationValue.Get<bool>() ),
490 case Property::INTEGER:
492 AddAnimatorConnector( AnimatorConnector<int>::New( targetObject,
495 new AnimateToInteger( destinationValue.Get<int>() ),
501 case Property::FLOAT:
503 if ( ( Dali::Actor::Property::SIZE_WIDTH == targetPropertyIndex ) ||
504 ( Dali::Actor::Property::SIZE_HEIGHT == targetPropertyIndex ) ||
505 ( Dali::Actor::Property::SIZE_DEPTH == targetPropertyIndex ) )
507 // Test whether this is actually an Actor
508 Actor* maybeActor = dynamic_cast<Actor*>( &targetObject );
511 // Notify the actor that its size is being animated
512 maybeActor->NotifySizeAnimation( *this, destinationValue.Get<float>(), targetPropertyIndex );
515 else if ( ( Dali::Actor::Property::POSITION_X == targetPropertyIndex ) ||
516 ( Dali::Actor::Property::POSITION_Y == targetPropertyIndex ) ||
517 ( Dali::Actor::Property::POSITION_Z == targetPropertyIndex ) )
519 // Test whether this is actually an Actor
520 Actor* maybeActor = dynamic_cast<Actor*>( &targetObject );
523 // Notify the actor that its position is being animated
524 maybeActor->NotifyPositionAnimation( *this, destinationValue.Get<float>(), targetPropertyIndex );
528 AddAnimatorConnector( AnimatorConnector<float>::New( targetObject,
531 new AnimateToFloat( destinationValue.Get<float>() ),
537 case Property::VECTOR2:
539 AddAnimatorConnector( AnimatorConnector<Vector2>::New( targetObject,
542 new AnimateToVector2( destinationValue.Get<Vector2>() ),
548 case Property::VECTOR3:
550 if ( Dali::Actor::Property::SIZE == targetPropertyIndex )
552 // Test whether this is actually an Actor
553 Actor* maybeActor = dynamic_cast<Actor*>( &targetObject );
556 // Notify the actor that its size is being animated
557 maybeActor->NotifySizeAnimation( *this, destinationValue.Get<Vector3>() );
560 else if ( Dali::Actor::Property::POSITION == targetPropertyIndex )
562 // Test whether this is actually an Actor
563 Actor* maybeActor = dynamic_cast<Actor*>( &targetObject );
566 // Notify the actor that its position is being animated
567 maybeActor->NotifyPositionAnimation( *this, destinationValue.Get<Vector3>() );
571 AddAnimatorConnector( AnimatorConnector<Vector3>::New( targetObject,
574 new AnimateToVector3( destinationValue.Get<Vector3>() ),
580 case Property::VECTOR4:
582 AddAnimatorConnector( AnimatorConnector<Vector4>::New( targetObject,
585 new AnimateToVector4( destinationValue.Get<Vector4>() ),
591 case Property::ROTATION:
593 AddAnimatorConnector( AnimatorConnector<Quaternion>::New( targetObject,
596 new RotateToQuaternion( destinationValue.Get<Quaternion>() ),
604 // non animatable types handled already
609 void Animation::AnimateBetween(Property target, const KeyFrames& keyFrames)
611 AnimateBetween(target, keyFrames, mDefaultAlpha, TimePeriod(mDurationSeconds), DEFAULT_INTERPOLATION );
614 void Animation::AnimateBetween(Property target, const KeyFrames& keyFrames, Interpolation interpolation )
616 AnimateBetween(target, keyFrames, mDefaultAlpha, TimePeriod(mDurationSeconds), interpolation );
619 void Animation::AnimateBetween(Property target, const KeyFrames& keyFrames, TimePeriod period)
621 AnimateBetween(target, keyFrames, mDefaultAlpha, period, DEFAULT_INTERPOLATION);
624 void Animation::AnimateBetween(Property target, const KeyFrames& keyFrames, TimePeriod period, Interpolation interpolation)
626 AnimateBetween(target, keyFrames, mDefaultAlpha, period, interpolation);
629 void Animation::AnimateBetween(Property target, const KeyFrames& keyFrames, AlphaFunction alpha)
631 AnimateBetween(target, keyFrames, alpha, TimePeriod(mDurationSeconds), DEFAULT_INTERPOLATION);
634 void Animation::AnimateBetween(Property target, const KeyFrames& keyFrames, AlphaFunction alpha, Interpolation interpolation)
636 AnimateBetween(target, keyFrames, alpha, TimePeriod(mDurationSeconds), interpolation);
639 void Animation::AnimateBetween(Property target, const KeyFrames& keyFrames, AlphaFunction alpha, TimePeriod period)
641 AnimateBetween(target, keyFrames, alpha, period, DEFAULT_INTERPOLATION);
644 void Animation::AnimateBetween(Property target, const KeyFrames& keyFrames, AlphaFunction alpha, TimePeriod period, Interpolation interpolation)
646 Object& object = GetImplementation( target.object );
648 ExtendDuration( period );
650 switch(keyFrames.GetType())
652 case Dali::Property::BOOLEAN:
654 const KeyFrameBoolean* kf;
655 GetSpecialization(keyFrames, kf);
656 KeyFrameBooleanPtr kfCopy = KeyFrameBoolean::Clone(*kf);
657 AddAnimatorConnector( AnimatorConnector<bool>::New( object,
658 target.propertyIndex,
659 target.componentIndex,
660 new KeyFrameBooleanFunctor(kfCopy),
666 case Dali::Property::INTEGER:
668 const KeyFrameInteger* kf;
669 GetSpecialization(keyFrames, kf);
670 KeyFrameIntegerPtr kfCopy = KeyFrameInteger::Clone(*kf);
671 AddAnimatorConnector( AnimatorConnector<int>::New( object,
672 target.propertyIndex,
673 target.componentIndex,
674 new KeyFrameIntegerFunctor(kfCopy,interpolation),
680 case Dali::Property::FLOAT:
682 const KeyFrameNumber* kf;
683 GetSpecialization(keyFrames, kf);
684 KeyFrameNumberPtr kfCopy = KeyFrameNumber::Clone(*kf);
685 AddAnimatorConnector( AnimatorConnector<float>::New( object,
686 target.propertyIndex,
687 target.componentIndex,
688 new KeyFrameNumberFunctor(kfCopy,interpolation),
694 case Dali::Property::VECTOR2:
696 const KeyFrameVector2* kf;
697 GetSpecialization(keyFrames, kf);
698 KeyFrameVector2Ptr kfCopy = KeyFrameVector2::Clone(*kf);
699 AddAnimatorConnector( AnimatorConnector<Vector2>::New( object,
700 target.propertyIndex,
701 target.componentIndex,
702 new KeyFrameVector2Functor(kfCopy,interpolation),
708 case Dali::Property::VECTOR3:
710 const KeyFrameVector3* kf;
711 GetSpecialization(keyFrames, kf);
712 KeyFrameVector3Ptr kfCopy = KeyFrameVector3::Clone(*kf);
713 AddAnimatorConnector( AnimatorConnector<Vector3>::New( object,
714 target.propertyIndex,
715 target.componentIndex,
716 new KeyFrameVector3Functor(kfCopy,interpolation),
722 case Dali::Property::VECTOR4:
724 const KeyFrameVector4* kf;
725 GetSpecialization(keyFrames, kf);
726 KeyFrameVector4Ptr kfCopy = KeyFrameVector4::Clone(*kf);
727 AddAnimatorConnector( AnimatorConnector<Vector4>::New( object,
728 target.propertyIndex,
729 target.componentIndex,
730 new KeyFrameVector4Functor(kfCopy,interpolation),
736 case Dali::Property::ROTATION:
738 const KeyFrameQuaternion* kf;
739 GetSpecialization(keyFrames, kf);
740 KeyFrameQuaternionPtr kfCopy = KeyFrameQuaternion::Clone(*kf);
741 AddAnimatorConnector( AnimatorConnector<Quaternion>::New( object,
742 target.propertyIndex,
743 target.componentIndex,
744 new KeyFrameQuaternionFunctor(kfCopy),
752 // non animatable types handled by keyframes
757 bool Animation::HasFinished()
759 bool hasFinished(false);
760 const int playedCount(mAnimation->GetPlayedCount());
762 // If the play count has been incremented, then another notification is required
763 mCurrentLoop = mAnimation->GetCurrentLoop();
765 if (playedCount > mNotificationCount)
767 // Note that only one signal is emitted, if the animation has been played repeatedly
768 mNotificationCount = playedCount;
772 mState = Dali::Animation::STOPPED;
778 Dali::Animation::AnimationSignalType& Animation::FinishedSignal()
780 return mFinishedSignal;
783 void Animation::EmitSignalFinish()
785 if ( !mFinishedSignal.Empty() )
787 Dali::Animation handle( this );
788 mFinishedSignal.Emit( handle );
791 // This callback is used internally, to avoid the overhead of using a signal.
792 if ( mFinishedCallback )
794 mFinishedCallback( mFinishedCallbackObject );
798 bool Animation::DoConnectSignal( BaseObject* object, ConnectionTrackerInterface* tracker, const std::string& signalName, FunctorDelegate* functor )
800 bool connected( true );
801 Animation* animation = static_cast< Animation* >(object); // TypeRegistry guarantees that this is the correct type.
803 if( 0 == signalName.compare( SIGNAL_FINISHED ) )
805 animation->FinishedSignal().Connect( tracker, functor );
809 // signalName does not match any signal
816 void Animation::SetFinishedCallback( FinishedCallback callback, Object* object )
818 mFinishedCallback = callback;
819 mFinishedCallbackObject = object;
822 void Animation::AddAnimatorConnector( AnimatorConnectorBase* connector )
824 DALI_ASSERT_DEBUG( NULL != connector );
826 connector->SetParent(*this);
828 mConnectors.PushBack( connector );
831 void Animation::Animate( Actor& actor, const Path& path, const Vector3& forward )
833 Animate( actor, path, forward, mDefaultAlpha, TimePeriod(mDurationSeconds) );
836 void Animation::Animate( Actor& actor, const Path& path, const Vector3& forward, AlphaFunction alpha )
838 Animate( actor, path, forward, alpha, TimePeriod(mDurationSeconds) );
841 void Animation::Animate( Actor& actor, const Path& path, const Vector3& forward, TimePeriod period )
843 Animate( actor, path, forward, mDefaultAlpha, period );
846 void Animation::Animate( Actor& actor, const Path& path, const Vector3& forward, AlphaFunction alpha, TimePeriod period)
848 ExtendDuration( period );
850 PathPtr pathCopy = Path::Clone(path);
853 AddAnimatorConnector( AnimatorConnector<Vector3>::New( actor,
854 Dali::Actor::Property::POSITION,
855 Property::INVALID_COMPONENT_INDEX,
856 new PathPositionFunctor( pathCopy ),
860 //If forward is zero, PathRotationFunctor will always return the unit quaternion
861 if( forward != Vector3::ZERO )
864 AddAnimatorConnector( AnimatorConnector<Quaternion>::New( actor,
865 Dali::Actor::Property::ORIENTATION,
866 Property::INVALID_COMPONENT_INDEX,
867 new PathRotationFunctor( pathCopy, forward ),
873 void Animation::Show(Actor& actor, float delaySeconds)
875 ExtendDuration( TimePeriod(delaySeconds, 0) );
877 AddAnimatorConnector( AnimatorConnector<bool>::New( actor,
878 Dali::Actor::Property::VISIBLE,
879 Property::INVALID_COMPONENT_INDEX,
880 new AnimateToBoolean(SHOW_VALUE),
882 TimePeriod(delaySeconds, 0.0f/*immediate*/) ) );
885 void Animation::Hide(Actor& actor, float delaySeconds)
887 ExtendDuration( TimePeriod(delaySeconds, 0) );
889 AddAnimatorConnector( AnimatorConnector<bool>::New( actor,
890 Dali::Actor::Property::VISIBLE,
891 Property::INVALID_COMPONENT_INDEX,
892 new AnimateToBoolean(HIDE_VALUE),
894 TimePeriod(delaySeconds, 0.0f/*immediate*/) ) );
897 bool Animation::DoAction( BaseObject* object, const std::string& actionName, const Property::Map& attributes )
900 Animation* animation = dynamic_cast<Animation*>( object );
904 if( 0 == actionName.compare( ACTION_PLAY ) )
906 if( Property::Value* value = attributes.Find("duration", Property::FLOAT) )
908 animation->SetDuration( value->Get<float>() );
914 else if( 0 == actionName.compare( ACTION_STOP ) )
919 else if( 0 == actionName.compare( ACTION_PAUSE ) )
929 void Animation::SetCurrentProgress(float progress)
931 if( mAnimation && progress >= mPlayRange.x && progress <= mPlayRange.y )
933 // mAnimation is being used in a separate thread; queue a message to set the current progress
934 SetCurrentProgressMessage( mEventThreadServices, *mAnimation, progress );
938 float Animation::GetCurrentProgress()
942 return mAnimation->GetCurrentProgress();
948 void Animation::ExtendDuration( const TimePeriod& timePeriod )
950 float duration = timePeriod.delaySeconds + timePeriod.durationSeconds;
952 if( duration > mDurationSeconds )
954 SetDuration( duration );
958 void Animation::SetSpeedFactor( float factor )
962 mSpeedFactor = factor;
963 SetSpeedFactorMessage( mEventThreadServices, *mAnimation, factor );
967 float Animation::GetSpeedFactor() const
972 void Animation::SetPlayRange( const Vector2& range)
974 //Make sure the range specified is between 0.0 and 1.0
975 if( range.x >= 0.0f && range.x <= 1.0f && range.y >= 0.0f && range.y <= 1.0f )
977 Vector2 orderedRange( range );
978 //If the range is not in order swap values
979 if( range.x > range.y )
981 orderedRange = Vector2(range.y, range.x);
984 // Cache for public getters
985 mPlayRange = orderedRange;
987 // mAnimation is being used in a separate thread; queue a message to set play range
988 SetPlayRangeMessage( mEventThreadServices, *mAnimation, orderedRange );
992 Vector2 Animation::GetPlayRange() const
998 } // namespace Internal