Merge "Update README for dali-swig" into devel/master
[platform/core/uifw/dali-toolkit.git] / dali-toolkit / internal / visuals / transition-data-impl.cpp
1 /*
2  * Copyright (c) 2016 Samsung Electronics Co., Ltd.
3  *
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
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
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.
15  *
16  */
17
18 // CLASS HEADER
19 #include <dali-toolkit/internal/visuals/transition-data-impl.h>
20
21 // EXTERNAL HEADERS
22 #include <dali/dali.h>
23 #include <dali/devel-api/scripting/enum-helper.h>
24 #include <dali/integration-api/debug.h>
25 #include <dali-toolkit/public-api/controls/control.h>
26 #include <dali-toolkit/public-api/controls/control-impl.h>
27 #include <sstream>
28
29 using namespace Dali;
30
31 namespace
32 {
33 const char* TOKEN_TARGET("target");
34 const char* TOKEN_PROPERTY("property");
35 const char* TOKEN_INITIAL_VALUE("initialValue");
36 const char* TOKEN_TARGET_VALUE("targetValue");
37 const char* TOKEN_ANIMATOR("animator");
38 const char* TOKEN_TIME_PERIOD("timePeriod");
39 const char* TOKEN_DURATION("duration");
40 const char* TOKEN_DELAY("delay");
41 const char* TOKEN_ALPHA_FUNCTION("alphaFunction");
42
43
44 DALI_ENUM_TO_STRING_TABLE_BEGIN( ALPHA_FUNCTION_BUILTIN )
45 DALI_ENUM_TO_STRING_WITH_SCOPE(AlphaFunction, LINEAR)
46 DALI_ENUM_TO_STRING_WITH_SCOPE(AlphaFunction, REVERSE)
47 DALI_ENUM_TO_STRING_WITH_SCOPE(AlphaFunction, EASE_IN)
48 DALI_ENUM_TO_STRING_WITH_SCOPE(AlphaFunction, EASE_OUT)
49 DALI_ENUM_TO_STRING_WITH_SCOPE(AlphaFunction, EASE_IN_OUT)
50 DALI_ENUM_TO_STRING_WITH_SCOPE(AlphaFunction, EASE_IN_SQUARE)
51 DALI_ENUM_TO_STRING_WITH_SCOPE(AlphaFunction, EASE_OUT_SQUARE)
52 DALI_ENUM_TO_STRING_WITH_SCOPE(AlphaFunction, EASE_IN_SINE)
53 DALI_ENUM_TO_STRING_WITH_SCOPE(AlphaFunction, EASE_OUT_SINE)
54 DALI_ENUM_TO_STRING_WITH_SCOPE(AlphaFunction, EASE_IN_OUT_SINE)
55 DALI_ENUM_TO_STRING_WITH_SCOPE(AlphaFunction, EASE_OUT_BACK)
56 DALI_ENUM_TO_STRING_WITH_SCOPE(AlphaFunction, BOUNCE)
57 DALI_ENUM_TO_STRING_WITH_SCOPE(AlphaFunction, SIN)
58 DALI_ENUM_TO_STRING_TABLE_END( ALPHA_FUNCTION_BUILTIN )
59 }
60
61 namespace Dali
62 {
63 namespace Toolkit
64 {
65 namespace Internal
66 {
67
68 TransitionData::TransitionData()
69 {
70 }
71
72 TransitionData::~TransitionData()
73 {
74 }
75
76 TransitionDataPtr TransitionData::New( const Property::Array& value )
77 {
78   TransitionDataPtr transitionData( new TransitionData() );
79   transitionData->Initialize(value);
80   return transitionData;
81 }
82
83 TransitionDataPtr TransitionData::New( const Property::Map& value )
84 {
85   TransitionDataPtr transitionData( new TransitionData() );
86   transitionData->Initialize(value);
87   return transitionData;
88 }
89
90
91 void TransitionData::Initialize( const Property::Map& map )
92 {
93   TransitionData::Animator* animator = ConvertMap( map );
94   Add( animator );
95 }
96
97 void TransitionData::Initialize( const Property::Array& array )
98 {
99   for( unsigned int arrayIdx = 0, transitionArrayCount = array.Count(); arrayIdx < transitionArrayCount; ++arrayIdx )
100   {
101     const Property::Value& element = array.GetElementAt( arrayIdx );
102     // Expect each child to be an object representing an animator:
103
104     Property::Map* map = element.GetMap();
105     if( map != NULL )
106     {
107       TransitionData::Animator* animator = ConvertMap( *map );
108       Add( animator );
109     }
110   }
111 }
112
113 TransitionData::Animator* TransitionData::ConvertMap( const Property::Map& map)
114 {
115   TransitionData::Animator* animator = new TransitionData::Animator();
116   animator->alphaFunction = AlphaFunction::LINEAR;
117   animator->timePeriodDelay = 0.0f;
118   animator->timePeriodDuration = 1.0f;
119
120   for( unsigned int mapIdx = 0; mapIdx < map.Count(); ++mapIdx )
121   {
122     const KeyValuePair pair( map.GetKeyValue( mapIdx ) );
123     if( pair.first.type == Property::Key::INDEX )
124     {
125       continue; // We don't consider index keys.
126     }
127
128     const std::string& key( pair.first.stringKey );
129     const Property::Value& value( pair.second );
130
131     if( key == TOKEN_TARGET )
132     {
133       animator->objectName = value.Get< std::string >();
134     }
135     else if( key == TOKEN_PROPERTY )
136     {
137       if( value.GetType() == Property::STRING )
138       {
139         animator->propertyKey = Property::Key( value.Get<std::string>() );
140       }
141       else
142       {
143         animator->propertyKey = Property::Key( value.Get<int>() );
144       }
145     }
146     else if( key == TOKEN_INITIAL_VALUE )
147     {
148       animator->initialValue = value;
149     }
150     else if( key == TOKEN_TARGET_VALUE )
151     {
152       animator->targetValue = value;
153     }
154     else if( key == TOKEN_ANIMATOR )
155     {
156       animator->animate = true;
157       Property::Map animatorMap = value.Get< Property::Map >();
158       for( size_t animatorMapIdx = 0; animatorMapIdx < animatorMap.Count(); ++animatorMapIdx )
159       {
160         const KeyValuePair pair( animatorMap.GetKeyValue( animatorMapIdx ) );
161
162         if( pair.first.type == Property::Key::INDEX )
163         {
164           continue; // We don't consider index keys.
165         }
166
167         const std::string& key( pair.first.stringKey );
168         const Property::Value& value( pair.second );
169
170         if( key == TOKEN_ALPHA_FUNCTION )
171         {
172           if( value.GetType() == Property::ARRAY )
173           {
174             bool valid = true;
175             Vector4 controlPoints;
176             Property::Array *array = value.GetArray();
177             if( array && array->Count() >= 4 )
178             {
179               for( size_t vecIdx = 0; vecIdx < 4; ++vecIdx )
180               {
181                 Property::Value& v = array->GetElementAt(vecIdx);
182                 if( v.GetType() == Property::FLOAT )
183                 {
184                   controlPoints[vecIdx] = v.Get<float>();
185                 }
186                 else
187                 {
188                   valid = false;
189                   break;
190                 }
191               }
192             }
193             else
194             {
195               valid = false;
196             }
197
198             if( valid )
199             {
200               Vector2 controlPoint1( controlPoints.x, controlPoints.y );
201               Vector2 controlPoint2( controlPoints.z, controlPoints.w );
202               animator->alphaFunction = AlphaFunction( controlPoint1, controlPoint2 );
203             }
204             else
205             {
206               animator->animate = false;
207             }
208           }
209           else if( value.GetType() == Property::VECTOR4 )
210           {
211             Vector4 controlPoints = value.Get<Vector4>();
212             Vector2 controlPoint1( controlPoints.x, controlPoints.y );
213             Vector2 controlPoint2( controlPoints.z, controlPoints.w );
214             animator->alphaFunction = AlphaFunction( controlPoint1, controlPoint2 );
215           }
216           else if( value.GetType() == Property::STRING )
217           {
218             std::string alphaFunctionValue = value.Get< std::string >();
219
220             if( alphaFunctionValue == "LINEAR" )
221             {
222               animator->alphaFunction = AlphaFunction(AlphaFunction::LINEAR);
223             }
224             else if( ! alphaFunctionValue.compare(0, 5, "EASE_" ) )
225             {
226               if( alphaFunctionValue == "EASE_IN" )
227               {
228                 animator->alphaFunction = AlphaFunction(AlphaFunction::EASE_IN);
229               }
230               else if( alphaFunctionValue == "EASE_OUT" )
231               {
232                 animator->alphaFunction = AlphaFunction(AlphaFunction::EASE_OUT);
233               }
234               else if( ! alphaFunctionValue.compare( 5, 3, "IN_" ) )
235               {
236                 if( ! alphaFunctionValue.compare(8, -1, "SQUARE" ))
237                 {
238                   animator->alphaFunction = AlphaFunction(AlphaFunction::EASE_IN_SQUARE);
239                 }
240                 else if( ! alphaFunctionValue.compare(8, -1, "OUT" ))
241                 {
242                   animator->alphaFunction = AlphaFunction(AlphaFunction::EASE_IN_OUT);
243                 }
244                 else if( ! alphaFunctionValue.compare(8, -1, "OUT_SINE" ))
245                 {
246                   animator->alphaFunction = AlphaFunction(AlphaFunction::EASE_IN_OUT_SINE);
247                 }
248                 else if( ! alphaFunctionValue.compare(8, -1, "SINE" ))
249                 {
250                   animator->alphaFunction = AlphaFunction(AlphaFunction::EASE_IN_SINE);
251                 }
252               }
253               else if( ! alphaFunctionValue.compare( 5, 4, "OUT_" ) )
254               {
255                 if( ! alphaFunctionValue.compare(9, -1, "SQUARE" ) )
256                 {
257                   animator->alphaFunction = AlphaFunction(AlphaFunction::EASE_OUT_SQUARE);
258                 }
259                 else if( ! alphaFunctionValue.compare(9, -1, "SINE" ) )
260                 {
261                   animator->alphaFunction = AlphaFunction(AlphaFunction::EASE_OUT_SINE);
262                 }
263                 else if( ! alphaFunctionValue.compare(9, -1, "BACK" ) )
264                 {
265                   animator->alphaFunction = AlphaFunction(AlphaFunction::EASE_OUT_BACK);
266                 }
267               }
268             }
269             else if( alphaFunctionValue == "REVERSE" )
270             {
271               animator->alphaFunction = AlphaFunction(AlphaFunction::REVERSE);
272             }
273             else if( alphaFunctionValue == "BOUNCE" )
274             {
275               animator->alphaFunction = AlphaFunction(AlphaFunction::BOUNCE);
276             }
277             else if( alphaFunctionValue == "SIN" )
278             {
279               animator->alphaFunction = AlphaFunction(AlphaFunction::SIN);
280             }
281           }
282           else
283           {
284             animator->animate = false;
285           }
286         }
287         else if( key == TOKEN_TIME_PERIOD )
288         {
289           Property::Map timeMap = value.Get< Property::Map >();
290           for( size_t timeMapIdx = 0; timeMapIdx < timeMap.Count(); ++timeMapIdx )
291           {
292             const KeyValuePair pair( timeMap.GetKeyValue( timeMapIdx ) );
293             if( pair.first.type == Property::Key::INDEX )
294             {
295               continue;
296             }
297             const std::string& key( pair.first.stringKey );
298
299             if( key == TOKEN_DELAY )
300             {
301               animator->timePeriodDelay = pair.second.Get< float >();
302             }
303             else if( key == TOKEN_DURATION )
304             {
305               animator->timePeriodDuration = pair.second.Get< float >();
306             }
307           }
308         }
309       }
310     }
311   }
312   return animator;
313 }
314
315 void TransitionData::Add( Animator* animator )
316 {
317   mAnimators.PushBack( animator );
318 }
319
320 TransitionData::Iterator TransitionData::Begin() const
321 {
322   return mAnimators.Begin();
323 }
324
325 TransitionData::Iterator TransitionData::End() const
326 {
327   return mAnimators.End();
328 }
329
330 size_t TransitionData::Count() const
331 {
332   return mAnimators.Count();
333 }
334
335 Property::Map TransitionData::GetAnimatorAt( size_t index )
336 {
337   DALI_ASSERT_ALWAYS( index < Count() && "index exceeds bounds" );
338
339   Animator* animator = mAnimators[index];
340   Property::Map map;
341   map[TOKEN_TARGET] = animator->objectName;
342   if( animator->propertyKey.type == Property::Key::INDEX )
343   {
344     map[TOKEN_PROPERTY] = animator->propertyKey.indexKey;
345   }
346   else
347   {
348     map[TOKEN_PROPERTY] = animator->propertyKey.stringKey;
349   }
350   if( animator->initialValue.GetType() != Property::NONE )
351   {
352     map[TOKEN_INITIAL_VALUE] = animator->initialValue;
353   }
354   if( animator->targetValue.GetType() != Property::NONE )
355   {
356     map[TOKEN_TARGET_VALUE] = animator->targetValue;
357   }
358   if( animator->animate )
359   {
360     Property::Map animateMap;
361
362     if( animator->alphaFunction.GetMode() == AlphaFunction::BUILTIN_FUNCTION )
363     {
364       animateMap.Add(TOKEN_ALPHA_FUNCTION, GetEnumerationName( animator->alphaFunction.GetBuiltinFunction(),
365                                                                ALPHA_FUNCTION_BUILTIN_TABLE,
366                                                                ALPHA_FUNCTION_BUILTIN_TABLE_COUNT ));
367     }
368     else if( animator->alphaFunction.GetMode() == AlphaFunction::BEZIER )
369     {
370       Vector4 controlPoints = animator->alphaFunction.GetBezierControlPoints();
371       animateMap.Add( TOKEN_ALPHA_FUNCTION, controlPoints );
372     }
373     animateMap.Add(TOKEN_TIME_PERIOD, Property::Map()
374                    .Add( TOKEN_DELAY, animator->timePeriodDelay )
375                    .Add( TOKEN_DURATION, animator->timePeriodDuration ));
376
377     map[TOKEN_ANIMATOR] = animateMap;
378   }
379
380   return map;
381 }
382
383 } // namespace Internal
384 } // namespace Toolkit
385 } // namespace Dali