-Control::Impl::AccessibleImpl::AccessibleImpl(Dali::Actor self, Dali::Accessibility::Role role, bool modal)
- : self(self), modal(modal)
-{
- auto control = Dali::Toolkit::Control::DownCast(self);
-
- Internal::Control& internalControl = Toolkit::Internal::GetImplementation( control );
- Internal::Control::Impl& controlImpl = Internal::Control::Impl::Get( internalControl );
- if( controlImpl.mAccessibilityRole == Dali::Accessibility::Role::UNKNOWN )
- controlImpl.mAccessibilityRole = role;
-
- self.PropertySetSignal().Connect(&controlImpl, [this, &controlImpl](Dali::Handle &handle, Dali::Property::Index index, Dali::Property::Value value)
- {
- if (this->self != Dali::Accessibility::Accessible::GetCurrentlyHighlightedActor())
- {
- return;
- }
-
- if (index == DevelControl::Property::ACCESSIBILITY_NAME
- || (index == GetNamePropertyIndex() && !controlImpl.mAccessibilityNameSet))
- {
- if (controlImpl.mAccessibilityGetNameSignal.Empty())
- {
- Emit(Dali::Accessibility::ObjectPropertyChangeEvent::NAME);
- }
- }
-
- if (index == DevelControl::Property::ACCESSIBILITY_DESCRIPTION
- || (index == GetDescriptionPropertyIndex() && !controlImpl.mAccessibilityDescriptionSet))
- {
- if (controlImpl.mAccessibilityGetDescriptionSignal.Empty())
- {
- Emit(Dali::Accessibility::ObjectPropertyChangeEvent::DESCRIPTION);
- }
- }
- });
-}
-
-std::string Control::Impl::AccessibleImpl::GetName()
-{
- auto control = Dali::Toolkit::Control::DownCast(self);
-
- Internal::Control& internalControl = Toolkit::Internal::GetImplementation( control );
- Internal::Control::Impl& controlImpl = Internal::Control::Impl::Get( internalControl );
-
- if (!controlImpl.mAccessibilityGetNameSignal.Empty()) {
- std::string ret;
- controlImpl.mAccessibilityGetNameSignal.Emit(ret);
- return ret;
- }
-
- if (controlImpl.mAccessibilityNameSet)
- return controlImpl.mAccessibilityName;
-
- if (auto raw = GetNameRaw(); !raw.empty())
- return raw;
-
- return self.GetProperty< std::string >( Actor::Property::NAME );
-}
-
-std::string Control::Impl::AccessibleImpl::GetNameRaw()
-{
- return {};
-}
-
-std::string Control::Impl::AccessibleImpl::GetDescription()
-{
- auto control = Dali::Toolkit::Control::DownCast(self);
-
- Internal::Control& internalControl = Toolkit::Internal::GetImplementation( control );
- Internal::Control::Impl& controlImpl = Internal::Control::Impl::Get( internalControl );
-
- if (!controlImpl.mAccessibilityGetDescriptionSignal.Empty()) {
- std::string ret;
- controlImpl.mAccessibilityGetDescriptionSignal.Emit(ret);
- return ret;
- }
-
- if (controlImpl.mAccessibilityDescriptionSet)
- return controlImpl.mAccessibilityDescription;
-
- return GetDescriptionRaw();
-}
-
-std::string Control::Impl::AccessibleImpl::GetDescriptionRaw()
-{
- return "";
-}
-
-Dali::Accessibility::Accessible* Control::Impl::AccessibleImpl::GetParent()
-{
- return Dali::Accessibility::Accessible::Get( self.GetParent() );
-}
-
-size_t Control::Impl::AccessibleImpl::GetChildCount()
-{
- return self.GetChildCount();
-}
-
-Dali::Accessibility::Accessible* Control::Impl::AccessibleImpl::GetChildAtIndex( size_t index )
-{
- return Dali::Accessibility::Accessible::Get( self.GetChildAt( static_cast< unsigned int >( index ) ) );
-}
-
-size_t Control::Impl::AccessibleImpl::GetIndexInParent()
-{
- auto s = self;
- auto parent = s.GetParent();
- DALI_ASSERT_ALWAYS( parent && "can't call GetIndexInParent on object without parent" );
- auto count = parent.GetChildCount();
- for( auto i = 0u; i < count; ++i )
- {
- auto c = parent.GetChildAt( i );
- if( c == s )
- return i;
- }
- DALI_ASSERT_ALWAYS( false && "object isn't child of it's parent" );
- return static_cast<size_t>(-1);
-}
-
-Dali::Accessibility::Role Control::Impl::AccessibleImpl::GetRole()
-{
- return self.GetProperty<Dali::Accessibility::Role>( Toolkit::DevelControl::Property::ACCESSIBILITY_ROLE );
-}
-
-Dali::Accessibility::States Control::Impl::AccessibleImpl::CalculateStates()
-{
- Dali::Accessibility::States s;
- s[Dali::Accessibility::State::FOCUSABLE] = self.GetProperty< bool >( Actor::Property::KEYBOARD_FOCUSABLE );
- s[Dali::Accessibility::State::FOCUSED] = Toolkit::KeyboardFocusManager::Get().GetCurrentFocusActor() == self;
- if(self.GetProperty( Toolkit::DevelControl::Property::ACCESSIBILITY_HIGHLIGHTABLE ).GetType() == Property::NONE )
- s[Dali::Accessibility::State::HIGHLIGHTABLE] = false;
- else
- s[Dali::Accessibility::State::HIGHLIGHTABLE] = self.GetProperty( Toolkit::DevelControl::Property::ACCESSIBILITY_HIGHLIGHTABLE ).Get< bool >();
- s[Dali::Accessibility::State::HIGHLIGHTED] = GetCurrentlyHighlightedActor() == self;
- s[Dali::Accessibility::State::ENABLED] = true;
- s[Dali::Accessibility::State::SENSITIVE] = true;
- s[Dali::Accessibility::State::ANIMATED] = self.GetProperty( Toolkit::DevelControl::Property::ACCESSIBILITY_ANIMATED ).Get< bool >();
- s[Dali::Accessibility::State::VISIBLE] = true;
- if( modal )
- {
- s[Dali::Accessibility::State::MODAL] = true;
- }
- s[Dali::Accessibility::State::SHOWING] = !self.GetProperty( Dali::DevelActor::Property::CULLED ).Get< bool >()
- && self.GetCurrentProperty< bool >( Actor::Property::VISIBLE );
-
- s[Dali::Accessibility::State::DEFUNCT] = !self.GetProperty( Dali::DevelActor::Property::CONNECTED_TO_SCENE ).Get< bool >();
- return s;
-}
-
-Dali::Accessibility::States Control::Impl::AccessibleImpl::GetStates()
-{
- return CalculateStates();
-}
-
-Dali::Accessibility::Attributes Control::Impl::AccessibleImpl::GetAttributes()
-{
- std::unordered_map< std::string, std::string > attribute_map;
- auto q = Dali::Toolkit::Control::DownCast( self );
- auto w =
- q.GetProperty( Dali::Toolkit::DevelControl::Property::ACCESSIBILITY_ATTRIBUTES );
- auto z = w.GetMap();
-
- if( z )
- {
- auto map_size = z->Count();
-
- for( unsigned int i = 0; i < map_size; i++ )
- {
- auto map_key = z->GetKeyAt( i );
- if( map_key.type == Property::Key::STRING )
- {
- std::string map_value;
- if( z->GetValue( i ).Get( map_value ) )
- {
- attribute_map.emplace( std::move( map_key.stringKey ),
- std::move( map_value ) );
- }
- }
- }
- }
-
- return attribute_map;
-}
-
-Dali::Accessibility::ComponentLayer Control::Impl::AccessibleImpl::GetLayer()
-{
- return Dali::Accessibility::ComponentLayer::WINDOW;
-}
-
-Dali::Rect<> Control::Impl::AccessibleImpl::GetExtents( Dali::Accessibility::CoordType ctype )
-{
- Vector2 screenPosition =
- self.GetProperty( Dali::DevelActor::Property::SCREEN_POSITION )
- .Get< Vector2 >();
- auto size = self.GetCurrentProperty< Vector3 >( Actor::Property::SIZE ) * self.GetCurrentProperty< Vector3 >( Actor::Property::WORLD_SCALE );
- bool positionUsesAnchorPoint =
- self.GetProperty( Dali::DevelActor::Property::POSITION_USES_ANCHOR_POINT )
- .Get< bool >();
- Vector3 anchorPointOffSet =
- size * ( positionUsesAnchorPoint ? self.GetCurrentProperty< Vector3 >( Actor::Property::ANCHOR_POINT )
- : AnchorPoint::TOP_LEFT );
- Vector2 position = Vector2( screenPosition.x - anchorPointOffSet.x,
- screenPosition.y - anchorPointOffSet.y );
-
- return { position.x, position.y, size.x, size.y };
-}
-
-int16_t Control::Impl::AccessibleImpl::GetMdiZOrder() { return 0; }
-double Control::Impl::AccessibleImpl::GetAlpha() { return 0; }
-
-bool Control::Impl::AccessibleImpl::GrabFocus()
-{
- return Toolkit::KeyboardFocusManager::Get().SetCurrentFocusActor( self );
-}
-
-static Dali::Actor CreateHighlightIndicatorActor()
-{
- std::string focusBorderImagePath(AssetManager::GetDaliImagePath());
- focusBorderImagePath += "/keyboard_focus.9.png";
- // Create the default if it hasn't been set and one that's shared by all the
- // keyboard focusable actors
- auto actor = Toolkit::ImageView::New( focusBorderImagePath );
- actor.SetResizePolicy( ResizePolicy::FILL_TO_PARENT, Dimension::ALL_DIMENSIONS );
- DevelControl::AppendAccessibilityAttribute( actor, "highlight", "" );
- actor.SetProperty( Toolkit::DevelControl::Property::ACCESSIBILITY_ANIMATED, true);
- actor.SetProperty( Toolkit::DevelControl::Property::ACCESSIBILITY_HIGHLIGHTABLE, false );
-
- return actor;
-}
-
-bool Control::Impl::AccessibleImpl::GrabHighlight()
-{
- auto old = GetCurrentlyHighlightedActor();
-
- if( !Dali::Accessibility::IsUp() )
- return false;
- if( self == old )
- return true;
- if( old )
- {
- auto c = dynamic_cast< Dali::Accessibility::Component* >( GetAccessibilityObject( old ) );
- if( c )
- c->ClearHighlight();
- }
- auto highlight = GetHighlightActor();
- if ( !highlight )
- {
- highlight = CreateHighlightIndicatorActor();
- SetHighlightActor( highlight );
- }
- highlight.SetProperty( Actor::Property::PARENT_ORIGIN, ParentOrigin::CENTER );
- highlight.SetProperty( Actor::Property::ANCHOR_POINT, AnchorPoint::CENTER );
- highlight.SetProperty( Actor::Property::POSITION_Z, 1.0f );
- highlight.SetProperty( Actor::Property::POSITION, Vector2( 0.0f, 0.0f ));
-
- EnsureSelfVisible();
- self.Add( highlight );
- SetCurrentlyHighlightedActor( self );
- EmitHighlighted( true );
-
- return true;
-}
-
-
-
-bool Control::Impl::AccessibleImpl::ClearHighlight()
-{
- if( !Dali::Accessibility::IsUp() )
- return false;
- if( GetCurrentlyHighlightedActor() == self )
- {
- self.Remove( GetHighlightActor() );
- SetCurrentlyHighlightedActor( {} );
- EmitHighlighted( false );
- return true;
- }
- return false;
-}
-
-std::string Control::Impl::AccessibleImpl::GetActionName( size_t index )
-{
- if ( index >= GetActionCount() ) return "";
- Dali::TypeInfo type;
- self.GetTypeInfo( type );
- DALI_ASSERT_ALWAYS( type && "no TypeInfo object" );
- return type.GetActionName( index );
-}
-std::string Control::Impl::AccessibleImpl::GetLocalizedActionName( size_t index )
-{
- // TODO: add localization
- return GetActionName( index );
-}
-std::string Control::Impl::AccessibleImpl::GetActionDescription( size_t index )
-{
- return "";
-}
-size_t Control::Impl::AccessibleImpl::GetActionCount()
-{
- Dali::TypeInfo type;
- self.GetTypeInfo( type );
- DALI_ASSERT_ALWAYS( type && "no TypeInfo object" );
- return type.GetActionCount();
-}
-std::string Control::Impl::AccessibleImpl::GetActionKeyBinding( size_t index )
-{
- return "";
-}
-bool Control::Impl::AccessibleImpl::DoAction( size_t index )
-{
- std::string actionName = GetActionName( index );
- return self.DoAction( actionName, {} );
-}
-bool Control::Impl::AccessibleImpl::DoAction(const std::string& name)
-{
- return self.DoAction( name, {} );
-}
-
-bool Control::Impl::AccessibleImpl::DoGesture(const Dali::Accessibility::GestureInfo &gestureInfo)
-{
- auto control = Dali::Toolkit::Control::DownCast(self);
-
- Internal::Control& internalControl = Toolkit::Internal::GetImplementation( control );
- Internal::Control::Impl& controlImpl = Internal::Control::Impl::Get( internalControl );
-
- if (!controlImpl.mAccessibilityDoGestureSignal.Empty()) {
- auto ret = std::make_pair(gestureInfo, false);
- controlImpl.mAccessibilityDoGestureSignal.Emit(ret);
- return ret.second;
- }
-
- return false;
-}
-
-std::vector<Dali::Accessibility::Relation> Control::Impl::AccessibleImpl::GetRelationSet()
-{
- auto control = Dali::Toolkit::Control::DownCast(self);
-
- Internal::Control& internalControl = Toolkit::Internal::GetImplementation( control );
- Internal::Control::Impl& controlImpl = Internal::Control::Impl::Get( internalControl );
-
- std::vector<Dali::Accessibility::Relation> ret;
-
- auto &v = controlImpl.mAccessibilityRelations;
- for (auto i = 0u; i < v.size(); ++i)
- {
- if ( v[i].empty() )
- continue;
-
- ret.emplace_back( Accessibility::Relation{ static_cast<Accessibility::RelationType>(i), v[i] } );
- }
-
- return ret;
-}
-
-void Control::Impl::AccessibleImpl::EnsureChildVisible(Actor child)
-{
-}
-
-void Control::Impl::AccessibleImpl::EnsureSelfVisible()
-{
- auto parent = dynamic_cast<Control::Impl::AccessibleImpl*>(GetParent());
- if (parent)
- {
- parent->EnsureChildVisible(self);
- }
-}
-
-Property::Index Control::Impl::AccessibleImpl::GetNamePropertyIndex()
-{
- return Actor::Property::NAME;
-}
-
-Property::Index Control::Impl::AccessibleImpl::GetDescriptionPropertyIndex()
-{
- return Property::INVALID_INDEX;
-}
-
-void Control::Impl::PositionOrSizeChangedCallback( PropertyNotification &p )
-{
- auto self = Dali::Actor::DownCast(p.GetTarget());
- if (Dali::Accessibility::IsUp() && !self.GetProperty( Toolkit::DevelControl::Property::ACCESSIBILITY_ANIMATED ).Get< bool >())
- {
- auto extents = DevelActor::CalculateScreenExtents( self );
- Dali::Accessibility::Accessible::Get( self )->EmitBoundsChanged( extents );
- }
-}
-
-void Control::Impl::CulledChangedCallback( PropertyNotification &p)
-{
- if (Dali::Accessibility::IsUp())
- {
- auto self = Dali::Actor::DownCast(p.GetTarget());
- Dali::Accessibility::Accessible::Get(self)->EmitShowing( !self.GetProperty( DevelActor::Property::CULLED ).Get<bool>() );
- }
-}
-
-void Control::Impl::AccessibilityRegister()
-{
- if (!accessibilityNotificationSet)
- {
- accessibilityNotificationPosition = mControlImpl.Self().AddPropertyNotification( Actor::Property::POSITION, StepCondition( 0.01f ) );
- accessibilityNotificationPosition.SetNotifyMode( PropertyNotification::NOTIFY_ON_CHANGED );
- accessibilityNotificationPosition.NotifySignal().Connect( &Control::Impl::PositionOrSizeChangedCallback );
-
- accessibilityNotificationSize = mControlImpl.Self().AddPropertyNotification( Actor::Property::SIZE, StepCondition( 0.01f ) );
- accessibilityNotificationSize.SetNotifyMode( PropertyNotification::NOTIFY_ON_CHANGED );
- accessibilityNotificationSize.NotifySignal().Connect( &Control::Impl::PositionOrSizeChangedCallback );
-
- accessibilityNotificationCulled = mControlImpl.Self().AddPropertyNotification( DevelActor::Property::CULLED, LessThanCondition( 0.5f ) );
- accessibilityNotificationCulled.SetNotifyMode( PropertyNotification::NOTIFY_ON_CHANGED );
- accessibilityNotificationCulled.NotifySignal().Connect( &Control::Impl::CulledChangedCallback );
-
- accessibilityNotificationSet = true;
- }
-}
-
-void Control::Impl::AccessibilityDeregister()
-{
- if (accessibilityNotificationSet)
- {
- accessibilityNotificationPosition = {};
- accessibilityNotificationSize = {};
- accessibilityNotificationCulled = {};
- accessibilityNotificationSet = false;
- }
-}
-