From: Radoslaw Cybulski Date: Wed, 25 Apr 2018 15:47:22 +0000 (+0200) Subject: [Tizen][ATSPI] Accessibility initial implementation X-Git-Tag: accepted/tizen/unified/20180509.073115~2 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=e5208b9110e3aa0fb53d4db1cd19408cc958bfbb;p=platform%2Fcore%2Fuifw%2Fdali-toolkit.git [Tizen][ATSPI] Accessibility initial implementation Conflicts: dali-toolkit/public-api/controls/text-controls/text-field.h Change-Id: Ie3e02898cb53a55515514347b78350095be4aa80 --- diff --git a/dali-toolkit/devel-api/controls/control-devel.h b/dali-toolkit/devel-api/controls/control-devel.h old mode 100644 new mode 100755 index ae90f4d..8d6ce47 --- a/dali-toolkit/devel-api/controls/control-devel.h +++ b/dali-toolkit/devel-api/controls/control-devel.h @@ -113,7 +113,10 @@ enum * @details Name "downFocusableActorId", type Property::INTEGER. * */ - DOWN_FOCUSABLE_ACTOR_ID = PADDING + 7 + DOWN_FOCUSABLE_ACTOR_ID = PADDING + 7, + + ACCESSIBILITY_ATTRIBUTES = PADDING + 8 + }; } // namespace Property diff --git a/dali-toolkit/internal/accessibility-manager/accessibility-manager-impl.cpp b/dali-toolkit/internal/accessibility-manager/accessibility-manager-impl.cpp old mode 100644 new mode 100755 diff --git a/dali-toolkit/internal/controls/buttons/button-impl.cpp b/dali-toolkit/internal/controls/buttons/button-impl.cpp index 84dd7a1..9d87e96 100644 --- a/dali-toolkit/internal/controls/buttons/button-impl.cpp +++ b/dali-toolkit/internal/controls/buttons/button-impl.cpp @@ -1652,6 +1652,23 @@ Actor Button::GetSelectedImage() const return imageView; } +std::string Button::AccessibleImpl::GetName() +{ + auto slf = Toolkit::Button::DownCast( self ); + return slf.GetLabelText(); +} + +Dali::Accessibility::States Button::AccessibleImpl::CalculateStates() +{ + auto tmp = Control::AccessibleImpl::CalculateStates(); + tmp[Dali::Accessibility::State::Selectable] = true; + auto slf = Toolkit::Button::DownCast( self ); + tmp[Dali::Accessibility::State::Enabled] = !slf.IsDisabled(); + if( slf.IsSelected() ) + tmp[Dali::Accessibility::State::Checked] = true; + return tmp; +} + } // namespace Internal } // namespace Toolkit diff --git a/dali-toolkit/internal/controls/buttons/button-impl.h b/dali-toolkit/internal/controls/buttons/button-impl.h index 8b1417c..eafa843 100644 --- a/dali-toolkit/internal/controls/buttons/button-impl.h +++ b/dali-toolkit/internal/controls/buttons/button-impl.h @@ -685,6 +685,14 @@ private: Image mSetButtonImage; ///< Store set image if deprecated SetButtonImage used. Image mSetSelectedImage; ///< Store set image if deprecated SetSelectedImage used. +protected: + struct AccessibleImpl : public Control::AccessibleImpl + { + using Control::AccessibleImpl::AccessibleImpl; + + Dali::Accessibility::States CalculateStates() override; + std::string GetName() override; + }; }; } // namespace Internal diff --git a/dali-toolkit/internal/controls/buttons/check-box-button-impl.cpp b/dali-toolkit/internal/controls/buttons/check-box-button-impl.cpp index 9554ccb..9c666a5 100644 --- a/dali-toolkit/internal/controls/buttons/check-box-button-impl.cpp +++ b/dali-toolkit/internal/controls/buttons/check-box-button-impl.cpp @@ -75,6 +75,10 @@ CheckBoxButton::CheckBoxButton() : Button() { SetTogglableButton( true ); + SetAccessibilityConstructor( []( Dali::Actor actor ) { + return std::unique_ptr< Dali::Accessibility::Accessible >( + new AccessibleImpl( actor, Dali::Accessibility::Role::CheckBox ) ); + } ); } CheckBoxButton::~CheckBoxButton() diff --git a/dali-toolkit/internal/controls/buttons/push-button-impl.cpp b/dali-toolkit/internal/controls/buttons/push-button-impl.cpp index 1b7f495..2cfb8ab 100644 --- a/dali-toolkit/internal/controls/buttons/push-button-impl.cpp +++ b/dali-toolkit/internal/controls/buttons/push-button-impl.cpp @@ -101,6 +101,10 @@ PushButton::PushButton() : Button(), mIconAlignment( RIGHT ) { + SetAccessibilityConstructor( []( Dali::Actor actor ) { + return std::unique_ptr< Dali::Accessibility::Accessible >( + new AccessibleImpl( actor, Dali::Accessibility::Role::PushButton ) ); + } ); } PushButton::~PushButton() diff --git a/dali-toolkit/internal/controls/buttons/radio-button-impl.cpp b/dali-toolkit/internal/controls/buttons/radio-button-impl.cpp index bbd151a..0e8495f 100644 --- a/dali-toolkit/internal/controls/buttons/radio-button-impl.cpp +++ b/dali-toolkit/internal/controls/buttons/radio-button-impl.cpp @@ -67,6 +67,10 @@ Dali::Toolkit::RadioButton RadioButton::New() RadioButton::RadioButton() { SetTogglableButton(true); + SetAccessibilityConstructor( []( Dali::Actor actor ) { + return std::unique_ptr< Dali::Accessibility::Accessible >( + new AccessibleImpl( actor, Dali::Accessibility::Role::RadioButton ) ); + } ); } RadioButton::~RadioButton() diff --git a/dali-toolkit/internal/controls/buttons/toggle-button-impl.cpp b/dali-toolkit/internal/controls/buttons/toggle-button-impl.cpp old mode 100755 new mode 100644 index 0ecae06..7299e42 --- a/dali-toolkit/internal/controls/buttons/toggle-button-impl.cpp +++ b/dali-toolkit/internal/controls/buttons/toggle-button-impl.cpp @@ -98,6 +98,10 @@ ToggleButton::ToggleButton() { DALI_LOG_INFO( gLogButtonFilter, Debug::General, "ToggleButton::Constructor\n" ); SetTogglableButton( false ); + SetAccessibilityConstructor( []( Dali::Actor actor ) { + return std::unique_ptr< Dali::Accessibility::Accessible >( + new AccessibleImpl( actor, Dali::Accessibility::Role::ToggleButton ) ); + } ); } ToggleButton::~ToggleButton() diff --git a/dali-toolkit/internal/controls/control/control-data-impl.cpp b/dali-toolkit/internal/controls/control/control-data-impl.cpp old mode 100644 new mode 100755 index 369c409..f9e316f --- a/dali-toolkit/internal/controls/control/control-data-impl.cpp +++ b/dali-toolkit/internal/controls/control/control-data-impl.cpp @@ -26,6 +26,11 @@ #include #include #include +#include +#include +#include +#include +#include #include #include @@ -175,13 +180,20 @@ static bool DoAction( BaseObject* object, const std::string& actionName, const P { bool ret = false; - if( object && ( 0 == strcmp( actionName.c_str(), ACTION_ACCESSIBILITY_ACTIVATED ) ) ) + if( object && + ( 0 == strcmp( actionName.c_str(), ACTION_ACCESSIBILITY_ACTIVATED ) || + actionName == "activate" ) ) { Toolkit::Control control = Toolkit::Control::DownCast( BaseHandle( object ) ); if( control ) { // if cast succeeds there is an implementation so no need to check - ret = Internal::GetImplementation( control ).OnAccessibilityActivated(); + if (!Internal::GetImplementation( control ).AccessibilityActivateSignal().Empty()) { + Internal::GetImplementation( control ).AccessibilityActivateSignal().Emit(); + ret = true; + } + else + ret = Internal::GetImplementation( control ).OnAccessibilityActivated(); } } @@ -271,7 +283,9 @@ SignalConnectorType registerSignal5( typeRegistration, SIGNAL_PANNED, &DoConnect SignalConnectorType registerSignal6( typeRegistration, SIGNAL_PINCHED, &DoConnectSignal ); SignalConnectorType registerSignal7( typeRegistration, SIGNAL_LONG_PRESSED, &DoConnectSignal ); -TypeAction registerAction( typeRegistration, ACTION_ACCESSIBILITY_ACTIVATED, &DoAction ); +TypeAction registerAction( typeRegistration, "activate", &DoAction ); +TypeAction registerAction2( typeRegistration, ACTION_ACCESSIBILITY_ACTIVATED, + &DoAction ); DALI_TYPE_REGISTRATION_END() @@ -311,6 +325,7 @@ const PropertyRegistration Control::Impl::PROPERTY_11( typeRegistration, "leftFo const PropertyRegistration Control::Impl::PROPERTY_12( typeRegistration, "rightFocusableActorId", Toolkit::DevelControl::Property::RIGHT_FOCUSABLE_ACTOR_ID,Property::INTEGER, &Control::Impl::SetProperty, &Control::Impl::GetProperty ); const PropertyRegistration Control::Impl::PROPERTY_13( typeRegistration, "upFocusableActorId", Toolkit::DevelControl::Property::UP_FOCUSABLE_ACTOR_ID, Property::INTEGER, &Control::Impl::SetProperty, &Control::Impl::GetProperty ); const PropertyRegistration Control::Impl::PROPERTY_14( typeRegistration, "downFocusableActorId", Toolkit::DevelControl::Property::DOWN_FOCUSABLE_ACTOR_ID, Property::INTEGER, &Control::Impl::SetProperty, &Control::Impl::GetProperty ); +const PropertyRegistration Control::Impl::PROPERTY_15( typeRegistration, "accessibilityAttributes", Toolkit::Control::Property::ACCESSIBILITY_ATTRIBUTES, Property::MAP, &Control::Impl::SetProperty, &Control::Impl::GetProperty ); Control::Impl::Impl( Control& controlImpl ) @@ -338,7 +353,10 @@ Control::Impl::Impl( Control& controlImpl ) mIsKeyboardNavigationSupported( false ), mIsKeyboardFocusGroup( false ) { - + Dali::Accessibility::Accessible::RegisterControlAccessibilityGetter( + []( Dali::Actor actor ) -> Dali::Accessibility::Accessible* { + return Control::GetAccessibilityObject( actor ); + } ); } Control::Impl::~Impl() @@ -792,6 +810,16 @@ void Control::Impl::DoAction( Dali::Property::Index visualIndex, Dali::Property: } } +void Control::Impl::AccessibilitySetAttribute( 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 ) ); @@ -982,10 +1010,26 @@ void Control::Impl::SetProperty( BaseObject* object, Property::Index index, cons break; } + case Toolkit::Control::Property::ACCESSIBILITY_ATTRIBUTES: + { + value.Get( controlImpl.mImpl->mAccessibilityAttributes ); + break; + } } } } +std::string Control::Impl::AccessibilityGetAttribute( const std::string& key ) +{ + std::string value; + auto place = mAccessibilityAttributes.Find( key ); + if( !place ) + return ""; + if( !place->Get( value ) ) + return ""; + return value; +} + Property::Value Control::Impl::GetProperty( BaseObject* object, Property::Index index ) { Property::Value value; @@ -1101,12 +1145,24 @@ Property::Value Control::Impl::GetProperty( BaseObject* object, Property::Index value = map; break; } + + case Toolkit::Control::Property::ACCESSIBILITY_ATTRIBUTES: + { + value = controlImpl.mImpl->mAccessibilityAttributes; + break; + } } } return value; } +void Control::Impl::AccessibilityEraseAttribute( std::string& key ) +{ + Property::Value* val = mAccessibilityAttributes.Find( key ); + if( val ) + mAccessibilityAttributes[key] = Property::Value(); +} void Control::Impl::CopyInstancedProperties( RegisteredVisualContainer& visuals, Dictionary& instancedProperties ) { diff --git a/dali-toolkit/internal/controls/control/control-data-impl.h b/dali-toolkit/internal/controls/control/control-data-impl.h old mode 100644 new mode 100755 index ddd7506..f9c3099 --- a/dali-toolkit/internal/controls/control/control-data-impl.h +++ b/dali-toolkit/internal/controls/control/control-data-impl.h @@ -32,6 +32,9 @@ #include #include #include +#include +#include +#include namespace Dali { @@ -300,6 +303,11 @@ public: */ Extents GetPadding() const; + void AccessibilitySetAttribute( const std::string& key, + const std::string value ); + std::string AccessibilityGetAttribute( const std::string& key ); + void AccessibilityEraseAttribute( std::string& key ); + private: /** @@ -344,6 +352,7 @@ public: Control& mControlImpl; DevelControl::State mState; std::string mSubStateName; + Property::Map mAccessibilityAttributes; int mLeftFocusableActorId; ///< Actor ID of Left focusable control. int mRightFocusableActorId; ///< Actor ID of Right focusable control. @@ -360,6 +369,7 @@ public: Toolkit::Control::KeyInputFocusSignalType mKeyInputFocusGainedSignal; Toolkit::Control::KeyInputFocusSignalType mKeyInputFocusLostSignal; Toolkit::Control::ResourceReadySignalType mResourceReadySignal; + Toolkit::Control::AccessibilityActivateSignalType mAccessibilityActivateSignal; // Gesture Detection PinchGestureDetector mPinchGestureDetector; @@ -391,6 +401,11 @@ public: static const PropertyRegistration PROPERTY_12; static const PropertyRegistration PROPERTY_13; static const PropertyRegistration PROPERTY_14; + static const PropertyRegistration PROPERTY_15; + + std::function< std::unique_ptr< Dali::Accessibility::Accessible >( Actor ) > + accessibilityConstructor; + std::unique_ptr< Dali::Accessibility::Accessible > accessibilityObject; }; diff --git a/dali-toolkit/internal/controls/image-view/image-view-impl.cpp b/dali-toolkit/internal/controls/image-view/image-view-impl.cpp old mode 100755 new mode 100644 index 8bfa80d..3a9cd53 --- a/dali-toolkit/internal/controls/image-view/image-view-impl.cpp +++ b/dali-toolkit/internal/controls/image-view/image-view-impl.cpp @@ -66,6 +66,10 @@ using namespace Dali; ImageView::ImageView() : Control( ControlBehaviour( CONTROL_BEHAVIOUR_DEFAULT ) ) { + SetAccessibilityConstructor( []( Dali::Actor actor ) { + return std::unique_ptr< Dali::Accessibility::Accessible >( + new AccessibleImpl( actor, Dali::Accessibility::Role::Image ) ); + } ); } ImageView::~ImageView() diff --git a/dali-toolkit/internal/controls/popup/confirmation-popup-impl.cpp b/dali-toolkit/internal/controls/popup/confirmation-popup-impl.cpp index 43758cb..9850ee1 100644 --- a/dali-toolkit/internal/controls/popup/confirmation-popup-impl.cpp +++ b/dali-toolkit/internal/controls/popup/confirmation-popup-impl.cpp @@ -99,6 +99,10 @@ ConfirmationPopup::ConfirmationPopup() mControlSignals.reserve( MAXIMUM_NUMBER_OF_CONTROLS ); mControlSignalNames[ Toolkit::ConfirmationPopup::CONTROL_OK ] = DEFAULT_CONNECT_SIGNAL_NAME; mControlSignalNames[ Toolkit::ConfirmationPopup::CONTROL_CANCEL ] = DEFAULT_CONNECT_SIGNAL_NAME; + SetAccessibilityConstructor( []( Dali::Actor actor ) { + return std::unique_ptr< Dali::Accessibility::Accessible >( + new AccessibleImpl( actor, Dali::Accessibility::Role::Dialog, true ) ); + } ); } ConfirmationPopup::~ConfirmationPopup() diff --git a/dali-toolkit/internal/controls/popup/popup-impl.cpp b/dali-toolkit/internal/controls/popup/popup-impl.cpp index cde648a..493169e 100644 --- a/dali-toolkit/internal/controls/popup/popup-impl.cpp +++ b/dali-toolkit/internal/controls/popup/popup-impl.cpp @@ -263,6 +263,10 @@ Popup::Popup() mTailRightImage( DEFAULT_TAIL_RIGHT_IMAGE_PATH ) { SetKeyboardNavigationSupport( true ); + SetAccessibilityConstructor( []( Dali::Actor actor ) { + return std::unique_ptr< Dali::Accessibility::Accessible >( + new AccessibleImpl( actor, Dali::Accessibility::Role::Dialog, true ) ); + } ); } void Popup::OnInitialize() diff --git a/dali-toolkit/internal/controls/progress-bar/progress-bar-impl.cpp b/dali-toolkit/internal/controls/progress-bar/progress-bar-impl.cpp old mode 100755 new mode 100644 index 2b89fed..fb6c1b4 --- a/dali-toolkit/internal/controls/progress-bar/progress-bar-impl.cpp +++ b/dali-toolkit/internal/controls/progress-bar/progress-bar-impl.cpp @@ -114,6 +114,10 @@ ProgressBar::ProgressBar() mSecondaryProgressValue( DEFAULT_VALUE ), mIndeterminate( false ) { + SetAccessibilityConstructor( []( Dali::Actor actor ) { + return std::unique_ptr< Dali::Accessibility::Accessible >( + new AccessibleImpl( actor, Dali::Accessibility::Role::ProgressBar ) ); + } ); } ProgressBar::~ProgressBar() @@ -589,6 +593,29 @@ void ProgressBar::OnStageConnection( int depth ) } } +double ProgressBar::AccessibleImpl::GetMinimum() { return DEFAULT_LOWER_BOUND; } + +double ProgressBar::AccessibleImpl::GetCurrent() +{ + auto p = Toolkit::ProgressBar::DownCast( self ); + return p.GetProperty( Toolkit::ProgressBar::Property::PROGRESS_VALUE ) + .Get< float >(); +} + +double ProgressBar::AccessibleImpl::GetMaximum() { return DEFAULT_UPPER_BOUND; } + +bool ProgressBar::AccessibleImpl::SetCurrent( double current ) +{ + if( current < GetMinimum() || current > GetMaximum() ) + return false; + auto p = Toolkit::ProgressBar::DownCast( self ); + p.SetProperty( Toolkit::ProgressBar::Property::PROGRESS_VALUE, + static_cast< float >( current ) ); + return true; +} + +double ProgressBar::AccessibleImpl::GetMinimumIncrement() { return 0.001; } + } // namespace Internal } // namespace Toolkit diff --git a/dali-toolkit/internal/controls/progress-bar/progress-bar-impl.h b/dali-toolkit/internal/controls/progress-bar/progress-bar-impl.h old mode 100755 new mode 100644 index 5b0ffd2..fbdf53b --- a/dali-toolkit/internal/controls/progress-bar/progress-bar-impl.h +++ b/dali-toolkit/internal/controls/progress-bar/progress-bar-impl.h @@ -256,6 +256,18 @@ private: float mProgressValue; ///< Current value of ProgressBar float mSecondaryProgressValue; ///< Current loading value of ProgressBar bool mIndeterminate; ///< Whether the progress state is determined or not + +protected: + struct AccessibleImpl : public Control::AccessibleImpl, + public virtual Dali::Accessibility::Value + { + using Control::AccessibleImpl::AccessibleImpl; + double GetMinimum() override; + double GetCurrent() override; + double GetMaximum() override; + bool SetCurrent( double ) override; + double GetMinimumIncrement() override; + }; }; } // namespace Internal diff --git a/dali-toolkit/internal/controls/scroll-bar/scroll-bar-impl.cpp b/dali-toolkit/internal/controls/scroll-bar/scroll-bar-impl.cpp old mode 100755 new mode 100644 index cd8438e..83cd71e --- a/dali-toolkit/internal/controls/scroll-bar/scroll-bar-impl.cpp +++ b/dali-toolkit/internal/controls/scroll-bar/scroll-bar-impl.cpp @@ -204,6 +204,10 @@ ScrollBar::ScrollBar(Toolkit::ScrollBar::Direction direction) mIsPanning(false), mIndicatorFirstShow(true) { + SetAccessibilityConstructor( []( Dali::Actor actor ) { + return std::unique_ptr< Dali::Accessibility::Accessible >( + new AccessibleImpl( actor, Dali::Accessibility::Role::ScrollBar ) ); + } ); } ScrollBar::~ScrollBar() @@ -857,6 +861,39 @@ Toolkit::ScrollBar ScrollBar::New(Toolkit::ScrollBar::Direction direction) return handle; } +double ScrollBar::AccessibleImpl::GetMinimum() +{ + auto p = Toolkit::ScrollBar::DownCast( self ); + return p.GetProperty( GetImpl( p ).mPropertyMinScrollPosition ).Get< float >(); +} + +double ScrollBar::AccessibleImpl::GetCurrent() +{ + auto p = Toolkit::ScrollBar::DownCast( self ); + if( GetImpl( p ).mPropertyScrollPosition == Property::INVALID_INDEX ) + throw Dali::Accessibility::AccessibleError( + "Scroll position is INVALID_INDEX" ); + return p.GetProperty( GetImpl( p ).mPropertyScrollPosition ).Get< float >(); +} + +double ScrollBar::AccessibleImpl::GetMaximum() +{ + auto p = Toolkit::ScrollBar::DownCast( self ); + return p.GetProperty( GetImpl( p ).mPropertyMaxScrollPosition ).Get< float >(); +} + +bool ScrollBar::AccessibleImpl::SetCurrent( double current ) +{ + if( current < GetMinimum() || current > GetMaximum() ) + return false; + auto p = Toolkit::ScrollBar::DownCast( self ); + p.SetProperty( GetImpl( p ).mPropertyScrollPosition, + static_cast< float >( current ) ); + return true; +} + +double ScrollBar::AccessibleImpl::GetMinimumIncrement() { return 0.001; } + } // namespace Internal } // namespace Toolkit diff --git a/dali-toolkit/internal/controls/scroll-bar/scroll-bar-impl.h b/dali-toolkit/internal/controls/scroll-bar/scroll-bar-impl.h old mode 100755 new mode 100644 index d95d190..6b022d5 --- a/dali-toolkit/internal/controls/scroll-bar/scroll-bar-impl.h +++ b/dali-toolkit/internal/controls/scroll-bar/scroll-bar-impl.h @@ -319,6 +319,18 @@ private: bool mIsPanning : 1; ///< Whether the scroll bar is being panned. bool mIndicatorFirstShow : 1; ///< True if the indicator has never been shown + +protected: + struct AccessibleImpl : public Control::AccessibleImpl, + public virtual Dali::Accessibility::Value + { + using Control::AccessibleImpl::AccessibleImpl; + double GetMinimum() override; + double GetCurrent() override; + double GetMaximum() override; + bool SetCurrent( double ) override; + double GetMinimumIncrement() override; + }; }; } // namespace Internal diff --git a/dali-toolkit/internal/controls/slider/slider-impl.cpp b/dali-toolkit/internal/controls/slider/slider-impl.cpp old mode 100755 new mode 100644 index 275995d..7c01138 --- a/dali-toolkit/internal/controls/slider/slider-impl.cpp +++ b/dali-toolkit/internal/controls/slider/slider-impl.cpp @@ -158,6 +158,10 @@ Slider::Slider() mShowValue( false ), mSnapToMarks( false ) { + SetAccessibilityConstructor( []( Dali::Actor actor ) { + return std::unique_ptr< Dali::Accessibility::Accessible >( + new AccessibleImpl( actor, Dali::Accessibility::Role::Slider ) ); + } ); } Slider::~Slider() @@ -1407,6 +1411,39 @@ Property::Value Slider::GetProperty( BaseObject* object, Property::Index propert return value; } +double Slider::AccessibleImpl::GetMinimum() +{ + auto p = Toolkit::Slider::DownCast( self ); + return p.GetProperty( GetImpl( p ).mLowerBound ).Get< float >(); +} + +double Slider::AccessibleImpl::GetCurrent() +{ + auto p = Toolkit::Slider::DownCast( self ); + return p.GetProperty( GetImpl( p ).mValue ).Get< float >(); +} + +double Slider::AccessibleImpl::GetMaximum() +{ + auto p = Toolkit::Slider::DownCast( self ); + return p.GetProperty( GetImpl( p ).mValue ).Get< float >(); +} + +bool Slider::AccessibleImpl::SetCurrent( double current ) +{ + if( current < GetMinimum() || current > GetMaximum() ) + return false; + auto p = Toolkit::Slider::DownCast( self ); + p.SetProperty( GetImpl( p ).mValue, static_cast< float >( current ) ); + return true; +} + +double Slider::AccessibleImpl::GetMinimumIncrement() +{ + auto p = Toolkit::Slider::DownCast( self ); + return p.GetProperty( GetImpl( p ).mMarkTolerance ).Get< float >(); +} + } // namespace Internal } // namespace Toolkit diff --git a/dali-toolkit/internal/controls/slider/slider-impl.h b/dali-toolkit/internal/controls/slider/slider-impl.h old mode 100755 new mode 100644 index cbb23b0..e7a9d47 --- a/dali-toolkit/internal/controls/slider/slider-impl.h +++ b/dali-toolkit/internal/controls/slider/slider-impl.h @@ -755,6 +755,18 @@ private: bool mShowPopup : 1, ///< Show the popup or not mShowValue : 1, ///< Whether to display the value number or not on the handle mSnapToMarks : 1; ///< Turn on or off snapping to marks + +protected: + struct AccessibleImpl : public Control::AccessibleImpl, + public virtual Dali::Accessibility::Value + { + using Control::AccessibleImpl::AccessibleImpl; + double GetMinimum() override; + double GetCurrent() override; + double GetMaximum() override; + bool SetCurrent( double ) override; + double GetMinimumIncrement() override; + }; }; } // namespace Internal diff --git a/dali-toolkit/internal/controls/text-controls/text-editor-impl.cpp b/dali-toolkit/internal/controls/text-controls/text-editor-impl.cpp index 20fd25c..e0722ab 100644 --- a/dali-toolkit/internal/controls/text-controls/text-editor-impl.cpp +++ b/dali-toolkit/internal/controls/text-controls/text-editor-impl.cpp @@ -513,9 +513,9 @@ void TextEditor::SetProperty( BaseObject* object, Property::Index index, const P if( impl.mController ) { - // The line spacing isn't supported by the TextEditor. Since it's supported - // by the TextLabel for now it must be ignored. The property is being shadowed - // locally so its value isn't affected. + // The line spacing isn't supported by the TextEditor. Since it's + // supported by the TextEditor for now it must be ignored. The + // property is being shadowed locally so its value isn't affected. const float lineSpacing = value.Get(); impl.mLineSpacing = lineSpacing; // set it to 0.0 due to missing implementation @@ -1150,6 +1150,8 @@ Property::Value TextEditor::GetProperty( BaseObject* object, Property::Index ind return value; } +Text::ControllerPtr TextEditor::getController() { return mController; } + bool TextEditor::DoConnectSignal( BaseObject* object, ConnectionTrackerInterface* tracker, const std::string& signalName, FunctorDelegate* functor ) { Dali::BaseHandle handle( object ); @@ -1834,6 +1836,10 @@ TextEditor::TextEditor() mScrollBarEnabled( false ), mScrollStarted( false ) { + SetAccessibilityConstructor( []( Dali::Actor actor ) { + return std::unique_ptr< Dali::Accessibility::Accessible >( + new AccessibleImpl( actor, Dali::Accessibility::Role::Text ) ); + } ); } TextEditor::~TextEditor() @@ -1847,6 +1853,97 @@ TextEditor::~TextEditor() } } +std::string TextEditor::AccessibleImpl::GetName() +{ + auto slf = Toolkit::TextEditor::DownCast( self ); + return slf.GetProperty( Toolkit::TextEditor::Property::TEXT ) + .Get< std::string >(); +} + +std::string TextEditor::AccessibleImpl::GetText( size_t startOffset, + size_t endOffset ) +{ + if( endOffset <= startOffset ) + return {}; + + auto slf = Toolkit::TextEditor::DownCast( self ); + auto txt = + slf.GetProperty( Toolkit::TextEditor::Property::TEXT ).Get< std::string >(); + + if( txt.size() > startOffset || txt.size() > endOffset ) + return {}; + + return txt.substr( startOffset, endOffset - startOffset ); +} + +size_t TextEditor::AccessibleImpl::GetCharacterCount() +{ + auto slf = Toolkit::TextEditor::DownCast( self ); + auto txt = + slf.GetProperty( Toolkit::TextEditor::Property::TEXT ).Get< std::string >(); + + return txt.size(); +} + +Dali::Accessibility::Range TextEditor::AccessibleImpl::GetTextAtOffset( + size_t offset, Dali::Accessibility::TextBoundary boundary ) +{ + return {}; +} + +Dali::Accessibility::Range +TextEditor::AccessibleImpl::GetSelection( size_t selectionNum ) +{ + // Since DALi supports only one selection indexes higher than 0 are ignored + if( selectionNum > 0 ) + return {}; + + auto slf = Toolkit::TextEditor::DownCast( self ); + std::string ret; + Dali::Toolkit::GetImpl( slf ).getController()->RetrieveSelection( ret ); + + return Dali::Accessibility::Range( 0, ret.size(), ret ); +} + +bool TextEditor::AccessibleImpl::RemoveSelection( size_t selectionNum ) +{ + // Since DALi supports only one selection indexes higher than 0 are ignored + if( selectionNum > 0 ) + return false; + + auto slf = Toolkit::TextEditor::DownCast( self ); + std::string ret; + Dali::Toolkit::GetImpl( slf ).getController()->SetSelection( 0, 0 ); + return true; +} + +bool TextEditor::AccessibleImpl::SetSelection( size_t selectionNum, + size_t startOffset, + size_t endOffset ) +{ + // Since DALi supports only one selection indexes higher than 0 are ignored + if( selectionNum > 0 ) + return false; + + auto slf = Toolkit::TextEditor::DownCast( self ); + std::string ret; + Dali::Toolkit::GetImpl( slf ).getController()->SetSelection( startOffset, + endOffset ); + return true; +} + +bool TextEditor::AccessibleImpl::CopyText( size_t startPosition, + size_t endPosition ) +{ + return {}; +} + +bool TextEditor::AccessibleImpl::CutText( size_t startPosition, + size_t endPosition ) +{ + return {}; +} + } // namespace Internal } // namespace Toolkit diff --git a/dali-toolkit/internal/controls/text-controls/text-editor-impl.h b/dali-toolkit/internal/controls/text-controls/text-editor-impl.h index a3a8854..1e8cfdd 100644 --- a/dali-toolkit/internal/controls/text-controls/text-editor-impl.h +++ b/dali-toolkit/internal/controls/text-controls/text-editor-impl.h @@ -20,6 +20,7 @@ // EXTERNAL INCLUDES #include +#include #include // INTERNAL INCLUDES @@ -191,6 +192,8 @@ private: // From Control */ virtual void AddDecoration( Actor& actor, bool needsClipping ); + Text::ControllerPtr getController(); + private: // Implementation /** @@ -306,6 +309,26 @@ private: // Data bool mScrollAnimationEnabled:1; bool mScrollBarEnabled:1; bool mScrollStarted:1; + + struct AccessibleImpl : public Control::AccessibleImpl, + public virtual Dali::Accessibility::Text, + public virtual Dali::Accessibility::EditableText + { + using Control::AccessibleImpl::AccessibleImpl; + + std::string GetName() override; + std::string GetText( size_t startOffset, size_t endOffset ) override; + size_t GetCharacterCount() override; + Dali::Accessibility::Range + GetTextAtOffset( size_t offset, + Dali::Accessibility::TextBoundary boundary ) override; + Dali::Accessibility::Range GetSelection( size_t selectionNum ) override; + bool RemoveSelection( size_t selectionNum ) override; + bool SetSelection( size_t selectionNum, size_t startOffset, + size_t endOffset ) override; + bool CopyText( size_t startPosition, size_t endPosition ) override; + bool CutText( size_t startPosition, size_t endPosition ) override; + }; }; } // namespace Internal diff --git a/dali-toolkit/internal/controls/text-controls/text-field-impl.cpp b/dali-toolkit/internal/controls/text-controls/text-field-impl.cpp index 137d0c4..20fa1b8 100644 --- a/dali-toolkit/internal/controls/text-controls/text-field-impl.cpp +++ b/dali-toolkit/internal/controls/text-controls/text-field-impl.cpp @@ -1431,6 +1431,8 @@ void TextField::OnRelayout( const Vector2& size, RelayoutContainer& container ) } } +Text::ControllerPtr TextField::getController() { return mController; } + void TextField::RenderText( Text::Controller::UpdateTextType updateTextType ) { Actor renderableActor; @@ -1795,6 +1797,10 @@ TextField::TextField() mExceedPolicy( Dali::Toolkit::TextField::EXCEED_POLICY_CLIP ), mHasBeenStaged( false ) { + SetAccessibilityConstructor( []( Dali::Actor actor ) { + return std::unique_ptr< Dali::Accessibility::Accessible >( + new AccessibleImpl( actor, Dali::Accessibility::Role::Text ) ); + } ); } TextField::~TextField() @@ -1807,6 +1813,115 @@ TextField::~TextField() } } +std::string TextField::AccessibleImpl::GetName() +{ + auto slf = Toolkit::TextField::DownCast( self ); + return slf.GetProperty( Toolkit::TextField::Property::TEXT ).Get< std::string >(); +} + +std::string TextField::AccessibleImpl::GetText( size_t startOffset, + size_t endOffset ) +{ + if( endOffset <= startOffset ) + return {}; + + auto slf = Toolkit::TextField::DownCast( self ); + auto txt = + slf.GetProperty( Toolkit::TextField::Property::TEXT ).Get< std::string >(); + + if( txt.size() > startOffset || txt.size() > endOffset ) + return {}; + + return txt.substr( startOffset, endOffset - startOffset ); +} + +size_t TextField::AccessibleImpl::GetCharacterCount() +{ + auto slf = Toolkit::TextField::DownCast( self ); + auto txt = + slf.GetProperty( Toolkit::TextField::Property::TEXT ).Get< std::string >(); + + return txt.size(); +} + +Dali::Accessibility::Range TextField::AccessibleImpl::GetTextAtOffset( + size_t offset, Dali::Accessibility::TextBoundary boundary ) +{ + return {}; +} + +Dali::Accessibility::Range +TextField::AccessibleImpl::GetSelection( size_t selectionNum ) +{ + // Since DALi supports only one selection indexes higher than 0 are ignored + if( selectionNum > 0 ) + return {}; + + auto slf = Toolkit::TextField::DownCast( self ); + std::string ret; + Dali::Toolkit::GetImpl( slf ).getController()->RetrieveSelection( ret ); + + return Dali::Accessibility::Range( 0, ret.size(), ret ); +} + +bool TextField::AccessibleImpl::RemoveSelection( size_t selectionNum ) +{ + // Since DALi supports only one selection indexes higher than 0 are ignored + if( selectionNum > 0 ) + return false; + + auto slf = Toolkit::TextField::DownCast( self ); + std::string ret; + Dali::Toolkit::GetImpl( slf ).getController()->SetSelection( 0, 0 ); + return true; +} + +bool TextField::AccessibleImpl::SetSelection( size_t selectionNum, + size_t startOffset, + size_t endOffset ) +{ + // Since DALi supports only one selection indexes higher than 0 are ignored + if( selectionNum > 0 ) + return false; + + auto slf = Toolkit::TextField::DownCast( self ); + std::string ret; + Dali::Toolkit::GetImpl( slf ).getController()->SetSelection( startOffset, + endOffset ); + return true; +} + +bool TextField::AccessibleImpl::CopyText( size_t startPosition, + size_t endPosition ) +{ + if( endPosition <= startPosition ) + return false; + + auto t = GetText( startPosition, endPosition ); + auto slf = Toolkit::TextField::DownCast( self ); + std::string ret; + Dali::Toolkit::GetImpl( slf ).getController()->CopyStringToClipboard( t ); + + return true; +} + +bool TextField::AccessibleImpl::CutText( size_t startPosition, + size_t endPosition ) +{ + if( endPosition <= startPosition ) + return false; + + auto txt = GetText( startPosition, endPosition ); + auto slf = Toolkit::TextField::DownCast( self ); + std::string ret; + Dali::Toolkit::GetImpl( slf ).getController()->CopyStringToClipboard( txt ); + + slf.SetProperty( Toolkit::TextField::Property::TEXT, + txt.substr( startPosition, endPosition - startPosition ) ); + + return true; +} + } // namespace Internal } // namespace Toolkit diff --git a/dali-toolkit/internal/controls/text-controls/text-field-impl.h b/dali-toolkit/internal/controls/text-controls/text-field-impl.h index b8f49ee..6a6be64 100644 --- a/dali-toolkit/internal/controls/text-controls/text-field-impl.h +++ b/dali-toolkit/internal/controls/text-controls/text-field-impl.h @@ -97,6 +97,8 @@ public: */ Toolkit::TextField::InputStyleChangedSignalType& InputStyleChangedSignal(); + Text::ControllerPtr getController(); + private: // From Control /** @@ -281,6 +283,27 @@ private: // Data int mRenderingBackend; int mExceedPolicy; bool mHasBeenStaged:1; + +protected: + struct AccessibleImpl : public Control::AccessibleImpl, + public virtual Dali::Accessibility::Text, + public virtual Dali::Accessibility::EditableText + { + using Control::AccessibleImpl::AccessibleImpl; + + std::string GetName() override; + std::string GetText( size_t startOffset, size_t endOffset ) override; + size_t GetCharacterCount() override; + Dali::Accessibility::Range + GetTextAtOffset( size_t offset, + Dali::Accessibility::TextBoundary boundary ) override; + Dali::Accessibility::Range GetSelection( size_t selectionNum ) override; + bool RemoveSelection( size_t selectionNum ) override; + bool SetSelection( size_t selectionNum, size_t startOffset, + size_t endOffset ) override; + bool CopyText( size_t startPosition, size_t endPosition ) override; + bool CutText( size_t startPosition, size_t endPosition ) override; + }; }; } // namespace Internal diff --git a/dali-toolkit/internal/controls/text-controls/text-label-impl.cpp b/dali-toolkit/internal/controls/text-controls/text-label-impl.cpp index c3607f5..591e614 100644 --- a/dali-toolkit/internal/controls/text-controls/text-label-impl.cpp +++ b/dali-toolkit/internal/controls/text-controls/text-label-impl.cpp @@ -544,12 +544,10 @@ void TextLabel::SetProperty( BaseObject* object, Property::Index index, const Pr impl.RequestTextRelayout(); } } - - - - } +Text::ControllerPtr TextLabel::getController() { return mController; } + Property::Value TextLabel::GetProperty( BaseObject* object, Property::Index index ) { Property::Value value; @@ -1085,12 +1083,94 @@ TextLabel::TextLabel() mRenderingBackend( DEFAULT_RENDERING_BACKEND ), mTextUpdateNeeded( false ) { + SetAccessibilityConstructor( []( Dali::Actor actor ) { + return std::unique_ptr< Dali::Accessibility::Accessible >( + new AccessibleImpl( actor, Dali::Accessibility::Role::Label ) ); + } ); } TextLabel::~TextLabel() { } +std::string TextLabel::AccessibleImpl::GetName() +{ + auto slf = Toolkit::TextLabel::DownCast( self ); + return slf.GetProperty( Toolkit::TextLabel::Property::TEXT ).Get< std::string >(); +} + +std::string TextLabel::AccessibleImpl::GetText( size_t startOffset, + size_t endOffset ) +{ + if( endOffset <= startOffset ) + return {}; + + auto slf = Toolkit::TextLabel::DownCast( self ); + auto txt = + slf.GetProperty( Toolkit::TextLabel::Property::TEXT ).Get< std::string >(); + + if( txt.size() > startOffset || txt.size() > endOffset ) + return {}; + + return txt.substr( startOffset, endOffset - startOffset ); +} + +size_t TextLabel::AccessibleImpl::GetCharacterCount() +{ + auto slf = Toolkit::TextLabel::DownCast( self ); + auto txt = + slf.GetProperty( Toolkit::TextLabel::Property::TEXT ).Get< std::string >(); + + return txt.size(); +} + +Dali::Accessibility::Range TextLabel::AccessibleImpl::GetTextAtOffset( + size_t offset, Dali::Accessibility::TextBoundary boundary ) +{ + return {}; +} + +Dali::Accessibility::Range +TextLabel::AccessibleImpl::GetSelection( size_t selectionNum ) +{ + // Since DALi supports only one selection indexes higher than 0 are ignored + if( selectionNum > 0 ) + return {}; + + auto slf = Toolkit::TextLabel::DownCast( self ); + std::string ret; + Dali::Toolkit::GetImpl( slf ).getController()->RetrieveSelection( ret ); + + return Dali::Accessibility::Range( 0, ret.size(), ret ); +} + +bool TextLabel::AccessibleImpl::RemoveSelection( size_t selectionNum ) +{ + // Since DALi supports only one selection indexes higher than 0 are ignored + if( selectionNum > 0 ) + return false; + + auto slf = Toolkit::TextLabel::DownCast( self ); + std::string ret; + Dali::Toolkit::GetImpl( slf ).getController()->SetSelection( 0, 0 ); + return true; +} + +bool TextLabel::AccessibleImpl::SetSelection( size_t selectionNum, + size_t startOffset, + size_t endOffset ) +{ + // Since DALi supports only one selection indexes higher than 0 are ignored + if( selectionNum > 0 ) + return false; + + auto slf = Toolkit::TextLabel::DownCast( self ); + std::string ret; + Dali::Toolkit::GetImpl( slf ).getController()->SetSelection( startOffset, + endOffset ); + return true; +} + } // namespace Internal } // namespace Toolkit diff --git a/dali-toolkit/internal/controls/text-controls/text-label-impl.h b/dali-toolkit/internal/controls/text-controls/text-label-impl.h index 85e94ab..b98456a 100644 --- a/dali-toolkit/internal/controls/text-controls/text-label-impl.h +++ b/dali-toolkit/internal/controls/text-controls/text-label-impl.h @@ -73,6 +73,8 @@ public: */ static Property::Value GetProperty( BaseObject* object, Property::Index index ); + Text::ControllerPtr getController(); + private: // From Control /** @@ -151,6 +153,24 @@ private: // Data int mRenderingBackend; bool mTextUpdateNeeded:1; + +protected: + struct AccessibleImpl : public Control::AccessibleImpl, + public virtual Dali::Accessibility::Text + { + using Control::AccessibleImpl::AccessibleImpl; + + std::string GetName() override; + std::string GetText( size_t startOffset, size_t endOffset ) override; + size_t GetCharacterCount() override; + Dali::Accessibility::Range + GetTextAtOffset( size_t offset, + Dali::Accessibility::TextBoundary boundary ) override; + Dali::Accessibility::Range GetSelection( size_t selectionNum ) override; + bool RemoveSelection( size_t selectionNum ) override; + bool SetSelection( size_t selectionNum, size_t startOffset, + size_t endOffset ) override; + }; }; } // namespace Internal diff --git a/dali-toolkit/internal/controls/text-controls/text-selection-popup-impl.cpp b/dali-toolkit/internal/controls/text-controls/text-selection-popup-impl.cpp index 26b14b6..2bbba0e 100644 --- a/dali-toolkit/internal/controls/text-controls/text-selection-popup-impl.cpp +++ b/dali-toolkit/internal/controls/text-controls/text-selection-popup-impl.cpp @@ -884,6 +884,10 @@ TextSelectionPopup::TextSelectionPopup( TextSelectionPopupCallbackInterface* cal TextSelectionPopup::~TextSelectionPopup() { + SetAccessibilityConstructor( []( Dali::Actor actor ) { + return std::unique_ptr< Dali::Accessibility::Accessible >( + new AccessibleImpl( actor, Dali::Accessibility::Role::Dialog, true ) ); + } ); } diff --git a/dali-toolkit/internal/focus-manager/keyboard-focus-manager-impl.cpp b/dali-toolkit/internal/focus-manager/keyboard-focus-manager-impl.cpp old mode 100644 new mode 100755 diff --git a/dali-toolkit/internal/text/text-controller-impl.cpp b/dali-toolkit/internal/text/text-controller-impl.cpp index 5f34488..5275627 100644 --- a/dali-toolkit/internal/text/text-controller-impl.cpp +++ b/dali-toolkit/internal/text/text-controller-impl.cpp @@ -1935,6 +1935,13 @@ void Controller::Impl::RetrieveSelection( std::string& selectedText, bool delete } } +void Controller::Impl::SetSelection( int start, int end ) +{ + mEventData->mLeftSelectionPosition = start; + mEventData->mRightSelectionPosition = end; + mEventData->mUpdateCursorPosition = true; +} + void Controller::Impl::ShowClipboard() { if( mClipboard ) diff --git a/dali-toolkit/internal/text/text-controller-impl.h b/dali-toolkit/internal/text/text-controller-impl.h index 52dad25..8d3690b 100644 --- a/dali-toolkit/internal/text/text-controller-impl.h +++ b/dali-toolkit/internal/text/text-controller-impl.h @@ -614,6 +614,8 @@ struct Controller::Impl */ void RetrieveSelection( std::string& selectedText, bool deleteAfterRetrieval ); + void SetSelection( int start, int end ); + void ShowClipboard(); void HideClipboard(); diff --git a/dali-toolkit/internal/text/text-controller.cpp b/dali-toolkit/internal/text/text-controller.cpp old mode 100755 new mode 100644 index f47b526..f1af74e --- a/dali-toolkit/internal/text/text-controller.cpp +++ b/dali-toolkit/internal/text/text-controller.cpp @@ -661,6 +661,26 @@ void Controller::UpdateAfterFontChange( const std::string& newDefaultFont ) } } +void Controller::RetrieveSelection( std::string& selectedText ) +{ + mImpl->RetrieveSelection( selectedText, false ); +} + +void Controller::SetSelection( int start, int end ) +{ + mImpl->SetSelection( start, end ); +} + +void Controller::CopyStringToClipboard( std::string& source ) +{ + mImpl->CopyStringToClipboard( source ); +} + +void Controller::SendSelectionToClipboard( bool deleteAfterSending ) +{ + mImpl->SendSelectionToClipboard( deleteAfterSending ); +} + // public : Default style & Input style void Controller::SetDefaultFontFamily( const std::string& defaultFontFamily ) diff --git a/dali-toolkit/internal/text/text-controller.h b/dali-toolkit/internal/text/text-controller.h old mode 100755 new mode 100644 index b2321c4..478d797 --- a/dali-toolkit/internal/text/text-controller.h +++ b/dali-toolkit/internal/text/text-controller.h @@ -550,6 +550,14 @@ public: // Update. */ void UpdateAfterFontChange( const std::string& newDefaultFont ); + void RetrieveSelection( std::string& selectedText ); + + void SetSelection( int start, int end ); + + void CopyStringToClipboard( std::string& source ); + + void SendSelectionToClipboard( bool deleteAfterSending ); + public: // Default style & Input style /** diff --git a/dali-toolkit/public-api/controls/control-impl.cpp b/dali-toolkit/public-api/controls/control-impl.cpp old mode 100755 new mode 100644 index 49064a8..50d1e9a --- a/dali-toolkit/public-api/controls/control-impl.cpp +++ b/dali-toolkit/public-api/controls/control-impl.cpp @@ -25,9 +25,13 @@ #include #include #include +#include #include +#include #include #include +#include +#include // INTERNAL INCLUDES #include @@ -44,6 +48,7 @@ #include #include #include +#include namespace Dali { @@ -485,6 +490,13 @@ Control::Control( ControlBehaviour behaviourFlags ) mImpl(new Impl(*this)) { mImpl->mFlags = behaviourFlags; + SetAccessibilityConstructor( + []( Dali::Actor actor ) + -> std::unique_ptr< Dali::Accessibility::Accessible > { + return std::unique_ptr< Dali::Accessibility::Accessible >( + new AccessibleImpl( actor, + Dali::Accessibility::Role::RedundantObject ) ); + } ); } Control::~Control() @@ -519,6 +531,11 @@ void Control::Initialize() { SetKeyboardNavigationSupport( true ); } + + Dali::TypeInfo type; + Self().GetTypeInfo( type ); + auto type_name = type.GetName(); + AccessibilitySetAttribute( "t", type_name ); } void Control::OnInitialize() @@ -802,6 +819,275 @@ const Control& GetImplementation( const Dali::Toolkit::Control& handle ) return impl; } +Toolkit::Control::AccessibilityActivateSignalType &Control::AccessibilityActivateSignal() +{ + return mImpl->mAccessibilityActivateSignal; +} + +Dali::Accessibility::Accessible *Control::GetAccessibilityObject(Dali::Actor actor) +{ + if( actor ) + { + auto q = Dali::Toolkit::Control::DownCast( actor ); + if( q ) + { + auto q2 = static_cast< Internal::Control* >( &q.GetImplementation() ); + if( !q2->mImpl->accessibilityObject ) + q2->mImpl->accessibilityObject = + q2->mImpl->accessibilityConstructor( actor ); + return q2->mImpl->accessibilityObject.get(); + } + } + return nullptr; +} + +void Control::SetAccessibilityConstructor( + std::function< std::unique_ptr< Dali::Accessibility::Accessible >( Dali::Actor ) > + constructor ) +{ + mImpl->accessibilityConstructor = constructor; +} + +std::string Control::AccessibleImpl::GetName() { return self.GetName(); } +std::string Control::AccessibleImpl::GetDescription() { return ""; } +Dali::Accessibility::Accessible* Control::AccessibleImpl::GetParent() +{ + return Dali::Accessibility::Accessible::Get( self.GetParent() ); +} +size_t Control::AccessibleImpl::GetChildCount() { return self.GetChildCount(); } +Dali::Accessibility::Accessible* +Control::AccessibleImpl::GetChildAtIndex( size_t index ) +{ + return Dali::Accessibility::Accessible::Get( + self.GetChildAt( static_cast< unsigned int >( index ) ) ); +} +size_t Control::AccessibleImpl::GetIndexInParent() +{ + auto s = self; + auto parent = s.GetParent(); + if( !parent ) + throw Dali::Accessibility::AccessibleError( + "can't call GetIndexInParent on object '" + GetAddress().ToString() + + "' without parent" ); + auto count = parent.GetChildCount(); + for( auto i = 0u; i < count; ++i ) + { + auto c = parent.GetChildAt( i ); + if( c == s ) + return i; + } + throw Dali::Accessibility::AccessibleError( + "object '" + GetAddress().ToString() + "' isn't child of it's parent" ); +} + +Dali::Accessibility::Role Control::AccessibleImpl::GetRole() { return role; } + +void Control::AccessibilitySetAttribute( const std::string& key, + const std::string value ) +{ + return mImpl->AccessibilitySetAttribute( key, value ); +} + +std::string Control::AccessibilityGetAttribute( const std::string& key ) +{ + return mImpl->AccessibilityGetAttribute( key ); +} + +void Control::AccessibilityEraseAttribute( std::string& key ) +{ + return mImpl->AccessibilityEraseAttribute( key ); +} + +bool Control::AccessibleImpl::CalculateIsVisible() const +{ + auto parent = self.GetParent(); + if( parent ) + { + auto p = Accessible::Get( parent ); + auto p2 = dynamic_cast< AccessibleImpl* >( p ); + if( p2 && !p2->CalculateIsVisible() ) + return false; + } + auto stage = Stage::GetCurrent(); + if( stage && self.OnStage() ) + { + auto position = + self.GetProperty( Dali::DevelActor::Property::SCREEN_POSITION ) + .Get< Vector2 >(); + auto size = stage.GetSize(); + if( position.x >= 0 && position.x < size.x ) + return true; + } + return false; +} + +Dali::Accessibility::States Control::AccessibleImpl::CalculateStates() +{ + Dali::Accessibility::States s; + s[Dali::Accessibility::State::Highlightable] = true; + s[Dali::Accessibility::State::Enabled] = true; + s[Dali::Accessibility::State::Sensitive] = true; + if( self.IsVisible() ) + s[Dali::Accessibility::State::Showing] = true; + if( modal ) + { + s[Dali::Accessibility::State::Modal] = true; + } + s[Dali::Accessibility::State::Visible] = CalculateIsVisible(); + auto am = Toolkit::AccessibilityManager::Get(); + if( self == am.GetCurrentFocusActor() ) + s[Dali::Accessibility::State::Highlighted] = true; + return s; +} + +Dali::Accessibility::States Control::AccessibleImpl::GetStates() +{ + return CalculateStates(); +} + +Dali::Accessibility::Attributes Control::AccessibleImpl::GetAttributes() +{ + std::unordered_map< std::string, std::string > attribute_map; + auto q = Dali::Toolkit::Control::DownCast( self ); + auto w = + q.GetProperty( Dali::Toolkit::Control::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::AccessibleImpl::GetLayer() +{ + return Dali::Accessibility::ComponentLayer::Window; +} + +Dali::Accessibility::Rectangle +Control::AccessibleImpl::GetExtents( Dali::Accessibility::CoordType ctype ) +{ + Vector2 screenPosition = + self.GetProperty( Dali::DevelActor::Property::SCREEN_POSITION ) + .Get< Vector2 >(); + Vector3 size = self.GetCurrentSize() * self.GetCurrentWorldScale(); + bool positionUsesAnchorPoint = + self.GetProperty( Dali::DevelActor::Property::POSITION_USES_ANCHOR_POINT ) + .Get< bool >(); + Vector3 anchorPointOffSet = + size * ( positionUsesAnchorPoint ? self.GetCurrentAnchorPoint() + : AnchorPoint::TOP_LEFT ); + Vector2 position = Vector2( screenPosition.x - anchorPointOffSet.x, + screenPosition.y - anchorPointOffSet.y ); + + return {Dali::Accessibility::Point( (int)position.x, (int)position.y ), + Dali::Accessibility::Size( (int)size.x, (int)size.y )}; +} + +int Control::AccessibleImpl::GetMdiZOrder() { return 0; } +bool Control::AccessibleImpl::GrabFocus() { return false; } +double Control::AccessibleImpl::GetAlpha() { return 0; } +bool Control::AccessibleImpl::SetExtents( Dali::Accessibility::Rectangle rect, + Dali::Accessibility::CoordType ctype ) +{ + return false; +} +bool Control::AccessibleImpl::GrabHighlight() +{ + auto am = Toolkit::AccessibilityManager::Get(); + auto old = am.GetCurrentFocusActor(); + if( old != self ) + { + if( old ) + { + auto c = dynamic_cast< Dali::Accessibility::Component* >( + GetAccessibilityObject( old ) ); + if( c ) + c->ClearHighlight(); + } + return am.SetCurrentFocusActor( self ); + } + return false; +} +bool Control::AccessibleImpl::ClearHighlight() +{ + auto am = Toolkit::AccessibilityManager::Get(); + if( am.GetCurrentFocusActor() == self ) + { + am.ClearFocus(); + return true; + } + return false; +} +int Control::AccessibleImpl::GetHighlightIndex() { return 0; } + +std::string Control::AccessibleImpl::GetActionName( size_t index ) +{ + if( index >= GetActionCount() ) + throw Dali::Accessibility::AccessibleError( + "index " + std::to_string( index ) + " is too large for action count " + + std::to_string( GetActionCount() ) ); + Dali::TypeInfo type; + self.GetTypeInfo( type ); + if( !type ) + throw Dali::Accessibility::AccessibleError( + "GetActionName failed for object '" + GetAddress().ToString() + + "' due to the lack of TypeInfo." ); + return type.GetActionName( index ); +} +std::string Control::AccessibleImpl::GetLocalizedActionName( size_t index ) +{ + // TODO: add localization + return GetActionName( index ); +} +std::string Control::AccessibleImpl::GetActionDescription( size_t index ) +{ + if( index >= GetActionCount() ) + throw Dali::Accessibility::AccessibleError( + "index " + std::to_string( index ) + " is too large for action count " + + std::to_string( GetActionCount() ) ); + return ""; +} +size_t Control::AccessibleImpl::GetActionCount() +{ + Dali::TypeInfo type; + self.GetTypeInfo( type ); + if( !type ) + throw Dali::Accessibility::AccessibleError( + "GetActionCount failed for object '" + GetAddress().ToString() + + "' due to the lack of TypeInfo." ); + return type.GetActionCount(); +} +std::string Control::AccessibleImpl::GetActionKeyBinding( size_t index ) +{ + if( index >= GetActionCount() ) + throw Dali::Accessibility::AccessibleError( + "index " + std::to_string( index ) + " is too large for action count " + + std::to_string( GetActionCount() ) ); + return ""; +} +bool Control::AccessibleImpl::DoAction( size_t index ) +{ + std::string actionName = GetActionName( index ); + return self.DoAction( actionName, {} ); +} + } // namespace Internal } // namespace Toolkit diff --git a/dali-toolkit/public-api/controls/control-impl.h b/dali-toolkit/public-api/controls/control-impl.h index 9a1e560..4cf3f2a 100644 --- a/dali-toolkit/public-api/controls/control-impl.h +++ b/dali-toolkit/public-api/controls/control-impl.h @@ -19,6 +19,8 @@ */ // EXTERNAL INCLUDES +#include +#include #include #include #include @@ -30,6 +32,10 @@ // INTERNAL INCLUDES #include +#include +#include +#include + namespace Dali { namespace Toolkit @@ -690,7 +696,55 @@ public: private: Impl* mImpl; /// @endcond - +public: + void SetAccessibilityConstructor(std::function(Dali::Actor)> constructor); + static Dali::Accessibility::Accessible *GetAccessibilityObject(Dali::Actor actor); + Toolkit::Control::AccessibilityActivateSignalType &AccessibilityActivateSignal(); + void AccessibilitySetAttribute( const std::string& key, const std::string value ); + std::string AccessibilityGetAttribute( const std::string& key ); + void AccessibilityEraseAttribute( std::string& key ); + + struct AccessibleImpl : public virtual Dali::Accessibility::Accessible, public virtual Dali::Accessibility::Component, public virtual Dali::Accessibility::Collection, + public virtual Dali::Accessibility::Action { + Dali::Actor self; + Dali::Accessibility::Role role; + bool modal = false, root = false; + + AccessibleImpl( Dali::Actor self, Dali::Accessibility::Role role, + bool modal = false ) + : self( self ), role( role ), modal( modal ) {} + + std::string GetName() override; + std::string GetDescription() override; + Dali::Accessibility::Accessible* GetParent() override; + size_t GetChildCount() override; + Dali::Accessibility::Accessible* GetChildAtIndex( size_t index ) override; + size_t GetIndexInParent() override; + Dali::Accessibility::Role GetRole() override; + Dali::Accessibility::States GetStates() override; + Dali::Accessibility::Attributes GetAttributes() override; + Dali::Accessibility::Rectangle + GetExtents( Dali::Accessibility::CoordType ctype ) override; + Dali::Accessibility::ComponentLayer GetLayer() override; + int GetMdiZOrder() override; + bool GrabFocus() override; + double GetAlpha() override; + bool SetExtents( Dali::Accessibility::Rectangle rect, + Dali::Accessibility::CoordType ctype ) override; + bool GrabHighlight() override; + bool ClearHighlight() override; + int GetHighlightIndex() override; + + std::string GetActionName( size_t index ) override; + std::string GetLocalizedActionName( size_t index ) override; + std::string GetActionDescription( size_t index ) override; + size_t GetActionCount() override; + std::string GetActionKeyBinding( size_t index ) override; + bool DoAction( size_t index ) override; + + virtual Dali::Accessibility::States CalculateStates(); + virtual bool CalculateIsVisible() const; + }; }; /** diff --git a/dali-toolkit/public-api/controls/control.cpp b/dali-toolkit/public-api/controls/control.cpp index 14205f9..5762fff 100644 --- a/dali-toolkit/public-api/controls/control.cpp +++ b/dali-toolkit/public-api/controls/control.cpp @@ -170,6 +170,12 @@ Control::ResourceReadySignalType& Control::ResourceReadySignal() return controlImpl.mResourceReadySignal; } +Control::AccessibilityActivateSignalType& Control::AccessibilityActivateSignal() +{ + return Internal::GetImplementation(*this).AccessibilityActivateSignal(); +} + + Control::Control(Internal::Control& implementation) : CustomActor(implementation) { @@ -181,6 +187,23 @@ Control::Control(Dali::Internal::CustomActor* internal) VerifyCustomActorPointer(internal); } +void Control::AccessibilitySetAttribute( const std::string& key, + const std::string value ) +{ + return Internal::GetImplementation( *this ).AccessibilitySetAttribute( key, + value ); +} + +std::string Control::AccessibilityGetAttribute( const std::string& key ) +{ + return Internal::GetImplementation( *this ).AccessibilityGetAttribute( key ); +} + +void Control::AccessibilityEraseAttribute( std::string& key ) +{ + return Internal::GetImplementation( *this ).AccessibilityEraseAttribute( key ); +} + } // namespace Toolkit } // namespace Dali diff --git a/dali-toolkit/public-api/controls/control.h b/dali-toolkit/public-api/controls/control.h old mode 100644 new mode 100755 index 8e522a2..12aaaf8 --- a/dali-toolkit/public-api/controls/control.h +++ b/dali-toolkit/public-api/controls/control.h @@ -154,6 +154,11 @@ public: MARGIN, /** + * @ TODO + */ + ACCESSIBILITY_ATTRIBUTES, + + /** * @brief The inner space of the control. * @details Name "padding", type Property::EXTENTS. * @SINCE_1_2.62 @@ -194,6 +199,8 @@ public: /// @brief ResourceReady signal type. @SINCE_1_2.60 typedef Signal ResourceReadySignalType; + typedef Signal< void ( ) > AccessibilityActivateSignalType; + public: // Creation & Destruction /** @@ -490,6 +497,8 @@ public: */ ResourceReadySignalType& ResourceReadySignal(); + Toolkit::Control::AccessibilityActivateSignalType &AccessibilityActivateSignal(); + public: // Intended for control developers /** @@ -563,6 +572,10 @@ public: // Templates for Deriving Classes } } + void AccessibilitySetAttribute( const std::string& key, + const std::string value ); + std::string AccessibilityGetAttribute( const std::string& key ); + void AccessibilityEraseAttribute( std::string& key ); }; /** diff --git a/dali-toolkit/public-api/controls/text-controls/text-field.h b/dali-toolkit/public-api/controls/text-controls/text-field.h old mode 100644 new mode 100755