2 * Copyright (c) 2014 Samsung Electronics Co., Ltd.
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
19 #include <dali/public-api/scripting/scripting.h>
22 #include <dali/public-api/actors/actor.h>
23 #include <dali/public-api/images/resource-image.h>
24 #include <dali/public-api/images/image-attributes.h>
25 #include <dali/public-api/object/type-registry.h>
26 #include <dali/internal/event/images/resource-image-impl.h>
27 #include <dali/internal/event/images/frame-buffer-image-impl.h>
28 #include <dali/internal/event/images/buffer-image-impl.h>
29 #include <dali/internal/event/effects/shader-effect-impl.h>
40 // Tables used here for converting strings to the enumerations and vice versa
42 const StringEnum< ColorMode > COLOR_MODE_TABLE[] =
44 { "USE_OWN_COLOR", USE_OWN_COLOR },
45 { "USE_PARENT_COLOR", USE_PARENT_COLOR },
46 { "USE_OWN_MULTIPLY_PARENT_COLOR", USE_OWN_MULTIPLY_PARENT_COLOR },
47 { "USE_OWN_MULTIPLY_PARENT_ALPHA", USE_OWN_MULTIPLY_PARENT_ALPHA },
49 const unsigned int COLOR_MODE_TABLE_COUNT = sizeof( COLOR_MODE_TABLE ) / sizeof( COLOR_MODE_TABLE[0] );
51 const StringEnum< PositionInheritanceMode > POSITION_INHERITANCE_MODE_TABLE[] =
53 { "INHERIT_PARENT_POSITION", INHERIT_PARENT_POSITION },
54 { "USE_PARENT_POSITION", USE_PARENT_POSITION },
55 { "USE_PARENT_POSITION_PLUS_LOCAL_POSITION", USE_PARENT_POSITION_PLUS_LOCAL_POSITION },
56 { "DONT_INHERIT_POSITION", DONT_INHERIT_POSITION },
58 const unsigned int POSITION_INHERITANCE_MODE_TABLE_COUNT = sizeof( POSITION_INHERITANCE_MODE_TABLE ) / sizeof( POSITION_INHERITANCE_MODE_TABLE[0] );
60 const StringEnum< DrawMode::Type > DRAW_MODE_TABLE[] =
62 { "NORMAL", DrawMode::NORMAL },
63 { "OVERLAY", DrawMode::OVERLAY },
64 { "STENCIL", DrawMode::STENCIL },
66 const unsigned int DRAW_MODE_TABLE_COUNT = sizeof( DRAW_MODE_TABLE ) / sizeof( DRAW_MODE_TABLE[0] );
68 const StringEnum< Vector3 > ANCHOR_CONSTANT_TABLE[] =
70 { "BACK_TOP_LEFT", ParentOrigin::BACK_TOP_LEFT },
71 { "BACK_TOP_CENTER", ParentOrigin::BACK_TOP_CENTER },
72 { "BACK_TOP_RIGHT", ParentOrigin::BACK_TOP_RIGHT },
73 { "BACK_CENTER_LEFT", ParentOrigin::BACK_CENTER_LEFT },
74 { "BACK_CENTER", ParentOrigin::BACK_CENTER },
75 { "BACK_CENTER_RIGHT", ParentOrigin::BACK_CENTER_RIGHT },
76 { "BACK_BOTTOM_LEFT", ParentOrigin::BACK_BOTTOM_LEFT },
77 { "BACK_BOTTOM_CENTER", ParentOrigin::BACK_BOTTOM_CENTER },
78 { "BACK_BOTTOM_RIGHT", ParentOrigin::BACK_BOTTOM_RIGHT },
79 { "TOP_LEFT", ParentOrigin::TOP_LEFT },
80 { "TOP_CENTER", ParentOrigin::TOP_CENTER },
81 { "TOP_RIGHT", ParentOrigin::TOP_RIGHT },
82 { "CENTER_LEFT", ParentOrigin::CENTER_LEFT },
83 { "CENTER", ParentOrigin::CENTER },
84 { "CENTER_RIGHT", ParentOrigin::CENTER_RIGHT },
85 { "BOTTOM_LEFT", ParentOrigin::BOTTOM_LEFT },
86 { "BOTTOM_CENTER", ParentOrigin::BOTTOM_CENTER },
87 { "BOTTOM_RIGHT", ParentOrigin::BOTTOM_RIGHT },
88 { "FRONT_TOP_LEFT", ParentOrigin::FRONT_TOP_LEFT },
89 { "FRONT_TOP_CENTER", ParentOrigin::FRONT_TOP_CENTER },
90 { "FRONT_TOP_RIGHT", ParentOrigin::FRONT_TOP_RIGHT },
91 { "FRONT_CENTER_LEFT", ParentOrigin::FRONT_CENTER_LEFT },
92 { "FRONT_CENTER", ParentOrigin::FRONT_CENTER },
93 { "FRONT_CENTER_RIGHT", ParentOrigin::FRONT_CENTER_RIGHT },
94 { "FRONT_BOTTOM_LEFT", ParentOrigin::FRONT_BOTTOM_LEFT },
95 { "FRONT_BOTTOM_CENTER", ParentOrigin::FRONT_BOTTOM_CENTER },
96 { "FRONT_BOTTOM_RIGHT", ParentOrigin::FRONT_BOTTOM_RIGHT },
98 const unsigned int ANCHOR_CONSTANT_TABLE_COUNT = sizeof( ANCHOR_CONSTANT_TABLE ) / sizeof( ANCHOR_CONSTANT_TABLE[0] );
100 const StringEnum< ResourceImage::LoadPolicy > IMAGE_LOAD_POLICY_TABLE[] =
102 { "IMMEDIATE", ResourceImage::IMMEDIATE },
103 { "ON_DEMAND", ResourceImage::ON_DEMAND },
105 const unsigned int IMAGE_LOAD_POLICY_TABLE_COUNT = sizeof( IMAGE_LOAD_POLICY_TABLE ) / sizeof( IMAGE_LOAD_POLICY_TABLE[0] );
107 const StringEnum< Image::ReleasePolicy > IMAGE_RELEASE_POLICY_TABLE[] =
109 { "UNUSED", Image::UNUSED },
110 { "NEVER", Image::NEVER },
112 const unsigned int IMAGE_RELEASE_POLICY_TABLE_COUNT = sizeof( IMAGE_RELEASE_POLICY_TABLE ) / sizeof( IMAGE_RELEASE_POLICY_TABLE[0] );
114 const StringEnum< Pixel::Format > PIXEL_FORMAT_TABLE[] =
118 { "LA88", Pixel::LA88 },
119 { "RGB565", Pixel::RGB565 },
120 { "BGR565", Pixel::BGR565 },
121 { "RGBA4444", Pixel::RGBA4444 },
122 { "BGRA4444", Pixel::BGRA4444 },
123 { "RGBA5551", Pixel::RGBA5551 },
124 { "BGRA5551", Pixel::BGRA5551 },
125 { "RGB888", Pixel::RGB888 },
126 { "RGB8888", Pixel::RGB8888 },
127 { "BGR8888", Pixel::BGR8888 },
128 { "RGBA8888", Pixel::RGBA8888 },
129 { "BGRA8888", Pixel::BGRA8888 },
130 { "COMPRESSED_R11_EAC", Pixel::COMPRESSED_R11_EAC },
131 { "COMPRESSED_SIGNED_R11_EAC", Pixel::COMPRESSED_SIGNED_R11_EAC },
132 { "COMPRESSED_RG11_EAC", Pixel::COMPRESSED_RG11_EAC },
133 { "COMPRESSED_SIGNED_RG11_EAC", Pixel::COMPRESSED_SIGNED_RG11_EAC },
134 { "COMPRESSED_RGB8_ETC2", Pixel::COMPRESSED_RGB8_ETC2 },
135 { "COMPRESSED_SRGB8_ETC2", Pixel::COMPRESSED_SRGB8_ETC2 },
136 { "COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2", Pixel::COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2 },
137 { "COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2", Pixel::COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2 },
138 { "COMPRESSED_RGBA8_ETC2_EAC", Pixel::COMPRESSED_RGBA8_ETC2_EAC },
139 { "COMPRESSED_SRGB8_ALPHA8_ETC2_EAC", Pixel::COMPRESSED_SRGB8_ALPHA8_ETC2_EAC },
140 { "COMPRESSED_RGB8_ETC1", Pixel::COMPRESSED_RGB8_ETC1 },
141 { "COMPRESSED_RGB_PVRTC_4BPPV1", Pixel::COMPRESSED_RGB_PVRTC_4BPPV1 },
143 const unsigned int PIXEL_FORMAT_TABLE_COUNT = sizeof( PIXEL_FORMAT_TABLE ) / sizeof( PIXEL_FORMAT_TABLE[0] );
145 const StringEnum< ImageAttributes::ScalingMode > IMAGE_SCALING_MODE_TABLE[] =
147 { "SHRINK_TO_FIT", ImageAttributes::ShrinkToFit },
148 { "SCALE_TO_FILL", ImageAttributes::ScaleToFill },
149 { "FIT_WIDTH", ImageAttributes::FitWidth },
150 { "FIT_HEIGHT", ImageAttributes::FitHeight },
152 const unsigned int IMAGE_SCALING_MODE_TABLE_COUNT = sizeof( IMAGE_SCALING_MODE_TABLE ) / sizeof( IMAGE_SCALING_MODE_TABLE[0] );
154 } // unnamed namespace
156 bool CompareEnums( const char * a, const char * b )
158 while( ( *a != '\0' ) && ( *b != '\0' ) )
163 if( ( ( ca == '-' ) || ( ca == '_') ) &&
164 ( ( cb == '-' ) || ( cb == '_') ) )
171 if( ( 'A' <= ca ) && ( ca <= 'Z') )
173 ca = ca + ( 'a' - 'A' );
176 if( ( 'A' <= cb ) && ( cb <= 'Z') )
178 cb = cb + ( 'a' - 'A' );
190 if( ( *a == '\0' ) && ( *b == '\0' ) )
199 ColorMode GetColorMode( const std::string& value )
201 return GetEnumeration< ColorMode >( value.c_str(), COLOR_MODE_TABLE, COLOR_MODE_TABLE_COUNT );
205 std::string GetColorMode( ColorMode value )
207 return GetEnumerationName< ColorMode >( value, COLOR_MODE_TABLE, COLOR_MODE_TABLE_COUNT );
210 PositionInheritanceMode GetPositionInheritanceMode( const std::string& value )
212 return GetEnumeration< PositionInheritanceMode >( value.c_str(), POSITION_INHERITANCE_MODE_TABLE, POSITION_INHERITANCE_MODE_TABLE_COUNT );
216 std::string GetPositionInheritanceMode( PositionInheritanceMode value )
218 return GetEnumerationName< PositionInheritanceMode >( value, POSITION_INHERITANCE_MODE_TABLE, POSITION_INHERITANCE_MODE_TABLE_COUNT );
222 DrawMode::Type GetDrawMode( const std::string& value )
224 return GetEnumeration< DrawMode::Type >( value.c_str(), DRAW_MODE_TABLE, DRAW_MODE_TABLE_COUNT );
228 std::string GetDrawMode( DrawMode::Type value )
230 return GetEnumerationName< DrawMode::Type >( value, DRAW_MODE_TABLE, DRAW_MODE_TABLE_COUNT );
234 Vector3 GetAnchorConstant( const std::string& value )
236 return GetEnumeration< Vector3 >( value.c_str(), ANCHOR_CONSTANT_TABLE, ANCHOR_CONSTANT_TABLE_COUNT );
240 Image NewImage( const Property::Value& map )
244 std::string filename;
245 ResourceImage::LoadPolicy loadPolicy = Dali::Internal::IMAGE_LOAD_POLICY_DEFAULT;
246 Image::ReleasePolicy releasePolicy = Dali::Internal::IMAGE_RELEASE_POLICY_DEFAULT;
247 ImageAttributes attributes = ImageAttributes::New();
249 if( Property::MAP == map.GetType() )
251 std::string field = "filename";
252 if( map.HasKey(field) )
254 DALI_ASSERT_ALWAYS(map.GetValue(field).GetType() == Property::STRING && "Image filename property is not a string" );
255 filename = map.GetValue(field).Get<std::string>();
258 field = "load-policy";
259 if( map.HasKey(field) )
261 DALI_ASSERT_ALWAYS(map.GetValue(field).GetType() == Property::STRING && "Image load-policy property is not a string" );
262 std::string v(map.GetValue(field).Get<std::string>());
263 loadPolicy = GetEnumeration< ResourceImage::LoadPolicy >( v.c_str(), IMAGE_LOAD_POLICY_TABLE, IMAGE_LOAD_POLICY_TABLE_COUNT );
266 field = "release-policy";
267 if( map.HasKey(field) )
269 DALI_ASSERT_ALWAYS(map.GetValue(field).GetType() == Property::STRING && "Image release-policy property is not a string" );
270 std::string v(map.GetValue(field).Get<std::string>());
271 releasePolicy = GetEnumeration< Image::ReleasePolicy >( v.c_str(), IMAGE_RELEASE_POLICY_TABLE, IMAGE_RELEASE_POLICY_TABLE_COUNT );
274 if( map.HasKey("width") && map.HasKey("height") )
276 Property::Value &value = map.GetValue("width");
277 unsigned int w = 0, h = 0;
278 // handle floats and integer the same for json script
279 if( value.GetType() == Property::FLOAT)
281 w = static_cast<unsigned int>( value.Get<float>() );
285 DALI_ASSERT_ALWAYS(value.GetType() == Property::INTEGER && "Image width property is not a number" );
286 w = value.Get<int>();
289 value = map.GetValue("height");
290 if( value.GetType() == Property::FLOAT)
292 h = static_cast<unsigned int>( value.Get<float>() );
296 DALI_ASSERT_ALWAYS(value.GetType() == Property::INTEGER && "Image width property is not a number" );
297 h = value.Get<int>();
300 attributes.SetSize( w, h );
303 field = "pixel-format";
304 Pixel::Format pixelFormat = Pixel::RGBA8888;
305 if( map.HasKey(field) )
307 DALI_ASSERT_ALWAYS(map.GetValue(field).GetType() == Property::STRING && "Image release-policy property is not a string" );
308 std::string s(map.GetValue(field).Get<std::string>());
309 pixelFormat = GetEnumeration< Pixel::Format >( s.c_str(), PIXEL_FORMAT_TABLE, PIXEL_FORMAT_TABLE_COUNT );
312 field = "scaling-mode";
313 if( map.HasKey(field) )
315 DALI_ASSERT_ALWAYS(map.GetValue(field).GetType() == Property::STRING && "Image release-policy property is not a string" );
316 std::string s(map.GetValue(field).Get<std::string>());
317 attributes.SetScalingMode( GetEnumeration< ImageAttributes::ScalingMode >( s.c_str(), IMAGE_SCALING_MODE_TABLE, IMAGE_SCALING_MODE_TABLE_COUNT ) );
320 if( map.HasKey("type") )
322 DALI_ASSERT_ALWAYS( map.GetValue("type").GetType() == Property::STRING );
323 std::string s(map.GetValue("type").Get<std::string>());
324 if("FrameBufferImage" == s)
326 ret = FrameBufferImage::New(attributes.GetWidth(),
327 attributes.GetHeight(),
331 else if("BufferImage" == s)
333 ret = BufferImage::New(attributes.GetWidth(),
334 attributes.GetHeight(),
338 else if("ResourceImage" == s)
340 ret = ResourceImage::New(filename, attributes, loadPolicy, releasePolicy);
344 DALI_ASSERT_ALWAYS( !"Unknown image type" );
349 ret = ResourceImage::New(filename, attributes, loadPolicy, releasePolicy);
355 } // Image NewImage( Property::Value map )
358 ShaderEffect NewShaderEffect( const Property::Value& map )
360 Internal::ShaderEffectPtr ret;
362 if( map.GetType() == Property::MAP )
364 ret = Internal::ShaderEffect::New(Dali::ShaderEffect::HINT_NONE); // hint can be reset if in map
366 if( map.HasKey("program") )
368 Property::Index index = ret->GetPropertyIndex("program");
369 DALI_ASSERT_DEBUG( map.GetValue("program").GetType() == Property::MAP );
370 ret->SetProperty(index, map.GetValue("program"));
373 for(int i = 0; i < map.GetSize(); ++i)
375 const std::string& key = map.GetKey(i);
378 Property::Index index = ret->GetPropertyIndex( key );
380 if( Property::INVALID_INDEX != index )
382 ret->SetProperty(index, map.GetItem(i));
386 // if its not a property then register it as a uniform (making a custom property)
388 if(map.GetItem(i).GetType() == Property::INTEGER)
390 // valid uniforms are floats, vec3's etc so we recast if the user accidentally
391 // set as integer. Note the map could have come from json script.
392 Property::Value asFloat( static_cast<float>( map.GetItem(i).Get<int>() ) );
393 ret->SetUniform( key, asFloat, Dali::ShaderEffect::COORDINATE_TYPE_DEFAULT );
397 ret->SetUniform( key, map.GetItem(i), Dali::ShaderEffect::COORDINATE_TYPE_DEFAULT );
404 return Dali::ShaderEffect(ret.Get());
408 Actor NewActor( const Property::Map& map )
412 // First find type and create Actor
413 Property::Value* typeValue = map.Find( "type" );
416 TypeInfo type = TypeRegistry::Get().GetTypeInfo( typeValue->Get< std::string >() );
419 handle = type.CreateInstance();
425 DALI_LOG_ERROR( "Actor type not provided, returning empty handle" );
429 Actor actor( Actor::DownCast( handle ) );
433 // Now set the properties, or create children
434 for ( unsigned int i = 0, mapCount = map.Count(); i < mapCount; ++i )
436 const StringValuePair& pair( map.GetPair( i ) );
437 const std::string& key( pair.first );
443 const Property::Value& value( pair.second );
445 if ( key == "actors" )
449 Property::Array actorArray = value.Get< Property::Array >();
450 for ( Property::Array::iterator arrayIter = actorArray.begin(), arrayEndIter = actorArray.end(); arrayIter != arrayEndIter; ++arrayIter )
452 actor.Add( NewActor( arrayIter->Get< Property::Map >() ) );
455 else if ( key == "signals" )
457 DALI_LOG_ERROR( "signals not supported" );
459 else if( key == "parent-origin" )
461 // Parent Origin can be a string constant as well as a Vector3
463 const Property::Type type( value.GetType() );
464 if ( type == Property::VECTOR3 )
466 actor.SetParentOrigin( value.Get< Vector3 >() );
468 else if( type == Property::STRING )
470 actor.SetParentOrigin( GetAnchorConstant( value.Get< std::string >() ) );
473 else if( key == "anchor-point" )
475 // Anchor Point can be a string constant as well as a Vector3
477 const Property::Type type( value.GetType() );
478 if ( type == Property::VECTOR3 )
480 actor.SetAnchorPoint( value.Get< Vector3 >() );
482 else if( type == Property::STRING )
484 actor.SetAnchorPoint( GetAnchorConstant( value.Get< std::string >() ) );
489 Property::Index index( actor.GetPropertyIndex( key ) );
491 if ( index != Property::INVALID_INDEX )
493 actor.SetProperty( index, value );
502 void CreatePropertyMap( Actor actor, Property::Map& map )
508 map[ "type" ] = actor.GetTypeName();
510 // Default properties
511 Property::IndexContainer indices;
512 actor.GetPropertyIndices( indices );
513 const Property::IndexContainer::const_iterator endIter = indices.end();
514 for ( Property::IndexContainer::iterator iter = indices.begin(); iter != endIter; ++iter )
516 map[ actor.GetPropertyName( *iter ) ] = actor.GetProperty( *iter );
520 unsigned int childCount( actor.GetChildCount() );
523 Property::Array childArray;
524 for ( unsigned int child = 0; child < childCount; ++child )
526 Property::Map childMap;
527 CreatePropertyMap( actor.GetChildAt( child ), childMap );
528 childArray.push_back( childMap );
530 map[ "actors" ] = childArray;
535 void CreatePropertyMap( Image image, Property::Map& map )
541 std::string imageType( "ResourceImage" );
543 // Get Type - cannot use TypeRegistry as Image is not an Object and thus, not registered
544 BufferImage bufferImage = BufferImage::DownCast( image );
547 imageType = "BufferImage";
548 map[ "pixel-format" ] = GetEnumerationName< Pixel::Format >( bufferImage.GetPixelFormat(), PIXEL_FORMAT_TABLE, PIXEL_FORMAT_TABLE_COUNT );
550 else if ( FrameBufferImage::DownCast( image ) )
552 imageType = "FrameBufferImage";
555 map[ "type" ] = imageType;
556 map[ "release-policy" ] = GetEnumerationName< Image::ReleasePolicy >( image.GetReleasePolicy(), IMAGE_RELEASE_POLICY_TABLE, IMAGE_RELEASE_POLICY_TABLE_COUNT );
558 ResourceImage resourceImage = ResourceImage::DownCast( image );
561 map[ "filename" ] = resourceImage.GetUrl();
562 map[ "load-policy" ] = GetEnumerationName< ResourceImage::LoadPolicy >( resourceImage.GetLoadPolicy(), IMAGE_LOAD_POLICY_TABLE, IMAGE_LOAD_POLICY_TABLE_COUNT );
564 ImageAttributes attributes( resourceImage.GetAttributes() );
565 map[ "scaling-mode" ] = GetEnumerationName< ImageAttributes::ScalingMode >( attributes.GetScalingMode(), IMAGE_SCALING_MODE_TABLE, IMAGE_SCALING_MODE_TABLE_COUNT );
568 int width( image.GetWidth() );
569 int height( image.GetHeight() );
571 if ( width && height )
573 map[ "width" ] = width;
574 map[ "height" ] = height;
579 } // namespace scripting