Merge "Enable Property::LABEL visual of a button when CreateVisuals" into devel/master
[platform/core/uifw/dali-toolkit.git] / dali-toolkit / internal / layouting / layout-transition-data-impl.cpp
1 /*
2  * Copyright (c) 2018 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 #include <dali/integration-api/debug.h>
18
19 #include <dali/public-api/animation/animation.h>
20 #include <dali/public-api/object/base-handle.h>
21 #include <dali/public-api/object/type-registry-helper.h>
22 #include <dali-toolkit/public-api/controls/control.h>
23 #include <dali/devel-api/object/handle-devel.h>
24 #include <dali-toolkit/devel-api/layouting/layout-item-impl.h>
25 #include <dali-toolkit/devel-api/layouting/layout-group-impl.h>
26 #include <dali-toolkit/internal/layouting/layout-transition-data-impl.h>
27 #include <dali-toolkit/internal/layouting/layout-item-data-impl.h>
28
29 #include <dali/devel-api/scripting/enum-helper.h>
30
31 namespace
32 {
33 #if defined(DEBUG_ENABLED)
34 Debug::Filter* gLayoutFilter = Debug::Filter::New( Debug::NoLogging, false, "LOG_LAYOUT" );
35 #endif
36
37 // Key tokens
38 const char* TOKEN_CONDITION("condition");
39 const char* TOKEN_AFFECTS_SIBLINGS("affectsSiblings");
40 const char* TOKEN_PROPERTY("property");
41 const char* TOKEN_INITIAL_VALUE("initialValue");
42 const char* TOKEN_TARGET_VALUE("targetValue");
43 const char* TOKEN_ANIMATOR("animator");
44 const char* TOKEN_TYPE("type");
45 const char* TOKEN_NAME("name");
46 const char* TOKEN_TIME_PERIOD("timePeriod");
47 const char* TOKEN_DURATION("duration");
48 const char* TOKEN_DELAY("delay");
49 const char* TOKEN_ALPHA_FUNCTION("alphaFunction");
50
51 DALI_ENUM_TO_STRING_TABLE_BEGIN( ANIMATOR_TYPE )
52 DALI_ENUM_TO_STRING_WITH_SCOPE( Dali::Toolkit::LayoutTransitionData::Animator::Type, ANIMATE_TO )
53 DALI_ENUM_TO_STRING_WITH_SCOPE( Dali::Toolkit::LayoutTransitionData::Animator::Type, ANIMATE_BY )
54 DALI_ENUM_TO_STRING_WITH_SCOPE( Dali::Toolkit::LayoutTransitionData::Animator::Type, ANIMATE_BETWEEN )
55 DALI_ENUM_TO_STRING_WITH_SCOPE( Dali::Toolkit::LayoutTransitionData::Animator::Type, ANIMATE_PATH )
56 DALI_ENUM_TO_STRING_TABLE_END( ANIMATOR_TYPE )
57
58 DALI_ENUM_TO_STRING_TABLE_BEGIN( ALPHA_FUNCTION_BUILTIN )
59 DALI_ENUM_TO_STRING_WITH_SCOPE(Dali::AlphaFunction, LINEAR)
60 DALI_ENUM_TO_STRING_WITH_SCOPE(Dali::AlphaFunction, REVERSE)
61 DALI_ENUM_TO_STRING_WITH_SCOPE(Dali::AlphaFunction, EASE_IN)
62 DALI_ENUM_TO_STRING_WITH_SCOPE(Dali::AlphaFunction, EASE_OUT)
63 DALI_ENUM_TO_STRING_WITH_SCOPE(Dali::AlphaFunction, EASE_IN_OUT)
64 DALI_ENUM_TO_STRING_WITH_SCOPE(Dali::AlphaFunction, EASE_IN_SQUARE)
65 DALI_ENUM_TO_STRING_WITH_SCOPE(Dali::AlphaFunction, EASE_OUT_SQUARE)
66 DALI_ENUM_TO_STRING_WITH_SCOPE(Dali::AlphaFunction, EASE_IN_SINE)
67 DALI_ENUM_TO_STRING_WITH_SCOPE(Dali::AlphaFunction, EASE_OUT_SINE)
68 DALI_ENUM_TO_STRING_WITH_SCOPE(Dali::AlphaFunction, EASE_IN_OUT_SINE)
69 DALI_ENUM_TO_STRING_WITH_SCOPE(Dali::AlphaFunction, EASE_OUT_BACK)
70 DALI_ENUM_TO_STRING_WITH_SCOPE(Dali::AlphaFunction, BOUNCE)
71 DALI_ENUM_TO_STRING_WITH_SCOPE(Dali::AlphaFunction, SIN)
72 DALI_ENUM_TO_STRING_TABLE_END( ALPHA_FUNCTION_BUILTIN )
73
74 }
75
76 namespace Dali
77 {
78 namespace Toolkit
79 {
80 namespace Internal
81 {
82
83 bool LayoutDataElement::AdjustMeasuredSize( float& width, float& height, Toolkit::LayoutTransitionData::Animator::Type animatorType )
84 {
85   bool adjusted = true;
86   if( targetValue.GetType() == Property::NONE )
87   {
88     return false;
89   }
90
91   Actor actor = handle.GetHandle();
92   float animateByMultiplier = ( animatorType == Toolkit::LayoutTransitionData::Animator::Type::ANIMATE_BY ) ? 1.0f : 0.0f;
93   Vector3 size = actor.GetCurrentSize();
94
95   switch ( targetValue.GetType() )
96   {
97     case Property::Type::VECTOR3:
98     {
99       Vector3 value = targetValue.Get<Vector3>();
100       switch( propertyIndex )
101       {
102         case Actor::Property::SCALE:
103         {
104           width = size.x * ( animateByMultiplier + value.x );
105           height = size.y * ( animateByMultiplier + value.y );
106           break;
107         }
108         case Actor::Property::SIZE:
109         {
110           width = value.x + ( animateByMultiplier * size.x );
111           height = value.y + ( animateByMultiplier * size.y );
112           break;
113         }
114         default:
115         {
116           adjusted = false;
117           break;
118         }
119       }
120       break;
121     }
122     case Property::Type::FLOAT:
123     {
124       float value = targetValue.Get<float>();
125       switch( propertyIndex )
126       {
127         case Actor::Property::SCALE_X:
128         {
129           width = size.x * ( animateByMultiplier + value );
130           break;
131         }
132         case Actor::Property::SCALE_Y:
133         {
134           height = size.y * ( animateByMultiplier + value );
135           break;
136         }
137         case Actor::Property::SIZE_WIDTH:
138         {
139           width = value + ( animateByMultiplier * size.x );
140           break;
141         }
142         case Actor::Property::SIZE_HEIGHT:
143         {
144           height = value + ( animateByMultiplier * size.y );
145           break;
146         }
147         default:
148         {
149           adjusted = true;
150           break;
151         }
152       }
153       break;
154     }
155     default:
156     {
157       adjusted = false;
158       break;
159     }
160   }
161
162   return adjusted;
163 }
164
165 void LayoutDataElement::UpdatePropertyIndex()
166 {
167   if( propertyIndex == -1 && !propertyName.empty() )
168   {
169     Actor actor = handle.GetHandle();
170     if( actor )
171     {
172       propertyIndex = DevelHandle::GetPropertyIndex( actor, Property::Key( propertyName ) );
173     }
174   }
175 }
176
177 void LayoutDataElement::UpdateAnimatorIndex( const LayoutAnimatorArray& animators )
178 {
179   if( animatorIndex == -1 )
180   {
181     if( animatorName.empty() )
182     {
183       animatorIndex = 0;
184       return;
185     }
186
187     std::string animatorName = this->animatorName;
188     auto animator = std::find_if( animators.begin(), animators.end(), [ &animatorName ](const LayoutDataAnimator& iter) {
189       return ( iter.name == animatorName ); } );
190     if( animator != animators.end() )
191     {
192       animatorIndex = std::distance( animators.begin(), animator );
193     }
194   }
195 }
196
197 void LayoutDataElement::UpdatePositionDataIndex( LayoutData& layoutData )
198 {
199     positionDataIndex = layoutData.layoutPositionDataArray.size() - 1;
200     switch( propertyIndex )
201     {
202       case Actor::Property::SCALE:
203       case Actor::Property::SCALE_X:
204       case Actor::Property::SCALE_Y:
205         if( positionDataIndex != -1 && updateMeasuredSize )
206         {
207           layoutData.layoutPositionDataArray[ positionDataIndex ].updateWithCurrentSize = true;
208         }
209         break;
210     }
211 }
212
213 LayoutTransitionData::LayoutTransitionData() :
214   mUpdateMeasuredSize( false )
215 {
216 }
217
218 LayoutTransitionData::~LayoutTransitionData()
219 {
220 }
221
222 LayoutTransitionDataPtr LayoutTransitionData::New()
223 {
224   LayoutTransitionDataPtr layoutAnimationData( new LayoutTransitionData() );
225   return layoutAnimationData;
226 }
227
228 LayoutTransitionData::PropertyAnimator::PropertyAnimator( )
229   : handle()
230   , map()
231   , interpolation( Animation::Linear )
232 {
233 }
234
235 LayoutTransitionData::PropertyAnimator::PropertyAnimator( Actor actor, Property::Map map )
236   : handle( actor )
237   , map( map )
238   , interpolation( Animation::Linear )
239 {
240 }
241
242 LayoutTransitionData::PropertyAnimator::PropertyAnimator( Actor actor,  Property::Map map, Path path, Vector3 forward )
243   : handle( actor )
244   , map( map )
245   , interpolation( Animation::Linear )
246   , path( path )
247   , forward( forward )
248 {
249 }
250
251 LayoutTransitionData::PropertyAnimator::PropertyAnimator( Actor actor, Property::Map map, KeyFrames keyFrames, Animation::Interpolation interpolation  )
252   : handle( actor )
253   , map( map )
254   , keyFrames( keyFrames )
255   , interpolation( interpolation )
256 {
257 }
258
259 void LayoutTransitionData::AddPropertyAnimator( Actor actor, Property::Map map )
260 {
261   LayoutDataElement layoutDataElement;
262   if( ConvertToLayoutDataElement( PropertyAnimator( actor, map ), layoutDataElement ) )
263   {
264     mLayoutDataElements.push_back( layoutDataElement );
265   }
266
267   UpdateAnimatorsIndices();
268 }
269
270 void LayoutTransitionData::AddPropertyAnimator( Actor actor, Property::Map map, KeyFrames keyFrames, Animation::Interpolation interpolation )
271 {
272   LayoutDataElement layoutDataElement;
273   if( ConvertToLayoutDataElement( PropertyAnimator( actor, map, keyFrames, interpolation ), layoutDataElement ) )
274   {
275     mLayoutDataElements.push_back( layoutDataElement );
276   }
277
278   UpdateAnimatorsIndices();
279 }
280
281 void LayoutTransitionData::AddPropertyAnimator( Actor actor, Property::Map map, Path path, Vector3 forward )
282 {
283   LayoutDataElement layoutDataElement;
284   if( ConvertToLayoutDataElement( PropertyAnimator( actor, map, path, forward ), layoutDataElement ) )
285   {
286     mLayoutDataElements.push_back( layoutDataElement );
287   }
288
289   UpdateAnimatorsIndices();
290 }
291
292 bool LayoutTransitionData::ConvertToLayoutAnimator( const Property::Map& animatorMap, const PropertyAnimator& propertyAnimator, LayoutDataAnimator& layoutDataAnimator )
293 {
294   bool valid = true;
295
296   for ( size_t animatorMapIdx = 0; animatorMapIdx < animatorMap.Count(); ++animatorMapIdx )
297   {
298     const KeyValuePair pair( animatorMap.GetKeyValue( animatorMapIdx ) );
299
300     Property::Index indexKey = Property::INVALID_INDEX;
301     if ( pair.first.type == Property::Key::STRING )
302     {
303       const std::string& key(pair.first.stringKey);
304       if( key == TOKEN_TYPE )
305       {
306         indexKey = Dali::Toolkit::LayoutTransitionData::AnimatorKey::TYPE;
307       }
308       else if( key == TOKEN_NAME )
309       {
310         indexKey = Dali::Toolkit::LayoutTransitionData::AnimatorKey::NAME;
311       }
312       else if( key == TOKEN_TIME_PERIOD )
313       {
314         indexKey = Dali::Toolkit::LayoutTransitionData::AnimatorKey::TIME_PERIOD;
315       }
316       else if( key == TOKEN_ALPHA_FUNCTION )
317       {
318         indexKey = Dali::Toolkit::LayoutTransitionData::AnimatorKey::ALPHA_FUNCTION;
319       }
320     }
321     else
322     {
323       indexKey = pair.first.indexKey;
324     }
325
326     const Property::Value& value( pair.second );
327
328     if ( indexKey == Dali::Toolkit::LayoutTransitionData::AnimatorKey::ALPHA_FUNCTION )
329     {
330       if ( value.GetType() == Property::ARRAY )
331       {
332         valid = true;
333         Vector4 controlPoints;
334         Property::Array *array = value.GetArray();
335         if ( array && array->Count() >= 4 )
336         {
337           for ( size_t vecIdx = 0; vecIdx < 4; ++vecIdx )
338           {
339             Property::Value& v = array->GetElementAt( vecIdx );
340             if ( v.GetType() == Property::FLOAT )
341             {
342               controlPoints[vecIdx] = v.Get<float>();
343             }
344             else
345             {
346               valid = false;
347               break;
348             }
349           }
350         }
351         else
352         {
353           valid = false;
354         }
355
356         if ( valid )
357         {
358           Vector2 controlPoint1( controlPoints.x, controlPoints.y );
359           Vector2 controlPoint2( controlPoints.z, controlPoints.w );
360           layoutDataAnimator.alphaFunction = AlphaFunction( controlPoint1, controlPoint2 );
361         }
362         else
363         {
364           valid = false;
365         }
366       }
367       else if ( value.GetType() == Property::VECTOR4 )
368       {
369         Vector4 controlPoints = value.Get<Vector4>();
370         Vector2 controlPoint1( controlPoints.x, controlPoints.y );
371         Vector2 controlPoint2( controlPoints.z, controlPoints.w );
372         layoutDataAnimator.alphaFunction = AlphaFunction( controlPoint1, controlPoint2 );
373       }
374       else if ( value.GetType() == Property::INTEGER )
375       {
376         layoutDataAnimator.alphaFunction = AlphaFunction( static_cast<AlphaFunction::BuiltinFunction>( value.Get<int>() ) );
377       }
378       else if ( value.GetType() == Property::STRING )
379       {
380         std::string alphaFunctionValue = value.Get<std::string>();
381
382         if ( alphaFunctionValue == "LINEAR" )
383         {
384           layoutDataAnimator.alphaFunction = AlphaFunction( AlphaFunction::LINEAR );
385         }
386         else if ( !alphaFunctionValue.compare( 0, 5, "EASE_" ) )
387         {
388           if ( alphaFunctionValue == "EASE_IN" )
389           {
390             layoutDataAnimator.alphaFunction = AlphaFunction( AlphaFunction::EASE_IN );
391           }
392           else if ( alphaFunctionValue == "EASE_OUT" )
393           {
394             layoutDataAnimator.alphaFunction = AlphaFunction( AlphaFunction::EASE_OUT );
395           }
396           else if ( !alphaFunctionValue.compare( 5, 3, "IN_" ) )
397           {
398             if ( !alphaFunctionValue.compare( 8, -1, "SQUARE" ) )
399             {
400               layoutDataAnimator.alphaFunction = AlphaFunction( AlphaFunction::EASE_IN_SQUARE );
401             }
402             else if ( !alphaFunctionValue.compare( 8, -1, "OUT" ) )
403             {
404               layoutDataAnimator.alphaFunction = AlphaFunction( AlphaFunction::EASE_IN_OUT );
405             }
406             else if ( !alphaFunctionValue.compare( 8, -1, "OUT_SINE" ) )
407             {
408               layoutDataAnimator.alphaFunction = AlphaFunction( AlphaFunction::EASE_IN_OUT_SINE );
409             }
410             else if ( !alphaFunctionValue.compare( 8, -1, "SINE" ) )
411             {
412               layoutDataAnimator.alphaFunction = AlphaFunction( AlphaFunction::EASE_IN_SINE );
413             }
414           }
415           else if ( !alphaFunctionValue.compare( 5, 4, "OUT_" ) )
416           {
417             if ( !alphaFunctionValue.compare( 9, -1, "SQUARE" ) )
418             {
419               layoutDataAnimator.alphaFunction = AlphaFunction( AlphaFunction::EASE_OUT_SQUARE );
420             }
421             else if ( !alphaFunctionValue.compare( 9, -1, "SINE" ) )
422             {
423               layoutDataAnimator.alphaFunction = AlphaFunction( AlphaFunction::EASE_OUT_SINE );
424             }
425             else if ( !alphaFunctionValue.compare( 9, -1, "BACK" ) )
426             {
427               layoutDataAnimator.alphaFunction = AlphaFunction( AlphaFunction::EASE_OUT_BACK );
428             }
429           }
430         }
431         else if ( alphaFunctionValue == "REVERSE" )
432         {
433           layoutDataAnimator.alphaFunction = AlphaFunction( AlphaFunction::REVERSE );
434         }
435         else if ( alphaFunctionValue == "BOUNCE" )
436         {
437           layoutDataAnimator.alphaFunction = AlphaFunction( AlphaFunction::BOUNCE );
438         }
439         else if ( alphaFunctionValue == "SIN" )
440         {
441           layoutDataAnimator.alphaFunction = AlphaFunction( AlphaFunction::SIN );
442         }
443         else
444         {
445           valid = false;
446         }
447       }
448       else
449       {
450         valid = false;
451       }
452     }
453     else if ( indexKey == Dali::Toolkit::LayoutTransitionData::AnimatorKey::NAME )
454     {
455       if( value.GetType() == Property::STRING )
456       {
457         layoutDataAnimator.name = value.Get<std::string>();
458       }
459     }
460     else if ( indexKey == Dali::Toolkit::LayoutTransitionData::AnimatorKey::TYPE )
461     {
462       if( value.GetType() == Property::STRING )
463       {
464         std::string animatorType = value.Get<std::string>();
465         if( animatorType == ANIMATOR_TYPE_TABLE[ Toolkit::LayoutTransitionData::Animator::Type::ANIMATE_TO ].string )
466         {
467           layoutDataAnimator.animatorType = Toolkit::LayoutTransitionData::Animator::Type::ANIMATE_TO;
468         }
469         else if( animatorType == ANIMATOR_TYPE_TABLE[ Toolkit::LayoutTransitionData::Animator::Type::ANIMATE_BY ].string )
470         {
471           layoutDataAnimator.animatorType = Toolkit::LayoutTransitionData::Animator::Type::ANIMATE_BY;
472         }
473         else if( animatorType == ANIMATOR_TYPE_TABLE[ Toolkit::LayoutTransitionData::Animator::Type::ANIMATE_BETWEEN ].string )
474         {
475           layoutDataAnimator.animatorType = Toolkit::LayoutTransitionData::Animator::Type::ANIMATE_BETWEEN;
476           layoutDataAnimator.keyFrames = propertyAnimator.keyFrames;
477         }
478         else if( animatorType == ANIMATOR_TYPE_TABLE[ Toolkit::LayoutTransitionData::Animator::Type::ANIMATE_PATH ].string )
479         {
480           layoutDataAnimator.animatorType = Toolkit::LayoutTransitionData::Animator::Type::ANIMATE_PATH;
481           layoutDataAnimator.path = propertyAnimator.path;
482           layoutDataAnimator.forward = propertyAnimator.forward;
483         }
484       }
485       else if ( value.GetType() == Property::INTEGER )
486       {
487         layoutDataAnimator.animatorType = static_cast<Toolkit::LayoutTransitionData::Animator::Type>( pair.second.Get<int>() );
488       }
489     }
490     else if ( indexKey == Dali::Toolkit::LayoutTransitionData::AnimatorKey::TIME_PERIOD )
491     {
492       Property::Map timeMap = value.Get<Property::Map>();
493       for ( size_t timeMapIdx = 0; timeMapIdx < timeMap.Count(); ++timeMapIdx )
494       {
495         const KeyValuePair pair( timeMap.GetKeyValue( timeMapIdx ) );
496         indexKey = Property::INVALID_INDEX;
497
498         if ( pair.first.type == Property::Key::STRING)
499         {
500           const std::string& key( pair.first.stringKey );
501           if( key == TOKEN_DURATION )
502           {
503             indexKey = Dali::Toolkit::LayoutTransitionData::AnimatorKey::DURATION;
504           }
505           else if( key == TOKEN_DELAY )
506           {
507             indexKey = Dali::Toolkit::LayoutTransitionData::AnimatorKey::DELAY;
508           }
509         }
510         else
511         {
512           indexKey = pair.first.indexKey;
513         }
514
515         if ( indexKey == Dali::Toolkit::LayoutTransitionData::AnimatorKey::DELAY )
516         {
517           layoutDataAnimator.timePeriod.delaySeconds = pair.second.Get<float>();
518         }
519         else if ( indexKey == Dali::Toolkit::LayoutTransitionData::AnimatorKey::DURATION )
520         {
521           layoutDataAnimator.timePeriod.durationSeconds = pair.second.Get<float>();
522         }
523       }
524     }
525   }
526
527   return valid;
528 }
529
530 bool LayoutTransitionData::ConvertToLayoutDataElement(
531     const PropertyAnimator& propertyAnimator, LayoutDataElement& layoutDataElement )
532 {
533   const Property::Map& map = propertyAnimator.map;
534   bool propertyFound = false;
535
536   if( mLayoutAnimators.size() == 0 )
537   {
538     mLayoutAnimators.push_back( LayoutDataAnimator() );
539   }
540
541   layoutDataElement.handle = propertyAnimator.handle;
542
543   for( unsigned int mapIdx = 0; mapIdx < map.Count(); ++mapIdx )
544   {
545     const KeyValuePair pair( map.GetKeyValue( mapIdx ) );
546     const Property::Value& value( pair.second );
547     Property::Index indexKey = Property::INVALID_INDEX;
548
549     if ( pair.first.type == Property::Key::STRING )
550     {
551       const std::string& key( pair.first.stringKey );
552       if ( key == TOKEN_CONDITION )
553       {
554         indexKey = Dali::Toolkit::LayoutTransitionData::AnimatorKey::CONDITION;
555       }
556       if ( key == TOKEN_PROPERTY )
557       {
558         indexKey = Dali::Toolkit::LayoutTransitionData::AnimatorKey::PROPERTY;
559       }
560       else if( key == TOKEN_INITIAL_VALUE )
561       {
562         indexKey = Dali::Toolkit::LayoutTransitionData::AnimatorKey::INITIAL_VALUE;
563       }
564       else if( key == TOKEN_TARGET_VALUE )
565       {
566         indexKey = Dali::Toolkit::LayoutTransitionData::AnimatorKey::TARGET_VALUE;
567       }
568       else if( key == TOKEN_ANIMATOR )
569       {
570         indexKey = Dali::Toolkit::LayoutTransitionData::AnimatorKey::ANIMATOR;
571       }
572       else if( key == TOKEN_AFFECTS_SIBLINGS )
573       {
574         indexKey = Dali::Toolkit::LayoutTransitionData::AnimatorKey::AFFECTS_SIBLINGS;
575       }
576     }
577     else
578     {
579       indexKey = pair.first.indexKey;
580     }
581
582     if( indexKey == Dali::Toolkit::LayoutTransitionData::AnimatorKey::CONDITION )
583     {
584       layoutDataElement.condition = value.Get<int>();
585     }
586     else if ( indexKey == Dali::Toolkit::LayoutTransitionData::AnimatorKey::AFFECTS_SIBLINGS )
587     {
588       layoutDataElement.updateMeasuredSize = value.Get<bool>();
589       if( layoutDataElement.updateMeasuredSize )
590       {
591         mUpdateMeasuredSize = true;
592       }
593     }
594     else if( indexKey == Dali::Toolkit::LayoutTransitionData::AnimatorKey::PROPERTY )
595     {
596       if( value.GetType() == Property::STRING )
597       {
598         layoutDataElement.propertyName = value.Get<std::string>();
599         layoutDataElement.UpdatePropertyIndex();
600       }
601       else
602       {
603         layoutDataElement.propertyIndex = value.Get<int>();
604       }
605       propertyFound = true;
606     }
607     else if( indexKey == Dali::Toolkit::LayoutTransitionData::AnimatorKey::INITIAL_VALUE )
608     {
609       layoutDataElement.initialValue = value;
610     }
611     else if( indexKey == Dali::Toolkit::LayoutTransitionData::AnimatorKey::TARGET_VALUE )
612     {
613       layoutDataElement.targetValue = value;
614     }
615     else if( indexKey == Dali::Toolkit::LayoutTransitionData::AnimatorKey::ANIMATOR )
616     {
617       if( value.GetType() == Property::STRING )
618       {
619         layoutDataElement.animatorName = value.Get<std::string>();
620         layoutDataElement.UpdateAnimatorIndex( mLayoutAnimators );
621       }
622       else if ( value.GetType() == Property::MAP )
623       {
624         Property::Map animatorMap = value.Get< Property::Map >();
625         LayoutDataAnimator layoutDataAnimator;
626         if( ConvertToLayoutAnimator( animatorMap, propertyAnimator, layoutDataAnimator ) )
627         {
628           mLayoutAnimators.push_back( layoutDataAnimator );
629           layoutDataElement.animatorIndex = mLayoutAnimators.size() - 1;
630         }
631       }
632     }
633   }
634
635   return propertyFound;
636 }
637
638 void LayoutTransitionData::CollectChildrenLayoutDataElements( Actor child, LayoutData& layoutData )
639 {
640   LayoutDataArray& layoutDataArray = layoutData.layoutDataArray;
641   // Add the children animators
642   for( const LayoutDataElement& iter : layoutData.childrenLayoutDataArray )
643   {
644     Actor actor = iter.handle.GetHandle();
645     if( actor && actor != child )
646     {
647       continue;
648     }
649
650     LayoutDataElement layoutDataElement = iter;
651     Actor gainedChild = layoutData.layoutTransition.gainedChild.GetHandle();
652     Actor lostChild = layoutData.layoutTransition.lostChild.GetHandle();
653     switch ( layoutDataElement.condition )
654     {
655       case Dali::Toolkit::LayoutTransitionData::Condition::ON_ADD:
656         if ( layoutData.layoutTransition.layoutTransitionType != Dali::Toolkit::LayoutTransitionData::ON_CHILD_ADD
657             || gainedChild != child )
658         {
659           continue;
660         }
661         break;
662       case Dali::Toolkit::LayoutTransitionData::Condition::ON_REMOVE:
663         if( layoutData.layoutTransition.layoutTransitionType != Dali::Toolkit::LayoutTransitionData::ON_CHILD_REMOVE
664             || lostChild != child )
665         {
666           continue;
667         }
668         break;
669       case Dali::Toolkit::LayoutTransitionData::Condition::ON_FOCUS_GAINED:
670         if( layoutData.layoutTransition.layoutTransitionType != Dali::Toolkit::LayoutTransitionData::ON_CHILD_FOCUS
671             || gainedChild != child )
672         {
673           continue;
674         }
675         break;
676       case Dali::Toolkit::LayoutTransitionData::Condition::ON_FOCUS_LOST:
677         if( layoutData.layoutTransition.layoutTransitionType != Dali::Toolkit::LayoutTransitionData::ON_CHILD_FOCUS
678             || lostChild != child )
679         {
680           continue;
681         }
682         break;
683       default:
684         break;
685     }
686
687     if( layoutData.updateMeasuredSize && !layoutDataElement.updateMeasuredSize )
688     {
689       continue;
690     }
691
692     layoutDataElement.handle = child;
693     layoutDataElement.UpdatePropertyIndex();
694     layoutDataElement.UpdatePositionDataIndex( layoutData );
695     layoutDataArray.push_back( layoutDataElement );
696   }
697 }
698
699 void LayoutTransitionData::UpdateAnimatorsIndices()
700 {
701   for( LayoutDataElement& iter: mLayoutDataElements )
702   {
703     iter.UpdateAnimatorIndex( mLayoutAnimators );
704   }
705 }
706
707 void LayoutTransitionData::CollectLayoutDataElements( Actor owner, LayoutData& layoutData )
708 {
709   LayoutAnimatorArray& layoutAnimatorArray = layoutData.layoutAnimatorArray;
710   LayoutAnimatorArray::iterator it = mLayoutAnimators.begin();
711   if (layoutAnimatorArray.size() != 0)
712   {
713     // skip default animator
714     ++it;
715   }
716   std::copy( it, mLayoutAnimators.end(), std::back_inserter( layoutAnimatorArray ) );
717
718   LayoutDataArray& layoutDataArray = layoutData.layoutDataArray;
719   // Collect the transition animators
720   for( const LayoutDataElement& iter : mLayoutDataElements )
721   {
722     Actor actor = iter.handle.GetHandle();
723     if( !actor || actor != owner )
724     {
725       layoutData.childrenLayoutDataArray.push_back( iter );
726       continue;
727     }
728
729     LayoutDataElement layoutDataElement = iter;
730     if( layoutData.updateMeasuredSize && !layoutDataElement.updateMeasuredSize )
731     {
732       continue;
733     }
734
735     layoutDataElement.UpdatePropertyIndex();
736     layoutDataElement.UpdatePositionDataIndex( layoutData );
737     layoutDataArray.push_back( layoutDataElement );
738   }
739 }
740
741 Dali::Toolkit::LayoutTransitionData::LayoutTransitionSignalType& LayoutTransitionData::FinishedSignal()
742 {
743   return mFinishedSignal;
744 }
745
746 void LayoutTransitionData::EmitSignalFinish( int layoutTransitionType )
747 {
748   if ( !mFinishedSignal.Empty() )
749   {
750     Dali::Toolkit::LayoutTransitionData handle( this );
751     mFinishedSignal.Emit( static_cast<Dali::Toolkit::LayoutTransitionData::Type>(layoutTransitionType), handle );
752   }
753 }
754
755 bool LayoutTransitionData::HasUpdateMeasuredSize()
756 {
757   return mUpdateMeasuredSize;
758 }
759
760 } // namespace Internal
761 } // namespace Toolkit
762 } // namespace Dali