[Tizen][ATSPI] Accessibility initial implementation 73/177273/3
authorRadoslaw Cybulski <r.cybulski@partner.samsung.com>
Wed, 25 Apr 2018 15:47:22 +0000 (17:47 +0200)
committerdongsug.song <dongsug.song@samsung.com>
Mon, 30 Apr 2018 12:46:12 +0000 (21:46 +0900)
Conflicts:
dali-toolkit/public-api/controls/text-controls/text-field.h

Change-Id: Ie3e02898cb53a55515514347b78350095be4aa80

36 files changed:
dali-toolkit/devel-api/controls/control-devel.h [changed mode: 0644->0755]
dali-toolkit/internal/accessibility-manager/accessibility-manager-impl.cpp [changed mode: 0644->0755]
dali-toolkit/internal/controls/buttons/button-impl.cpp
dali-toolkit/internal/controls/buttons/button-impl.h
dali-toolkit/internal/controls/buttons/check-box-button-impl.cpp
dali-toolkit/internal/controls/buttons/push-button-impl.cpp
dali-toolkit/internal/controls/buttons/radio-button-impl.cpp
dali-toolkit/internal/controls/buttons/toggle-button-impl.cpp [changed mode: 0755->0644]
dali-toolkit/internal/controls/control/control-data-impl.cpp [changed mode: 0644->0755]
dali-toolkit/internal/controls/control/control-data-impl.h [changed mode: 0644->0755]
dali-toolkit/internal/controls/image-view/image-view-impl.cpp [changed mode: 0755->0644]
dali-toolkit/internal/controls/popup/confirmation-popup-impl.cpp
dali-toolkit/internal/controls/popup/popup-impl.cpp
dali-toolkit/internal/controls/progress-bar/progress-bar-impl.cpp [changed mode: 0755->0644]
dali-toolkit/internal/controls/progress-bar/progress-bar-impl.h [changed mode: 0755->0644]
dali-toolkit/internal/controls/scroll-bar/scroll-bar-impl.cpp [changed mode: 0755->0644]
dali-toolkit/internal/controls/scroll-bar/scroll-bar-impl.h [changed mode: 0755->0644]
dali-toolkit/internal/controls/slider/slider-impl.cpp [changed mode: 0755->0644]
dali-toolkit/internal/controls/slider/slider-impl.h [changed mode: 0755->0644]
dali-toolkit/internal/controls/text-controls/text-editor-impl.cpp
dali-toolkit/internal/controls/text-controls/text-editor-impl.h
dali-toolkit/internal/controls/text-controls/text-field-impl.cpp
dali-toolkit/internal/controls/text-controls/text-field-impl.h
dali-toolkit/internal/controls/text-controls/text-label-impl.cpp
dali-toolkit/internal/controls/text-controls/text-label-impl.h
dali-toolkit/internal/controls/text-controls/text-selection-popup-impl.cpp
dali-toolkit/internal/focus-manager/keyboard-focus-manager-impl.cpp [changed mode: 0644->0755]
dali-toolkit/internal/text/text-controller-impl.cpp
dali-toolkit/internal/text/text-controller-impl.h
dali-toolkit/internal/text/text-controller.cpp [changed mode: 0755->0644]
dali-toolkit/internal/text/text-controller.h [changed mode: 0755->0644]
dali-toolkit/public-api/controls/control-impl.cpp [changed mode: 0755->0644]
dali-toolkit/public-api/controls/control-impl.h
dali-toolkit/public-api/controls/control.cpp
dali-toolkit/public-api/controls/control.h [changed mode: 0644->0755]
dali-toolkit/public-api/controls/text-controls/text-field.h [changed mode: 0644->0755]

old mode 100644 (file)
new mode 100755 (executable)
index ae90f4d..8d6ce47
@@ -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
index 84dd7a1..9d87e96 100644 (file)
@@ -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
index 8b1417c..eafa843 100644 (file)
@@ -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
index 9554ccb..9c666a5 100644 (file)
@@ -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()
index 1b7f495..2cfb8ab 100644 (file)
@@ -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()
index bbd151a..0e8495f 100644 (file)
@@ -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()
old mode 100755 (executable)
new mode 100644 (file)
index 0ecae06..7299e42
@@ -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()
old mode 100644 (file)
new mode 100755 (executable)
index 369c409..f9e316f
 #include <dali/devel-api/scripting/scripting.h>
 #include <dali/integration-api/debug.h>
 #include <dali/public-api/object/type-registry-helper.h>
+#include <dali/public-api/common/stage.h>
+#include <dali-toolkit/public-api/controls/control.h>
+#include <dali/public-api/object/object-registry.h>
+#include <dali/devel-api/adaptor-framework/accessibility.h>
+#include <dali-toolkit/public-api/controls/control-impl.h>
 #include <cstring>
 #include <limits>
 
@@ -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<Property::Map>& instancedProperties )
 {
old mode 100644 (file)
new mode 100755 (executable)
index ddd7506..f9c3099
@@ -32,6 +32,9 @@
 #include <dali-toolkit/internal/builder/style.h>
 #include <dali-toolkit/internal/builder/dictionary.h>
 #include <dali-toolkit/public-api/visuals/visual-properties.h>
+#include <dali/devel-api/common/owner-container.h>
+#include <dali/integration-api/debug.h>
+#include <memory>
 
 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;
 };
 
 
old mode 100755 (executable)
new mode 100644 (file)
index 8bfa80d..3a9cd53
@@ -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()
index 43758cb..9850ee1 100644 (file)
@@ -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()
index cde648a..493169e 100644 (file)
@@ -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()
old mode 100755 (executable)
new mode 100644 (file)
index 2b89fed..fb6c1b4
@@ -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
old mode 100755 (executable)
new mode 100644 (file)
index 5b0ffd2..fbdf53b
@@ -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
old mode 100755 (executable)
new mode 100644 (file)
index cd8438e..83cd71e
@@ -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
old mode 100755 (executable)
new mode 100644 (file)
index d95d190..6b022d5
@@ -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
old mode 100755 (executable)
new mode 100644 (file)
index 275995d..7c01138
@@ -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
old mode 100755 (executable)
new mode 100644 (file)
index cbb23b0..e7a9d47
@@ -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
index 20fd25c..e0722ab 100644 (file)
@@ -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<float>();
           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
index a3a8854..1e8cfdd 100644 (file)
@@ -20,6 +20,7 @@
 
 // EXTERNAL INCLUDES
 #include <dali/devel-api/adaptor-framework/clipboard-event-notifier.h>
+#include <dali/public-api/adaptor-framework/accessibility.h>
 #include <dali/public-api/animation/animation.h>
 
 // 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
index 137d0c4..20fa1b8 100644 (file)
@@ -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
index b8f49ee..6a6be64 100644 (file)
@@ -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
index c3607f5..591e614 100644 (file)
@@ -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
index 85e94ab..b98456a 100644 (file)
@@ -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
index 26b14b6..2bbba0e 100644 (file)
@@ -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 ) );
+  } );
 }
 
 
index 5f34488..5275627 100644 (file)
@@ -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 )
index 52dad25..8d3690b 100644 (file)
@@ -614,6 +614,8 @@ struct Controller::Impl
    */
   void RetrieveSelection( std::string& selectedText, bool deleteAfterRetrieval );
 
+  void SetSelection( int start, int end );
+
   void ShowClipboard();
 
   void HideClipboard();
old mode 100755 (executable)
new mode 100644 (file)
index f47b526..f1af74e
@@ -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 )
old mode 100755 (executable)
new mode 100644 (file)
index b2321c4..478d797
@@ -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
 
   /**
old mode 100755 (executable)
new mode 100644 (file)
index 49064a8..50d1e9a
 #include <typeinfo>
 #include <dali/public-api/animation/constraint.h>
 #include <dali/public-api/object/type-registry-helper.h>
+#include <dali/public-api/object/type-info.h>
 #include <dali/public-api/size-negotiation/relayout-container.h>
+#include <dali/public-api/common/stage.h>
 #include <dali/devel-api/scripting/scripting.h>
 #include <dali/integration-api/debug.h>
+#include <dali/devel-api/actors/actor-devel.h>
+#include <dali-toolkit/public-api/accessibility-manager/accessibility-manager.h>
 
 // INTERNAL INCLUDES
 #include <dali-toolkit/public-api/align-enumerations.h>
@@ -44,6 +48,7 @@
 #include <dali-toolkit/internal/visuals/color/color-visual.h>
 #include <dali-toolkit/internal/visuals/visual-string-constants.h>
 #include <dali-toolkit/internal/controls/control/control-data-impl.h>
+#include <dali/devel-api/actors/actor-devel.h>
 
 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
index 9a1e560..4cf3f2a 100644 (file)
@@ -19,6 +19,8 @@
  */
 
 // EXTERNAL INCLUDES
+#include <dali/devel-api/adaptor-framework/accessibility.h>
+#include <dali/integration-api/debug.h>
 #include <dali/public-api/adaptor-framework/style-change.h>
 #include <dali/public-api/events/long-press-gesture.h>
 #include <dali/public-api/events/pan-gesture.h>
 // INTERNAL INCLUDES
 #include <dali-toolkit/public-api/controls/control.h>
 
+#include <functional>
+#include <memory>
+#include <string>
+
 namespace Dali
 {
 namespace Toolkit
@@ -690,7 +696,55 @@ public:
 private:
   Impl* mImpl;
   /// @endcond
-
+public:
+  void SetAccessibilityConstructor(std::function<std::unique_ptr<Dali::Accessibility::Accessible>(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;
+  };
 };
 
 /**
index 14205f9..5762fff 100644 (file)
@@ -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::Control>(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
old mode 100644 (file)
new mode 100755 (executable)
index 8e522a2..12aaaf8
@@ -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<void ( Control ) > 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 );
 };
 
 /**