2 // Copyright (c) 2014 Samsung Electronics Co., Ltd.
4 // Licensed under the Flora License, Version 1.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://floralicense.org/license/
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.
18 #include <dali/integration-api/debug.h>
21 #include <dali-toolkit/internal/builder/builder-impl.h>
22 #include <dali-toolkit/internal/builder/builder-get-is.inl.h>
24 namespace // unnamed namespace
29 TimePeriod GetTimePeriod( const TreeNode& child )
31 OptionalFloat delay = IsFloat( IsChild(child, "delay" ) );
32 OptionalFloat duration = IsFloat( IsChild(child, "duration" ) );
33 DALI_ASSERT_ALWAYS( duration && "Time period must have at least a duration" );
37 return TimePeriod( *delay, *duration );
41 return TimePeriod( *duration );
45 Property::Value GetPropertyValue( const Property::Type& propType, const TreeNode& child )
49 case Property::BOOLEAN:
51 return Property::Value( GetBoolean( child ) );
56 return Property::Value( GetFloat( child ) );
59 case Property::VECTOR2:
61 return Property::Value( GetVector2( child ) );
64 case Property::VECTOR3:
66 return Property::Value( GetVector3( child ) );
69 case Property::VECTOR4:
71 return Property::Value( GetVector4( child ) );
74 case Property::ROTATION:
76 if( 4 == child.Size() )
78 Vector4 v(GetVector4(child));
79 // angle, axis as per spec
80 return Property::Value( Quaternion(Radian(Degree(v[3])),
81 Vector3(v[0],v[1],v[2])) );
85 // degrees as per spec
86 Vector3 rotation = GetVector3( child );
87 return Property::Value( Quaternion(Radian(Degree(rotation.x)),
88 Radian(Degree(rotation.y)),
89 Radian(Degree(rotation.z))) );
93 case Property::NONE: // fall
96 DALI_ASSERT_ALWAYS( !"Property type incorrect" );
97 return Property::Value();
102 AlphaFunction GetAlphaFunction( const std::string& alphaFunction )
104 typedef std::map< const std::string, Dali::AlphaFunction > AlphaFunctionLut;
105 static AlphaFunctionLut alphaFunctionLut;
107 if( 0 == alphaFunctionLut.size() )
109 // coding convention is uppercase enums
110 alphaFunctionLut["DEFAULT"] = Dali::AlphaFunctions::Default;
111 alphaFunctionLut["LINEAR"] = Dali::AlphaFunctions::Linear;
112 alphaFunctionLut["REVERSE"] = Dali::AlphaFunctions::Reverse;
113 alphaFunctionLut["EASE_IN"] = Dali::AlphaFunctions::EaseIn;
114 alphaFunctionLut["EASE_OUT"] = Dali::AlphaFunctions::EaseOut;
115 alphaFunctionLut["EASE_IN_OUT"] = Dali::AlphaFunctions::EaseInOut;
116 alphaFunctionLut["EASE_IN_SINE"] = Dali::AlphaFunctions::EaseInSine;
117 alphaFunctionLut["EASE_OUT_SINE"] = Dali::AlphaFunctions::EaseOutSine;
118 alphaFunctionLut["EASE_IN_OUT_SINE"]= Dali::AlphaFunctions::EaseInOutSine;
119 alphaFunctionLut["BOUNCE"] = Dali::AlphaFunctions::Bounce;
120 alphaFunctionLut["BOUNCE_BACK"] = Dali::AlphaFunctions::BounceBack;
121 alphaFunctionLut["EASE_OUT_BACK"] = Dali::AlphaFunctions::EaseOutBack;
122 alphaFunctionLut["SIN"] = Dali::AlphaFunctions::Sin;
123 alphaFunctionLut["SIN2X"] = Dali::AlphaFunctions::Sin;
126 const AlphaFunctionLut::const_iterator iter( alphaFunctionLut.find( alphaFunction ) );
128 if( iter != alphaFunctionLut.end() )
134 DALI_ASSERT_ALWAYS( iter != alphaFunctionLut.end() && "Unknown Anchor Constant" );
135 return Dali::AlphaFunctions::Default;
139 } // unnamed namespace
151 Animation CreateAnimation( const TreeNode& child )
153 float durationSum = 0.f;
155 Animation animation( Animation::New( 0.f ) );
157 if( OptionalBoolean looping = IsBoolean( IsChild(child, "loop" ) ) )
159 animation.SetLooping( *looping );
162 if( OptionalString endAction = IsString( IsChild(child, "end-action" ) ) )
164 if("BAKE" == *endAction)
166 animation.SetEndAction( Animation::Bake );
168 else if("DISCARD" == *endAction)
170 animation.SetEndAction( Animation::Discard );
174 if( OptionalString endAction = IsString( IsChild(child, "destroy-action" ) ) )
176 if("BAKE" == *endAction)
178 animation.SetDestroyAction( Animation::Bake );
180 else if("DISCARD" == *endAction)
182 animation.SetDestroyAction( Animation::Discard );
186 OptionalChild propertiesNode = IsChild(child, "properties" );
189 const TreeNode::ConstIterator endIter = (*propertiesNode).CEnd();
190 for( TreeNode::ConstIterator iter = (*propertiesNode).CBegin(); endIter != iter; ++iter )
192 const TreeNode::KeyNodePair& pKeyChild = *iter;
194 OptionalString actorName( IsString( pKeyChild.second, "actor" ) );
195 OptionalString property( IsString( pKeyChild.second, "property" ) );
196 DALI_ASSERT_ALWAYS( actorName && "Animation must specify actor name" );
197 DALI_ASSERT_ALWAYS( property && "Animation must specify a property name" );
199 Actor targetActor = Stage::GetCurrent().GetRootLayer().FindChildByName( *actorName );
200 DALI_ASSERT_ALWAYS( targetActor && "Actor must exist for property" );
202 Property::Index idx( targetActor.GetPropertyIndex( *property ) );
204 // A limitation here is that its possible that between binding to the signal and
205 // the signal call that the ShaderEffect of the targetActor has been changed.
206 // However this is a unlikely use case especially when using scripts.
207 if( idx == Property::INVALID_INDEX )
209 if( ShaderEffect effect = targetActor.GetShaderEffect() )
211 idx = effect.GetPropertyIndex( *property );
212 if(idx != Property::INVALID_INDEX)
214 targetActor = effect;
218 DALI_SCRIPT_WARNING( "Cannot find property on object or ShaderEffect\n" );
224 DALI_SCRIPT_WARNING( "Cannot find property on object or ShaderEffect\n" );
229 if( idx == Property::INVALID_INDEX)
231 DALI_ASSERT_ALWAYS( idx != Property::INVALID_INDEX && "Animation must specify a valid property" );
235 Property prop( Property( targetActor, idx ) );
236 Property::Value propValue;
238 // these are the defaults
239 AlphaFunction alphaFunction( AlphaFunctions::Default );
240 TimePeriod timePeriod( 0.f );
242 if( OptionalChild timeChild = IsChild( pKeyChild.second, "time-period" ) )
244 timePeriod = GetTimePeriod( *timeChild );
247 durationSum = std::max( durationSum, timePeriod.delaySeconds + timePeriod.durationSeconds );
249 if( OptionalString alphaChild = IsString( pKeyChild.second, "alpha-function" ) )
251 alphaFunction = GetAlphaFunction( *alphaChild );
254 if( OptionalChild keyFrameChild = IsChild(pKeyChild.second, "key-frames") )
256 KeyFrames keyframes = KeyFrames::New();
258 const TreeNode::ConstIterator endIter = (*keyFrameChild).CEnd();
259 for( TreeNode::ConstIterator iter = (*keyFrameChild).CBegin(); endIter != iter; ++iter )
261 const TreeNode::KeyNodePair& kfKeyChild = *iter;
263 OptionalFloat kfProgress = IsFloat( kfKeyChild.second, "progress" );
264 DALI_ASSERT_ALWAYS( kfProgress && "Key frame entry must have 'progress'" );
266 OptionalChild kfValue = IsChild( kfKeyChild.second, "value" );
267 DALI_ASSERT_ALWAYS( kfValue && "Key frame entry must have 'value'" );
271 propValue = GetPropertyValue( prop.object.GetPropertyType(prop.propertyIndex), *kfValue );
275 DALI_LOG_WARNING( "Property:'%s' type does not match value type '%s'\n",
277 PropertyTypes::GetName(prop.object.GetPropertyType(prop.propertyIndex)) );
282 AlphaFunction kfAlphaFunction( AlphaFunctions::Default );
283 if( OptionalString alphaFuncStr = IsString( pKeyChild.second, "alpha-function") )
285 kfAlphaFunction = GetAlphaFunction( *alphaFuncStr );
288 keyframes.Add( *kfProgress, propValue, kfAlphaFunction );
291 animation.AnimateBetween( prop, keyframes, alphaFunction, timePeriod );
297 propValue = GetPropertyValue( prop.object.GetPropertyType(prop.propertyIndex), *IsChild(pKeyChild.second, "value") );
301 DALI_LOG_WARNING( "Property:'%s' type does not match value type '%s'\n", (*property).c_str(),
302 PropertyTypes::GetName( prop.object.GetPropertyType(prop.propertyIndex) ) );
307 if( OptionalBoolean relative = IsBoolean(pKeyChild.second, "relative") )
309 animation.AnimateBy( prop, propValue, alphaFunction, timePeriod );
313 animation.AnimateTo( prop, propValue, alphaFunction, timePeriod );
319 if( OptionalFloat duration = IsFloat( child, "duration" ) )
321 animation.SetDuration( *duration );
325 animation.SetDuration( durationSum );
331 } // namespace Internal
333 } // namespace Toolkit