/*
- * Copyright (c) 2014 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
#include <dali/internal/event/common/property-helper.h>
#include <dali/internal/event/common/stage-impl.h>
#include <dali/internal/event/common/thread-local-storage.h>
-#include <dali/internal/event/effects/shader-effect-impl.h>
+#include <dali/internal/update/animation/scene-graph-animator.h>
#include <dali/internal/update/manager/update-manager.h>
using Dali::Internal::SceneGraph::UpdateManager;
mPlayRange( Vector2(0.0f,1.0f)),
mEndAction( endAction ),
mDisconnectAction( disconnectAction ),
- mDefaultAlpha( defaultAlpha )
+ mDefaultAlpha( defaultAlpha ),
+ mState(Dali::Animation::STOPPED)
{
}
// Update the current playlist
mPlaylist.OnPlay( *this );
+ mState = Dali::Animation::PLAYING;
+
+ unsigned int connectorTargetValuesIndex( 0 );
+ unsigned int numberOfConnectorTargetValues = mConnectorActorTargetValues.size();
+
+ /*
+ * Loop through all Animator connectors, if connector index matches the current index stored in mConnectorActorTargetValues container then
+ * should apply target values for this index to the Actor.
+ * Confirm object is an actor and it is a POSITION or SIZE Property Index before sending Notify message to Actor.
+ */
+ for ( unsigned int connectorIndex = 0; connectorIndex < mConnectors.Count(); connectorIndex ++)
+ {
+ // Use index to check if the current connector is next in the mConnectorActorTargetValues container, meaning targetValues have been pushed in AnimateXXFunction
+ if ( connectorTargetValuesIndex < numberOfConnectorTargetValues )
+ {
+ ConnectorTargetValues& connectorPair = mConnectorActorTargetValues[ connectorTargetValuesIndex ];
+
+ if ( connectorPair.connectorIndex == connectorIndex )
+ {
+ // Current connector index matches next in the stored connectors with target values so apply target value.
+ connectorTargetValuesIndex++; // Found a match for connector so increment index to next one
+
+ AnimatorConnectorBase* connector = mConnectors[ connectorIndex ];
+
+ Actor* maybeActor = static_cast<Actor*>( connector->GetObject() ); // Only Actors would be in mConnectorActorTargetValues container
+
+ if ( maybeActor )
+ {
+ // Get Stored Target Value and corresponding connector index
+ const Property::Type valueType = connectorPair.targetValue.GetType();
+ Property::Index propertyIndex = connector->GetPropertyIndex();
+
+ if ( valueType == Property::VECTOR3 )
+ {
+ Vector3 targetVector3 = connectorPair.targetValue.Get<Vector3>();
+
+ if ( propertyIndex == Dali::Actor::Property::POSITION )
+ {
+ maybeActor->NotifyPositionAnimation( *this, targetVector3 );
+ }
+ else if ( propertyIndex == Dali::Actor::Property::SIZE )
+ {
+ maybeActor->NotifySizeAnimation( *this, targetVector3 );
+ }
+ }
+ else if ( valueType == Property::FLOAT )
+ {
+ float targetFloat = connectorPair.targetValue.Get<float>();
+
+ if ( ( Dali::Actor::Property::POSITION_X == propertyIndex ) ||
+ ( Dali::Actor::Property::POSITION_Y == propertyIndex ) ||
+ ( Dali::Actor::Property::POSITION_Z == propertyIndex ) )
+ {
+ maybeActor->NotifyPositionAnimation( *this, targetFloat, propertyIndex );
+ }
+ else if ( ( Dali::Actor::Property::SIZE_WIDTH == propertyIndex ) ||
+ ( Dali::Actor::Property::SIZE_HEIGHT == propertyIndex ) ||
+ ( Dali::Actor::Property::SIZE_DEPTH == propertyIndex ) )
+
+ {
+ maybeActor->NotifySizeAnimation( *this, targetFloat, propertyIndex );
+ }
+ }
+ else
+ {
+ // Currently only FLOAT and VECTOR3 is supported for Target values in AnimateXXFunctions
+ DALI_LOG_WARNING("Animation::Play Unsupported Value Type provided as TargetValue\n");
+ }
+ }
+ }
+ }
+ }
+
// mAnimation is being used in a separate thread; queue a Play message
PlayAnimationMessage( mEventThreadServices, *mAnimation );
}
// Update the current playlist
mPlaylist.OnPlay( *this );
+ mState = Dali::Animation::PLAYING;
+
// mAnimation is being used in a separate thread; queue a Play message
PlayAnimationFromMessage( mEventThreadServices, *mAnimation, progress );
}
void Animation::Pause()
{
+ mState = Dali::Animation::PAUSED;
+
// mAnimation is being used in a separate thread; queue a Pause message
PauseAnimationMessage( mEventThreadServices, *mAnimation );
}
+Dali::Animation::State Animation::GetState() const
+{
+ return mState;
+}
+
void Animation::Stop()
{
+ mState = Dali::Animation::STOPPED;
+
// mAnimation is being used in a separate thread; queue a Stop message
StopAnimationMessage( mEventThreadServices.GetUpdateManager(), *mAnimation );
}
void Animation::AnimateBy(Property& target, Property::Value& relativeValue, AlphaFunction alpha, TimePeriod period)
{
- Object& object = dynamic_cast<Object&>( GetImplementation(target.object) );
+ Object& object = GetImplementation( target.object );
+ const Property::Type targetType = object.GetPropertyType( target.propertyIndex );
+ const Property::Type destinationType = relativeValue.GetType();
+ DALI_ASSERT_ALWAYS( targetType == destinationType && "Animated value and Property type don't match" );
ExtendDuration( period );
- switch ( relativeValue.GetType() )
+ switch ( targetType )
{
case Property::BOOLEAN:
{
}
default:
- DALI_ASSERT_ALWAYS( false && "Property type enumeration out of bounds" ); // should never come here
- break;
+ {
+ // non animatable types handled already
+ }
}
}
void Animation::AnimateTo(Property& target, Property::Value& destinationValue, AlphaFunction alpha, TimePeriod period)
{
- Object& object = dynamic_cast<Object&>( GetImplementation(target.object) );
+ Object& object = GetImplementation(target.object);
AnimateTo( object, target.propertyIndex, target.componentIndex, destinationValue, alpha, period );
}
void Animation::AnimateTo(Object& targetObject, Property::Index targetPropertyIndex, int componentIndex, Property::Value& destinationValue, AlphaFunction alpha, TimePeriod period)
{
- Property::Type type = targetObject.GetPropertyType(targetPropertyIndex);
- if(componentIndex != Property::INVALID_COMPONENT_INDEX)
+ Property::Type targetType = targetObject.GetPropertyType(targetPropertyIndex);
+ if( componentIndex != Property::INVALID_COMPONENT_INDEX )
{
- if( type == Property::VECTOR2
- || type == Property::VECTOR3
- || type == Property::VECTOR4 )
+ if( ( targetType == Property::VECTOR2 ) ||
+ ( targetType == Property::VECTOR3 ) ||
+ ( targetType == Property::VECTOR4 ) )
{
- type = Property::FLOAT;
+ targetType = Property::FLOAT;
}
}
- DALI_ASSERT_ALWAYS( type == destinationValue.GetType() && "DestinationValue does not match Target Property type" );
+ const Property::Type destinationType = destinationValue.GetType();
+ DALI_ASSERT_ALWAYS( targetType == destinationType && "Animated value and Property type don't match" );
ExtendDuration( period );
- switch (destinationValue.GetType())
+ switch ( destinationType )
{
case Property::BOOLEAN:
{
{
if ( ( Dali::Actor::Property::SIZE_WIDTH == targetPropertyIndex ) ||
( Dali::Actor::Property::SIZE_HEIGHT == targetPropertyIndex ) ||
- ( Dali::Actor::Property::SIZE_DEPTH == targetPropertyIndex ) )
+ ( Dali::Actor::Property::SIZE_DEPTH == targetPropertyIndex ) ||
+ ( Dali::Actor::Property::POSITION_X == targetPropertyIndex ) ||
+ ( Dali::Actor::Property::POSITION_Y == targetPropertyIndex ) ||
+ ( Dali::Actor::Property::POSITION_Z == targetPropertyIndex ) )
{
- // Test whether this is actually an Actor
- Actor* maybeActor = dynamic_cast<Actor*>( &targetObject );
- if ( maybeActor )
- {
- // Notify the actor that its size is being animated
- maybeActor->NotifySizeAnimation( *this, destinationValue.Get<float>(), targetPropertyIndex );
- }
- }
- else if ( ( Dali::Actor::Property::POSITION_X == targetPropertyIndex ) ||
- ( Dali::Actor::Property::POSITION_Y == targetPropertyIndex ) ||
- ( Dali::Actor::Property::POSITION_Z == targetPropertyIndex ) )
- {
- // Test whether this is actually an Actor
+
Actor* maybeActor = dynamic_cast<Actor*>( &targetObject );
if ( maybeActor )
{
- // Notify the actor that its position is being animated
- maybeActor->NotifyPositionAnimation( *this, destinationValue.Get<float>(), targetPropertyIndex );
+ // Store data to later notify the actor that its size or position is being animated
+ ConnectorTargetValues connectorPair;
+ connectorPair.targetValue = destinationValue;
+ connectorPair.connectorIndex = mConnectors.Count();
+
+ mConnectorActorTargetValues.push_back( connectorPair );
}
}
case Property::VECTOR3:
{
- if ( Dali::Actor::Property::SIZE == targetPropertyIndex )
+ if ( Dali::Actor::Property::SIZE == targetPropertyIndex || Dali::Actor::Property::POSITION == targetPropertyIndex )
{
// Test whether this is actually an Actor
Actor* maybeActor = dynamic_cast<Actor*>( &targetObject );
if ( maybeActor )
{
- // Notify the actor that its size is being animated
- maybeActor->NotifySizeAnimation( *this, destinationValue.Get<Vector3>() );
- }
- }
- else if ( Dali::Actor::Property::POSITION == targetPropertyIndex )
- {
- // Test whether this is actually an Actor
- Actor* maybeActor = dynamic_cast<Actor*>( &targetObject );
- if ( maybeActor )
- {
- // Notify the actor that its position is being animated
- maybeActor->NotifyPositionAnimation( *this, destinationValue.Get<Vector3>() );
+ // Store data to later notify the actor that its size or position is being animated
+ ConnectorTargetValues connectorPair;
+ connectorPair.targetValue = destinationValue;
+ connectorPair.connectorIndex = mConnectors.Count();
+
+ mConnectorActorTargetValues.push_back( connectorPair );
}
}
}
default:
- DALI_ASSERT_ALWAYS( false && "Property type enumeration out of bounds" ); // should never come here
- break;
+ {
+ // non animatable types handled already
+ }
}
}
void Animation::AnimateBetween(Property target, const KeyFrames& keyFrames, AlphaFunction alpha, TimePeriod period, Interpolation interpolation)
{
- Object& object = dynamic_cast<Object&>( GetImplementation(target.object) );
+ Object& object = GetImplementation( target.object );
ExtendDuration( period );
break;
}
- default: // not all property types are animateable
- break;
+ default:
+ {
+ // non animatable types handled by keyframes
+ }
}
}
mNotificationCount = playedCount;
hasFinished = true;
+
+ mState = Dali::Animation::STOPPED;
}
return hasFinished;
bool Animation::DoConnectSignal( BaseObject* object, ConnectionTrackerInterface* tracker, const std::string& signalName, FunctorDelegate* functor )
{
bool connected( true );
- Animation* animation = dynamic_cast<Animation*>(object);
+ Animation* animation = static_cast< Animation* >(object); // TypeRegistry guarantees that this is the correct type.
if( 0 == signalName.compare( SIGNAL_FINISHED ) )
{