9796b48e86ab2aebdeebbdb52a8e233e68c4a003
[platform/core/uifw/dali-core.git] / dali / devel-api / scripting / scripting.cpp
1 /*
2  * Copyright (c) 2015 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/devel-api/scripting/scripting.h>
20
21 // INTERNAL INCLUDES
22 #include <dali/public-api/actors/actor.h>
23 #include <dali/public-api/images/resource-image.h>
24 #include <dali/public-api/object/type-registry.h>
25 #include <dali/public-api/object/property-array.h>
26 #include <dali/internal/common/image-attributes.h>
27 #include <dali/internal/event/images/resource-image-impl.h>
28 #include <dali/internal/event/images/frame-buffer-image-impl.h>
29 #include <dali/internal/event/images/buffer-image-impl.h>
30 #include <dali/internal/event/effects/shader-effect-impl.h>
31
32 namespace Dali
33 {
34
35 namespace Scripting
36 {
37
38 namespace
39 {
40
41 // Tables used here for converting strings to the enumerations and vice versa
42 struct AnchorValue
43 {
44   const char* name;
45   const Vector3 value;
46 };
47 const AnchorValue ANCHOR_CONSTANT_TABLE[] =
48 {
49   { "TOP_LEFT",               ParentOrigin::TOP_LEFT               },
50   { "TOP_CENTER",             ParentOrigin::TOP_CENTER             },
51   { "TOP_RIGHT",              ParentOrigin::TOP_RIGHT              },
52   { "CENTER_LEFT",            ParentOrigin::CENTER_LEFT            },
53   { "CENTER",                 ParentOrigin::CENTER                 },
54   { "CENTER_RIGHT",           ParentOrigin::CENTER_RIGHT           },
55   { "BOTTOM_LEFT",            ParentOrigin::BOTTOM_LEFT            },
56   { "BOTTOM_CENTER",          ParentOrigin::BOTTOM_CENTER          },
57   { "BOTTOM_RIGHT",           ParentOrigin::BOTTOM_RIGHT           },
58 };
59 const unsigned int ANCHOR_CONSTANT_TABLE_COUNT = sizeof( ANCHOR_CONSTANT_TABLE ) / sizeof( ANCHOR_CONSTANT_TABLE[0] );
60
61 const StringEnum COLOR_MODE_TABLE[] =
62 {
63   { "USE_OWN_COLOR",                    USE_OWN_COLOR                    },
64   { "USE_PARENT_COLOR",                 USE_PARENT_COLOR                 },
65   { "USE_OWN_MULTIPLY_PARENT_COLOR",    USE_OWN_MULTIPLY_PARENT_COLOR    },
66   { "USE_OWN_MULTIPLY_PARENT_ALPHA",    USE_OWN_MULTIPLY_PARENT_ALPHA    },
67 };
68 const unsigned int COLOR_MODE_TABLE_COUNT = sizeof( COLOR_MODE_TABLE ) / sizeof( COLOR_MODE_TABLE[0] );
69
70 const StringEnum POSITION_INHERITANCE_MODE_TABLE[] =
71 {
72   { "INHERIT_PARENT_POSITION",                    INHERIT_PARENT_POSITION                    },
73   { "USE_PARENT_POSITION",                        USE_PARENT_POSITION                        },
74   { "USE_PARENT_POSITION_PLUS_LOCAL_POSITION",    USE_PARENT_POSITION_PLUS_LOCAL_POSITION    },
75   { "DONT_INHERIT_POSITION",                      DONT_INHERIT_POSITION                      },
76 };
77 const unsigned int POSITION_INHERITANCE_MODE_TABLE_COUNT = sizeof( POSITION_INHERITANCE_MODE_TABLE ) / sizeof( POSITION_INHERITANCE_MODE_TABLE[0] );
78
79 const StringEnum DRAW_MODE_TABLE[] =
80 {
81   { "NORMAL",     DrawMode::NORMAL     },
82   { "OVERLAY_2D", DrawMode::OVERLAY_2D },
83   { "STENCIL",    DrawMode::STENCIL    },
84 };
85 const unsigned int DRAW_MODE_TABLE_COUNT = sizeof( DRAW_MODE_TABLE ) / sizeof( DRAW_MODE_TABLE[0] );
86
87 const StringEnum IMAGE_LOAD_POLICY_TABLE[] =
88 {
89   { "IMMEDIATE", ResourceImage::IMMEDIATE },
90   { "ON_DEMAND", ResourceImage::ON_DEMAND },
91 };
92 const unsigned int IMAGE_LOAD_POLICY_TABLE_COUNT = sizeof( IMAGE_LOAD_POLICY_TABLE ) / sizeof( IMAGE_LOAD_POLICY_TABLE[0] );
93
94 const StringEnum IMAGE_RELEASE_POLICY_TABLE[] =
95 {
96   { "UNUSED", Image::UNUSED },
97   { "NEVER",  Image::NEVER  },
98 };
99 const unsigned int IMAGE_RELEASE_POLICY_TABLE_COUNT = sizeof( IMAGE_RELEASE_POLICY_TABLE ) / sizeof( IMAGE_RELEASE_POLICY_TABLE[0] );
100
101 const StringEnum PIXEL_FORMAT_TABLE[] =
102 {
103   { "A8",                                           Pixel::A8                                           },
104   { "L8",                                           Pixel::L8                                           },
105   { "LA88",                                         Pixel::LA88                                         },
106   { "RGB565",                                       Pixel::RGB565                                       },
107   { "BGR565",                                       Pixel::BGR565                                       },
108   { "RGBA4444",                                     Pixel::RGBA4444                                     },
109   { "BGRA4444",                                     Pixel::BGRA4444                                     },
110   { "RGBA5551",                                     Pixel::RGBA5551                                     },
111   { "BGRA5551",                                     Pixel::BGRA5551                                     },
112   { "RGB888",                                       Pixel::RGB888                                       },
113   { "RGB8888",                                      Pixel::RGB8888                                      },
114   { "BGR8888",                                      Pixel::BGR8888                                      },
115   { "RGBA8888",                                     Pixel::RGBA8888                                     },
116   { "BGRA8888",                                     Pixel::BGRA8888                                     },
117   { "COMPRESSED_R11_EAC",                           Pixel::COMPRESSED_R11_EAC                           },
118   { "COMPRESSED_SIGNED_R11_EAC",                    Pixel::COMPRESSED_SIGNED_R11_EAC                    },
119   { "COMPRESSED_SIGNED_RG11_EAC",                   Pixel::COMPRESSED_SIGNED_RG11_EAC                   },
120   { "COMPRESSED_RG11_EAC",                          Pixel::COMPRESSED_RG11_EAC                          },
121   { "COMPRESSED_RGB8_ETC2",                         Pixel::COMPRESSED_RGB8_ETC2                         },
122   { "COMPRESSED_SRGB8_ETC2",                        Pixel::COMPRESSED_SRGB8_ETC2                        },
123   { "COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2",     Pixel::COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2     },
124   { "COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2",    Pixel::COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2    },
125   { "COMPRESSED_RGBA8_ETC2_EAC",                    Pixel::COMPRESSED_RGBA8_ETC2_EAC                    },
126   { "COMPRESSED_SRGB8_ALPHA8_ETC2_EAC",             Pixel::COMPRESSED_SRGB8_ALPHA8_ETC2_EAC             },
127   { "COMPRESSED_RGB8_ETC1",                         Pixel::COMPRESSED_RGB8_ETC1                         },
128   { "COMPRESSED_RGB_PVRTC_4BPPV1",                  Pixel::COMPRESSED_RGB_PVRTC_4BPPV1                  },
129 };
130 const unsigned int PIXEL_FORMAT_TABLE_COUNT = sizeof( PIXEL_FORMAT_TABLE ) / sizeof( PIXEL_FORMAT_TABLE[0] );
131
132 const StringEnum IMAGE_FITTING_MODE_TABLE[] =
133 {
134   { "SHRINK_TO_FIT", FittingMode::SHRINK_TO_FIT },
135   { "SCALE_TO_FILL", FittingMode::SCALE_TO_FILL },
136   { "FIT_WIDTH",     FittingMode::FIT_WIDTH    },
137   { "FIT_HEIGHT",    FittingMode::FIT_HEIGHT   },
138 };
139 const unsigned int IMAGE_FITTING_MODE_TABLE_COUNT = sizeof( IMAGE_FITTING_MODE_TABLE ) / sizeof( IMAGE_FITTING_MODE_TABLE[0] );
140
141 const StringEnum IMAGE_SAMPLING_MODE_TABLE[] =
142 {
143   { "BOX",              SamplingMode::BOX            },
144   { "NEAREST",          SamplingMode::NEAREST        },
145   { "LINEAR",           SamplingMode::LINEAR         },
146   { "BOX_THEN_NEAREST", SamplingMode::BOX_THEN_NEAREST },
147   { "BOX_THEN_LINEAR",  SamplingMode::BOX_THEN_LINEAR  },
148   { "NO_FILTER",        SamplingMode::NO_FILTER       },
149   { "DONT_CARE",        SamplingMode::DONT_CARE       },
150 };
151 const unsigned int IMAGE_SAMPLING_MODE_TABLE_COUNT = sizeof( IMAGE_SAMPLING_MODE_TABLE ) / sizeof( IMAGE_SAMPLING_MODE_TABLE[0] );
152
153 const char* ImageTypeName[] = { "ResourceImage", "FrameBufferImage", "BufferImage" };
154 enum ImageType                { RESOURCE_IMAGE,  FRAME_BUFFER_IMAGE, BUFFER_IMAGE };
155 const unsigned int imageTypeCount = sizeof( ImageTypeName ) / sizeof( const char* );
156
157 bool CompareEnums( const char * a, const char * b )
158 {
159   while( ( *a != '\0' ) && ( *b != '\0' ) )
160   {
161     char ca = *a;
162     char cb = *b;
163
164     if( ( ( ca == '-' ) || ( ca == '_') ) &&
165         ( ( cb == '-' ) || ( cb == '_') ) )
166     {
167       ++a;
168       ++b;
169       continue;
170     }
171
172     if( ( 'A' <= ca ) && ( ca <= 'Z') )
173     {
174       ca = ca + ( 'a' - 'A' );
175     }
176
177     if( ( 'A' <= cb ) && ( cb <= 'Z') )
178     {
179       cb = cb + ( 'a' - 'A' );
180     }
181
182     if( ca != cb )
183     {
184       return false;
185     }
186
187     ++a;
188     ++b;
189   }
190
191   if( ( *a == '\0' ) && ( *b == '\0' ) )
192   {
193     return true;
194   }
195
196   return false;
197 }
198
199 } // unnamed namespace
200
201 unsigned int FindEnumIndex( const char* value, const StringEnum* table, unsigned int tableCount )
202 {
203   unsigned int index = 0;
204   bool found = false;
205   for ( unsigned int i = 0; i < tableCount; ++i, ++index )
206   {
207     if( CompareEnums( value, table->string ) )
208     {
209       found = true;
210       break;
211     }
212     ++table;
213   }
214   if ( !found )
215   {
216     DALI_LOG_ERROR( "Unknown enumeration string %s\n", value );
217   }
218   return index;
219 }
220
221 ColorMode GetColorMode( const std::string& value )
222 {
223   // return default on error
224   ColorMode mode( USE_OWN_MULTIPLY_PARENT_ALPHA );
225   GetEnumeration< ColorMode >( value.c_str(), COLOR_MODE_TABLE, COLOR_MODE_TABLE_COUNT, mode );
226   return mode;
227 }
228
229
230 std::string GetColorMode( ColorMode value )
231 {
232   const char* name = GetEnumerationName< ColorMode >( value, COLOR_MODE_TABLE, COLOR_MODE_TABLE_COUNT );
233   if( name )
234   {
235     return std::string( name );
236   }
237   return std::string();
238 }
239
240 PositionInheritanceMode GetPositionInheritanceMode( const std::string& value )
241 {
242   // return default on error
243   PositionInheritanceMode mode( INHERIT_PARENT_POSITION );
244   GetEnumeration< PositionInheritanceMode >( value.c_str(), POSITION_INHERITANCE_MODE_TABLE, POSITION_INHERITANCE_MODE_TABLE_COUNT, mode );
245   return mode;
246 }
247
248
249 std::string GetPositionInheritanceMode( PositionInheritanceMode value )
250 {
251   const char* name = GetEnumerationName< PositionInheritanceMode >( value, POSITION_INHERITANCE_MODE_TABLE, POSITION_INHERITANCE_MODE_TABLE_COUNT );
252   if( name )
253   {
254     return std::string( name );
255   }
256   return std::string();
257 }
258
259
260 DrawMode::Type GetDrawMode( const std::string& value )
261 {
262   // return default on error
263   DrawMode::Type mode( DrawMode::NORMAL );
264   GetEnumeration< DrawMode::Type >( value.c_str(), DRAW_MODE_TABLE, DRAW_MODE_TABLE_COUNT, mode );
265   return mode;
266 }
267
268
269 std::string GetDrawMode( DrawMode::Type value )
270 {
271   const char* name = GetEnumerationName< DrawMode::Type >( value, DRAW_MODE_TABLE, DRAW_MODE_TABLE_COUNT );
272   if( name )
273   {
274     return std::string( name );
275   }
276   return std::string();
277 }
278
279
280 Vector3 GetAnchorConstant( const std::string& value )
281 {
282   for( unsigned int i = 0; i < ANCHOR_CONSTANT_TABLE_COUNT; ++i )
283   {
284     if( CompareEnums( value.c_str(), ANCHOR_CONSTANT_TABLE[ i ].name ) )
285     {
286       return ANCHOR_CONSTANT_TABLE[ i ].value;
287     }
288   }
289   return Vector3();
290 }
291
292
293 Image NewImage( const Property::Value& property )
294 {
295   Image ret;
296
297   std::string filename;
298   ResourceImage::LoadPolicy loadPolicy = Dali::Internal::IMAGE_LOAD_POLICY_DEFAULT;
299   Image::ReleasePolicy releasePolicy   = Dali::Internal::IMAGE_RELEASE_POLICY_DEFAULT;
300   Internal::ImageAttributes attributes = Internal::ImageAttributes::New();
301
302   const Property::Map* map = property.GetMap();
303   ImageType imageType = RESOURCE_IMAGE; // default to resource image
304   if( map )
305   {
306     // first check the type as it determines, which other parameters are needed
307     const Property::Value* value = map->Find( "type" );
308     if( value )
309     {
310       std::string type;
311       value->Get( type );
312       for( unsigned int i = 0; i < imageTypeCount; ++i )
313       {
314         if( 0 == type.compare( ImageTypeName[ i ] ) )
315         {
316           imageType = static_cast<ImageType>( i );
317           break;
318         }
319       }
320     }
321
322     // filename is only needed for resource images
323     if( RESOURCE_IMAGE == imageType )
324     {
325       const Property::Value* value = map->Find( "filename" );
326       if( value )
327       {
328         value->Get( filename );
329       }
330       // if empty file, no need to go further
331       if( filename.size() == 0 )
332       {
333         DALI_LOG_ERROR( "No filename\n" );
334         return Image();
335       }
336     }
337
338     value = map->Find( "loadPolicy" );
339     if( value )
340     {
341       std::string policy;
342       value->Get( policy );
343       // keep default value on error
344       GetEnumeration< ResourceImage::LoadPolicy >( policy.c_str(), IMAGE_LOAD_POLICY_TABLE, IMAGE_LOAD_POLICY_TABLE_COUNT, loadPolicy );
345     }
346
347     value = map->Find( "releasePolicy" );
348     if( value )
349     {
350       std::string policy;
351       value->Get( policy );
352       // keep default value on error
353       GetEnumeration< Image::ReleasePolicy >( policy.c_str(), IMAGE_RELEASE_POLICY_TABLE, IMAGE_RELEASE_POLICY_TABLE_COUNT, releasePolicy );
354     }
355
356     // Width and height can be set individually. Dali derives the unspecified
357     // dimension from the aspect ratio of the raw image.
358     int width = 0, height = 0;
359
360     value = map->Find( "width" );
361     if( value )
362     {
363       // handle floats and integer the same for json script
364       if( value->GetType() == Property::FLOAT )
365       {
366         width = static_cast<unsigned int>( value->Get<float>() );
367       }
368       else
369       {
370         value->Get( width );
371       }
372     }
373     value = map->Find( "height" );
374     if( value )
375     {
376       if( value->GetType() == Property::FLOAT )
377       {
378         height = static_cast<int>( value->Get<float>() );
379       }
380       else
381       {
382         value->Get( height );
383       }
384     }
385     attributes.SetSize( width, height );
386
387     Pixel::Format pixelFormat = Pixel::RGBA8888;
388     value = map->Find( "pixelFormat" );
389     if( value )
390     {
391       std::string format;
392       value->Get( format );
393       GetEnumeration< Pixel::Format >( format.c_str(), PIXEL_FORMAT_TABLE, PIXEL_FORMAT_TABLE_COUNT, pixelFormat );
394     }
395
396     value = map->Find( "fittingMode" );
397     if( value )
398     {
399       std::string fitting;
400       value->Get( fitting );
401       FittingMode::Type mode;
402       if( GetEnumeration< FittingMode::Type >( fitting.c_str(), IMAGE_FITTING_MODE_TABLE, IMAGE_FITTING_MODE_TABLE_COUNT, mode ) )
403       {
404         attributes.SetScalingMode( mode );
405       }
406     }
407
408     value = map->Find( "samplingMode" );
409     if( value )
410     {
411       std::string sampling;
412       value->Get( sampling );
413       SamplingMode::Type mode;
414       if( GetEnumeration< SamplingMode::Type >( sampling.c_str(), IMAGE_SAMPLING_MODE_TABLE, IMAGE_SAMPLING_MODE_TABLE_COUNT, mode ) )
415       {
416         attributes.SetFilterMode( mode );
417       }
418     }
419
420     value = map->Find( "orientation" );
421     if( value )
422     {
423       bool b = value->Get<bool>();
424       attributes.SetOrientationCorrection( b );
425     }
426
427     switch( imageType )
428     {
429       case RESOURCE_IMAGE :
430       {
431         ret = ResourceImage::New( filename, loadPolicy, releasePolicy,
432                                   ImageDimensions( attributes.GetSize().x, attributes.GetSize().y ),
433                                   attributes.GetScalingMode(), attributes.GetFilterMode(), attributes.GetOrientationCorrection() );
434         break;
435       }
436       case BUFFER_IMAGE :
437       {
438         ret = BufferImage::New( attributes.GetWidth(),
439                                 attributes.GetHeight(),
440                                 pixelFormat,
441                                 releasePolicy );
442         break;
443       }
444       case FRAME_BUFFER_IMAGE :
445       {
446         ret = FrameBufferImage::New( attributes.GetWidth(),
447                                      attributes.GetHeight(),
448                                      pixelFormat,
449                                      releasePolicy );
450         break;
451       }
452     }
453   }
454
455   return ret;
456
457 } // Image NewImage( Property::Value map )
458
459
460 ShaderEffect NewShaderEffect( const Property::Value& property )
461 {
462   Internal::ShaderEffectPtr ret;
463
464   const Property::Map* map = property.GetMap();
465   if( map )
466   {
467     ret = Internal::ShaderEffect::New( Dali::ShaderEffect::HINT_NONE ); // hint can be reset if in map
468
469     const Property::Value* value = map->Find( "program" );
470     if( value )
471     {
472       Property::Index index = ret->GetPropertyIndex( "program" );
473       ret->SetProperty( index, *value );
474     }
475
476     for( unsigned int i = 0; i < map->Count(); ++i )
477     {
478       const std::string& key = map->GetKey( i );
479       if( key != "program" )
480       {
481         Property::Index index = ret->GetPropertyIndex( key );
482
483         const Property::Value& value = map->GetValue( i );
484         if( Property::INVALID_INDEX != index )
485         {
486           ret->SetProperty( index, value );
487         }
488         else
489         {
490           // if its not a property then register it as a uniform (making a custom property)
491           if( value.GetType() == Property::INTEGER )
492           {
493             // valid uniforms are floats, vec3's etc so we recast if the user accidentally
494             // set as integer. Note the map could have come from json script.
495             Property::Value asFloat( static_cast<float>( value.Get<int>() ) );
496             ret->SetUniform( key, asFloat, Dali::ShaderEffect::COORDINATE_TYPE_DEFAULT );
497           }
498           else
499           {
500             ret->SetUniform( key, value, Dali::ShaderEffect::COORDINATE_TYPE_DEFAULT );
501           }
502         }
503       }
504     }
505   }
506
507   return Dali::ShaderEffect(ret.Get());
508 }
509
510
511 Actor NewActor( const Property::Map& map )
512 {
513   BaseHandle handle;
514
515   // First find type and create Actor
516   Property::Value* typeValue = map.Find( "type" );
517   if ( typeValue )
518   {
519     TypeInfo type = TypeRegistry::Get().GetTypeInfo( typeValue->Get< std::string >() );
520     if ( type )
521     {
522       handle = type.CreateInstance();
523     }
524   }
525
526   if ( !handle )
527   {
528     DALI_LOG_ERROR( "Actor type not provided\n" );
529     return Actor();
530   }
531
532   Actor actor( Actor::DownCast( handle ) );
533
534   if ( actor )
535   {
536     // Now set the properties, or create children
537     for ( unsigned int i = 0, mapCount = map.Count(); i < mapCount; ++i )
538     {
539       const StringValuePair& pair( map.GetPair( i ) );
540       const std::string& key( pair.first );
541       if ( key == "type" )
542       {
543         continue;
544       }
545
546       const Property::Value& value( pair.second );
547
548       if ( key == "actors" )
549       {
550         // Create children
551         Property::Array actorArray = value.Get< Property::Array >();
552         for ( Property::Array::SizeType i = 0; i < actorArray.Size(); ++i)
553         {
554           actor.Add( NewActor( actorArray[i].Get< Property::Map >() ) );
555         }
556       }
557       else if( key ==  "parentOrigin" )
558       {
559         // Parent Origin can be a string constant as well as a Vector3
560
561         const Property::Type type( value.GetType() );
562         if ( type == Property::VECTOR3 )
563         {
564           actor.SetParentOrigin( value.Get< Vector3 >() );
565         }
566         else if( type == Property::STRING )
567         {
568           actor.SetParentOrigin( GetAnchorConstant( value.Get< std::string >() ) );
569         }
570       }
571       else if( key ==  "anchorPoint" )
572       {
573         // Anchor Point can be a string constant as well as a Vector3
574
575         const Property::Type type( value.GetType() );
576         if ( type == Property::VECTOR3 )
577         {
578           actor.SetAnchorPoint( value.Get< Vector3 >() );
579         }
580         else if( type == Property::STRING )
581         {
582           actor.SetAnchorPoint( GetAnchorConstant( value.Get< std::string >() ) );
583         }
584       }
585       else
586       {
587         Property::Index index( actor.GetPropertyIndex( key ) );
588
589         if ( index != Property::INVALID_INDEX )
590         {
591           actor.SetProperty( index, value );
592         }
593       }
594     }
595   }
596
597   return actor;
598 }
599
600 void CreatePropertyMap( Actor actor, Property::Map& map )
601 {
602   map.Clear();
603
604   if ( actor )
605   {
606     map[ "type" ] = actor.GetTypeName();
607
608     // Default properties
609     Property::IndexContainer indices;
610     actor.GetPropertyIndices( indices );
611     const Property::IndexContainer::ConstIterator endIter = indices.End();
612
613     for ( Property::IndexContainer::Iterator iter = indices.Begin(); iter != endIter; ++iter )
614     {
615       map[ actor.GetPropertyName( *iter ) ] = actor.GetProperty( *iter );
616     }
617
618     // Children
619     unsigned int childCount( actor.GetChildCount() );
620     if ( childCount )
621     {
622       Property::Array childArray;
623       for ( unsigned int child = 0; child < childCount; ++child )
624       {
625         Property::Map childMap;
626         CreatePropertyMap( actor.GetChildAt( child ), childMap );
627         childArray.PushBack( childMap );
628       }
629       map[ "actors" ] = childArray;
630     }
631   }
632 }
633
634 void CreatePropertyMap( Image image, Property::Map& map )
635 {
636   map.Clear();
637
638   if ( image )
639   {
640     std::string imageType( "ResourceImage" );
641
642     // Get Type - cannot use TypeRegistry as Image is not an Object and thus, not registered
643     BufferImage bufferImage = BufferImage::DownCast( image );
644     if ( bufferImage )
645     {
646       imageType = "BufferImage";
647       map[ "pixelFormat" ] = GetEnumerationName< Pixel::Format >( bufferImage.GetPixelFormat(), PIXEL_FORMAT_TABLE, PIXEL_FORMAT_TABLE_COUNT );
648     }
649     else if ( FrameBufferImage::DownCast( image ) )
650     {
651       imageType = "FrameBufferImage";
652     }
653
654     map[ "type" ] = imageType;
655     map[ "releasePolicy" ] = GetEnumerationName< Image::ReleasePolicy >( image.GetReleasePolicy(), IMAGE_RELEASE_POLICY_TABLE, IMAGE_RELEASE_POLICY_TABLE_COUNT );
656
657     ResourceImage resourceImage = ResourceImage::DownCast( image );
658     if( resourceImage )
659     {
660       map[ "filename" ] = resourceImage.GetUrl();
661       map[ "loadPolicy" ] = GetEnumerationName< ResourceImage::LoadPolicy >( resourceImage.GetLoadPolicy(), IMAGE_LOAD_POLICY_TABLE, IMAGE_LOAD_POLICY_TABLE_COUNT );
662     }
663
664     int width( image.GetWidth() );
665     int height( image.GetHeight() );
666
667     if ( width && height )
668     {
669       map[ "width" ] = width;
670       map[ "height" ] = height;
671     }
672   }
673 }
674
675 void NewAnimation( const Property::Map& map, Dali::AnimationData& outputAnimationData )
676 {
677   // Note: Builder cannot currently pass generic Property::Maps "{" that are nested, so currently we can only have one AnimateTo per animation.
678   Dali::AnimationData::AnimationDataElement* element = new Dali::AnimationData::AnimationDataElement();
679   element->alphaFunction = AlphaFunction::LINEAR;
680   element->timePeriodDelay = 0.0f;
681   element->timePeriodDuration = 1.0f;
682
683   // Now set the properties, or create children
684   for( unsigned int i = 0, animationMapCount = map.Count(); i < animationMapCount; ++i )
685   {
686     const StringValuePair& pair( map.GetPair( i ) );
687     const std::string& key( pair.first );
688     const Property::Value& value( pair.second );
689
690     if( key == "actor" )
691     {
692       element->actor = value.Get< std::string >();
693     }
694     else if( key == "property" )
695     {
696       element->property = value.Get< std::string >();
697     }
698     else if( key == "value" )
699     {
700       element->value = value;
701     }
702     else if( key == "alphaFunction" )
703     {
704       std::string alphaFunctionValue = value.Get< std::string >();
705
706       if( alphaFunctionValue == "LINEAR" )
707       {
708         element->alphaFunction = AlphaFunction::LINEAR;
709       }
710       else if( alphaFunctionValue == "REVERSE" )
711       {
712         element->alphaFunction = AlphaFunction::REVERSE;
713       }
714       else if( alphaFunctionValue == "EASE_IN_SQUARE" )
715       {
716         element->alphaFunction = AlphaFunction::EASE_IN_SQUARE;
717       }
718       else if( alphaFunctionValue == "EASE_OUT_SQUARE" )
719       {
720         element->alphaFunction = AlphaFunction::EASE_OUT_SQUARE;
721       }
722       else if( alphaFunctionValue == "EASE_IN" )
723       {
724         element->alphaFunction = AlphaFunction::EASE_IN;
725       }
726       else if( alphaFunctionValue == "EASE_OUT" )
727       {
728         element->alphaFunction = AlphaFunction::EASE_OUT;
729       }
730       else if( alphaFunctionValue == "EASE_IN_OUT" )
731       {
732         element->alphaFunction = AlphaFunction::EASE_IN_OUT;
733       }
734       else if( alphaFunctionValue == "EASE_IN_SINE" )
735       {
736         element->alphaFunction = AlphaFunction::EASE_IN_SINE;
737       }
738       else if( alphaFunctionValue == "EASE_OUT_SINE" )
739       {
740         element->alphaFunction = AlphaFunction::EASE_OUT_SINE;
741       }
742       else if( alphaFunctionValue == "EASE_IN_OUT_SINE" )
743       {
744         element->alphaFunction = AlphaFunction::EASE_IN_OUT_SINE;
745       }
746       else if( alphaFunctionValue == "BOUNCE" )
747       {
748         element->alphaFunction = AlphaFunction::BOUNCE;
749       }
750       else if( alphaFunctionValue == "SIN" )
751       {
752         element->alphaFunction = AlphaFunction::SIN;
753       }
754       else if( alphaFunctionValue == "EASE_OUT_BACK" )
755       {
756         element->alphaFunction = AlphaFunction::EASE_OUT_BACK;
757       }
758     }
759     else if( key == "timePeriod" )
760     {
761       Property::Array timeArray = value.Get< Property::Array >();
762
763       // TODO: Builder treats "{" within a Property::Map as a Property::Array.
764       // This means there is no key to determine what the values belong to.
765       if( timeArray.Size() >= 2 )
766       {
767         element->timePeriodDelay = timeArray[0].Get< float >();
768         element->timePeriodDuration = timeArray[1].Get< float >();
769       }
770     }
771   }
772
773   outputAnimationData.Add( element );
774 }
775
776 } // namespace scripting
777
778 } // namespace Dali
779
780
781
782