From: Lee Morgan Date: Thu, 24 Apr 2014 16:41:08 +0000 (+0100) Subject: Scripting: Json format changes; style sets, includes X-Git-Tag: dali-2014-wk20-release~23 X-Git-Url: http://review.tizen.org/git/?p=platform%2Fcore%2Fuifw%2Fdali-toolkit.git;a=commitdiff_plain;h=6bd46a2944d89638f1c1a1c609f72c9348db6abb Scripting: Json format changes; style sets, includes Styles section split into templates & styles. Includes section added. [Issue#] (N/A) [Problem] [Cause] [Solution] Change-Id: I5bbfc3d05862bda3420b0c2ff5e7f39639325bc4 Signed-off-by: Lee Morgan --- diff --git a/automated-tests/src/dali-toolkit-unmanaged/utc-Dali-Builder.cpp b/automated-tests/src/dali-toolkit-unmanaged/utc-Dali-Builder.cpp index 2399c98..6f63515 100644 --- a/automated-tests/src/dali-toolkit-unmanaged/utc-Dali-Builder.cpp +++ b/automated-tests/src/dali-toolkit-unmanaged/utc-Dali-Builder.cpp @@ -28,40 +28,23 @@ namespace // Note: To avoid escaping double quotes single quotes are used and then replaced // before parsing. JSON uses double quotes // - std::string JSON_TEXTSTYLE_ONLY("\ -{ \ - 'text-styles': \ - { \ - 'title-text-style':{'font-name': 'Vera', \ - 'font-style': 'Bold', \ - 'point-size': 12.0, \ - 'weight': 'light', \ - 'text-color': [0.0,0.5,0.5,1], \ - 'italic': false, \ - 'underline': false, \ - 'shadow': true, \ - 'glow': true, \ - 'outline': true, \ - 'shadow-color': [0.0,1.0,0.0,1.0], \ - 'shadow-offset': [3.0,2.0], \ - 'shadow-size': 2.0, \ - 'glow-color': [0.9,0.6,0.3,1.0], \ - 'glow-intensity':0.1, \ - 'smooth-edge': 0.45, \ - 'outline-color': [1.0,0.5,0.0,1.0], \ - 'outline-thickness': [0.7,0.6] \ - } \ - } \ -} \ -"); std::string JSON_TEXT_ACTOR("\ { \ - 'styles': \ + 'templates': \ { \ 'basic-text': \ { \ 'type':'TextActor', \ + 'text':'Template Hello', \ + 'size': [150,170,1], \ + 'position':[-10,10,0] \ + } \ + }, \ + 'styles': \ + { \ + 'basic-text': \ + { \ 'text':'Hello', \ 'font':'', \ 'parent-origin':[0.0,0.0,0], \ @@ -118,7 +101,7 @@ namespace std::string JSON_CORE_ACTOR_TREE("\ { \ - 'styles': \ + 'templates': \ { \ 'my-camera': { \ 'type':'CameraActor', \ @@ -135,14 +118,17 @@ namespace 'smooth-edge':0.2, \ 'position': [-10.0, 10.0, -1000.0], \ 'size': [300.0, 250.0, 0.0] \ - }, \ - 'theme2-text': { \ - 'type':'TextActor', \ - 'text':'Hello', \ - 'font':'Freesans', \ - 'smooth-edge':0.8 \ } \ }, \ + 'styles': \ + { \ + 'theme2-text': { \ + 'type':'TextActor', \ + 'text':'Hello', \ + 'font':'Freesans', \ + 'smooth-edge':0.8 \ + } \ + }, \ 'stage': \ [ \ {'name':'txt1', \ @@ -186,18 +172,18 @@ void builder_cleanup(void) test_return_value = TET_PASS; } -int UtcDaliBuilderTextActorCreateFromStyle(void) +int UtcDaliBuilderTextActorCreate(void) { ToolkitTestApplication application; Stage stage = Stage::GetCurrent(); - tet_infoline(" UtcDaliBuilderTextActorCreateFromStyle"); + tet_infoline(" UtcDaliBuilderTextActorCreate"); Builder builder = Builder::New(); builder.LoadFromString(ReplaceQuotes(JSON_TEXT_ACTOR)); - TextActor actor( TextActor::DownCast( builder.CreateFromStyle("basic-text") ) ); + TextActor actor( TextActor::DownCast( builder.Create("basic-text") ) ); DALI_TEST_CHECK( actor ); @@ -218,9 +204,9 @@ int UtcDaliBuilderTextActorCreateFromStyle(void) DALI_TEST_CHECK(v.y == 170.0); DALI_TEST_CHECK(v.z == 1.0); - DALI_TEST_CHECK(actor.GetText() == "Hello"); + DALI_TEST_CHECK(actor.GetText() == "Template Hello"); - actor = TextActor::DownCast( builder.CreateFromStyle("*(&^") ); + actor = TextActor::DownCast( builder.Create("*(&^") ); DALI_TEST_CHECK(!actor); END_TEST; @@ -343,7 +329,7 @@ int UtcDaliBuilderStyles(void) builder.LoadFromString(ReplaceQuotes(JSON_CORE_ACTOR_TREE)); - BaseHandle handle = builder.CreateFromStyle("my-camera"); + BaseHandle handle = builder.Create("my-camera"); CameraActor camera = CameraActor::DownCast(handle); DALI_TEST_CHECK(camera); @@ -356,7 +342,7 @@ int UtcDaliBuilderStyles(void) v = camera.GetProperty( camera.GetPropertyIndex("aspect-ratio") ); DALI_TEST_CHECK( 5.0f == v.Get() ); - handle = builder.CreateFromStyle("basic-text"); + handle = builder.Create("basic-text"); TextActor textActor = TextActor::DownCast(handle); v = textActor.GetProperty( textActor.GetPropertyIndex("smooth-edge") ); diff --git a/dali-toolkit/internal/builder/builder-filesystem.h b/dali-toolkit/internal/builder/builder-filesystem.h index b3fa958..19d038d 100644 --- a/dali-toolkit/internal/builder/builder-filesystem.h +++ b/dali-toolkit/internal/builder/builder-filesystem.h @@ -18,6 +18,9 @@ // // EXTERNAL INCLUDES +#include +#include + #include #include #include @@ -45,4 +48,10 @@ inline std::string ExePath(void) return std::string(buf); } +inline std::string GetFileContents(const std::string &fn) +{ + std::ifstream t(fn.c_str()); + return std::string((std::istreambuf_iterator(t)), std::istreambuf_iterator()); +} + #endif // __DALI_TOOLKIT_INTERNAL_BUILDER_FILESYSTEM_H__ diff --git a/dali-toolkit/internal/builder/builder-impl.cpp b/dali-toolkit/internal/builder/builder-impl.cpp index a7b887c..226883e 100644 --- a/dali-toolkit/internal/builder/builder-impl.cpp +++ b/dali-toolkit/internal/builder/builder-impl.cpp @@ -25,6 +25,7 @@ #include #include +#include #include #include @@ -58,6 +59,14 @@ Integration::Log::Filter* gFilterScript = Integration::Log::Filter::New(Debug:: namespace { +const std::string KEYNAME_STYLES = "styles"; +const std::string KEYNAME_TYPE = "type"; +const std::string KEYNAME_ACTORS = "actors"; +const std::string KEYNAME_SIGNALS = "signals"; +const std::string KEYNAME_NAME = "name"; +const std::string KEYNAME_TEMPLATES = "templates"; +const std::string KEYNAME_INCLUDES = "includes"; + typedef std::vector TreeNodeList; template @@ -169,9 +178,41 @@ std::string PropertyValueToString( const Property::Value& value ) } /* + * Recursively collects all stylesin a node (An array of style names). + * + * stylesCollection The set of styles from the json file (a json object of named styles) + * style The style array to begin the collection from + * styleList The style list to add nodes to apply + */ +void CollectAllStyles( const TreeNode& stylesCollection, const TreeNode& style, TreeNodeList& styleList ) +{ + // style is an array of style names + if( TreeNode::ARRAY == style.GetType() ) + { + for(TreeNode::ConstIterator iter = style.CBegin(); iter != style.CEnd(); ++iter) + { + if( OptionalString styleName = IsString( (*iter).second ) ) + { + if( OptionalChild node = IsChild( stylesCollection, *styleName) ) + { + styleList.push_back( &(*node) ); + + if( OptionalChild subStyle = IsChild( *node, KEYNAME_STYLES ) ) + { + CollectAllStyles( stylesCollection, *subStyle, styleList ); + } + } + } + } + } +} + +} // namespace anon + +/* * Sets the handle properties found in the tree node */ -void SetProperties( const TreeNode& node, Handle& handle, Builder& builder, const Replacement& constant ) +void Builder::SetProperties( const TreeNode& node, Handle& handle, const Replacement& constant ) { if( handle ) { @@ -182,7 +223,7 @@ void SetProperties( const TreeNode& node, Handle& handle, Builder& builder, cons std::string key( keyChild.first ); // ignore special fields; type,actors,signals - if(key == "type" || key == "actors" || key == "signals") + if(key == KEYNAME_TYPE || key == KEYNAME_ACTORS || key == KEYNAME_SIGNALS || key == KEYNAME_STYLES) { continue; } @@ -198,7 +239,7 @@ void SetProperties( const TreeNode& node, Handle& handle, Builder& builder, cons { if( OptionalString s = constant.IsString( keyChild.second ) ) { - FrameBufferImage fb = builder.GetFrameBufferImage(*s, constant); + FrameBufferImage fb = GetFrameBufferImage(*s, constant); if(fb) { imageActor.SetImage( fb ); @@ -215,7 +256,7 @@ void SetProperties( const TreeNode& node, Handle& handle, Builder& builder, cons OptionalString s = constant.IsString( keyChild.second ); if(actor && s) { - ShaderEffect e = builder.GetShaderEffect(*s, constant); + ShaderEffect e = GetShaderEffect(*s, constant); actor.SetShaderEffect(e); } else @@ -259,108 +300,150 @@ void SetProperties( const TreeNode& node, Handle& handle, Builder& builder, cons } } -/* - * Split a string by delimiter - */ -std::vector SplitString(const std::string &s, char delim, std::vector &elems) +// Set properties from node on handle. +void Builder::ApplyProperties( const TreeNode& root, const TreeNode& node, + Dali::Handle& handle, const Replacement& constant ) { - std::stringstream ss(s); - std::string item; - while(std::getline(ss, item, delim)) + if( Actor actor = Actor::DownCast(handle) ) { - elems.push_back(item); - } - return elems; -} + SetProperties( node, actor, constant ); -/* - * Recursively collects all styles listed in a json node 'type' field. (Could be a comma separated list). - * It also returns the first found base typeInfo from the TypeRegistry. This is the concrete object to instance. - * i.e. the type field can name a json style section or a TypeRegistry base type. - */ -void CollectAllStyles( const TreeNode& styles, const std::string& typeStyleString, TreeNodeList& additionalStyles, TypeInfo& typeInfo ) -{ - typedef std::vector StyleNames; - StyleNames styleNames; + if( actor ) + { + SetupActor( node, actor ); - SplitString(typeStyleString, ',', styleNames); + Control control = Control::DownCast(actor); - for(StyleNames::iterator iter = styleNames.begin(); iter != styleNames.end(); ++iter) + if( control ) + { + SetupControl( node, control ); + } + + // add signals + SetupSignalAction( mSlotDelegate.GetConnectionTracker(), root, node, actor ); + + SetupPropertyNotification( mSlotDelegate.GetConnectionTracker(), root, node, actor ); + } + } + else { - const std::string typeName(*iter); + SetProperties( node, handle, constant ); + } +} - OptionalChild style = IsChild(styles, typeName); - if(style) +// Appling by style helper +// use FindChildByName() to apply properties referenced in KEYNAME_ACTORS in the node +void Builder::ApplyStylesByActor( const TreeNode& root, const TreeNode& node, + Dali::Handle& handle, const Replacement& constant ) +{ + if( Dali::Actor actor = Dali::Actor::DownCast( handle ) ) + { + if( const TreeNode* actors = node.GetChild( KEYNAME_ACTORS ) ) { - additionalStyles.push_back(&(*style)); - - OptionalString styleType = IsString( IsChild(*style, "type") ); - if( styleType ) + // in a style the actor subtree properties referenced by actor name + for( TreeConstIter iter = actors->CBegin(); iter != actors->CEnd(); ++iter ) { - CollectAllStyles(styles, *styleType, additionalStyles, typeInfo); - } - else - { - if(!typeInfo) + Dali::Actor foundActor; + + if( (*iter).first ) { - // if its not a style then check for a type but only the first found - typeInfo = TypeRegistry::Get().GetTypeInfo( typeName ); + foundActor = actor.FindChildByName( (*iter).first ); + } + + if( !foundActor ) + { + // debug log cannot find searched for actor +#if defined(DEBUG_ENABLED) + DALI_SCRIPT_VERBOSE("Cannot find actor in style application '%s'\n", (*iter).first); +#endif + } + else + { +#if defined(DEBUG_ENABLED) + DALI_SCRIPT_VERBOSE("Styles applied to actor '%s'\n", (*iter).first); +#endif + ApplyProperties( root, (*iter).second, foundActor, constant ); } } } - else - { - DALI_ASSERT_DEBUG(!typeInfo); - typeInfo = TypeRegistry::Get().GetTypeInfo( typeName ); - } } } -/* - * Recursively collects all styles listed in a json node 'type' field. (Could be a comma separated list). - * Adds the given node to the end of the additional styles list. - * It also returns the first found base typeInfo from the TypeRegistry. This is the concrete object to instance. - * i.e. the type field can name a json style section or a TypeRegistry base type. - */ -void CollectAllStyles( const OptionalChild& optionalStyles, const TreeNode& node, TreeNodeList& additionalStyles, TypeInfo& typeInfo ) + +void Builder::ApplyAllStyleProperties( const TreeNode& root, const TreeNode& node, + Dali::Handle& handle, const Replacement& constant ) { - OptionalString type = IsString( IsChild(node, "type") ); + OptionalChild styles = IsChild(root, KEYNAME_STYLES); + OptionalChild style = IsChild(node, KEYNAME_STYLES); - if(!type) - { - DALI_SCRIPT_WARNING("Cannot create style as type section is missing\n"); - } - else + if( styles && style ) { - additionalStyles.push_back(&node); + TreeNodeList additionalStyles; + + CollectAllStyles( *styles, *style, additionalStyles ); - if( optionalStyles ) +#if defined(DEBUG_ENABLED) + for(TreeNode::ConstIterator iter = (*style).CBegin(); iter != (*style).CEnd(); ++iter) { - CollectAllStyles( *optionalStyles, *type, additionalStyles, typeInfo ); + if( OptionalString styleName = IsString( (*iter).second ) ) + { + DALI_SCRIPT_VERBOSE("Style Applied '%s'\n", (*styleName).c_str()); + } } - else +#endif + + // a style may have other styles, which has other styles etc so we apply in reverse by convention. + for(TreeNodeList::reverse_iterator iter = additionalStyles.rbegin(); iter != additionalStyles.rend(); ++iter) { - typeInfo = TypeRegistry::Get().GetTypeInfo( *type ); - } + ApplyProperties( root, *(*iter), handle, constant ); + ApplyStylesByActor( root, *(*iter), handle, constant ); + } } + + // applying given node last + ApplyProperties( root, node, handle, constant ); + + ApplyStylesByActor( root, node, handle, constant ); + } -} // namespace anon /* * Create a dali type from a node. * If parent given and an actor type was created then add it to the parent and * recursively add nodes children. */ -BaseHandle Builder::Create( const OptionalChild& optionalStyles, const TreeNode& node, const TreeNode& root, Actor parent, - const Replacement& replacements ) +BaseHandle Builder::DoCreate( const TreeNode& root, const TreeNode& node, + Actor parent, const Replacement& replacements ) { BaseHandle baseHandle; - TreeNodeList allStyles; TypeInfo typeInfo; + const TreeNode* templateNode = NULL; - CollectAllStyles( optionalStyles, node, allStyles, typeInfo ); + if( OptionalString typeName = IsString(node, KEYNAME_TYPE) ) + { + typeInfo = TypeRegistry::Get().GetTypeInfo( *typeName ); + + if( !typeInfo ) + { + // a template name is also allowed inplace of the type name + OptionalChild templates = IsChild( root, KEYNAME_TEMPLATES); + + if( templates ) + { + if( OptionalChild isTemplate = IsChild( *templates, *typeName ) ) + { + templateNode = &(*isTemplate); + + if( OptionalString templateTypeName = IsString(*templateNode, KEYNAME_TYPE) ) + { + typeInfo = TypeRegistry::Get().GetTypeInfo( *templateTypeName ); + } + } + } + } + } if(!typeInfo) { @@ -377,7 +460,6 @@ BaseHandle Builder::Create( const OptionalChild& optionalStyles, const TreeNode& { DALI_SCRIPT_VERBOSE("Create:%s\n", typeInfo.GetName().c_str()); - DALI_SCRIPT_VERBOSE(" %d style sections\n", allStyles.size()); #if defined(DEBUG_ENABLED) if(handle) @@ -397,82 +479,42 @@ BaseHandle Builder::Create( const OptionalChild& optionalStyles, const TreeNode& } #endif // DEBUG_ENABLED - for(TreeNodeList::reverse_iterator iter = allStyles.rbegin(); iter != allStyles.rend(); ++iter) + if( templateNode ) { - if( (*iter)->GetType() == TreeNode::ARRAY ) + ApplyProperties( root, *templateNode, handle, replacements ); + + if( OptionalChild actors = IsChild( *templateNode, KEYNAME_ACTORS ) ) { - // if its an array then its a list of styles to set to objects already in the hiearchy by name - if( actor ) - { - const TreeNode& styleList = *(*iter); - for( TreeNode::ConstIterator iterSubStyle = styleList.CBegin(); iterSubStyle != styleList.CEnd(); ++iterSubStyle ) - { - const TreeNode* nameNode = (*iterSubStyle).second.Find("name"); - if( nameNode && nameNode->GetType() == TreeNode::STRING ) - { - Dali::Actor found = actor.FindChildByName( nameNode->GetString() ); - if( found ) - { - SetProperties( (*iterSubStyle).second, found, *this, replacements ); - } - else - { - DALI_SCRIPT_VERBOSE("Cannot find object '%s' in tree to style\n", nameNode->GetString()); - } - } - else - { - DALI_SCRIPT_VERBOSE("Style name is not a string '%s' '%d'\n", - nameNode->GetString(), (*iterSubStyle).second.GetType()); - } - } - } - else + for( TreeConstIter iter = (*actors).CBegin(); iter != (*actors).CEnd(); ++iter ) { - DALI_SCRIPT_VERBOSE("Cannot apply style list to non actor\n"); + DoCreate( root, (*iter).second, actor, replacements ); } } - else - { - DALI_ASSERT_DEBUG( (*iter)->GetType() == TreeNode::OBJECT ); - // else it should be a map of properties - SetProperties( *(*iter), handle, *this, replacements ); - } - - if( actor ) - { - SetupActor( *(*iter), actor); + } - if( control ) - { - SetupControl( *(*iter), control); - } + ApplyProperties( root, node, handle, replacements ); - // add children of all the styles - if( OptionalChild actors = IsChild( *(*iter), "actors" ) ) + if( actor) + { + // add children of all the styles + if( OptionalChild actors = IsChild( node, KEYNAME_ACTORS ) ) + { + for( TreeConstIter iter = (*actors).CBegin(); iter != (*actors).CEnd(); ++iter ) { - for( TreeConstIter iter = (*actors).CBegin(); iter != (*actors).CEnd(); ++iter ) - { - Create( optionalStyles, (*iter).second, root, actor, replacements ); - } + DoCreate( root, (*iter).second, actor, replacements ); } } - } - if( actor ) - { - // add signals first - SetupSignalAction( mSlotDelegate.GetConnectionTracker(), root, node, actor ); - - SetupPropertyNotification( mSlotDelegate.GetConnectionTracker(), root, node, actor ); + // apply style on top as they need the children to exist + ApplyAllStyleProperties( root, node, actor, replacements ); // then add to parent if( parent ) { parent.Add( actor ); } - } + } else { @@ -557,12 +599,14 @@ void Builder::SetupTask( RenderTask& task, const TreeNode& node, const Replaceme } // other setup is via the property system - SetProperties( node, task, *this, constant ); // @ todo, remove 'source-actor', 'camera-actor'? + SetProperties( node, task, constant ); // @ todo, remove 'source-actor', 'camera-actor'? } void Builder::CreateRenderTask( const std::string &name ) { + DALI_ASSERT_ALWAYS(mParser.GetRoot() && "Builder script not loaded"); + Replacement constant(mReplacementMap); const Stage& stage = Stage::GetCurrent(); @@ -608,12 +652,14 @@ void Builder::CreateRenderTask( const std::string &name ) ShaderEffect Builder::GetShaderEffect( const std::string &name) { - Replacement constant; + Replacement constant( mReplacementMap ); return GetShaderEffect( name, constant ); } ShaderEffect Builder::GetShaderEffect( const std::string &name, const Replacement& constant ) { + DALI_ASSERT_ALWAYS(mParser.GetRoot() && "Builder script not loaded"); + ShaderEffect ret; ShaderEffectLut::const_iterator iter( mShaderEffectLut.find( name ) ); @@ -642,12 +688,14 @@ ShaderEffect Builder::GetShaderEffect( const std::string &name, const Replacemen FrameBufferImage Builder::GetFrameBufferImage( const std::string &name ) { - Replacement constant; + Replacement constant( mReplacementMap ); return GetFrameBufferImage(name, constant); } FrameBufferImage Builder::GetFrameBufferImage( const std::string &name, const Replacement& constant ) { + DALI_ASSERT_ALWAYS(mParser.GetRoot() && "Builder script not loaded"); + FrameBufferImage ret; ImageLut::const_iterator iter( mFrameBufferImageLut.find( name ) ); @@ -664,7 +712,7 @@ FrameBufferImage Builder::GetFrameBufferImage( const std::string &name, const Re Dali::Property::Value propertyMap(Property::MAP); if( SetPropertyFromNode( *image, Property::MAP, propertyMap, constant ) ) { - propertyMap.SetValue("type", Property::Value(std::string("FrameBufferImage"))); + propertyMap.SetValue(KEYNAME_TYPE, Property::Value(std::string("FrameBufferImage"))); ret = Dali::Scripting::NewImage( propertyMap ); mFrameBufferImageLut[ name ] = ret; } @@ -708,19 +756,19 @@ void Builder::AddActors( Actor toActor ) void Builder::AddActors( const std::string §ionName, Actor toActor ) { + DALI_ASSERT_ALWAYS(mParser.GetRoot() && "Builder script not loaded"); + PropertyValueMap overrideMap; Replacement replacements(overrideMap, mReplacementMap); - OptionalChild addToStage = IsChild(*mParser.GetRoot(), sectionName); + OptionalChild add = IsChild(*mParser.GetRoot(), sectionName); - if( addToStage ) + if( add ) { - OptionalChild styles = IsChild(*mParser.GetRoot(), "styles"); - - for( TreeNode::ConstIterator iter = (*addToStage).CBegin(); iter != (*addToStage).CEnd(); ++iter ) + for( TreeNode::ConstIterator iter = (*add).CBegin(); iter != (*add).CEnd(); ++iter ) { // empty actor adds directly to the stage - BaseHandle baseHandle = Create( styles, (*iter).second, *mParser.GetRoot(), Actor(), replacements ); + BaseHandle baseHandle = DoCreate( *mParser.GetRoot(), (*iter).second, Actor(), replacements ); Actor actor = Actor::DownCast(baseHandle); if(actor) { @@ -745,6 +793,8 @@ void Builder::AddActors( const std::string §ionName, Actor toActor ) Animation Builder::CreateAnimation( const std::string& animationName, const Replacement& replacement, Dali::Actor sourceActor ) { + DALI_ASSERT_ALWAYS(mParser.GetRoot() && "Builder script not loaded"); + Animation anim; if( OptionalChild animations = IsChild(*mParser.GetRoot(), "animations") ) @@ -796,20 +846,55 @@ void Builder::LoadFromString( std::string const& data, Dali::Toolkit::Builder::U { DALI_ASSERT_ALWAYS( format == Dali::Toolkit::Builder::JSON && "Currently only JSON is supported" ); - if( !mParser.Parse(data) ) + // parser to get constants and includes only + Dali::Toolkit::JsonParser parser = Dali::Toolkit::JsonParser::New(); + + if( !parser.Parse( data ) ) { DALI_LOG_WARNING( "JSON Parse Error:%d:%d:'%s'\n", - mParser.GetErrorLineNumber(), - mParser.GetErrorColumn(), - mParser.GetErrorDescription().c_str() ); + parser.GetErrorLineNumber(), + parser.GetErrorColumn(), + parser.GetErrorDescription().c_str() ); DALI_ASSERT_ALWAYS(!"Cannot parse JSON"); + } + else + { + // load constant map (allows the user to override the constants in the json after loading) + LoadConstants( *parser.GetRoot(), mReplacementMap ); - DALI_ASSERT_ALWAYS(mParser.GetRoot() && "Cannot parse JSON"); + // merge includes + if( OptionalChild includes = IsChild(*parser.GetRoot(), KEYNAME_INCLUDES) ) + { + Replacement replacer( mReplacementMap ); + + for(TreeNode::ConstIterator iter = (*includes).CBegin(); iter != (*includes).CEnd(); ++iter) + { + OptionalString filename = replacer.IsString( (*iter).second ); - // load constant map (allows the user to override the constants in the json after loading) - LoadConstants(); + if( filename ) + { +#if defined(DEBUG_ENABLED) + DALI_SCRIPT_VERBOSE("Loading Include '%s'\n", (*filename).c_str()); +#endif + LoadFromString( GetFileContents(*filename) ); + } + } + } + + if( !mParser.Parse( data ) ) + { + DALI_LOG_WARNING( "JSON Parse Error:%d:%d:'%s'\n", + mParser.GetErrorLineNumber(), + mParser.GetErrorColumn(), + mParser.GetErrorDescription().c_str() ); + + DALI_ASSERT_ALWAYS(!"Cannot parse JSON"); + } + } + + DALI_ASSERT_ALWAYS(mParser.GetRoot() && "Cannot parse JSON"); } @@ -845,11 +930,11 @@ const Property::Value& Builder::GetConstant( const std::string& key ) const } } -void Builder::LoadConstants() +void Builder::LoadConstants( const TreeNode& root, PropertyValueMap& intoMap ) { - Replacement replacer(mReplacementMap); + Replacement replacer(intoMap); - if( OptionalChild constants = IsChild(*mParser.GetRoot(), "constants") ) + if( OptionalChild constants = IsChild(root, "constants") ) { for(TreeNode::ConstIterator iter = (*constants).CBegin(); iter != (*constants).CEnd(); ++iter) @@ -862,7 +947,7 @@ void Builder::LoadConstants() #endif if( SetPropertyFromNode( (*iter).second, property, replacer ) ) { - mReplacementMap[ (*iter).second.GetName() ] = property; + intoMap[ (*iter).second.GetName() ] = property; } else { @@ -874,8 +959,8 @@ void Builder::LoadConstants() } #if defined(DEBUG_ENABLED) - PropertyValueMap::const_iterator iter = mReplacementMap.find( "CONFIG_SCRIPT_LOG_LEVEL" ); - if( iter != mReplacementMap.end() && (*iter).second.GetType() == Property::STRING ) + PropertyValueMap::const_iterator iter = intoMap.find( "CONFIG_SCRIPT_LOG_LEVEL" ); + if( iter != intoMap.end() && (*iter).second.GetType() == Property::STRING ) { std::string logLevel( (*iter).second.Get< std::string >() ); if( logLevel == "NoLogging" ) @@ -901,110 +986,64 @@ void Builder::LoadConstants() void Builder::ApplyStyle( const std::string& styleName, Handle& handle ) { - Replacement replacer; + Replacement replacer( mReplacementMap ); ApplyStyle( styleName, handle, replacer ); } void Builder::ApplyStyle( const std::string& styleName, Handle& handle, const Replacement& replacement ) { - OptionalChild styles = IsChild(*mParser.GetRoot(), "styles"); - - if( styles ) - { - if( OptionalChild style = IsChild(*styles, styleName) ) - { - TreeNodeList allStyles; - TypeInfo typeInfo; + DALI_ASSERT_ALWAYS(mParser.GetRoot() && "Builder script not loaded"); - CollectAllStyles( styles, *style, allStyles, typeInfo ); + OptionalChild styles = IsChild( *mParser.GetRoot(), KEYNAME_STYLES ); + OptionalChild style = IsChild( *styles, styleName ); - for(TreeNodeList::reverse_iterator iter = allStyles.rbegin(); iter != allStyles.rend(); ++iter) - { - if( (*iter)->GetType() == TreeNode::ARRAY ) - { - // if its an array then its a list of styles to set to objects already in the hiearchy by name - if( Dali::Actor actor = Dali::Actor::DownCast( handle ) ) - { - const TreeNode& styleList = *(*iter); - for( TreeNode::ConstIterator iterSubStyle = styleList.CBegin(); iterSubStyle != styleList.CEnd(); ++iterSubStyle ) - { - const TreeNode* nameNode = (*iterSubStyle).second.Find("name"); - if( nameNode && nameNode->GetType() == TreeNode::STRING ) - { - Dali::Actor found = actor.FindChildByName( nameNode->GetString() ); - if( found ) - { - SetProperties( (*iterSubStyle).second, found, *this, replacement ); - } - else - { - DALI_SCRIPT_VERBOSE("Cannot find object '%s' in tree to style\n", nameNode->GetString()); - } - } - else - { - DALI_SCRIPT_VERBOSE("Style name is not a string '%s' '%d'\n", - nameNode->GetString(), (*iterSubStyle).second.GetType()); - } - } - } - else - { - DALI_SCRIPT_VERBOSE("Cannot apply style list to non actor\n"); - } - } - else - { - DALI_ASSERT_DEBUG( (*iter)->GetType() == TreeNode::OBJECT ); - SetProperties( *style, handle, *this, replacement ); - } - } - } - else - { - DALI_SCRIPT_WARNING("Could not find style:%s\n", styleName.c_str()); - } + if( styles && style ) + { + ApplyAllStyleProperties( *mParser.GetRoot(), *style, handle, replacement ); } else { - DALI_SCRIPT_WARNING("No style section available for style:%s\n", styleName.c_str()); + DALI_SCRIPT_WARNING("No styles section to create style '%s'\n", styleName.c_str()); } + } -BaseHandle Builder::CreateFromStyle( const std::string& styleName, const PropertyValueMap& map ) +BaseHandle Builder::Create( const std::string& templateName, const PropertyValueMap& map ) { Replacement replacement( map, mReplacementMap ); - return CreateFromStyle( styleName, replacement ); + return Create( templateName, replacement ); } -BaseHandle Builder::CreateFromStyle( const std::string& styleName, const Replacement& constant ) +BaseHandle Builder::Create( const std::string& templateName, const Replacement& constant ) { + DALI_ASSERT_ALWAYS(mParser.GetRoot() && "Builder script not loaded"); + BaseHandle baseHandle; - OptionalChild styles = IsChild(*mParser.GetRoot(), "styles"); + OptionalChild templates = IsChild(*mParser.GetRoot(), KEYNAME_TEMPLATES); - if( !styles ) + if( !templates ) { - DALI_SCRIPT_WARNING("No style section found to CreateFromStyle\n"); + DALI_SCRIPT_WARNING("No template section found to CreateFromTemplate\n"); } else { - OptionalChild style = IsChild(*styles, styleName); - if(!style) + OptionalChild childTemplate = IsChild(*templates, templateName); + if(!childTemplate) { - DALI_SCRIPT_WARNING("Style '%s' does not exist in style section\n", styleName.c_str()); + DALI_SCRIPT_WARNING("Template '%s' does not exist in template section\n", templateName.c_str()); } else { - OptionalString type = constant.IsString( IsChild(*style, "type") ); + OptionalString type = constant.IsString( IsChild(*childTemplate, KEYNAME_TYPE) ); if(!type) { - DALI_SCRIPT_WARNING("Cannot create style '%s' as style section is missing 'type'\n", styleName.c_str()); + DALI_SCRIPT_WARNING("Cannot create template '%s' as template section is missing 'type'\n", templateName.c_str()); } else { - baseHandle = Create( styles, *style, *mParser.GetRoot(), Actor(), constant ); + baseHandle = DoCreate( *mParser.GetRoot(), *childTemplate, Actor(), constant ); } } } @@ -1013,11 +1052,10 @@ BaseHandle Builder::CreateFromStyle( const std::string& styleName, const Replace } -BaseHandle Builder::CreateFromStyle( const std::string& styleName ) +BaseHandle Builder::Create( const std::string& templateName ) { - PropertyValueMap overrideMap; - Replacement replacement( overrideMap, mReplacementMap ); - return CreateFromStyle( styleName, replacement ); + Replacement replacement( mReplacementMap ); + return Create( templateName, replacement ); } Builder::Builder() diff --git a/dali-toolkit/internal/builder/builder-impl.h b/dali-toolkit/internal/builder/builder-impl.h index 3378eee..87a35b9 100644 --- a/dali-toolkit/internal/builder/builder-impl.h +++ b/dali-toolkit/internal/builder/builder-impl.h @@ -119,16 +119,16 @@ public: Animation CreateAnimation( const std::string& animationName, const PropertyValueMap& map, Dali::Actor sourceActor ); /** - * @copydoc Toolkit::Builder::CreateFromStyle( const std::string& styleName ); + * @copydoc Toolkit::Builder::Create( const std::string& templateName ); */ - BaseHandle CreateFromStyle( const std::string& styleName ); + BaseHandle Create( const std::string& templateName ); /** - * @copydoc Toolkit::Builder::CreateFromStyle( const std::string& styleName, const PropertyValueMap& map ); + * @copydoc Toolkit::Builder::Create( const std::string& templateName, const PropertyValueMap& map ); */ - BaseHandle CreateFromStyle( const std::string& styleName, const PropertyValueMap& map ); + BaseHandle Create( const std::string& templateName, const PropertyValueMap& map ); - /** + /** * @copydoc Toolkit::Builder::GetFont */ Font GetFont(const std::string &name) const; @@ -153,6 +153,8 @@ public: */ void ApplyStyle( const std::string& styleName, Handle& handle ); + void AnimateTo( const std::string& styleName, Handle& handle ); + /** * @copydoc Toolkit::Builder::AddActors */ @@ -222,16 +224,29 @@ private: PropertyValueMap mReplacementMap; - BaseHandle Create( const OptionalChild& optionalStyles, const TreeNode& node, const TreeNode& root, Actor parent, - const Replacement& replacement ); + BaseHandle Create( const std::string& templateName, const Replacement& constant ); + + BaseHandle DoCreate( const TreeNode& root, const TreeNode& node, Actor parent, const Replacement& replacements ); + + void LoadConstants( const TreeNode& root, PropertyValueMap& intoMap ); - void LoadConstants(); + void LoadIncludes( const std::string& data ); void ApplyStyle( const std::string& styleName, Handle& handle, const Replacement& replacement); Animation CreateAnimation( const std::string& animationName, const Replacement& replacement, Dali::Actor sourceActor ); - BaseHandle CreateFromStyle( const std::string& styleName, const Replacement& replacement ); + void ApplyProperties( const TreeNode& root, const TreeNode& node, + Dali::Handle& handle, const Replacement& constant ); + + void ApplyStylesByActor( const TreeNode& root, const TreeNode& node, + Dali::Handle& handle, const Replacement& constant ); + + void ApplyAllStyleProperties( const TreeNode& root, const TreeNode& node, + Dali::Handle& handle, const Replacement& constant ); + + void SetProperties( const TreeNode& node, Handle& handle, const Replacement& constant ); + }; } // namespace Internal diff --git a/dali-toolkit/internal/builder/replacement.cpp b/dali-toolkit/internal/builder/replacement.cpp index 701b7c8..657840f 100644 --- a/dali-toolkit/internal/builder/replacement.cpp +++ b/dali-toolkit/internal/builder/replacement.cpp @@ -343,6 +343,13 @@ OptionalString Replacement::IsString( const TreeNode& node ) const #endif } } + else + { + if( Property::STRING == value.GetType() ) + { + ret = v; // sets the unexpanded. Expansion may occur later in processing with include files + } + } } } else diff --git a/dali-toolkit/public-api/builder/builder.cpp b/dali-toolkit/public-api/builder/builder.cpp index 669dd37..aed1cbe 100644 --- a/dali-toolkit/public-api/builder/builder.cpp +++ b/dali-toolkit/public-api/builder/builder.cpp @@ -95,12 +95,22 @@ Animation Builder::CreateAnimation( const std::string& animationName, const Prop BaseHandle Builder::CreateFromStyle( const std::string& styleName ) { - return GetImpl(*this).CreateFromStyle( styleName ); + return BaseHandle(); } BaseHandle Builder::CreateFromStyle( const std::string& styleName, const PropertyValueMap& map ) { - return GetImpl(*this).CreateFromStyle( styleName, map ); + return BaseHandle(); +} + +BaseHandle Builder::Create( const std::string& templateName ) +{ + return GetImpl(*this).Create( templateName ); +} + +BaseHandle Builder::Create( const std::string& templateName, const PropertyValueMap& map ) +{ + return GetImpl(*this).Create( templateName, map ); } void Builder::ApplyStyle( const std::string& styleName, Handle& handle ) diff --git a/dali-toolkit/public-api/builder/builder.h b/dali-toolkit/public-api/builder/builder.h index 1f2796b..2d67093 100644 --- a/dali-toolkit/public-api/builder/builder.h +++ b/dali-toolkit/public-api/builder/builder.h @@ -79,8 +79,8 @@ typedef std::map PropertyValueMap; * // 1) load all actors in the "stage" section to the root layer * builder.AddActors( Stage::GetCurrent().GetRootLayer() ); * - * // or 2) create an actor from the library "styles" section - * TextActor actor = TextActor::DownCast( builder.CreateFromStyle( "default-text" ) ); + * // or 2) create an actor from the library "templates" section + * TextActor actor = TextActor::DownCast( builder.Create( "default-text" ) ); * * @endcode */ @@ -210,7 +210,7 @@ typedef std::map PropertyValueMap; * * The animation is applied to a specific actor. * e.g. - * Actor myInstance = builder.CreateFromStyle( "template-actor-tree" ) + * Actor myInstance = builder.Create( "template-actor-tree" ) * Animation a = builder.CreateAnimation( "wobble", myInstance ); * * @pre The Builder has been initialized. @@ -229,7 +229,7 @@ typedef std::map PropertyValueMap; * e.g. * PropertyValueMap map; * map["ACTOR"] = actor.GetName(); // replaces '{ACTOR} in the template - * Actor myInstance = builder.CreateFromStyle( "template-actor-tree" ) + * Actor myInstance = builder.Create( "template-actor-tree" ) * Animation a = builder.CreateAnimation( "wobble", myInstance); * * @pre The Builder has been initialized. @@ -244,19 +244,29 @@ typedef std::map PropertyValueMap; Animation CreateAnimation( const std::string& animationName, const PropertyValueMap& map, Dali::Actor sourceActor ); /** + * @deprecated Use Create() + */ + BaseHandle CreateFromStyle( const std::string& styleName ); + + /** + * @deprecated Use Create() + */ + BaseHandle CreateFromStyle( const std::string& styleName, const PropertyValueMap& map ); + + /** * @brief Creates an object (e.g. an actor) from the set of known style templates * * e.g. - * mActor.Add( Actor::DownCast(builder.CreateFromStyle( "default-text")) ); + * mActor.Add( Actor::DownCast(builder.Create( "default-text")) ); * * @pre The Builder has been initialized. * @pre Preconditions have been met for creating dali objects ie Images, Actors etc - * @pre The styleName has been loaded from the styles section of the data representation + * @pre The templateName exists in the templates section of the data representation * and contains 'type' property used to create the object. - * @param styleName The set of styles/properties to set on the handle object. + * @param templateName The template to apply in creation. * @returns The base handle of the created object */ - BaseHandle CreateFromStyle( const std::string& styleName ); + BaseHandle Create( const std::string& templateName ); /** * @brief Creates an object from the style templates with user defined constants @@ -264,18 +274,17 @@ typedef std::map PropertyValueMap; * e.g. * PropertyValueMap map; * map["IMAGE_DIR"] = "/usr/share/images"; // replaces '{IMAGE_DIR} in the template - * mActor.Add( Actor::DownCast(builder.CreateFromStyle( "default-image", map) ) ); + * mActor.Add( Actor::DownCast(builder.Create( "default-image", map) ) ); * * @pre The Builder has been initialized. * @pre Preconditions have been met for creating dali objects ie Images, Actors etc - * @pre The styleName has been loaded from the styles section of the data representation + * @pre The templateName exists in the templates section of the data representation * and contains 'type' property used to create the object. - * @pre The map contains all the constant expansions in the style template - * @param styleName The set of styles/properties to set on the handle object. - * @param map The user defined constants used in style template expansion. + * @param templateName The template used to create the object. + * @param map The user defined constants used in template expansion. * @returns The base handle of the created object */ - BaseHandle CreateFromStyle( const std::string& styleName, const PropertyValueMap& map ); + BaseHandle Create( const std::string& templateName, const PropertyValueMap& map ); /** * Apply a style (a collection of properties) to an actor.