Add size animation in layout measure phase.
[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 = Actor::DownCast( handle );
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 && handle && !propertyName.empty() )
168   {
169     Actor actor = Actor::DownCast( handle );
170     propertyIndex = DevelHandle::GetPropertyIndex( actor, Property::Key( propertyName ) );
171   }
172 }
173
174 void LayoutDataElement::UpdateAnimatorIndex( const LayoutAnimatorArray& animators )
175 {
176   if( animatorIndex == -1 )
177   {
178     if( animatorName.empty() )
179     {
180       animatorIndex = 0;
181       return;
182     }
183
184     std::string animatorName = this->animatorName;
185     auto animator = std::find_if( animators.begin(), animators.end(), [ &animatorName ](const LayoutDataAnimator& iter) {
186       return ( iter.name == animatorName ); } );
187     if( animator != animators.end() )
188     {
189       animatorIndex = std::distance( animators.begin(), animator );
190     }
191   }
192 }
193
194 void LayoutDataElement::UpdatePositionDataIndex( LayoutData& layoutData )
195 {
196     positionDataIndex = layoutData.layoutPositionDataArray.size() - 1;
197     switch( propertyIndex )
198     {
199       case Actor::Property::SCALE:
200       case Actor::Property::SCALE_X:
201       case Actor::Property::SCALE_Y:
202         if( positionDataIndex != -1 && updateMeasuredSize )
203         {
204           layoutData.layoutPositionDataArray[ positionDataIndex ].updateWithCurrentSize = true;
205         }
206         break;
207     }
208 }
209
210 LayoutTransitionData::LayoutTransitionData() :
211   mUpdateMeasuredSize( false )
212 {
213 }
214
215 LayoutTransitionData::~LayoutTransitionData()
216 {
217 }
218
219 LayoutTransitionDataPtr LayoutTransitionData::New()
220 {
221   LayoutTransitionDataPtr layoutAnimationData( new LayoutTransitionData() );
222   return layoutAnimationData;
223 }
224
225 LayoutTransitionData::PropertyAnimator::PropertyAnimator( )
226   : handle( Actor( ) )
227   , map()
228   , interpolation( Animation::Linear )
229 {
230 }
231
232 LayoutTransitionData::PropertyAnimator::PropertyAnimator( Actor actor, Property::Map map )
233   : handle( actor )
234   , map( map )
235   , interpolation( Animation::Linear )
236 {
237 }
238
239 LayoutTransitionData::PropertyAnimator::PropertyAnimator( Actor actor,  Property::Map map, Path path, Vector3 forward )
240   : handle( actor )
241   , map( map )
242   , interpolation( Animation::Linear )
243   , path( path )
244   , forward( forward )
245 {
246 }
247
248 LayoutTransitionData::PropertyAnimator::PropertyAnimator( Actor actor, Property::Map map, KeyFrames keyFrames, Animation::Interpolation interpolation  )
249   : handle( actor )
250   , map( map )
251   , keyFrames( keyFrames )
252   , interpolation( interpolation )
253 {
254 }
255
256 void LayoutTransitionData::AddPropertyAnimator( Actor actor, Property::Map map )
257 {
258   LayoutDataElement layoutDataElement;
259   if( ConvertToLayoutDataElement( PropertyAnimator( actor, map ), layoutDataElement ) )
260   {
261     mLayoutDataElements.push_back( layoutDataElement );
262   }
263
264   UpdateAnimatorsIndices();
265 }
266
267 void LayoutTransitionData::AddPropertyAnimator( Actor actor, Property::Map map, KeyFrames keyFrames, Animation::Interpolation interpolation )
268 {
269   LayoutDataElement layoutDataElement;
270   if( ConvertToLayoutDataElement( PropertyAnimator( actor, map, keyFrames, interpolation ), layoutDataElement ) )
271   {
272     mLayoutDataElements.push_back( layoutDataElement );
273   }
274
275   UpdateAnimatorsIndices();
276 }
277
278 void LayoutTransitionData::AddPropertyAnimator( Actor actor, Property::Map map, Path path, Vector3 forward )
279 {
280   LayoutDataElement layoutDataElement;
281   if( ConvertToLayoutDataElement( PropertyAnimator( actor, map, path, forward ), layoutDataElement ) )
282   {
283     mLayoutDataElements.push_back( layoutDataElement );
284   }
285
286   UpdateAnimatorsIndices();
287 }
288
289 bool LayoutTransitionData::ConvertToLayoutAnimator( const Property::Map& animatorMap, const PropertyAnimator& propertyAnimator, LayoutDataAnimator& layoutDataAnimator )
290 {
291   bool valid = true;
292
293   for ( size_t animatorMapIdx = 0; animatorMapIdx < animatorMap.Count(); ++animatorMapIdx )
294   {
295     const KeyValuePair pair( animatorMap.GetKeyValue( animatorMapIdx ) );
296
297     Property::Index indexKey = Property::INVALID_INDEX;
298     if ( pair.first.type == Property::Key::STRING )
299     {
300       const std::string& key(pair.first.stringKey);
301       if( key == TOKEN_TYPE )
302       {
303         indexKey = Dali::Toolkit::LayoutTransitionData::AnimatorKey::TYPE;
304       }
305       else if( key == TOKEN_NAME )
306       {
307         indexKey = Dali::Toolkit::LayoutTransitionData::AnimatorKey::NAME;
308       }
309       else if( key == TOKEN_TIME_PERIOD )
310       {
311         indexKey = Dali::Toolkit::LayoutTransitionData::AnimatorKey::TIME_PERIOD;
312       }
313       else if( key == TOKEN_ALPHA_FUNCTION )
314       {
315         indexKey = Dali::Toolkit::LayoutTransitionData::AnimatorKey::ALPHA_FUNCTION;
316       }
317     }
318     else
319     {
320       indexKey = pair.first.indexKey;
321     }
322
323     const Property::Value& value( pair.second );
324
325     if ( indexKey == Dali::Toolkit::LayoutTransitionData::AnimatorKey::ALPHA_FUNCTION )
326     {
327       if ( value.GetType() == Property::ARRAY )
328       {
329         valid = true;
330         Vector4 controlPoints;
331         Property::Array *array = value.GetArray();
332         if ( array && array->Count() >= 4 )
333         {
334           for ( size_t vecIdx = 0; vecIdx < 4; ++vecIdx )
335           {
336             Property::Value& v = array->GetElementAt( vecIdx );
337             if ( v.GetType() == Property::FLOAT )
338             {
339               controlPoints[vecIdx] = v.Get<float>();
340             }
341             else
342             {
343               valid = false;
344               break;
345             }
346           }
347         }
348         else
349         {
350           valid = false;
351         }
352
353         if ( valid )
354         {
355           Vector2 controlPoint1( controlPoints.x, controlPoints.y );
356           Vector2 controlPoint2( controlPoints.z, controlPoints.w );
357           layoutDataAnimator.alphaFunction = AlphaFunction( controlPoint1, controlPoint2 );
358         }
359         else
360         {
361           valid = false;
362         }
363       }
364       else if ( value.GetType() == Property::VECTOR4 )
365       {
366         Vector4 controlPoints = value.Get<Vector4>();
367         Vector2 controlPoint1( controlPoints.x, controlPoints.y );
368         Vector2 controlPoint2( controlPoints.z, controlPoints.w );
369         layoutDataAnimator.alphaFunction = AlphaFunction( controlPoint1, controlPoint2 );
370       }
371       else if ( value.GetType() == Property::INTEGER )
372       {
373         layoutDataAnimator.alphaFunction = AlphaFunction( static_cast<AlphaFunction::BuiltinFunction>( value.Get<int>() ) );
374       }
375       else if ( value.GetType() == Property::STRING )
376       {
377         std::string alphaFunctionValue = value.Get<std::string>();
378
379         if ( alphaFunctionValue == "LINEAR" )
380         {
381           layoutDataAnimator.alphaFunction = AlphaFunction( AlphaFunction::LINEAR );
382         }
383         else if ( !alphaFunctionValue.compare( 0, 5, "EASE_" ) )
384         {
385           if ( alphaFunctionValue == "EASE_IN" )
386           {
387             layoutDataAnimator.alphaFunction = AlphaFunction( AlphaFunction::EASE_IN );
388           }
389           else if ( alphaFunctionValue == "EASE_OUT" )
390           {
391             layoutDataAnimator.alphaFunction = AlphaFunction( AlphaFunction::EASE_OUT );
392           }
393           else if ( !alphaFunctionValue.compare( 5, 3, "IN_" ) )
394           {
395             if ( !alphaFunctionValue.compare( 8, -1, "SQUARE" ) )
396             {
397               layoutDataAnimator.alphaFunction = AlphaFunction( AlphaFunction::EASE_IN_SQUARE );
398             }
399             else if ( !alphaFunctionValue.compare( 8, -1, "OUT" ) )
400             {
401               layoutDataAnimator.alphaFunction = AlphaFunction( AlphaFunction::EASE_IN_OUT );
402             }
403             else if ( !alphaFunctionValue.compare( 8, -1, "OUT_SINE" ) )
404             {
405               layoutDataAnimator.alphaFunction = AlphaFunction( AlphaFunction::EASE_IN_OUT_SINE );
406             }
407             else if ( !alphaFunctionValue.compare( 8, -1, "SINE" ) )
408             {
409               layoutDataAnimator.alphaFunction = AlphaFunction( AlphaFunction::EASE_IN_SINE );
410             }
411           }
412           else if ( !alphaFunctionValue.compare( 5, 4, "OUT_" ) )
413           {
414             if ( !alphaFunctionValue.compare( 9, -1, "SQUARE" ) )
415             {
416               layoutDataAnimator.alphaFunction = AlphaFunction( AlphaFunction::EASE_OUT_SQUARE );
417             }
418             else if ( !alphaFunctionValue.compare( 9, -1, "SINE" ) )
419             {
420               layoutDataAnimator.alphaFunction = AlphaFunction( AlphaFunction::EASE_OUT_SINE );
421             }
422             else if ( !alphaFunctionValue.compare( 9, -1, "BACK" ) )
423             {
424               layoutDataAnimator.alphaFunction = AlphaFunction( AlphaFunction::EASE_OUT_BACK );
425             }
426           }
427         }
428         else if ( alphaFunctionValue == "REVERSE" )
429         {
430           layoutDataAnimator.alphaFunction = AlphaFunction( AlphaFunction::REVERSE );
431         }
432         else if ( alphaFunctionValue == "BOUNCE" )
433         {
434           layoutDataAnimator.alphaFunction = AlphaFunction( AlphaFunction::BOUNCE );
435         }
436         else if ( alphaFunctionValue == "SIN" )
437         {
438           layoutDataAnimator.alphaFunction = AlphaFunction( AlphaFunction::SIN );
439         }
440         else
441         {
442           valid = false;
443         }
444       }
445       else
446       {
447         valid = false;
448       }
449     }
450     else if ( indexKey == Dali::Toolkit::LayoutTransitionData::AnimatorKey::NAME )
451     {
452       if( value.GetType() == Property::STRING )
453       {
454         layoutDataAnimator.name = value.Get<std::string>();
455       }
456     }
457     else if ( indexKey == Dali::Toolkit::LayoutTransitionData::AnimatorKey::TYPE )
458     {
459       if( value.GetType() == Property::STRING )
460       {
461         std::string animatorType = value.Get<std::string>();
462         if( animatorType == ANIMATOR_TYPE_TABLE[ Toolkit::LayoutTransitionData::Animator::Type::ANIMATE_TO ].string )
463         {
464           layoutDataAnimator.animatorType = Toolkit::LayoutTransitionData::Animator::Type::ANIMATE_TO;
465         }
466         else if( animatorType == ANIMATOR_TYPE_TABLE[ Toolkit::LayoutTransitionData::Animator::Type::ANIMATE_BY ].string )
467         {
468           layoutDataAnimator.animatorType = Toolkit::LayoutTransitionData::Animator::Type::ANIMATE_BY;
469         }
470         else if( animatorType == ANIMATOR_TYPE_TABLE[ Toolkit::LayoutTransitionData::Animator::Type::ANIMATE_BETWEEN ].string )
471         {
472           layoutDataAnimator.animatorType = Toolkit::LayoutTransitionData::Animator::Type::ANIMATE_BETWEEN;
473           layoutDataAnimator.keyFrames = propertyAnimator.keyFrames;
474         }
475         else if( animatorType == ANIMATOR_TYPE_TABLE[ Toolkit::LayoutTransitionData::Animator::Type::ANIMATE_PATH ].string )
476         {
477           layoutDataAnimator.animatorType = Toolkit::LayoutTransitionData::Animator::Type::ANIMATE_PATH;
478           layoutDataAnimator.path = propertyAnimator.path;
479           layoutDataAnimator.forward = propertyAnimator.forward;
480         }
481       }
482       else if ( value.GetType() == Property::INTEGER )
483       {
484         layoutDataAnimator.animatorType = static_cast<Toolkit::LayoutTransitionData::Animator::Type>( pair.second.Get<int>() );
485       }
486     }
487     else if ( indexKey == Dali::Toolkit::LayoutTransitionData::AnimatorKey::TIME_PERIOD )
488     {
489       Property::Map timeMap = value.Get<Property::Map>();
490       for ( size_t timeMapIdx = 0; timeMapIdx < timeMap.Count(); ++timeMapIdx )
491       {
492         const KeyValuePair pair( timeMap.GetKeyValue( timeMapIdx ) );
493         indexKey = Property::INVALID_INDEX;
494
495         if ( pair.first.type == Property::Key::STRING)
496         {
497           const std::string& key( pair.first.stringKey );
498           if( key == TOKEN_DURATION )
499           {
500             indexKey = Dali::Toolkit::LayoutTransitionData::AnimatorKey::DURATION;
501           }
502           else if( key == TOKEN_DELAY )
503           {
504             indexKey = Dali::Toolkit::LayoutTransitionData::AnimatorKey::DELAY;
505           }
506         }
507         else
508         {
509           indexKey = pair.first.indexKey;
510         }
511
512         if ( indexKey == Dali::Toolkit::LayoutTransitionData::AnimatorKey::DELAY )
513         {
514           layoutDataAnimator.timePeriod.delaySeconds = pair.second.Get<float>();
515         }
516         else if ( indexKey == Dali::Toolkit::LayoutTransitionData::AnimatorKey::DURATION )
517         {
518           layoutDataAnimator.timePeriod.durationSeconds = pair.second.Get<float>();
519         }
520       }
521     }
522   }
523
524   return valid;
525 }
526
527 bool LayoutTransitionData::ConvertToLayoutDataElement(
528     const PropertyAnimator& propertyAnimator, LayoutDataElement& layoutDataElement )
529 {
530   const Property::Map& map = propertyAnimator.map;
531   bool propertyFound = false;
532
533   if( mLayoutAnimators.size() == 0 )
534   {
535     mLayoutAnimators.push_back( LayoutDataAnimator() );
536   }
537
538   layoutDataElement.handle = propertyAnimator.handle;
539
540   for( unsigned int mapIdx = 0; mapIdx < map.Count(); ++mapIdx )
541   {
542     const KeyValuePair pair( map.GetKeyValue( mapIdx ) );
543     const Property::Value& value( pair.second );
544     Property::Index indexKey = Property::INVALID_INDEX;
545
546     if ( pair.first.type == Property::Key::STRING )
547     {
548       const std::string& key( pair.first.stringKey );
549       if ( key == TOKEN_CONDITION )
550       {
551         indexKey = Dali::Toolkit::LayoutTransitionData::AnimatorKey::CONDITION;
552       }
553       if ( key == TOKEN_PROPERTY )
554       {
555         indexKey = Dali::Toolkit::LayoutTransitionData::AnimatorKey::PROPERTY;
556       }
557       else if( key == TOKEN_INITIAL_VALUE )
558       {
559         indexKey = Dali::Toolkit::LayoutTransitionData::AnimatorKey::INITIAL_VALUE;
560       }
561       else if( key == TOKEN_TARGET_VALUE )
562       {
563         indexKey = Dali::Toolkit::LayoutTransitionData::AnimatorKey::TARGET_VALUE;
564       }
565       else if( key == TOKEN_ANIMATOR )
566       {
567         indexKey = Dali::Toolkit::LayoutTransitionData::AnimatorKey::ANIMATOR;
568       }
569       else if( key == TOKEN_AFFECTS_SIBLINGS )
570       {
571         indexKey = Dali::Toolkit::LayoutTransitionData::AnimatorKey::AFFECTS_SIBLINGS;
572       }
573     }
574     else
575     {
576       indexKey = pair.first.indexKey;
577     }
578
579     if( indexKey == Dali::Toolkit::LayoutTransitionData::AnimatorKey::CONDITION )
580     {
581       layoutDataElement.condition = value.Get<int>();
582     }
583     else if ( indexKey == Dali::Toolkit::LayoutTransitionData::AnimatorKey::AFFECTS_SIBLINGS )
584     {
585       layoutDataElement.updateMeasuredSize = value.Get<bool>();
586       if( layoutDataElement.updateMeasuredSize )
587       {
588         mUpdateMeasuredSize = true;
589       }
590     }
591     else if( indexKey == Dali::Toolkit::LayoutTransitionData::AnimatorKey::PROPERTY )
592     {
593       if( value.GetType() == Property::STRING )
594       {
595         layoutDataElement.propertyName = value.Get<std::string>();
596         layoutDataElement.UpdatePropertyIndex();
597       }
598       else
599       {
600         layoutDataElement.propertyIndex = value.Get<int>();
601       }
602       propertyFound = true;
603     }
604     else if( indexKey == Dali::Toolkit::LayoutTransitionData::AnimatorKey::INITIAL_VALUE )
605     {
606       layoutDataElement.initialValue = value;
607     }
608     else if( indexKey == Dali::Toolkit::LayoutTransitionData::AnimatorKey::TARGET_VALUE )
609     {
610       layoutDataElement.targetValue = value;
611     }
612     else if( indexKey == Dali::Toolkit::LayoutTransitionData::AnimatorKey::ANIMATOR )
613     {
614       if( value.GetType() == Property::STRING )
615       {
616         layoutDataElement.animatorName = value.Get<std::string>();
617         layoutDataElement.UpdateAnimatorIndex( mLayoutAnimators );
618       }
619       else if ( value.GetType() == Property::MAP )
620       {
621         Property::Map animatorMap = value.Get< Property::Map >();
622         LayoutDataAnimator layoutDataAnimator;
623         if( ConvertToLayoutAnimator( animatorMap, propertyAnimator, layoutDataAnimator ) )
624         {
625           mLayoutAnimators.push_back( layoutDataAnimator );
626           layoutDataElement.animatorIndex = mLayoutAnimators.size() - 1;
627         }
628       }
629     }
630   }
631
632   return propertyFound;
633 }
634
635 void LayoutTransitionData::CollectChildrenLayoutDataElements( Actor child, LayoutData& layoutData )
636 {
637   LayoutDataArray& layoutDataArray = layoutData.layoutDataArray;
638   // Add the children animators
639   for( const LayoutDataElement& iter : layoutData.childrenLayoutDataArray )
640   {
641     if( iter.handle != nullptr && iter.handle != child )
642     {
643       continue;
644     }
645
646     LayoutDataElement layoutDataElement = iter;
647     switch ( layoutDataElement.condition )
648     {
649       case Dali::Toolkit::LayoutTransitionData::Condition::ON_ADD:
650         if ( layoutData.layoutTransition.layoutTransitionType != Dali::Toolkit::LayoutTransitionData::ON_CHILD_ADD
651             || layoutData.layoutTransition.gainedChild != child )
652         {
653           continue;
654         }
655         break;
656       case Dali::Toolkit::LayoutTransitionData::Condition::ON_REMOVE:
657         if( layoutData.layoutTransition.layoutTransitionType != Dali::Toolkit::LayoutTransitionData::ON_CHILD_REMOVE
658             || layoutData.layoutTransition.lostChild != child )
659         {
660           continue;
661         }
662         break;
663       case Dali::Toolkit::LayoutTransitionData::Condition::ON_FOCUS_GAINED:
664         if( layoutData.layoutTransition.layoutTransitionType != Dali::Toolkit::LayoutTransitionData::ON_CHILD_FOCUS
665             || layoutData.layoutTransition.gainedChild != child )
666         {
667           continue;
668         }
669         break;
670       case Dali::Toolkit::LayoutTransitionData::Condition::ON_FOCUS_LOST:
671         if( layoutData.layoutTransition.layoutTransitionType != Dali::Toolkit::LayoutTransitionData::ON_CHILD_FOCUS
672             || layoutData.layoutTransition.lostChild != child )
673         {
674           continue;
675         }
676         break;
677       default:
678         break;
679     }
680
681     if( layoutData.updateMeasuredSize && !layoutDataElement.updateMeasuredSize )
682     {
683       continue;
684     }
685
686     layoutDataElement.handle = child;
687     layoutDataElement.UpdatePropertyIndex();
688     layoutDataElement.UpdatePositionDataIndex( layoutData );
689     layoutDataArray.push_back( layoutDataElement );
690   }
691 }
692
693 void LayoutTransitionData::UpdateAnimatorsIndices()
694 {
695   for( LayoutDataElement& iter: mLayoutDataElements )
696   {
697     iter.UpdateAnimatorIndex( mLayoutAnimators );
698   }
699 }
700
701 void LayoutTransitionData::CollectLayoutDataElements( Actor owner, LayoutData& layoutData )
702 {
703   LayoutAnimatorArray& layoutAnimatorArray = layoutData.layoutAnimatorArray;
704   LayoutAnimatorArray::iterator it = mLayoutAnimators.begin();
705   if (layoutAnimatorArray.size() != 0)
706   {
707     // skip default animator
708     ++it;
709   }
710   std::copy( it, mLayoutAnimators.end(), std::back_inserter( layoutAnimatorArray ) );
711
712   LayoutDataArray& layoutDataArray = layoutData.layoutDataArray;
713   // Collect the transition animators
714   for( const LayoutDataElement& iter : mLayoutDataElements )
715   {
716     if( iter.handle == nullptr || iter.handle != owner )
717     {
718       layoutData.childrenLayoutDataArray.push_back( iter );
719       continue;
720     }
721
722     LayoutDataElement layoutDataElement = iter;
723     if( layoutData.updateMeasuredSize && !layoutDataElement.updateMeasuredSize )
724     {
725       continue;
726     }
727
728     layoutDataElement.UpdatePropertyIndex();
729     layoutDataElement.UpdatePositionDataIndex( layoutData );
730     layoutDataArray.push_back( layoutDataElement );
731   }
732 }
733
734 Dali::Toolkit::LayoutTransitionData::LayoutTransitionSignalType& LayoutTransitionData::FinishedSignal()
735 {
736   return mFinishedSignal;
737 }
738
739 void LayoutTransitionData::EmitSignalFinish( int layoutTransitionType )
740 {
741   if ( !mFinishedSignal.Empty() )
742   {
743     Dali::Toolkit::LayoutTransitionData handle( this );
744     mFinishedSignal.Emit( static_cast<Dali::Toolkit::LayoutTransitionData::Type>(layoutTransitionType), handle );
745   }
746 }
747
748 bool LayoutTransitionData::HasUpdateMeasuredSize()
749 {
750   return mUpdateMeasuredSize;
751 }
752
753 } // namespace Internal
754 } // namespace Toolkit
755 } // namespace Dali