-//
-// Copyright (c) 2014 Samsung Electronics Co., Ltd.
-//
-// Licensed under the Flora License, Version 1.0 (the License);
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://floralicense.org/license/
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an AS IS BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-//
+/*
+ * Copyright (c) 2014 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.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
// EXTERNAL INCLUDES
+#include <dali/public-api/actors/layer.h>
#include <dali/integration-api/debug.h>
// INTERNAL INCLUDES
#include <dali-toolkit/internal/builder/builder-impl.h>
#include <dali-toolkit/internal/builder/builder-get-is.inl.h>
+#include <dali-toolkit/internal/builder/replacement.h>
namespace // unnamed namespace
{
using namespace Dali;
-TimePeriod GetTimePeriod( const TreeNode& child )
+TimePeriod GetTimePeriod( const TreeNode& child, const Toolkit::Internal::Replacement& constant )
{
- OptionalFloat delay = IsFloat( IsChild(child, "delay" ) );
- OptionalFloat duration = IsFloat( IsChild(child, "duration" ) );
+ OptionalFloat delay = constant.IsFloat( IsChild(child, "delay" ) );
+ OptionalFloat duration = constant.IsFloat( IsChild(child, "duration" ) );
DALI_ASSERT_ALWAYS( duration && "Time period must have at least a duration" );
if( delay )
default:
{
DALI_ASSERT_ALWAYS( !"Property type incorrect" );
- return Property::Value();
}
}
}
if( 0 == alphaFunctionLut.size() )
{
// coding convention is uppercase enums
- alphaFunctionLut["DEFAULT"] = Dali::AlphaFunctions::Default;
- alphaFunctionLut["LINEAR"] = Dali::AlphaFunctions::Linear;
- alphaFunctionLut["REVERSE"] = Dali::AlphaFunctions::Reverse;
- alphaFunctionLut["EASE_IN"] = Dali::AlphaFunctions::EaseIn;
- alphaFunctionLut["EASE_OUT"] = Dali::AlphaFunctions::EaseOut;
- alphaFunctionLut["EASE_IN_OUT"] = Dali::AlphaFunctions::EaseInOut;
- alphaFunctionLut["EASE_IN_SINE"] = Dali::AlphaFunctions::EaseInSine;
- alphaFunctionLut["EASE_OUT_SINE"] = Dali::AlphaFunctions::EaseOutSine;
- alphaFunctionLut["EASE_IN_OUT_SINE"]= Dali::AlphaFunctions::EaseInOutSine;
- alphaFunctionLut["BOUNCE"] = Dali::AlphaFunctions::Bounce;
- alphaFunctionLut["BOUNCE_BACK"] = Dali::AlphaFunctions::BounceBack;
- alphaFunctionLut["EASE_OUT_BACK"] = Dali::AlphaFunctions::EaseOutBack;
- alphaFunctionLut["SIN"] = Dali::AlphaFunctions::Sin;
- alphaFunctionLut["SIN2X"] = Dali::AlphaFunctions::Sin;
+ alphaFunctionLut["DEFAULT"] = AlphaFunction(AlphaFunction::DEFAULT);
+ alphaFunctionLut["LINEAR"] = AlphaFunction(AlphaFunction::LINEAR);
+ alphaFunctionLut["REVERSE"] = AlphaFunction(AlphaFunction::REVERSE);
+ alphaFunctionLut["EASE_IN_SQUARE"] = AlphaFunction(AlphaFunction::EASE_IN_SQUARE);
+ alphaFunctionLut["EASE_OUT_SQUARE"] = AlphaFunction(AlphaFunction::EASE_OUT_SQUARE);
+ alphaFunctionLut["EASE_IN"] = AlphaFunction(AlphaFunction::EASE_IN);
+ alphaFunctionLut["EASE_OUT"] = AlphaFunction(AlphaFunction::EASE_OUT);
+ alphaFunctionLut["EASE_IN_OUT"] = AlphaFunction(AlphaFunction::EASE_IN_OUT);
+ alphaFunctionLut["EASE_IN_SINE"] = AlphaFunction(AlphaFunction::EASE_IN_SINE);
+ alphaFunctionLut["EASE_OUT_SINE"] = AlphaFunction(AlphaFunction::EASE_OUT_SINE);
+ alphaFunctionLut["EASE_IN_OUT_SINE"] = AlphaFunction(AlphaFunction::EASE_IN_OUT_SINE);
+ alphaFunctionLut["BOUNCE"] = AlphaFunction(AlphaFunction::BOUNCE);
+ alphaFunctionLut["SIN"] = AlphaFunction(AlphaFunction::SIN);
+ alphaFunctionLut["EASE_OUT_BACK"] = AlphaFunction(AlphaFunction::EASE_OUT_BACK);
}
const AlphaFunctionLut::const_iterator iter( alphaFunctionLut.find( alphaFunction ) );
}
else
{
- DALI_ASSERT_ALWAYS( iter != alphaFunctionLut.end() && "Unknown Anchor Constant" );
- return Dali::AlphaFunctions::Default;
+ DALI_ASSERT_ALWAYS( iter != alphaFunctionLut.end() && "Unknown Alpha Constant" );
+ return Dali::AlphaFunction::DEFAULT;
}
}
namespace Internal
{
-Animation CreateAnimation( const TreeNode& child )
+Animation CreateAnimation( const TreeNode& child, const Replacement& constant, Dali::Actor searchRoot, Builder* const builder )
{
float durationSum = 0.f;
+ Dali::Actor searchActor = searchRoot ? searchRoot : Dali::Stage::GetCurrent().GetRootLayer();
+
Animation animation( Animation::New( 0.f ) );
- if( OptionalBoolean looping = IsBoolean( IsChild(child, "loop" ) ) )
+ // duration needs to be set before AnimateTo calls for correct operation when AnimateTo has no "timePeriod".
+ OptionalFloat duration = constant.IsFloat( IsChild(child, "duration" ) );
+
+ if( duration )
+ {
+ animation.SetDuration( *duration );
+ }
+
+ if( OptionalBoolean looping = constant.IsBoolean( IsChild(child, "loop" ) ) )
{
animation.SetLooping( *looping );
}
- if( OptionalString endAction = IsString( IsChild(child, "end-action" ) ) )
+ if( OptionalString endAction = constant.IsString( IsChild(child, "endAction" ) ) )
{
if("BAKE" == *endAction)
{
{
animation.SetEndAction( Animation::Discard );
}
+ else if("BAKE_FINAL" == *endAction)
+ {
+ animation.SetEndAction( Animation::BakeFinal );
+ }
}
- if( OptionalString endAction = IsString( IsChild(child, "destroy-action" ) ) )
+ if( OptionalString endAction = constant.IsString( IsChild(child, "disconnectAction" ) ) )
{
if("BAKE" == *endAction)
{
- animation.SetDestroyAction( Animation::Bake );
+ animation.SetDisconnectAction( Animation::Bake );
}
else if("DISCARD" == *endAction)
{
- animation.SetDestroyAction( Animation::Discard );
+ animation.SetDisconnectAction( Animation::Discard );
+ }
+ else if("BAKE_FINAL" == *endAction)
+ {
+ animation.SetDisconnectAction( Animation::BakeFinal );
}
}
{
const TreeNode::KeyNodePair& pKeyChild = *iter;
- OptionalString actorName( IsString( pKeyChild.second, "actor" ) );
- OptionalString property( IsString( pKeyChild.second, "property" ) );
+ 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" );
- Actor targetActor = Stage::GetCurrent().GetRootLayer().FindChildByName( *actorName );
- DALI_ASSERT_ALWAYS( targetActor && "Actor must exist for property" );
+ Handle targetHandle = searchActor.FindChildByName( *actorName );
+ DALI_ASSERT_ALWAYS( targetHandle && "Actor must exist for property" );
- Property::Index idx( targetActor.GetPropertyIndex( *property ) );
-
- // A limitation here is that its possible that between binding to the signal and
- // the signal call that the ShaderEffect of the targetActor has been changed.
- // However this is a unlikely use case especially when using scripts.
- if( idx == Property::INVALID_INDEX )
+ Property::Value propValue;
+ Property::Index propIndex = Property::INVALID_INDEX;
+ if( property )
{
- if( ShaderEffect effect = targetActor.GetShaderEffect() )
+ 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 )
{
- idx = effect.GetPropertyIndex( *property );
- if(idx != Property::INVALID_INDEX)
- {
- targetActor = effect;
- }
- else
- {
- DALI_SCRIPT_WARNING( "Cannot find property on object or ShaderEffect\n" );
+ DALI_SCRIPT_WARNING( "Cannot find property on object\n" );
continue;
- }
- }
- else
- {
- DALI_SCRIPT_WARNING( "Cannot find property on object or ShaderEffect\n" );
- continue;
}
}
- if( idx == Property::INVALID_INDEX)
- {
- DALI_ASSERT_ALWAYS( idx != Property::INVALID_INDEX && "Animation must specify a valid property" );
- continue;
- }
-
- Property prop( Property( targetActor, idx ) );
- Property::Value propValue;
-
// these are the defaults
- AlphaFunction alphaFunction( AlphaFunctions::Default );
+ AlphaFunction alphaFunction( AlphaFunction::DEFAULT );
TimePeriod timePeriod( 0.f );
- if( OptionalChild timeChild = IsChild( pKeyChild.second, "time-period" ) )
+ OptionalChild timeChild = IsChild( pKeyChild.second, "timePeriod" );
+
+ if( timeChild )
{
- timePeriod = GetTimePeriod( *timeChild );
+ timePeriod = GetTimePeriod( *timeChild, constant );
}
durationSum = std::max( durationSum, timePeriod.delaySeconds + timePeriod.durationSeconds );
- if( OptionalString alphaChild = IsString( pKeyChild.second, "alpha-function" ) )
+ if( OptionalString alphaChild = constant.IsString( IsChild(pKeyChild.second, "alphaFunction" ) ) )
{
alphaFunction = GetAlphaFunction( *alphaChild );
}
- if( OptionalChild keyFrameChild = IsChild(pKeyChild.second, "key-frames") )
+ if( OptionalChild keyFrameChild = IsChild(pKeyChild.second, "keyFrames") )
{
+ 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();
{
const TreeNode::KeyNodePair& kfKeyChild = *iter;
- OptionalFloat kfProgress = IsFloat( kfKeyChild.second, "progress" );
+ OptionalFloat kfProgress = constant.IsFloat( IsChild(kfKeyChild.second, "progress" ) );
DALI_ASSERT_ALWAYS( kfProgress && "Key frame entry must have 'progress'" );
OptionalChild kfValue = IsChild( kfKeyChild.second, "value" );
throw;
}
- AlphaFunction kfAlphaFunction( AlphaFunctions::Default );
- if( OptionalString alphaFuncStr = IsString( pKeyChild.second, "alpha-function") )
+ AlphaFunction kfAlphaFunction( AlphaFunction::DEFAULT );
+ if( OptionalString alphaFuncStr = constant.IsString( IsChild(pKeyChild.second, "alphaFunction") ) )
{
kfAlphaFunction = GetAlphaFunction( *alphaFuncStr );
}
keyframes.Add( *kfProgress, propValue, kfAlphaFunction );
}
- animation.AnimateBetween( prop, keyframes, alphaFunction, timePeriod );
+ if( timeChild )
+ {
+ animation.AnimateBetween( prop, keyframes, alphaFunction, timePeriod );
+ }
+ else
+ {
+ 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") );
throw;
}
- if( OptionalBoolean relative = IsBoolean(pKeyChild.second, "relative") )
+ if( OptionalBoolean relative = constant.IsBoolean( IsChild(pKeyChild.second, "relative") ) )
{
- animation.AnimateBy( prop, propValue, alphaFunction, timePeriod );
+ if( timeChild )
+ {
+ animation.AnimateBy( prop, propValue, alphaFunction, timePeriod );
+ }
+ else
+ {
+ animation.AnimateBy( prop, propValue, alphaFunction );
+ }
}
else
{
- animation.AnimateTo( prop, propValue, alphaFunction, timePeriod );
+ if( timeChild )
+ {
+ animation.AnimateTo( prop, propValue, alphaFunction, timePeriod );
+ }
+ else
+ {
+ animation.AnimateTo( prop, propValue, alphaFunction );
+ }
}
}
}
}
- if( OptionalFloat duration = IsFloat( child, "duration" ) )
- {
- animation.SetDuration( *duration );
- }
- else
+ if( !duration )
{
animation.SetDuration( durationSum );
}
return animation;
}
+Animation CreateAnimation( const TreeNode& child, Builder* const builder )
+{
+ Replacement replacement;
+ return CreateAnimation( child, replacement, Stage::GetCurrent().GetRootLayer(), builder );
+}
+
} // namespace Internal
} // namespace Toolkit