namespace Internal
{
-Animation CreateAnimation( const TreeNode& child, const Replacement& constant, Dali::Actor searchRoot )
+Animation CreateAnimation( const TreeNode& child, const Replacement& constant, Dali::Actor searchRoot, Builder* const builder )
{
float durationSum = 0.f;
OptionalString actorName( constant.IsString( IsChild(pKeyChild.second, "actor" ) ) );
OptionalString property( constant.IsString( IsChild(pKeyChild.second, "property" ) ) );
DALI_ASSERT_ALWAYS( actorName && "Animation must specify actor name" );
- DALI_ASSERT_ALWAYS( property && "Animation must specify a property name" );
Handle targetHandle = searchActor.FindChildByName( *actorName );
DALI_ASSERT_ALWAYS( targetHandle && "Actor must exist for property" );
- Property::Index idx( targetHandle.GetPropertyIndex( *property ) );
-
- // if the property is not found from the (actor) handle, try to downcast it to renderable actor
- // to allow animating shader uniforms
- if( idx == Property::INVALID_INDEX )
+ Property::Value propValue;
+ Property::Index propIndex;
+ if( property )
{
- RenderableActor renderable = RenderableActor::DownCast( targetHandle );
- if( renderable )
+ propIndex = targetHandle.GetPropertyIndex( *property );
+
+ // if the property is not found from the (actor) handle, try to downcast it to renderable actor
+ // to allow animating shader uniforms
+ if( propIndex == Property::INVALID_INDEX )
{
- // A limitation here is that its possible that between creation of animation
- // and running it the ShaderEffect of the actor has been changed.
- // However this is a unlikely use case especially when using scripts.
- if( ShaderEffect effect = renderable.GetShaderEffect() )
+ RenderableActor renderable = RenderableActor::DownCast( targetHandle );
+ if( renderable )
{
- idx = effect.GetPropertyIndex( *property );
- if(idx != Property::INVALID_INDEX)
+ // A limitation here is that its possible that between creation of animation
+ // and running it the ShaderEffect of the actor has been changed.
+ // However this is a unlikely use case especially when using scripts.
+ if( ShaderEffect effect = renderable.GetShaderEffect() )
{
- targetHandle = effect;
- }
- else
- {
- DALI_SCRIPT_WARNING( "Cannot find property on object or ShaderEffect\n" );
- continue;
+ propIndex = effect.GetPropertyIndex( *property );
+ if(propIndex != Property::INVALID_INDEX)
+ {
+ targetHandle = effect;
+ }
+ else
+ {
+ DALI_SCRIPT_WARNING( "Cannot find property on object or ShaderEffect\n" );
+ continue;
+ }
}
}
+ else
+ {
+ DALI_SCRIPT_WARNING( "Cannot find property on object or ShaderEffect\n" );
+ continue;
+ }
}
- else
+
+ if( propIndex == Property::INVALID_INDEX)
{
- DALI_SCRIPT_WARNING( "Cannot find property on object or ShaderEffect\n" );
+ DALI_ASSERT_ALWAYS( propIndex != Property::INVALID_INDEX && "Animation must specify a valid property" );
continue;
}
}
- if( idx == Property::INVALID_INDEX)
- {
- DALI_ASSERT_ALWAYS( idx != Property::INVALID_INDEX && "Animation must specify a valid property" );
- continue;
- }
-
- Property prop( Property( targetHandle, idx ) );
- Property::Value propValue;
-
// these are the defaults
AlphaFunction alphaFunction( AlphaFunctions::Default );
TimePeriod timePeriod( 0.f );
if( OptionalChild keyFrameChild = IsChild(pKeyChild.second, "key-frames") )
{
+ DALI_ASSERT_ALWAYS( property && "Animation must specify a property name" );
+ Property prop = Property( targetHandle, propIndex );
+
KeyFrames keyframes = KeyFrames::New();
const TreeNode::ConstIterator endIter = (*keyFrameChild).CEnd();
animation.AnimateBetween( prop, keyframes, alphaFunction );
}
}
+ else if( OptionalString pathChild = IsString(pKeyChild.second, "path") )
+ {
+ //Get path
+ Path path = builder->GetPath(*pathChild);
+ if( path )
+ {
+ //Get forward vector if specified
+ Vector3 forward( 0.0f, 0.0f, 0.0f );
+ OptionalVector3 forwardProperty = constant.IsVector3( IsChild(pKeyChild.second, "forward" ) );
+ if( forwardProperty )
+ {
+ forward = *forwardProperty;
+ }
+
+ Actor actor = Actor::DownCast( targetHandle );
+ if( actor )
+ {
+ if( timeChild )
+ {
+ animation.Animate( actor, path, forward, alphaFunction, timePeriod );
+ }
+ else
+ {
+ animation.Animate( actor, path, forward, alphaFunction );
+ }
+
+ }
+ }
+ else
+ {
+ //Path not found
+ DALI_SCRIPT_WARNING( "Cannot find animation path '%s'\n", (*pathChild).c_str() );
+ }
+ }
else
{
+ DALI_ASSERT_ALWAYS( property && "Animation must specify a property name" );
+
+ Property prop = Property( targetHandle, propIndex );
try
{
propValue = GetPropertyValue( prop.object.GetPropertyType(prop.propertyIndex), *IsChild(pKeyChild.second, "value") );
return animation;
}
-Animation CreateAnimation( const TreeNode& child )
+Animation CreateAnimation( const TreeNode& child, Builder* const builder )
{
Replacement replacement;
- return CreateAnimation( child, replacement, Stage::GetCurrent().GetRootLayer() );
+ return CreateAnimation( child, replacement, Stage::GetCurrent().GetRootLayer(), builder );
}
} // namespace Internal
{
class Replacement;
-extern Animation CreateAnimation(const TreeNode& child, const Replacement& replacements, const Dali::Actor searchRoot );
+extern Animation CreateAnimation(const TreeNode& child, const Replacement& replacements, const Dali::Actor searchRoot, Builder* const builder );
extern bool SetPropertyFromNode( const TreeNode& node, Property::Value& value );
extern bool SetPropertyFromNode( const TreeNode& node, Property::Value& value, const Replacement& replacements );
extern bool SetPropertyFromNode( const TreeNode& node, Property::Type type, Property::Value& value );
extern bool SetPropertyFromNode( const TreeNode& node, Property::Type type, Property::Value& value, const Replacement& replacements );
-extern Actor SetupSignalAction(ConnectionTracker* tracker, const TreeNode &root, const TreeNode &child, Actor actor, boost::function<void (void)> quitAction);
-extern Actor SetupPropertyNotification(ConnectionTracker* tracker, const TreeNode &root, const TreeNode &child, Actor actor, boost::function<void (void)> quitAction);
+extern Actor SetupSignalAction(ConnectionTracker* tracker, const TreeNode &root, const TreeNode &child, Actor actor, boost::function<void (void)> quitAction, Dali::Toolkit::Internal::Builder* const builder);
+extern Actor SetupPropertyNotification(ConnectionTracker* tracker, const TreeNode &root, const TreeNode &child, Actor actor, boost::function<void (void)> quitAction, Dali::Toolkit::Internal::Builder* const builder);
extern Actor SetupActor( const TreeNode& node, Actor& actor, const Replacement& constant );
#if defined(DEBUG_ENABLED)
// add signals
QuitAction quitAction( *this );
- SetupSignalAction( mSlotDelegate.GetConnectionTracker(), root, node, actor, quitAction );
- SetupPropertyNotification( mSlotDelegate.GetConnectionTracker(), root, node, actor, quitAction );
+ SetupSignalAction( mSlotDelegate.GetConnectionTracker(), root, node, actor, quitAction, this );
+ SetupPropertyNotification( mSlotDelegate.GetConnectionTracker(), root, node, actor, quitAction, this );
}
}
else
return ret;
}
+Path Builder::GetPath( const std::string& name )
+{
+ DALI_ASSERT_ALWAYS(mParser.GetRoot() && "Builder script not loaded");
+
+ Path ret;
+
+ PathLut::const_iterator iter( mPathLut.find( name ) );
+ if( iter != mPathLut.end() )
+ {
+ ret = iter->second;
+ }
+ else
+ {
+ if( OptionalChild paths = IsChild( *mParser.GetRoot(), "paths") )
+ {
+ if( OptionalChild path = IsChild( *paths, name ) )
+ {
+ //points property
+ if( OptionalChild pointsProperty = IsChild( *path, "points") )
+ {
+ Dali::Property::Value points(Property::ARRAY);
+ if( SetPropertyFromNode( *pointsProperty, Property::ARRAY, points ) )
+ {
+ ret = Path::New();
+ ret.SetProperty( Path::POINTS, points);
+
+ //control-points property
+ if( OptionalChild pointsProperty = IsChild( *path, "control-points") )
+ {
+ Dali::Property::Value points(Property::ARRAY);
+ if( SetPropertyFromNode( *pointsProperty, Property::ARRAY, points ) )
+ {
+ ret.SetProperty( Path::CONTROL_POINTS, points);
+ }
+ }
+ else
+ {
+ //Curvature
+ float curvature(0.25f);
+ if( OptionalFloat pointsProperty = IsFloat( *path, "curvature") )
+ {
+ curvature = *pointsProperty;
+ }
+ ret.GenerateControlPoints(curvature);
+ }
+
+ //Add the new path to the hash table for paths
+ mPathLut[ name ] = ret;
+ }
+ }
+ else
+ {
+ //Interpolation points not specified
+ DALI_SCRIPT_WARNING("Interpolation points not specified for path '%s'\n", name.c_str() );
+ }
+ }
+
+ }
+ }
+
+ return ret;
+}
+
Toolkit::Builder::Signal& Builder::QuitSignal()
{
return mQuitSignal;
{
if( OptionalChild animation = IsChild(*animations, animationName) )
{
- anim = Dali::Toolkit::Internal::CreateAnimation( *animation, replacement, sourceActor );
+ anim = Dali::Toolkit::Internal::CreateAnimation( *animation, replacement, sourceActor, this );
}
else
{
*/
FrameBufferImage GetFrameBufferImage( const std::string &name, const Replacement& constant );
+ /**
+ * @copydoc Toolkit::Builder::GetPath
+ */
+ Path GetPath( const std::string &name );
/**
* @copydoc Toolkit::Builder::QuitSignal
*/
typedef std::map<const std::string, ShaderEffect> ShaderEffectLut;
ShaderEffectLut mShaderEffectLut;
+ typedef std::map<const std::string, Path> PathLut;
+ PathLut mPathLut;
+
SlotDelegate<Builder> mSlotDelegate;
Property::Map mReplacementMap;
{
namespace Internal
{
-extern Animation CreateAnimation( const TreeNode& child );
+extern Animation CreateAnimation( const TreeNode& child, Dali::Toolkit::Internal::Builder* const builder );
extern bool SetPropertyFromNode( const TreeNode& node, Property::Value& value );
}
}
// Delay an animation play; ie wait as its not on stage yet
struct DelayedAnimationPlay
{
- Toolkit::JsonParser memento;
+ OptionalChild animNode;
+ Dali::IntrusivePtr<Dali::Toolkit::Internal::Builder> builder;
void operator()(void)
{
- Animation anim = Toolkit::Internal::CreateAnimation(*memento.GetRoot());
+ Animation anim = Toolkit::Internal::CreateAnimation(*animNode, builder.Get() );
if(anim)
{
anim.Play();
/**
* Get an action as boost function callback
*/
-boost::function<void (void)> GetAction(const TreeNode &root, const TreeNode &child, Actor actor, boost::function<void (void)> quitAction)
+boost::function<void (void)> GetAction(const TreeNode &root, const TreeNode &child, Actor actor, boost::function<void (void)> quitAction, Dali::Toolkit::Internal::Builder* const builder)
{
OptionalString childActorName(IsString( IsChild(&child, "child-actor")) );
OptionalString actorName(IsString( IsChild(&child, "actor")) );
if( OptionalChild animNode = IsChild(*animations, *animationName) )
{
DelayedAnimationPlay action;
- action.memento = Toolkit::JsonParser::New(*animNode);
+ action.animNode = animNode;
+ action.builder = builder;
// @todo; put constants into the map
callback = action;
}
namespace Internal
{
-Actor SetupSignalAction(const TreeNode &child, Actor actor);
-Actor SetupPropertyNotification(const TreeNode &child, Actor actor);
+Actor SetupSignalAction(const TreeNode &child, Actor actor, Dali::Toolkit::Internal::Builder* const builder );
+Actor SetupPropertyNotification(const TreeNode &child, Actor actor, Dali::Toolkit::Internal::Builder* const builder );
/**
* Setup signals and actions on an actor
*/
-Actor SetupSignalAction(ConnectionTracker* tracker, const TreeNode &root, const TreeNode &child, Actor actor, boost::function<void (void)> quitAction)
+Actor SetupSignalAction(ConnectionTracker* tracker, const TreeNode &root, const TreeNode &child, Actor actor, boost::function<void (void)> quitAction, Dali::Toolkit::Internal::Builder* const builder )
{
DALI_ASSERT_ALWAYS(actor);
OptionalString name( IsString( IsChild( key_child.second, "name")) );
DALI_ASSERT_ALWAYS(name && "Signal must have a name");
- boost::function<void (void)> callback = GetAction(root, key_child.second, actor, quitAction);
+ boost::function<void (void)> callback = GetAction(root, key_child.second, actor, quitAction, builder );
actor.ConnectSignal(tracker, *name, callback);
}
/**
* Setup Property notifications for an actor
*/
-Actor SetupPropertyNotification(ConnectionTracker* tracker, const TreeNode &root, const TreeNode &child, Actor actor, boost::function<void (void)> quitAction)
+Actor SetupPropertyNotification(ConnectionTracker* tracker, const TreeNode &root, const TreeNode &child, Actor actor, boost::function<void (void)> quitAction, Dali::Toolkit::Internal::Builder* const builder )
{
DALI_ASSERT_ALWAYS(actor);
// Actor actions reference by pointer because of circular reference actor->signal
// So this callback should only go onto the actor maintained list.
- boost::function<void (void)> callback = GetAction(root, key_child.second, actor, quitAction);
+ boost::function<void (void)> callback = GetAction(root, key_child.second, actor, quitAction, builder );
OptionalString prop(IsString( IsChild(key_child.second, "property")) );
DALI_ASSERT_ALWAYS(prop && "Notification signal must specify a property");
return GetImpl(*this).GetFrameBufferImage( name );
}
+Path Builder::GetPath( const std::string &name )
+{
+ return GetImpl(*this).GetPath( name );
+}
+
Builder::Signal& Builder::QuitSignal()
{
return GetImpl( *this ).QuitSignal();
*/
FrameBufferImage GetFrameBufferImage( const std::string &name );
+ /**
+ * Get or create Path from the Path instance library.
+ * An empty handle is returned otherwise.
+ * @pre The Builder has been initialized.
+ * @param name The name of a Path in the loaded representation
+ * @return A handle to a Path if found, otherwise empty
+ */
+ Path GetPath( const std::string &name );
+
// Signals
/**