+Dali::Animation Control::Impl::CreateTransition( const Toolkit::TransitionData& transitionData )
+{
+ Dali::Animation transition;
+
+ if( transitionData.Count() > 0 )
+ {
+ AddTransitions( transition, transitionData, true );
+ }
+ return transition;
+}
+
+
+
+void Control::Impl::DoAction( Dali::Property::Index visualIndex, Dali::Property::Index actionId, const Dali::Property::Value attributes )
+{
+ RegisteredVisualContainer::Iterator iter;
+ if ( FindVisual( visualIndex, mVisuals, iter ) )
+ {
+ Toolkit::GetImplementation((*iter)->visual).DoAction( actionId, attributes );
+ }
+}
+
+void Control::Impl::AppendAccessibilityAttribute( const std::string& key,
+ const std::string value )
+{
+ Property::Value* val = mAccessibilityAttributes.Find( key );
+ if( val )
+ {
+ mAccessibilityAttributes[key] = Property::Value( value );
+ }
+ else
+ {
+ mAccessibilityAttributes.Insert( key, value );
+ }
+}
+
+void Control::Impl::SetProperty( BaseObject* object, Property::Index index, const Property::Value& value )
+{
+ Toolkit::Control control = Toolkit::Control::DownCast( BaseHandle( object ) );
+
+ if ( control )
+ {
+ Control& controlImpl( GetImplementation( control ) );
+
+ switch ( index )
+ {
+ case Toolkit::Control::Property::STYLE_NAME:
+ {
+ controlImpl.SetStyleName( value.Get< std::string >() );
+ break;
+ }
+
+ case Toolkit::DevelControl::Property::STATE:
+ {
+ bool withTransitions=true;
+ const Property::Value* valuePtr=&value;
+ const Property::Map* map = value.GetMap();
+ if(map)
+ {
+ Property::Value* value2 = map->Find("withTransitions");
+ if( value2 )
+ {
+ withTransitions = value2->Get<bool>();
+ }
+
+ valuePtr = map->Find("state");
+ }
+
+ if( valuePtr )
+ {
+ Toolkit::DevelControl::State state( controlImpl.mImpl->mState );
+ if( Scripting::GetEnumerationProperty< Toolkit::DevelControl::State >( *valuePtr, ControlStateTable, ControlStateTableCount, state ) )
+ {
+ controlImpl.mImpl->SetState( state, withTransitions );
+ }
+ }
+ }
+ break;
+
+ case Toolkit::DevelControl::Property::SUB_STATE:
+ {
+ std::string subState;
+ if( value.Get( subState ) )
+ {
+ controlImpl.mImpl->SetSubState( subState );
+ }
+ }
+ break;
+
+ case Toolkit::DevelControl::Property::LEFT_FOCUSABLE_ACTOR_ID:
+ {
+ int focusId;
+ if( value.Get( focusId ) )
+ {
+ controlImpl.mImpl->mLeftFocusableActorId = focusId;
+ }
+ }
+ break;
+
+ case Toolkit::DevelControl::Property::RIGHT_FOCUSABLE_ACTOR_ID:
+ {
+ int focusId;
+ if( value.Get( focusId ) )
+ {
+ controlImpl.mImpl->mRightFocusableActorId = focusId;
+ }
+ }
+ break;
+
+ case Toolkit::DevelControl::Property::ACCESSIBILITY_NAME:
+ {
+ std::string name;
+ if( value.Get( name ) )
+ {
+ controlImpl.mImpl->mAccessibilityName = name;
+ controlImpl.mImpl->mAccessibilityNameSet = true;
+ }
+ else
+ {
+ controlImpl.mImpl->mAccessibilityNameSet = false;
+ }
+ }
+ break;
+
+ case Toolkit::DevelControl::Property::ACCESSIBILITY_DESCRIPTION:
+ {
+ std::string txt;
+ if( value.Get( txt ) )
+ {
+ controlImpl.mImpl->mAccessibilityDescription = txt;
+ controlImpl.mImpl->mAccessibilityDescriptionSet = true;
+ }
+ else
+ {
+ controlImpl.mImpl->mAccessibilityDescriptionSet = false;
+ }
+ }
+ break;
+
+ case Toolkit::DevelControl::Property::ACCESSIBILITY_TRANSLATION_DOMAIN:
+ {
+ std::string txt;
+ if( value.Get( txt ) )
+ {
+ controlImpl.mImpl->mAccessibilityTranslationDomain = txt;
+ controlImpl.mImpl->mAccessibilityTranslationDomainSet = true;
+ }
+ else
+ {
+ controlImpl.mImpl->mAccessibilityTranslationDomainSet = false;
+ }
+ }
+ break;
+
+ case Toolkit::DevelControl::Property::ACCESSIBILITY_HIGHLIGHTABLE:
+ {
+ bool highlightable;
+ if( value.Get( highlightable ) )
+ {
+ controlImpl.mImpl->mAccessibilityHighlightable = highlightable;
+ controlImpl.mImpl->mAccessibilityHighlightableSet = true;
+ }
+ else
+ {
+ controlImpl.mImpl->mAccessibilityHighlightableSet = false;
+ }
+ }
+ break;
+
+ case Toolkit::DevelControl::Property::ACCESSIBILITY_ROLE:
+ {
+ Dali::Accessibility::Role val;
+ if( value.Get( val ) )
+ {
+ controlImpl.mImpl->mAccessibilityRole = val;
+ }
+ }
+ break;
+
+ case Toolkit::DevelControl::Property::UP_FOCUSABLE_ACTOR_ID:
+ {
+ int focusId;
+ if( value.Get( focusId ) )
+ {
+ controlImpl.mImpl->mUpFocusableActorId = focusId;
+ }
+ }
+ break;
+
+ case Toolkit::DevelControl::Property::DOWN_FOCUSABLE_ACTOR_ID:
+ {
+ int focusId;
+ if( value.Get( focusId ) )
+ {
+ controlImpl.mImpl->mDownFocusableActorId = focusId;
+ }
+ }
+ break;
+
+ case Toolkit::Control::Property::KEY_INPUT_FOCUS:
+ {
+ if ( value.Get< bool >() )
+ {
+ controlImpl.SetKeyInputFocus();
+ }
+ else
+ {
+ controlImpl.ClearKeyInputFocus();
+ }
+ break;
+ }
+
+ case Toolkit::Control::Property::BACKGROUND:
+ {
+ std::string url;
+ Vector4 color;
+ const Property::Map* map = value.GetMap();
+ if( map && !map->Empty() )
+ {
+ controlImpl.SetBackground( *map );
+ }
+ else if( value.Get( url ) )
+ {
+ // don't know the size to load
+ Toolkit::Visual::Base visual = Toolkit::VisualFactory::Get().CreateVisual( url, ImageDimensions() );
+ if( visual )
+ {
+ controlImpl.mImpl->RegisterVisual( Toolkit::Control::Property::BACKGROUND, visual, DepthIndex::BACKGROUND );
+ }
+ }
+ else if( value.Get( color ) )
+ {
+ controlImpl.SetBackgroundColor(color);
+ }
+ else
+ {
+ // The background is an empty property map, so we should clear the background
+ controlImpl.ClearBackground();
+ }
+ break;
+ }
+
+ case Toolkit::Control::Property::MARGIN:
+ {
+ Extents margin;
+ if( value.Get( margin ) )
+ {
+ controlImpl.mImpl->SetMargin( margin );
+ }
+ break;
+ }
+
+ case Toolkit::Control::Property::PADDING:
+ {
+ Extents padding;
+ if( value.Get( padding ) )
+ {
+ controlImpl.mImpl->SetPadding( padding );
+ }
+ break;
+ }
+
+ case Toolkit::DevelControl::Property::TOOLTIP:
+ {
+ TooltipPtr& tooltipPtr = controlImpl.mImpl->mTooltip;
+ if( ! tooltipPtr )
+ {
+ tooltipPtr = Tooltip::New( control );
+ }
+ tooltipPtr->SetProperties( value );
+ break;
+ }
+
+ case Toolkit::DevelControl::Property::SHADOW:
+ {
+ const Property::Map* map = value.GetMap();
+ if( map && !map->Empty() )
+ {
+ controlImpl.mImpl->SetShadow( *map );
+ }
+ else
+ {
+ // The shadow is an empty property map, so we should clear the shadow
+ controlImpl.mImpl->ClearShadow();
+ }
+ break;
+ }
+
+ case Toolkit::DevelControl::Property::ACCESSIBILITY_ATTRIBUTES:
+ {
+ value.Get( controlImpl.mImpl->mAccessibilityAttributes );
+ break;
+ }
+
+ case Toolkit::DevelControl::Property::ACCESSIBILITY_ANIMATED:
+ {
+ value.Get( controlImpl.mImpl->mAccessibilityAnimated );
+ break;
+ }
+ }
+ }
+}
+
+Property::Value Control::Impl::GetProperty( BaseObject* object, Property::Index index )
+{
+ Property::Value value;
+
+ Toolkit::Control control = Toolkit::Control::DownCast( BaseHandle( object ) );
+
+ if ( control )
+ {
+ Control& controlImpl( GetImplementation( control ) );
+
+ switch ( index )
+ {
+ case Toolkit::Control::Property::STYLE_NAME:
+ {
+ value = controlImpl.GetStyleName();
+ break;
+ }
+
+ case Toolkit::DevelControl::Property::STATE:
+ {
+ value = controlImpl.mImpl->mState;
+ break;
+ }
+
+ case Toolkit::DevelControl::Property::SUB_STATE:
+ {
+ value = controlImpl.mImpl->mSubStateName;
+ break;
+ }
+
+ case Toolkit::DevelControl::Property::LEFT_FOCUSABLE_ACTOR_ID:
+ {
+ value = controlImpl.mImpl->mLeftFocusableActorId;
+ break;
+ }
+
+ case Toolkit::DevelControl::Property::RIGHT_FOCUSABLE_ACTOR_ID:
+ {
+ value = controlImpl.mImpl->mRightFocusableActorId;
+ break;
+ }
+
+ case Toolkit::DevelControl::Property::ACCESSIBILITY_NAME:
+ {
+ if (controlImpl.mImpl->mAccessibilityNameSet)
+ {
+ value = controlImpl.mImpl->mAccessibilityName;
+ }
+ break;
+ }
+
+ case Toolkit::DevelControl::Property::ACCESSIBILITY_DESCRIPTION:
+ {
+ if (controlImpl.mImpl->mAccessibilityDescriptionSet)
+ {
+ value = controlImpl.mImpl->mAccessibilityDescription;
+ }
+ break;
+ }
+
+ case Toolkit::DevelControl::Property::ACCESSIBILITY_TRANSLATION_DOMAIN:
+ {
+ if (controlImpl.mImpl->mAccessibilityTranslationDomainSet)
+ {
+ value = controlImpl.mImpl->mAccessibilityTranslationDomain;
+ }
+ break;
+ }
+
+ case Toolkit::DevelControl::Property::ACCESSIBILITY_HIGHLIGHTABLE:
+ {
+ if (controlImpl.mImpl->mAccessibilityHighlightableSet)
+ {
+ value = controlImpl.mImpl->mAccessibilityHighlightable;
+ }
+ break;
+ }
+
+ case Toolkit::DevelControl::Property::ACCESSIBILITY_ROLE:
+ {
+ value = Property::Value(controlImpl.mImpl->mAccessibilityRole);
+ break;
+ }
+
+ case Toolkit::DevelControl::Property::UP_FOCUSABLE_ACTOR_ID:
+ {
+ value = controlImpl.mImpl->mUpFocusableActorId;
+ break;
+ }
+
+ case Toolkit::DevelControl::Property::DOWN_FOCUSABLE_ACTOR_ID:
+ {
+ value = controlImpl.mImpl->mDownFocusableActorId;
+ break;
+ }
+
+ case Toolkit::Control::Property::KEY_INPUT_FOCUS:
+ {
+ value = controlImpl.HasKeyInputFocus();
+ break;
+ }
+
+ case Toolkit::Control::Property::BACKGROUND:
+ {
+ Property::Map map;
+ Toolkit::Visual::Base visual = controlImpl.mImpl->GetVisual( Toolkit::Control::Property::BACKGROUND );
+ if( visual )
+ {
+ visual.CreatePropertyMap( map );
+ }
+
+ value = map;
+ break;
+ }
+
+ case Toolkit::Control::Property::MARGIN:
+ {
+ value = controlImpl.mImpl->GetMargin();
+ break;
+ }
+
+ case Toolkit::Control::Property::PADDING:
+ {
+ value = controlImpl.mImpl->GetPadding();
+ break;
+ }
+
+ case Toolkit::DevelControl::Property::TOOLTIP:
+ {
+ Property::Map map;
+ if( controlImpl.mImpl->mTooltip )
+ {
+ controlImpl.mImpl->mTooltip->CreatePropertyMap( map );
+ }
+ value = map;
+ break;
+ }
+
+ case Toolkit::DevelControl::Property::SHADOW:
+ {
+ Property::Map map;
+ Toolkit::Visual::Base visual = controlImpl.mImpl->GetVisual( Toolkit::DevelControl::Property::SHADOW );
+ if( visual )
+ {
+ visual.CreatePropertyMap( map );
+ }
+
+ value = map;
+ break;
+ }
+
+ case Toolkit::DevelControl::Property::ACCESSIBILITY_ATTRIBUTES:
+ {
+ value = controlImpl.mImpl->mAccessibilityAttributes;
+ break;
+ }
+
+ case Toolkit::DevelControl::Property::ACCESSIBILITY_ANIMATED:
+ {
+ value = controlImpl.mImpl->mAccessibilityAnimated;
+ break;
+ }
+ }
+ }
+
+ return value;
+}
+
+void Control::Impl::RemoveAccessibilityAttribute( const std::string& key )
+{
+ Property::Value* val = mAccessibilityAttributes.Find( key );
+ if( val )
+ mAccessibilityAttributes[key] = Property::Value();
+}
+
+void Control::Impl::ClearAccessibilityAttributes()
+{
+ mAccessibilityAttributes.Clear();
+}
+
+void Control::Impl::SetAccessibilityReadingInfoType( const Dali::Accessibility::ReadingInfoTypes types )
+{
+ std::string value;
+ if ( types[ Dali::Accessibility::ReadingInfoType::NAME ] )
+ {
+ value += READING_INFO_TYPE_NAME;
+ }
+ if ( types[ Dali::Accessibility::ReadingInfoType::ROLE ] )
+ {
+ if( !value.empty() )
+ {
+ value += READING_INFO_TYPE_SEPARATOR;
+ }
+ value += READING_INFO_TYPE_ROLE;
+ }
+ if ( types[ Dali::Accessibility::ReadingInfoType::DESCRIPTION ] )
+ {
+ if( !value.empty() )
+ {
+ value += READING_INFO_TYPE_SEPARATOR;
+ }
+ value += READING_INFO_TYPE_DESCRIPTION;
+ }
+ if ( types[ Dali::Accessibility::ReadingInfoType::STATE ] )
+ {
+ if( !value.empty() )
+ {
+ value += READING_INFO_TYPE_SEPARATOR;
+ }
+ value += READING_INFO_TYPE_STATE;
+ }
+ AppendAccessibilityAttribute( READING_INFO_TYPE_ATTRIBUTE_NAME, value );
+}
+
+Dali::Accessibility::ReadingInfoTypes Control::Impl::GetAccessibilityReadingInfoType() const
+{
+ std::string value;
+ auto place = mAccessibilityAttributes.Find( READING_INFO_TYPE_ATTRIBUTE_NAME );
+ if( place )
+ {
+ place->Get( value );
+ }
+
+ if ( value.empty() )
+ {
+ return {};
+ }
+
+ Dali::Accessibility::ReadingInfoTypes types;
+
+ if ( value.find( READING_INFO_TYPE_NAME ) != std::string::npos )
+ {
+ types[ Dali::Accessibility::ReadingInfoType::NAME ] = true;
+ }
+ if ( value.find( READING_INFO_TYPE_ROLE ) != std::string::npos )
+ {
+ types[ Dali::Accessibility::ReadingInfoType::ROLE ] = true;
+ }
+ if ( value.find( READING_INFO_TYPE_DESCRIPTION ) != std::string::npos )
+ {
+ types[ Dali::Accessibility::ReadingInfoType::DESCRIPTION ] = true;
+ }
+ if ( value.find( READING_INFO_TYPE_STATE ) != std::string::npos )
+ {
+ types[ Dali::Accessibility::ReadingInfoType::STATE ] = true;
+ }
+
+ return types;
+}
+
+void Control::Impl::CopyInstancedProperties( RegisteredVisualContainer& visuals, Dictionary<Property::Map>& instancedProperties )
+{
+ for(RegisteredVisualContainer::Iterator iter = visuals.Begin(); iter!= visuals.End(); iter++)
+ {
+ if( (*iter)->visual )
+ {
+ Property::Map instanceMap;
+ Toolkit::GetImplementation((*iter)->visual).CreateInstancePropertyMap(instanceMap);
+ instancedProperties.Add( (*iter)->visual.GetName(), instanceMap );
+ }
+ }
+}
+
+
+void Control::Impl::RemoveVisual( RegisteredVisualContainer& visuals, const std::string& visualName )
+{
+ Actor self( mControlImpl.Self() );
+
+ for ( RegisteredVisualContainer::Iterator visualIter = visuals.Begin();
+ visualIter != visuals.End(); ++visualIter )
+ {
+ Toolkit::Visual::Base visual = (*visualIter)->visual;
+ if( visual && visual.GetName() == visualName )
+ {
+ Toolkit::GetImplementation(visual).SetOffScene( self );
+ (*visualIter)->visual.Reset();
+ visuals.Erase( visualIter );
+ break;
+ }
+ }
+}
+
+void Control::Impl::RemoveVisuals( RegisteredVisualContainer& visuals, DictionaryKeys& removeVisuals )
+{
+ Actor self( mControlImpl.Self() );
+ for( DictionaryKeys::iterator iter = removeVisuals.begin(); iter != removeVisuals.end(); ++iter )
+ {
+ const std::string visualName = *iter;
+ RemoveVisual( visuals, visualName );
+ }
+}
+
+void Control::Impl::RecreateChangedVisuals( Dictionary<Property::Map>& stateVisualsToChange,
+ Dictionary<Property::Map>& instancedProperties )
+{
+ Dali::CustomActor handle( mControlImpl.GetOwner() );
+ for( Dictionary<Property::Map>::iterator iter = stateVisualsToChange.Begin();
+ iter != stateVisualsToChange.End(); ++iter )
+ {
+ const std::string& visualName = (*iter).key;
+ const Property::Map& toMap = (*iter).entry;
+
+ // is it a candidate for re-creation?
+ bool recreate = false;
+
+ Toolkit::Visual::Base visual = GetVisualByName( mVisuals, visualName );
+ if( visual )
+ {
+ Property::Map fromMap;
+ visual.CreatePropertyMap( fromMap );
+
+ Toolkit::Visual::Type fromType = GetVisualTypeFromMap( fromMap );
+ Toolkit::Visual::Type toType = GetVisualTypeFromMap( toMap );
+
+ if( fromType != toType )
+ {
+ recreate = true;
+ }
+ else
+ {
+ if( fromType == Toolkit::Visual::IMAGE || fromType == Toolkit::Visual::N_PATCH
+ || fromType == Toolkit::Visual::SVG || fromType == Toolkit::Visual::ANIMATED_IMAGE )
+ {
+ Property::Value* fromUrl = fromMap.Find( Toolkit::ImageVisual::Property::URL, IMAGE_URL_NAME );
+ Property::Value* toUrl = toMap.Find( Toolkit::ImageVisual::Property::URL, IMAGE_URL_NAME );
+
+ if( fromUrl && toUrl )
+ {
+ std::string fromUrlString;
+ std::string toUrlString;
+ fromUrl->Get(fromUrlString);
+ toUrl->Get(toUrlString);
+
+ if( fromUrlString != toUrlString )
+ {
+ recreate = true;
+ }
+ }
+ }
+ }
+
+ const Property::Map* instancedMap = instancedProperties.FindConst( visualName );
+ if( recreate || instancedMap )
+ {
+ RemoveVisual( mVisuals, visualName );
+ Style::ApplyVisual( handle, visualName, toMap, instancedMap );
+ }
+ else
+ {
+ // @todo check to see if we can apply toMap without recreating the visual
+ // e.g. by setting only animatable properties
+ // For now, recreate all visuals, but merge in instance data.