X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=dali-toolkit%2Finternal%2Fbuilder%2Fbuilder-impl.cpp;h=8bcdff1d863f6f273f051f4d9c640573b61c82a6;hb=8d7facdc053ca256566f8e91c180b9027692ef2a;hp=fdf8d21261f0117cf4d274f675ab78058f0583ee;hpb=3dce4163d27820a63fedb91ad4628efc3f864152;p=platform%2Fcore%2Fuifw%2Fdali-toolkit.git diff --git a/dali-toolkit/internal/builder/builder-impl.cpp b/dali-toolkit/internal/builder/builder-impl.cpp index fdf8d21..8bcdff1 100644 --- a/dali-toolkit/internal/builder/builder-impl.cpp +++ b/dali-toolkit/internal/builder/builder-impl.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016 Samsung Electronics Co., Ltd. + * Copyright (c) 2020 Samsung Electronics Co., Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -29,12 +29,14 @@ #include #include #include +#include #include #include #include // INTERNAL INCLUDES #include +#include #include #include @@ -72,13 +74,19 @@ namespace #define TOKEN_STRING(x) #x const std::string KEYNAME_ACTORS = "actors"; +const std::string KEYNAME_ENTRY_TRANSITION = "entryTransition"; +const std::string KEYNAME_EXIT_TRANSITION = "exitTransition"; const std::string KEYNAME_INCLUDES = "includes"; +const std::string KEYNAME_INHERIT = "inherit"; const std::string KEYNAME_MAPPINGS = "mappings"; const std::string KEYNAME_NAME = "name"; const std::string KEYNAME_SIGNALS = "signals"; +const std::string KEYNAME_STATES = "states"; const std::string KEYNAME_STYLES = "styles"; const std::string KEYNAME_TEMPLATES = "templates"; +const std::string KEYNAME_TRANSITIONS = "transitions"; const std::string KEYNAME_TYPE = "type"; +const std::string KEYNAME_VISUALS = "visuals"; const std::string PROPERTIES = "properties"; const std::string ANIMATABLE_PROPERTIES = "animatableProperties"; @@ -124,7 +132,12 @@ void CollectAllStyles( const TreeNode& stylesCollection, const TreeNode& style, { styleList.push_back( &(*node) ); - if( OptionalChild subStyle = IsChild( *node, KEYNAME_STYLES ) ) + OptionalChild subStyle = IsChild( *node, KEYNAME_INHERIT ); + if( ! subStyle ) + { + subStyle = IsChild( *node, KEYNAME_STYLES ); + } + if( subStyle ) { CollectAllStyles( stylesCollection, *subStyle, styleList ); } @@ -144,10 +157,10 @@ Builder::Builder() mParser = Dali::Toolkit::JsonParser::New(); Property::Map defaultDirs; - defaultDirs[ TOKEN_STRING(DALI_IMAGE_DIR) ] = DALI_IMAGE_DIR; - defaultDirs[ TOKEN_STRING(DALI_SOUND_DIR) ] = DALI_SOUND_DIR; - defaultDirs[ TOKEN_STRING(DALI_STYLE_DIR) ] = DALI_STYLE_DIR; - defaultDirs[ TOKEN_STRING(DALI_STYLE_IMAGE_DIR) ] = DALI_STYLE_IMAGE_DIR; + defaultDirs[TOKEN_STRING(DALI_IMAGE_DIR)] = AssetManager::GetDaliImagePath(); + defaultDirs[TOKEN_STRING(DALI_SOUND_DIR)] = AssetManager::GetDaliSoundPath(); + defaultDirs[TOKEN_STRING(DALI_STYLE_DIR)] = AssetManager::GetDaliStylePath(); + defaultDirs[TOKEN_STRING(DALI_STYLE_IMAGE_DIR)] = AssetManager::GetDaliStyleImagePath(); AddConstants( defaultDirs ); } @@ -170,7 +183,8 @@ void Builder::LoadFromString( std::string const& data, Dali::Toolkit::Builder::U { // load constant map (allows the user to override the constants in the json after loading) LoadConstants( *parser.GetRoot(), mReplacementMap ); - + // load configuration map + LoadConfiguration( *parser.GetRoot(), mConfigurationMap ); // merge includes if( OptionalChild includes = IsChild(*parser.GetRoot(), KEYNAME_INCLUDES) ) { @@ -190,7 +204,12 @@ void Builder::LoadFromString( std::string const& data, Dali::Toolkit::Builder::U } } - if( !mParser.Parse( data ) ) + if( mParser.Parse( data ) ) + { + // Drop the styles and get them to be rebuilt against the new parse tree as required. + mStyles.Clear(); + } + else { DALI_LOG_WARNING( "JSON Parse Error:%d:%d:'%s'\n", mParser.GetErrorLineNumber(), @@ -201,8 +220,8 @@ void Builder::LoadFromString( std::string const& data, Dali::Toolkit::Builder::U } } - DUMP_PARSE_TREE(parser); // This macro only writes out if DEBUG is enabled and the "DUMP_TREE" constant is defined in the stylesheet. - DUMP_TEST_MAPPINGS(parser); + DUMP_PARSE_TREE(mParser); // This macro only writes out if DEBUG is enabled and the "DUMP_TREE" constant is defined in the stylesheet. + DUMP_TEST_MAPPINGS(mParser); DALI_ASSERT_ALWAYS(mParser.GetRoot() && "Cannot parse JSON"); } @@ -217,6 +236,11 @@ void Builder::AddConstant( const std::string& key, const Property::Value& value mReplacementMap[key] = value; } +const Property::Map& Builder::GetConfigurations() const +{ + return mConfigurationMap; +} + const Property::Map& Builder::GetConstants() const { return mReplacementMap; @@ -318,6 +342,34 @@ bool Builder::ApplyStyle( const std::string& styleName, Handle& handle ) return ApplyStyle( styleName, handle, replacer ); } +bool Builder::LookupStyleName( const std::string& styleName ) +{ + DALI_ASSERT_ALWAYS(mParser.GetRoot() && "Builder script not loaded"); + + OptionalChild styles = IsChild( *mParser.GetRoot(), KEYNAME_STYLES ); + OptionalChild style = IsChildIgnoreCase( *styles, styleName ); + + if( styles && style ) + { + return true; + } + return false; +} + +const StylePtr Builder::GetStyle( const std::string& styleName ) +{ + const StylePtr* style = mStyles.FindConst( styleName ); + + if( style==NULL ) + { + return StylePtr(NULL); + } + else + { + return *style; + } +} + void Builder::AddActors( Actor toActor ) { // 'stage' is the default/by convention section to add from @@ -408,48 +460,6 @@ void Builder::CreateRenderTask( const std::string &name ) } } -FrameBufferImage Builder::GetFrameBufferImage( const std::string &name ) -{ - 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 ) ); - if( iter != mFrameBufferImageLut.end() ) - { - ret = iter->second; - } - else - { - if( OptionalChild images = IsChild( *mParser.GetRoot(), "frameBufferImages") ) - { - if( OptionalChild image = IsChild( *images, name ) ) - { - Dali::Property::Value property(Property::MAP); - if( DeterminePropertyFromNode( *image, Property::MAP, property, constant ) ) - { - Property::Map* map = property.GetMap(); - - if( map ) - { - (*map)[ KEYNAME_TYPE ] = Property::Value(std::string("FrameBufferImage") ); - ret = FrameBufferImage::DownCast( Dali::Scripting::NewImage( property ) ); - mFrameBufferImageLut[ name ] = ret; - } - } - } - } - } - - return ret; -} - Path Builder::GetPath( const std::string& name ) { DALI_ASSERT_ALWAYS(mParser.GetRoot() && "Builder script not loaded"); @@ -734,6 +744,80 @@ Builder::~Builder() { } +void Builder::LoadConfiguration( const TreeNode& root, Property::Map& intoMap ) +{ + Replacement replacer(intoMap); + + if( OptionalChild constants = IsChild(root, "config") ) + { + for(TreeNode::ConstIterator iter = (*constants).CBegin(); + iter != (*constants).CEnd(); ++iter) + { + Dali::Property::Value property; + if( (*iter).second.GetName() ) + { + DeterminePropertyFromNode( (*iter).second, property, replacer ); + + // If config is string, find constant and replace it to original value. + if( (*iter).second.GetType() == TreeNode::STRING ) + { + std::string stringConfigValue; + if( property.Get( stringConfigValue ) ) + { + std::size_t pos = 0; + + while( pos < stringConfigValue.size() ) + { + // If we can't find "{","}" pair in stringConfigValue, will out loop. + std::size_t leftPos = stringConfigValue.find( "{", pos ); + if( leftPos != std::string::npos ) + { + std::size_t rightPos = stringConfigValue.find( "}", pos+1 ); + + if( rightPos != std::string::npos ) + { + // If we find "{","}" pair but can't find matched constant + // try to find other "{","}" pair after current left position. + pos = leftPos+1; + + for( uint32_t i = 0; i < mReplacementMap.Count() ; i++ ) + { + Property::Key constant = mReplacementMap.GetKeyAt(i); + + // Compare string which is between "{" and "}" with constant string + // If they are same, change string in stringConfigValue to mapped constant value. + if ( 0 == stringConfigValue.compare( leftPos+1, rightPos-leftPos-1, constant.stringKey ) ) + { + std::string replaceString; + mReplacementMap.GetValue(i).Get( replaceString ); + + stringConfigValue.replace( leftPos, rightPos-leftPos+1, replaceString ); + pos = leftPos + replaceString.size(); + break; + } + } + } + else + { + // If we cannot find constant in const value, will out loop. + pos = stringConfigValue.size(); + } + } + else + { + // If we cannot find constant in const value, will out loop. + pos = stringConfigValue.size(); + } + } + property = Property::Value( stringConfigValue ); + } + } + intoMap[ (*iter).second.GetName() ] = property; + } + } + } +} + void Builder::LoadConstants( const TreeNode& root, Property::Map& intoMap ) { Replacement replacer(intoMap); @@ -902,13 +986,13 @@ BaseHandle Builder::DoCreate( const TreeNode& root, const TreeNode& node, if(actor) { - DALI_SCRIPT_VERBOSE(" Is Actor id=%d\n", actor.GetId()); + DALI_SCRIPT_VERBOSE(" Is Actor id=%d\n", actor.GetProperty< int >( Actor::Property::ID )); } Toolkit::Control control = Toolkit::Control::DownCast(handle); if(control) { - DALI_SCRIPT_VERBOSE(" Is Control id=%d\n", actor.GetId()); + DALI_SCRIPT_VERBOSE(" Is Control id=%d\n", actor.GetProperty< int >( Actor::Property::ID )); } #endif // DEBUG_ENABLED @@ -990,19 +1074,6 @@ void Builder::SetupTask( RenderTask& task, const TreeNode& node, const Replaceme } } - if( OptionalString s = constant.IsString( IsChild(node, "targetFrameBuffer") ) ) - { - FrameBufferImage fb = GetFrameBufferImage( *s, constant ); - if(fb) - { - task.SetTargetFrameBuffer( fb ); - } - else - { - DALI_SCRIPT_WARNING("Cannot find target frame buffer '%s'\n", (*s).c_str() ); - } - } - if( OptionalString s = constant.IsString( IsChild(node, "screenToFrameBufferFunction") ) ) { if("DEFAULT_SCREEN_TO_FRAMEBUFFER_FUNCTION" == *s) @@ -1023,7 +1094,6 @@ void Builder::SetupTask( RenderTask& task, const TreeNode& node, const Replaceme SetProperties( node, task, constant ); } - bool Builder::ApplyStyle( const std::string& styleName, Handle& handle, const Replacement& replacement ) { DALI_ASSERT_ALWAYS(mParser.GetRoot() && "Builder script not loaded"); @@ -1047,59 +1117,261 @@ bool Builder::ApplyStyle( const std::string& styleName, Handle& handle, const Re void Builder::ApplyAllStyleProperties( const TreeNode& root, const TreeNode& node, Dali::Handle& handle, const Replacement& constant ) { - OptionalChild styles = IsChild(root, KEYNAME_STYLES); - OptionalChild style = IsChild(node, KEYNAME_STYLES); + const char* styleName = node.GetName(); - if( styles && style ) + StylePtr style = Style::New(); + + StylePtr* matchedStyle = NULL; + if( styleName ) { - TreeNodeList additionalStyles; + matchedStyle = mStyles.Find( styleName ); + if( ! matchedStyle ) + { + OptionalChild styleNodes = IsChild(root, KEYNAME_STYLES); + OptionalChild inheritFromNode = IsChild(node, KEYNAME_INHERIT); + if( !inheritFromNode ) + { + inheritFromNode = IsChild( node, KEYNAME_STYLES ); + } - CollectAllStyles( *styles, *style, additionalStyles ); + if( styleNodes ) + { + if( inheritFromNode ) + { + TreeNodeList additionalStyleNodes; + + CollectAllStyles( *styleNodes, *inheritFromNode, additionalStyleNodes ); #if defined(DEBUG_ENABLED) - for(TreeNode::ConstIterator iter = (*style).CBegin(); iter != (*style).CEnd(); ++iter) + for(TreeNode::ConstIterator iter = (*inheritFromNode).CBegin(); iter != (*inheritFromNode).CEnd(); ++iter) + { + if( OptionalString styleName = IsString( (*iter).second ) ) + { + DALI_SCRIPT_VERBOSE("Style Applied '%s'\n", (*styleName).c_str()); + } + } +#endif + + // a style may have other styles, which has other styles etc so we apply in reverse by convention. + for(TreeNodeList::reverse_iterator iter = additionalStyleNodes.rbegin(); iter != additionalStyleNodes.rend(); ++iter) + { + RecordStyle( style, *(*iter), handle, constant ); + ApplySignals( root, *(*iter), handle ); + ApplyStylesByActor( root, *(*iter), handle, constant ); + } + } + + RecordStyle( style, node, handle, constant ); + mStyles.Add( styleName, style ); // shallow copy + matchedStyle = &style; + } + } + } + + if( matchedStyle ) + { + StylePtr style( *matchedStyle ); + Dictionary instancedProperties; + style->ApplyVisualsAndPropertiesRecursively( handle, instancedProperties ); + } + else // If there were no styles, instead set properties + { + SetProperties( node, handle, constant ); + } + ApplySignals( root, node, handle ); + ApplyStylesByActor( root, node, handle, constant ); +} + +void Builder::RecordStyle( StylePtr style, + const TreeNode& node, + Dali::Handle& handle, + const Replacement& replacements ) +{ + // With repeated calls, accumulate inherited states, visuals and properties + // but override any with same name + + for( TreeNode::ConstIterator iter = node.CBegin(); iter != node.CEnd(); ++iter ) + { + const TreeNode::KeyNodePair& keyValue = *iter; + std::string key( keyValue.first ); + if( key == KEYNAME_STATES ) { - if( OptionalString styleName = IsString( (*iter).second ) ) + const TreeNode& states = keyValue.second; + if( states.GetType() != TreeNode::OBJECT ) { - DALI_SCRIPT_VERBOSE("Style Applied '%s'\n", (*styleName).c_str()); + DALI_LOG_WARNING( "RecordStyle() Node \"%s\" is not a JSON object\n", key.c_str() ); + continue; + } + + for( TreeNode::ConstIterator iter = states.CBegin(); iter != states.CEnd(); ++iter ) + { + const TreeNode& stateNode = (*iter).second; + const char* stateName = stateNode.GetName(); + if( stateNode.GetType() != TreeNode::OBJECT ) + { + DALI_LOG_WARNING( "RecordStyle() Node \"%s\" is not a JSON object\n", stateName ); + continue; + } + + StylePtr* stylePtr = style->subStates.Find( stateName ); + if( stylePtr ) + { + StylePtr style(*stylePtr); + RecordStyle( style, stateNode, handle, replacements ); + } + else + { + StylePtr subState = Style::New(); + RecordStyle( subState, stateNode, handle, replacements ); + style->subStates.Add( stateName, subState ); + } } } -#endif + else if( key == KEYNAME_VISUALS ) + { + for( TreeNode::ConstIterator iter = keyValue.second.CBegin(); iter != keyValue.second.CEnd(); ++iter ) + { + // Each key in this table should be a property name matching a visual. + const TreeNode::KeyNodePair& visual = *iter; + Dali::Property::Value property(Property::MAP); + if( DeterminePropertyFromNode( visual.second, Property::MAP, property, replacements ) ) + { + Property::Map* mapPtr = style->visuals.Find( visual.first ); + if( mapPtr ) + { + // Override existing visuals + mapPtr->Clear(); + mapPtr->Merge( *property.GetMap() ); + } + else + { + Property::Map* map = property.GetMap(); + if( map ) + { + style->visuals.Add( visual.first, *map ); + } + } + } + } + } + else if( key == KEYNAME_ENTRY_TRANSITION ) + { + RecordTransitionData( keyValue, style->entryTransition, replacements ); + } + else if( key == KEYNAME_EXIT_TRANSITION ) + { + RecordTransitionData( keyValue, style->exitTransition, replacements ); + } + else if( key == KEYNAME_TRANSITIONS ) + { + RecordTransitions( keyValue, style->transitions, replacements ); + } + else if( key == KEYNAME_TYPE || + key == KEYNAME_ACTORS || + key == KEYNAME_SIGNALS || + key == KEYNAME_STYLES || + key == KEYNAME_MAPPINGS || + key == KEYNAME_INHERIT ) + { + continue; + } + else // It's a property + { + Property::Index index; + Property::Value value; + if( MapToTargetProperty( handle, key, keyValue.second, replacements, index, value ) ) + { + Property::Value* existingValuePtr = style->properties.Find( index ); + if( existingValuePtr != NULL ) + { + *existingValuePtr = value; // Overwrite existing property. + } + else + { + style->properties.Add( index, value ); + } + } + } + } +} - // 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) +void Builder::RecordTransitions( + const TreeNode::KeyNodePair& keyValue, + Property::Array& value, + const Replacement& replacements ) +{ + //@todo add new transitions to style.transitions + // override existing transitions. A transition matches on target & property name + const TreeNode& node = keyValue.second; + if( node.GetType() == TreeNode::ARRAY ) + { + Dali::Property::Value property(Property::ARRAY); + if( DeterminePropertyFromNode( node, Property::ARRAY, property, replacements ) ) { - ApplyProperties( root, *(*iter), handle, constant ); - ApplyStylesByActor( root, *(*iter), handle, constant ); + value = *property.GetArray(); } } + else if( node.GetType() == TreeNode::OBJECT ) + { + Dali::Property::Value property(Property::MAP); + if( DeterminePropertyFromNode( node, Property::MAP, property, replacements ) ) + { + Property::Array propertyArray; + propertyArray.Add( property ); + value = propertyArray; + } + } + else + { + DALI_LOG_WARNING( "RecordStyle() Node \"%s\" is not a JSON array or object\n", keyValue.first ); + } +} - // applying given node last - ApplyProperties( root, node, handle, constant ); - ApplyStylesByActor( root, node, handle, constant ); +void Builder::RecordTransitionData( + const TreeNode::KeyNodePair& keyValue, + Toolkit::TransitionData& transitionData, + const Replacement& replacements ) +{ + const TreeNode& node = keyValue.second; + if( node.GetType() == TreeNode::ARRAY ) + { + Dali::Property::Value property(Property::ARRAY); + if( DeterminePropertyFromNode( keyValue.second, Property::ARRAY, property, replacements ) ) + { + transitionData = Toolkit::TransitionData::New( *property.GetArray() ); + } + } + else if( node.GetType() == TreeNode::OBJECT ) + { + Dali::Property::Value property(Property::MAP); + if( DeterminePropertyFromNode( keyValue.second, Property::MAP, property, replacements ) ) + { + transitionData = Toolkit::TransitionData::New( *property.GetMap() ); + } + } } + // Set properties from node on handle. void Builder::ApplyProperties( const TreeNode& root, const TreeNode& node, Dali::Handle& handle, const Replacement& constant ) { - if( Actor actor = Actor::DownCast(handle) ) - { - SetProperties( node, actor, constant ); + SetProperties( node, handle, constant ); + ApplySignals( root, node, handle ); +} - if( actor ) - { - // add signals - SetupSignalAction( mSlotDelegate.GetConnectionTracker(), root, node, actor, this ); - SetupPropertyNotification( mSlotDelegate.GetConnectionTracker(), root, node, actor, this ); - } - } - else +void Builder::ApplySignals(const TreeNode& root, const TreeNode& node, Dali::Handle& handle ) +{ + Actor actor = Actor::DownCast(handle); + if( actor ) { - SetProperties( node, handle, constant ); + // add signals + SetupSignalAction( mSlotDelegate.GetConnectionTracker(), root, node, actor, this ); + SetupPropertyNotification( mSlotDelegate.GetConnectionTracker(), root, node, actor, this ); } } + // 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, @@ -1121,16 +1393,11 @@ void Builder::ApplyStylesByActor( const TreeNode& root, const TreeNode& node, 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 ); } } @@ -1152,51 +1419,30 @@ void Builder::SetProperties( const TreeNode& node, Handle& handle, const Replace std::string key( keyChild.first ); // ignore special fields; - if( key == KEYNAME_TYPE || key == KEYNAME_ACTORS || key == KEYNAME_SIGNALS || key == KEYNAME_STYLES || key == KEYNAME_MAPPINGS ) + if( key == KEYNAME_TYPE || + key == KEYNAME_ACTORS || + key == KEYNAME_SIGNALS || + key == KEYNAME_STYLES || + key == KEYNAME_MAPPINGS || + key == KEYNAME_INHERIT || + key == KEYNAME_STATES || + key == KEYNAME_VISUALS || + key == KEYNAME_ENTRY_TRANSITION || + key == KEYNAME_EXIT_TRANSITION || + key == KEYNAME_TRANSITIONS ) { continue; } - Handle propertyObject( handle ); - - Dali::Property::Index index = propertyObject.GetPropertyIndex( key ); + Property::Index index; + Property::Value value; - if( Property::INVALID_INDEX != index ) + bool mapped = MapToTargetProperty( handle, key, keyChild.second, constant, index, value ); + if( mapped ) { - Property::Type type = propertyObject.GetPropertyType(index); - Property::Value value; - bool mapped = false; + DALI_SCRIPT_VERBOSE("SetProperty '%s' Index=:%d Value Type=%d Value '%s'\n", key.c_str(), index, value.GetType(), PropertyValueToString(value).c_str() ); - // if node.value is a mapping, get the property value from the "mappings" table - if( keyChild.second.GetType() == TreeNode::STRING ) - { - std::string mappingKey; - if( GetMappingKey(keyChild.second.GetString(), mappingKey) ) - { - OptionalChild mappingRoot = IsChild( mParser.GetRoot(), KEYNAME_MAPPINGS ); - mapped = GetPropertyMap( *mappingRoot, mappingKey.c_str(), type, value ); - } - } - if( ! mapped ) - { - mapped = DeterminePropertyFromNode( keyChild.second, type, value, constant ); - if( ! mapped ) - { - // Just determine the property from the node and if it's valid, let the property object handle it - DeterminePropertyFromNode( keyChild.second, value, constant ); - mapped = ( value.GetType() != Property::NONE ); - } - } - if( mapped ) - { - DALI_SCRIPT_VERBOSE("SetProperty '%s' Index=:%d Value Type=%d Value '%s'\n", key.c_str(), index, value.GetType(), PropertyValueToString(value).c_str() ); - - propertyObject.SetProperty( index, value ); - } - } - else - { - DALI_LOG_ERROR("Key '%s' not found.\n", key.c_str()); + handle.SetProperty( index, value ); } // Add custom properties @@ -1211,6 +1457,49 @@ void Builder::SetProperties( const TreeNode& node, Handle& handle, const Replace } } +bool Builder::MapToTargetProperty( + Handle& propertyObject, + const std::string& key, + const TreeNode& node, + const Replacement& constant, + Property::Index& index, + Property::Value& value ) +{ + bool mapped = false; + + index = propertyObject.GetPropertyIndex( key ); + if( Property::INVALID_INDEX != index ) + { + Property::Type type = propertyObject.GetPropertyType(index); + + // if node.value is a mapping, get the property value from the "mappings" table + if( node.GetType() == TreeNode::STRING ) + { + std::string mappingKey; + if( GetMappingKey( node.GetString(), mappingKey) ) + { + OptionalChild mappingRoot = IsChild( mParser.GetRoot(), KEYNAME_MAPPINGS ); + mapped = GetPropertyMap( *mappingRoot, mappingKey.c_str(), type, value ); + } + } + if( ! mapped ) + { + mapped = DeterminePropertyFromNode( node, type, value, constant ); + if( ! mapped ) + { + // Just determine the property from the node and if it's valid, let the property object handle it + DeterminePropertyFromNode( node, value, constant ); + mapped = ( value.GetType() != Property::NONE ); + } + } + } + else + { + DALI_LOG_ERROR("Key '%s' not found.\n", key.c_str()); + } + return mapped; +} + bool Builder::GetPropertyMap( const TreeNode& mappingRoot, const char* theKey, Property::Type propertyType, Property::Value& value ) { KeyStack keyStack; @@ -1339,7 +1628,6 @@ void Builder::SetCustomProperties( const TreeNode& node, Handle& handle, const R { const TreeNode::KeyNodePair& keyChild = *iter; std::string key( keyChild.first ); - Property::Value value; DeterminePropertyFromNode( keyChild.second, value, constant ); @@ -1349,6 +1637,7 @@ void Builder::SetCustomProperties( const TreeNode& node, Handle& handle, const R } } + } // namespace Internal } // namespace Toolkit