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/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/image-impl.h>
27 #include <dali/internal/event/images/frame-buffer-image-impl.h>
28 #include <dali/internal/event/images/bitmap-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< Image::LoadPolicy > IMAGE_LOAD_POLICY_TABLE[] =
102 { "IMMEDIATE", Image::Immediate },
103 { "ON_DEMAND", Image::OnDemand },
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 std::string& a, const std::string& b)
158 std::string::const_iterator ia = a.begin();
159 std::string::const_iterator ib = b.begin();
161 while( (ia != a.end()) && (ib != b.end()) )
166 if(ca == '-' || ca == '_')
172 if(cb == '-' || cb == '_')
178 if( 'A' <= ca && ca <= 'Z')
180 ca = ca + ('a' - 'A');
183 if( 'A' <= cb && cb <= 'Z')
185 cb = cb + ('a' - 'A');
197 if( (ia == a.end() && ib == b.end() ) )
209 ColorMode GetColorMode( const std::string& value )
211 return GetEnumeration< ColorMode >( value, COLOR_MODE_TABLE, COLOR_MODE_TABLE_COUNT );
215 std::string GetColorMode( ColorMode value )
217 return GetEnumerationName< ColorMode >( value, COLOR_MODE_TABLE, COLOR_MODE_TABLE_COUNT );
220 PositionInheritanceMode GetPositionInheritanceMode( const std::string& value )
222 return GetEnumeration< PositionInheritanceMode >( value, POSITION_INHERITANCE_MODE_TABLE, POSITION_INHERITANCE_MODE_TABLE_COUNT );
226 std::string GetPositionInheritanceMode( PositionInheritanceMode value )
228 return GetEnumerationName< PositionInheritanceMode >( value, POSITION_INHERITANCE_MODE_TABLE, POSITION_INHERITANCE_MODE_TABLE_COUNT );
232 DrawMode::Type GetDrawMode( const std::string& value )
234 return GetEnumeration< DrawMode::Type >( value, DRAW_MODE_TABLE, DRAW_MODE_TABLE_COUNT );
238 std::string GetDrawMode( DrawMode::Type value )
240 return GetEnumerationName< DrawMode::Type >( value, DRAW_MODE_TABLE, DRAW_MODE_TABLE_COUNT );
244 Vector3 GetAnchorConstant( const std::string& value )
246 return GetEnumeration< Vector3 >( value, ANCHOR_CONSTANT_TABLE, ANCHOR_CONSTANT_TABLE_COUNT );
250 Image NewImage( const Property::Value& map )
254 std::string filename;
255 Image::LoadPolicy loadPolicy = Dali::Internal::ImageLoadPolicyDefault;
256 Image::ReleasePolicy releasePolicy = Dali::Internal::ImageReleasePolicyDefault;
257 ImageAttributes attributes = ImageAttributes::New();
259 if( Property::MAP == map.GetType() )
261 std::string field = "filename";
262 if( map.HasKey(field) )
264 DALI_ASSERT_ALWAYS(map.GetValue(field).GetType() == Property::STRING && "Image filename property is not a string" );
265 filename = map.GetValue(field).Get<std::string>();
268 field = "load-policy";
269 if( map.HasKey(field) )
271 DALI_ASSERT_ALWAYS(map.GetValue(field).GetType() == Property::STRING && "Image load-policy property is not a string" );
272 std::string v(map.GetValue(field).Get<std::string>());
273 loadPolicy = GetEnumeration< Image::LoadPolicy >( v, IMAGE_LOAD_POLICY_TABLE, IMAGE_LOAD_POLICY_TABLE_COUNT );
276 field = "release-policy";
277 if( map.HasKey(field) )
279 DALI_ASSERT_ALWAYS(map.GetValue(field).GetType() == Property::STRING && "Image release-policy property is not a string" );
280 std::string v(map.GetValue(field).Get<std::string>());
281 releasePolicy = GetEnumeration< Image::ReleasePolicy >( v, IMAGE_RELEASE_POLICY_TABLE, IMAGE_RELEASE_POLICY_TABLE_COUNT );
284 if( map.HasKey("width") && map.HasKey("height") )
286 Property::Value &value = map.GetValue("width");
287 unsigned int w = 0, h = 0;
288 // handle floats and integer the same for json script
289 if( value.GetType() == Property::FLOAT)
291 w = static_cast<unsigned int>( value.Get<float>() );
295 DALI_ASSERT_ALWAYS(value.GetType() == Property::INTEGER && "Image width property is not a number" );
296 w = value.Get<int>();
299 value = map.GetValue("height");
300 if( value.GetType() == Property::FLOAT)
302 h = static_cast<unsigned int>( value.Get<float>() );
306 DALI_ASSERT_ALWAYS(value.GetType() == Property::INTEGER && "Image width property is not a number" );
307 h = value.Get<int>();
310 attributes.SetSize( w, h );
313 field = "pixel-format";
314 if( map.HasKey(field) )
316 DALI_ASSERT_ALWAYS(map.GetValue(field).GetType() == Property::STRING && "Image release-policy property is not a string" );
317 std::string s(map.GetValue(field).Get<std::string>());
318 attributes.SetPixelFormat( GetEnumeration< Pixel::Format >( s, PIXEL_FORMAT_TABLE, PIXEL_FORMAT_TABLE_COUNT ));
321 field = "scaling-mode";
322 if( map.HasKey(field) )
324 DALI_ASSERT_ALWAYS(map.GetValue(field).GetType() == Property::STRING && "Image release-policy property is not a string" );
325 std::string s(map.GetValue(field).Get<std::string>());
326 attributes.SetScalingMode( GetEnumeration< ImageAttributes::ScalingMode >( s, IMAGE_SCALING_MODE_TABLE, IMAGE_SCALING_MODE_TABLE_COUNT ) );
329 if( map.HasKey("type") )
331 DALI_ASSERT_ALWAYS( map.GetValue("type").GetType() == Property::STRING );
332 std::string s(map.GetValue("type").Get<std::string>());
333 if("FrameBufferImage" == s)
335 ret = Image( new Internal::FrameBufferImage(attributes.GetWidth(),
336 attributes.GetHeight(),
337 attributes.GetPixelFormat(),
340 else if("BitmapImage" == s)
342 ret = Image( new Internal::BitmapImage(attributes.GetWidth(),
343 attributes.GetHeight(),
344 attributes.GetPixelFormat(),
348 else if("Image" == s)
350 ret = Image::New(filename, attributes, loadPolicy, releasePolicy);
354 DALI_ASSERT_ALWAYS( !"Unknown image type" );
359 ret = Image::New(filename, attributes, loadPolicy, releasePolicy);
365 } // Image NewImage( Property::Value map )
368 ShaderEffect NewShaderEffect( const Property::Value& map )
370 Internal::ShaderEffectPtr ret;
372 if( map.GetType() == Property::MAP )
374 ret = Internal::ShaderEffect::New(Dali::ShaderEffect::HINT_NONE); // hint can be reset if in map
376 if( map.HasKey("program") )
378 Property::Index index = ret->GetPropertyIndex("program");
379 DALI_ASSERT_DEBUG( map.GetValue("program").GetType() == Property::MAP );
380 ret->SetProperty(index, map.GetValue("program"));
383 for(int i = 0; i < map.GetSize(); ++i)
385 const std::string& key = map.GetKey(i);
388 Property::Index index = ret->GetPropertyIndex( key );
390 if( Property::INVALID_INDEX != index )
392 ret->SetProperty(index, map.GetItem(i));
396 // if its not a property then register it as a uniform (making a custom property)
398 if(map.GetItem(i).GetType() == Property::INTEGER)
400 // valid uniforms are floats, vec3's etc so we recast if the user accidentally
401 // set as integer. Note the map could have come from json script.
402 Property::Value asFloat( static_cast<float>( map.GetItem(i).Get<int>() ) );
403 ret->SetUniform( key, asFloat, Dali::ShaderEffect::COORDINATE_TYPE_DEFAULT );
407 ret->SetUniform( key, map.GetItem(i), Dali::ShaderEffect::COORDINATE_TYPE_DEFAULT );
414 return Dali::ShaderEffect(ret.Get());
418 Actor NewActor( const Property::Map& map )
422 // First find type and create Actor
423 Property::Value* typeValue = map.Find( "type" );
426 TypeInfo type = TypeRegistry::Get().GetTypeInfo( typeValue->Get< std::string >() );
429 handle = type.CreateInstance();
435 DALI_LOG_ERROR( "Actor type not provided, returning empty handle" );
439 Actor actor( Actor::DownCast( handle ) );
443 // Now set the properties, or create children
444 for ( unsigned int i = 0, mapCount = map.Count(); i < mapCount; ++i )
446 const StringValuePair& pair( map.GetPair( i ) );
447 const std::string& key( pair.first );
453 const Property::Value& value( pair.second );
455 if ( key == "actors" )
459 Property::Array actorArray = value.Get< Property::Array >();
460 for ( Property::Array::iterator arrayIter = actorArray.begin(), arrayEndIter = actorArray.end(); arrayIter != arrayEndIter; ++arrayIter )
462 actor.Add( NewActor( arrayIter->Get< Property::Map >() ) );
465 else if ( key == "signals" )
467 DALI_LOG_ERROR( "signals not supported" );
469 else if( key == "parent-origin" )
471 // Parent Origin can be a string constant as well as a Vector3
473 const Property::Type type( value.GetType() );
474 if ( type == Property::VECTOR3 )
476 actor.SetParentOrigin( value.Get< Vector3 >() );
478 else if( type == Property::STRING )
480 actor.SetParentOrigin( GetAnchorConstant( value.Get< std::string >() ) );
483 else if( key == "anchor-point" )
485 // Anchor Point can be a string constant as well as a Vector3
487 const Property::Type type( value.GetType() );
488 if ( type == Property::VECTOR3 )
490 actor.SetAnchorPoint( value.Get< Vector3 >() );
492 else if( type == Property::STRING )
494 actor.SetAnchorPoint( GetAnchorConstant( value.Get< std::string >() ) );
499 Property::Index index( actor.GetPropertyIndex( key ) );
501 if ( index != Property::INVALID_INDEX )
503 actor.SetProperty( index, value );
512 void CreatePropertyMap( Actor actor, Property::Map& map )
518 map[ "type" ] = actor.GetTypeName();
520 // Default properties
521 Property::IndexContainer indices;
522 actor.GetPropertyIndices( indices );
523 const Property::IndexContainer::const_iterator endIter = indices.end();
524 for ( Property::IndexContainer::iterator iter = indices.begin(); iter != endIter; ++iter )
526 map[ actor.GetPropertyName( *iter ) ] = actor.GetProperty( *iter );
530 unsigned int childCount( actor.GetChildCount() );
533 Property::Array childArray;
534 for ( unsigned int child = 0; child < childCount; ++child )
536 Property::Map childMap;
537 CreatePropertyMap( actor.GetChildAt( child ), childMap );
538 childArray.push_back( childMap );
540 map[ "actors" ] = childArray;
545 void CreatePropertyMap( Image image, Property::Map& map )
551 std::string imageType( "Image" );
553 // Get Type - cannot use TypeRegistry as Image is not a ProxyObject and thus, not registered
554 if ( BitmapImage::DownCast( image ) )
556 imageType = "BitmapImage";
558 else if ( FrameBufferImage::DownCast( image ) )
560 imageType = "FrameBufferImage";
563 map[ "type" ] = imageType;
564 map[ "filename" ] = image.GetFilename();
565 map[ "load-policy" ] = GetEnumerationName< Image::LoadPolicy >( image.GetLoadPolicy(), IMAGE_LOAD_POLICY_TABLE, IMAGE_LOAD_POLICY_TABLE_COUNT );
566 map[ "release-policy" ] = GetEnumerationName< Image::ReleasePolicy >( image.GetReleasePolicy(), IMAGE_RELEASE_POLICY_TABLE, IMAGE_RELEASE_POLICY_TABLE_COUNT );
568 ImageAttributes attributes( image.GetAttributes() );
569 map[ "pixel-format" ] = GetEnumerationName< Pixel::Format >( attributes.GetPixelFormat(), PIXEL_FORMAT_TABLE, PIXEL_FORMAT_TABLE_COUNT );
570 map[ "scaling-mode" ] = GetEnumerationName< ImageAttributes::ScalingMode >( attributes.GetScalingMode(), IMAGE_SCALING_MODE_TABLE, IMAGE_SCALING_MODE_TABLE_COUNT );
572 int width( image.GetWidth() );
573 int height( image.GetHeight() );
575 if ( width && height )
577 map[ "width" ] = width;
578 map[ "height" ] = height;
583 } // namespace scripting