Merge "[AT-SPI] fix a crash on scroll-view" into devel/master
authorShinwoo Kim <cinoo.kim@samsung.com>
Fri, 18 Mar 2022 01:01:00 +0000 (01:01 +0000)
committerGerrit Code Review <gerrit@review>
Fri, 18 Mar 2022 01:01:00 +0000 (01:01 +0000)
61 files changed:
dali-toolkit/devel-api/controls/control-accessible.cpp
dali-toolkit/devel-api/controls/control-accessible.h
dali-toolkit/devel-api/controls/control-devel.cpp
dali-toolkit/devel-api/controls/control-devel.h
dali-toolkit/internal/controls/alignment/alignment-impl.cpp
dali-toolkit/internal/controls/bloom-view/bloom-view-impl.cpp
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/check-box-button-impl.h
dali-toolkit/internal/controls/buttons/push-button-impl.cpp
dali-toolkit/internal/controls/buttons/push-button-impl.h
dali-toolkit/internal/controls/buttons/radio-button-impl.cpp
dali-toolkit/internal/controls/buttons/radio-button-impl.h
dali-toolkit/internal/controls/buttons/toggle-button-impl.cpp
dali-toolkit/internal/controls/buttons/toggle-button-impl.h
dali-toolkit/internal/controls/canvas-view/canvas-view-impl.cpp
dali-toolkit/internal/controls/control/control-data-impl.cpp
dali-toolkit/internal/controls/control/control-data-impl.h
dali-toolkit/internal/controls/effects-view/effects-view-impl.cpp
dali-toolkit/internal/controls/flex-container/flex-container-impl.cpp
dali-toolkit/internal/controls/gaussian-blur-view/gaussian-blur-view-impl.cpp
dali-toolkit/internal/controls/image-view/image-view-impl.cpp
dali-toolkit/internal/controls/magnifier/magnifier-impl.cpp
dali-toolkit/internal/controls/model3d-view/model3d-view-impl.cpp
dali-toolkit/internal/controls/navigation-view/navigation-view-impl.cpp
dali-toolkit/internal/controls/page-turn-view/page-turn-view-impl.cpp
dali-toolkit/internal/controls/popup/popup-impl.cpp
dali-toolkit/internal/controls/popup/popup-impl.h
dali-toolkit/internal/controls/progress-bar/progress-bar-impl.cpp
dali-toolkit/internal/controls/progress-bar/progress-bar-impl.h
dali-toolkit/internal/controls/scroll-bar/scroll-bar-impl.cpp
dali-toolkit/internal/controls/scroll-bar/scroll-bar-impl.h
dali-toolkit/internal/controls/scrollable/item-view/item-view-impl.cpp
dali-toolkit/internal/controls/scrollable/item-view/item-view-impl.h
dali-toolkit/internal/controls/scrollable/scroll-view/scroll-view-impl.cpp
dali-toolkit/internal/controls/scrollable/scroll-view/scroll-view-impl.h
dali-toolkit/internal/controls/scrollable/scrollable-impl.cpp
dali-toolkit/internal/controls/scrollable/scrollable-impl.h
dali-toolkit/internal/controls/shadow-view/shadow-view-impl.cpp
dali-toolkit/internal/controls/slider/slider-impl.cpp
dali-toolkit/internal/controls/slider/slider-impl.h
dali-toolkit/internal/controls/super-blur-view/super-blur-view-impl.cpp
dali-toolkit/internal/controls/table-view/table-view-impl.cpp
dali-toolkit/internal/controls/text-controls/common-text-utils.cpp
dali-toolkit/internal/controls/text-controls/common-text-utils.h
dali-toolkit/internal/controls/text-controls/text-anchor-impl.cpp
dali-toolkit/internal/controls/text-controls/text-anchor-impl.h
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/controls/text-controls/text-selection-popup-impl.h
dali-toolkit/internal/controls/text-controls/text-selection-toolbar-impl.cpp
dali-toolkit/internal/controls/tool-bar/tool-bar-impl.cpp
dali-toolkit/internal/controls/video-view/video-view-impl.cpp
dali-toolkit/public-api/controls/control-impl.cpp
dali-toolkit/public-api/controls/control-impl.h

index ae7eff0..9a3da6c 100644 (file)
@@ -66,20 +66,15 @@ static Dali::Actor CreateHighlightIndicatorActor()
 }
 } // unnamed namespace
 
-ControlAccessible::ControlAccessible(Dali::Actor self, Dali::Accessibility::Role role, bool modal)
-: ActorAccessible(self),
-  mIsModal(modal)
+ControlAccessible::ControlAccessible(Dali::Actor self)
+: ActorAccessible(self)
 {
-  auto control = Dali::Toolkit::Control::DownCast(Self());
+  auto control = Toolkit::Control::DownCast(self);
 
   Internal::Control&       internalControl = Toolkit::Internal::GetImplementation(control);
   Internal::Control::Impl& controlImpl     = Internal::Control::Impl::Get(internalControl);
-  if(controlImpl.mAccessibilityRole == Dali::Accessibility::Role::UNKNOWN)
-  {
-    controlImpl.mAccessibilityRole = role;
-  }
 
-  Self().PropertySetSignal().Connect(&controlImpl, [this, &controlImpl](Dali::Handle& handle, Dali::Property::Index index, Dali::Property::Value value) {
+  self.PropertySetSignal().Connect(&controlImpl, [this, &controlImpl](Dali::Handle& handle, Dali::Property::Index index, Dali::Property::Value value) {
     if(this->Self() != Dali::Accessibility::Accessible::GetCurrentlyHighlightedActor())
     {
       return;
@@ -222,32 +217,22 @@ bool ControlAccessible::IsShowing()
 
 Dali::Accessibility::States ControlAccessible::CalculateStates()
 {
-  Dali::Actor self = Self();
-  Dali::Accessibility::States state;
-  state[Dali::Accessibility::State::FOCUSABLE] = self.GetProperty<bool>(Actor::Property::KEYBOARD_FOCUSABLE);
-  state[Dali::Accessibility::State::FOCUSED]   = Toolkit::KeyboardFocusManager::Get().GetCurrentFocusActor() == self;
+  using Dali::Accessibility::State;
 
-  if(self.GetProperty(Toolkit::DevelControl::Property::ACCESSIBILITY_HIGHLIGHTABLE).GetType() == Dali::Property::NONE)
-  {
-    state[Dali::Accessibility::State::HIGHLIGHTABLE] = false;
-  }
-  else
-  {
-    state[Dali::Accessibility::State::HIGHLIGHTABLE] = self.GetProperty(Toolkit::DevelControl::Property::ACCESSIBILITY_HIGHLIGHTABLE).Get<bool>();
-  }
+  Dali::Actor self = Self();
+  Dali::Accessibility::States states;
 
-  state[Dali::Accessibility::State::HIGHLIGHTED] = GetCurrentlyHighlightedActor() == self;
-  state[Dali::Accessibility::State::ENABLED]     = true;
-  state[Dali::Accessibility::State::SENSITIVE]   = true;
-  state[Dali::Accessibility::State::VISIBLE]     = self.GetProperty<bool>(Actor::Property::VISIBLE);
+  states[State::FOCUSABLE]     = self.GetProperty<bool>(Actor::Property::KEYBOARD_FOCUSABLE);
+  states[State::FOCUSED]       = Toolkit::KeyboardFocusManager::Get().GetCurrentFocusActor() == self;
+  states[State::HIGHLIGHTABLE] = self.GetProperty<bool>(Toolkit::DevelControl::Property::ACCESSIBILITY_HIGHLIGHTABLE);
+  states[State::HIGHLIGHTED]   = GetCurrentlyHighlightedActor() == self;
+  states[State::ENABLED]       = true;
+  states[State::SENSITIVE]     = true;
+  states[State::VISIBLE]       = self.GetProperty<bool>(Actor::Property::VISIBLE);
+  states[State::SHOWING]       = IsShowing();
+  states[State::DEFUNCT]       = !self.GetProperty(Dali::DevelActor::Property::CONNECTED_TO_SCENE).Get<bool>();
 
-  if(mIsModal)
-  {
-    state[Dali::Accessibility::State::MODAL] = true;
-  }
-  state[Dali::Accessibility::State::SHOWING] = IsShowing();
-  state[Dali::Accessibility::State::DEFUNCT] = !self.GetProperty(Dali::DevelActor::Property::CONNECTED_TO_SCENE).Get<bool>();
-  return state;
+  return states;
 }
 
 Dali::Accessibility::States ControlAccessible::GetStates()
@@ -348,10 +333,10 @@ bool ControlAccessible::GrabHighlight()
   // Clear the old highlight.
   if(oldHighlightedActor)
   {
-    auto oldHighlightObject = dynamic_cast<Dali::Accessibility::Component*>(Internal::Control::Impl::GetAccessibilityObject(oldHighlightedActor));
-    if(oldHighlightObject)
+    auto oldHighlightedObject = Dali::Accessibility::Component::DownCast(Accessible::Get(oldHighlightedActor));
+    if(oldHighlightedObject)
     {
-      oldHighlightObject->ClearHighlight();
+      oldHighlightedObject->ClearHighlight();
     }
   }
 
index 7b0ae78..dd8389a 100644 (file)
@@ -33,10 +33,9 @@ namespace Dali::Toolkit::DevelControl {
 /**
  * @brief Represents the Accessible object for Dali::Toolkit::Control and derived classes
  *
- * You can create a derived class (and register it using SetAccessibilityConstructor)
+ * You can create a derived class (and override Control::CreateAccessibleObject)
  * in order to customize Accessibility for a given control.
  *
- * @see Dali::Toolkit::DevelControl::SetAccessibilityConstructor
  * @see Dali::Accessibility::Accessible
  * @see Dali::Accessibility::Component
  * @see Dali::Accessibility::Collection
@@ -51,8 +50,6 @@ struct DALI_TOOLKIT_API ControlAccessible : public Dali::Accessibility::ActorAcc
 protected:
   Vector2                       mLastPosition{0.0f, 0.0f};
   Dali::WeakHandle<Dali::Actor> mCurrentHighlightActor;
-  bool mIsModal = false;
-  bool mIsRoot = false;
 
   void ScrollToSelf();
 
@@ -73,7 +70,7 @@ protected:
   bool IsShowing();
 
 public:
-  ControlAccessible(Dali::Actor self, Dali::Accessibility::Role role, bool modal = false);
+  ControlAccessible(Dali::Actor self);
 
   /**
    * @copydoc Dali::Accessibility::Accessible::GetName()
index a98cefe..a604433 100644 (file)
@@ -224,11 +224,6 @@ void ClearAccessibilityRelations(Toolkit::Control control)
   GetControlImplementation(control).mAccessibilityRelations.clear();
 }
 
-void SetAccessibilityConstructor(Dali::Actor control, std::function<std::unique_ptr<Dali::Accessibility::Accessible>(Dali::Actor)> constructor)
-{
-  GetControlImplementation(Toolkit::Control::DownCast(control)).mAccessibilityConstructor = constructor;
-}
-
 void AppendAccessibilityAttribute(Toolkit::Control control, const std::string& key, const std::string& value)
 {
   GetControlImplementation(control).AppendAccessibilityAttribute(key, value);
@@ -256,28 +251,22 @@ Dali::Accessibility::ReadingInfoTypes GetAccessibilityReadingInfoType(Toolkit::C
 
 bool ClearAccessibilityHighlight(Toolkit::Control control)
 {
-  auto* accessible = Dali::Accessibility::Component::DownCast(GetControlImplementation(control).GetAccessibilityObject());
-
-  return accessible ? accessible->ClearHighlight() : false;
+  return GetControlImplementation(control).GetAccessibleObject()->ClearHighlight();
 }
 
 bool GrabAccessibilityHighlight(Toolkit::Control control)
 {
-  auto* accessible = Dali::Accessibility::Component::DownCast(GetControlImplementation(control).GetAccessibilityObject());
-
-  return accessible ? accessible->GrabHighlight() : false;
+  return GetControlImplementation(control).GetAccessibleObject()->GrabHighlight();
 }
 
 Dali::Accessibility::States GetAccessibilityStates(Toolkit::Control control)
 {
-  auto* accessible = GetControlImplementation(control).GetAccessibilityObject();
-
-  return accessible->GetStates();
+  return GetControlImplementation(control).GetAccessibleObject()->GetStates();
 }
 
 void NotifyAccessibilityStateChange(Toolkit::Control control, Dali::Accessibility::States states, bool recurse)
 {
-  GetControlImplementation(control).GetAccessibilityObject()->NotifyAccessibilityStateChange(std::move(states), recurse);
+  GetControlImplementation(control).GetAccessibleObject()->NotifyAccessibilityStateChange(std::move(states), recurse);
 }
 
 } // namespace DevelControl
index 07b5040..895e404 100644 (file)
@@ -561,25 +561,6 @@ DALI_TOOLKIT_API Dali::Accessibility::States GetAccessibilityStates(Toolkit::Con
  */
 DALI_TOOLKIT_API void NotifyAccessibilityStateChange(Toolkit::Control control, Dali::Accessibility::States states, bool recurse);
 
-/**
- * The method allows to set specific constructor for creating accessibility structure
- *
- * Thank to this method hierarchy of accessibility objects can be based on internal hierarchy of Actors.
- * It prevents from necessity of keeping two trees synchronized.
- * The method should be called inside OnInitialize method of all classes inheriting from Control.
- *
- * Possible usage can be as follows:
- * @code
- *   SetAccessibilityConstructor( []( Dali::Actor actor ) {
-       return std::unique_ptr< Dali::Accessibility::Accessible >(
-       new ControlAccessible( actor, Dali::Accessibility::Role::DIALOG, true ) );
-      } );
-  * @endcode
-  *
-  * param constructor callback creating Accessible object
-  */
-DALI_TOOLKIT_API void SetAccessibilityConstructor(Dali::Actor control, std::function<std::unique_ptr<Dali::Accessibility::Accessible>(Dali::Actor)> constructor);
-
 } // namespace DevelControl
 
 } // namespace Toolkit
index d9b3b4d..002ab93 100644 (file)
@@ -187,10 +187,7 @@ const Toolkit::Alignment::Padding& Alignment::GetPadding() const
 
 void Alignment::OnInitialize()
 {
-  DevelControl::SetAccessibilityConstructor(Self(), [](Dali::Actor actor) {
-    return std::unique_ptr<Dali::Accessibility::Accessible>(
-      new DevelControl::ControlAccessible(actor, Dali::Accessibility::Role::FILLER));
-  });
+  Self().SetProperty(DevelControl::Property::ACCESSIBILITY_ROLE, Dali::Accessibility::Role::FILLER);
 }
 
 void Alignment::OnRelayout(const Vector2& size, RelayoutContainer& container)
index 5ed17c8..d7e474f 100644 (file)
@@ -217,10 +217,7 @@ void BloomView::OnInitialize()
   // bind properties for / set shader constants to defaults
   SetupProperties();
 
-  DevelControl::SetAccessibilityConstructor(Self(), [](Dali::Actor actor) {
-    return std::unique_ptr<Dali::Accessibility::Accessible>(
-      new DevelControl::ControlAccessible(actor, Dali::Accessibility::Role::ANIMATION));
-  });
+  Self().SetProperty(DevelControl::Property::ACCESSIBILITY_ROLE, Dali::Accessibility::Role::ANIMATION);
 }
 
 void BloomView::OnSizeSet(const Vector3& targetSize)
index 7fb1ab8..6c33e19 100644 (file)
@@ -620,6 +620,11 @@ bool Button::OnAccessibilityActivated()
   return OnKeyboardEnter();
 }
 
+DevelControl::ControlAccessible* Button::CreateAccessibleObject()
+{
+  return new ButtonAccessible(Self());
+}
+
 bool Button::OnTouch(Actor actor, const TouchEvent& touch)
 {
   if(!IsDisabled() && (actor == touch.GetHitActor(0)))
@@ -1303,7 +1308,7 @@ Padding Button::GetForegroundPadding()
   return mForegroundPadding;
 }
 
-std::string Button::AccessibleImpl::GetNameRaw() const
+std::string Button::ButtonAccessible::GetNameRaw() const
 {
   std::string   labelText;
   auto          slf      = Toolkit::Button::DownCast(Self());
@@ -1318,7 +1323,7 @@ std::string Button::AccessibleImpl::GetNameRaw() const
   return labelText;
 }
 
-Property::Index Button::AccessibleImpl::GetNamePropertyIndex()
+Property::Index Button::ButtonAccessible::GetNamePropertyIndex()
 {
   Property::Index label    = Toolkit::Button::Property::LABEL;
   Property::Map   labelMap = Self().GetProperty<Property::Map>(label);
@@ -1333,7 +1338,7 @@ Property::Index Button::AccessibleImpl::GetNamePropertyIndex()
   }
 }
 
-Dali::Accessibility::States Button::AccessibleImpl::CalculateStates()
+Dali::Accessibility::States Button::ButtonAccessible::CalculateStates()
 {
   auto tmp                                    = DevelControl::ControlAccessible::CalculateStates();
   tmp[Dali::Accessibility::State::SELECTABLE] = true;
index 3e36873..cae3dc8 100644 (file)
@@ -322,6 +322,11 @@ protected: // From Control
   bool OnAccessibilityActivated() override;
 
   /**
+   * @copydoc Toolkit::Internal::Control::CreateAccessibleObject()
+   */
+  DevelControl::ControlAccessible* CreateAccessibleObject() override;
+
+  /**
    * @copydoc Toolkit::Control::OnKeyboardEnter()
    */
   bool OnKeyboardEnter() override;
@@ -535,13 +540,25 @@ private:
   bool mClickActionPerforming; ///< Used to manage signal emissions during action
 
 protected:
-  struct AccessibleImpl : public DevelControl::ControlAccessible
+  class ButtonAccessible : public DevelControl::ControlAccessible
   {
+  public:
     using DevelControl::ControlAccessible::ControlAccessible;
 
+    /**
+     * @copydoc Dali::Toolkit::DevelControl::ControlAccessible::CalculateStates()
+     */
     Dali::Accessibility::States CalculateStates() override;
-    std::string                 GetNameRaw() const override;
-    Property::Index             GetNamePropertyIndex() override;
+
+    /**
+     * @copydoc Dali::Toolkit::DevelControl::ControlAccessible::GetNameRaw()
+     */
+    std::string GetNameRaw() const override;
+
+    /**
+     * @copydoc Dali::Toolkit::DevelControl::ControlAccessible::GetNamePropertyIndex()
+     */
+    Property::Index GetNamePropertyIndex() override;
   };
 };
 
index 98733ea..78a2794 100644 (file)
@@ -77,15 +77,17 @@ void CheckBoxButton::OnInitialize()
 {
   Button::OnInitialize();
 
-  DevelControl::SetAccessibilityConstructor(Self(), [](Dali::Actor actor) {
-    return std::unique_ptr<Dali::Accessibility::Accessible>(
-      new AccessibleImpl(actor, Dali::Accessibility::Role::CHECK_BOX));
-  });
+  Self().SetProperty(DevelControl::Property::ACCESSIBILITY_ROLE, Dali::Accessibility::Role::CHECK_BOX);
 }
 
-Dali::Accessibility::States CheckBoxButton::AccessibleImpl::CalculateStates()
+DevelControl::ControlAccessible* CheckBoxButton::CreateAccessibleObject()
 {
-  auto state = Button::AccessibleImpl::CalculateStates();
+  return new CheckBoxButton::CheckBoxButtonAccessible(Self());
+}
+
+Dali::Accessibility::States CheckBoxButton::CheckBoxButtonAccessible::CalculateStates()
+{
+  auto state = Button::ButtonAccessible::CalculateStates();
   auto self = Toolkit::Button::DownCast(Self());
   if(self.GetProperty<bool>(Toolkit::Button::Property::SELECTED))
   {
@@ -97,10 +99,9 @@ Dali::Accessibility::States CheckBoxButton::AccessibleImpl::CalculateStates()
 void CheckBoxButton::OnStateChange(State newState)
 {
   // TODO: replace it with OnPropertySet hook once Button::Property::SELECTED will be consistently used
-  if(Dali::Accessibility::IsUp() && (Dali::Accessibility::Accessible::GetCurrentlyHighlightedActor() == Self())
-     && (newState == SELECTED_STATE || newState == UNSELECTED_STATE))
+  if((Dali::Accessibility::Accessible::GetCurrentlyHighlightedActor() == Self()) && (newState == SELECTED_STATE || newState == UNSELECTED_STATE))
   {
-    Dali::Accessibility::Accessible::Get(Self())->EmitStateChanged(Dali::Accessibility::State::CHECKED, newState == SELECTED_STATE ? 1 : 0, 0);
+    GetAccessibleObject()->EmitStateChanged(Dali::Accessibility::State::CHECKED, newState == SELECTED_STATE ? 1 : 0, 0);
   }
 }
 
index ffae507..c542143 100644 (file)
@@ -63,6 +63,11 @@ private: // From Button
    */
   void OnInitialize() override;
 
+  /**
+   * @copydoc Toolkit::Internal::Control::CreateAccessibleObject()
+   */
+  DevelControl::ControlAccessible* CreateAccessibleObject() override;
+
 private:
   // Undefined
   CheckBoxButton(const CheckBoxButton&);
@@ -71,12 +76,17 @@ private:
   CheckBoxButton& operator=(const CheckBoxButton&);
 
 protected:
-  struct AccessibleImpl : public Button::AccessibleImpl
+  class CheckBoxButtonAccessible : public Button::ButtonAccessible
   {
-    using Button::AccessibleImpl::AccessibleImpl;
+  public:
+    using Button::ButtonAccessible::ButtonAccessible;
 
+    /**
+     * @copydoc Dali::Toolkit::DevelControl::ControlAccessible::CalculateStates()
+     */
     Dali::Accessibility::States CalculateStates() override;
   };
+
   void OnStateChange(State newState) override;
 };
 
index 2958766..9ff9531 100644 (file)
@@ -95,10 +95,12 @@ void PushButton::OnInitialize()
   Actor self = Self();
   self.SetProperty(Actor::Property::LEAVE_REQUIRED, true);
 
-  DevelControl::SetAccessibilityConstructor(self, [](Dali::Actor actor) {
-    return std::unique_ptr<Dali::Accessibility::Accessible>(
-      new AccessibleImpl(actor, Dali::Accessibility::Role::PUSH_BUTTON));
-  });
+  self.SetProperty(DevelControl::Property::ACCESSIBILITY_ROLE, Dali::Accessibility::Role::PUSH_BUTTON);
+}
+
+DevelControl::ControlAccessible* PushButton::CreateAccessibleObject()
+{
+  return new PushButtonAccessible(Self());
 }
 
 void PushButton::SetIconAlignment(const PushButton::IconAlignment iconAlignment)
@@ -194,9 +196,9 @@ Property::Value PushButton::GetProperty(BaseObject* object, Property::Index prop
   return value;
 }
 
-Dali::Accessibility::States PushButton::AccessibleImpl::CalculateStates()
+Dali::Accessibility::States PushButton::PushButtonAccessible::CalculateStates()
 {
-  auto state = Button::AccessibleImpl::CalculateStates();
+  auto state = Button::ButtonAccessible::CalculateStates();
   auto self = Toolkit::Button::DownCast(Self());
   state[Dali::Accessibility::State::PRESSED] = self.GetProperty<bool>(Toolkit::Button::Property::SELECTED);
   return state;
@@ -205,14 +207,15 @@ Dali::Accessibility::States PushButton::AccessibleImpl::CalculateStates()
 void PushButton::OnStateChange(State newState)
 {
   // TODO: replace it with OnPropertySet hook once Button::Property::SELECTED will be consistently used
-  if(Dali::Accessibility::IsUp() && (Dali::Accessibility::Accessible::GetCurrentlyHighlightedActor() == Self())
-     && (newState == SELECTED_STATE || newState == UNSELECTED_STATE))
+  if((Dali::Accessibility::Accessible::GetCurrentlyHighlightedActor() == Self()) && (newState == SELECTED_STATE || newState == UNSELECTED_STATE))
   {
-    Dali::Accessibility::Accessible::Get(Self())->EmitStateChanged(Dali::Accessibility::State::PRESSED, newState == SELECTED_STATE ? 1 : 0, 0);
+    auto* accessible = GetAccessibleObject();
+
+    accessible->EmitStateChanged(Dali::Accessibility::State::PRESSED, newState == SELECTED_STATE ? 1 : 0, 0);
 
     if(Self().GetProperty<bool>(Toolkit::Button::Property::TOGGLABLE))
     {
-      Dali::Accessibility::Accessible::Get(Self())->EmitStateChanged(Dali::Accessibility::State::CHECKED, newState == SELECTED_STATE ? 1 : 0, 0);
+      accessible->EmitStateChanged(Dali::Accessibility::State::CHECKED, newState == SELECTED_STATE ? 1 : 0, 0);
     }
   }
 }
index 6300fe2..21a4d01 100644 (file)
@@ -93,6 +93,11 @@ private: // From Button
    */
   void OnInitialize() override;
 
+  /**
+   * @copydoc Toolkit::Internal::Control::CreateAccessibleObject()
+   */
+  DevelControl::ControlAccessible* CreateAccessibleObject() override;
+
 private:
   /**
    * @brief Sets the alignment mode to use to align the icon to the label.
@@ -119,12 +124,17 @@ private:
   IconAlignment mIconAlignment; ///< The alignment of the icon against the label.
 
 protected:
-  struct AccessibleImpl : public Button::AccessibleImpl
+  class PushButtonAccessible : public Button::ButtonAccessible
   {
-    using Button::AccessibleImpl::AccessibleImpl;
+  public:
+    using Button::ButtonAccessible::ButtonAccessible;
 
+    /**
+     * @copydoc Dali::Toolkit::DevelControl::ControlAccessible::CalculateStates()
+     */
     Dali::Accessibility::States CalculateStates() override;
   };
+
   void OnStateChange(State newState) override;
 };
 
index 4b4e070..bf35f99 100644 (file)
@@ -71,10 +71,12 @@ void RadioButton::OnInitialize()
 {
   Button::OnInitialize();
 
-  DevelControl::SetAccessibilityConstructor(Self(), [](Dali::Actor actor) {
-    return std::unique_ptr<Dali::Accessibility::Accessible>(
-      new AccessibleImpl(actor, Dali::Accessibility::Role::RADIO_BUTTON));
-  });
+  Self().SetProperty(DevelControl::Property::ACCESSIBILITY_ROLE, Dali::Accessibility::Role::RADIO_BUTTON);
+}
+
+DevelControl::ControlAccessible* RadioButton::CreateAccessibleObject()
+{
+  return new RadioButtonAccessible(Self());
 }
 
 bool RadioButton::OnToggleReleased()
@@ -105,16 +107,15 @@ void RadioButton::OnStateChange(State newState)
   }
 
   // TODO: replace it with OnPropertySet hook once Button::Property::SELECTED will be consistently used
-  if(Dali::Accessibility::IsUp() && (Dali::Accessibility::Accessible::GetCurrentlyHighlightedActor() == Self())
-     && (newState == SELECTED_STATE || newState == UNSELECTED_STATE))
+  if((Dali::Accessibility::Accessible::GetCurrentlyHighlightedActor() == Self()) && (newState == SELECTED_STATE || newState == UNSELECTED_STATE))
   {
-    Dali::Accessibility::Accessible::Get(Self())->EmitStateChanged(Dali::Accessibility::State::CHECKED, newState == SELECTED_STATE ? 1 : 0, 0);
+    GetAccessibleObject()->EmitStateChanged(Dali::Accessibility::State::CHECKED, newState == SELECTED_STATE ? 1 : 0, 0);
   }
 }
 
-Dali::Accessibility::States RadioButton::AccessibleImpl::CalculateStates()
+Dali::Accessibility::States RadioButton::RadioButtonAccessible::CalculateStates()
 {
-  auto state = Button::AccessibleImpl::CalculateStates();
+  auto state = Button::ButtonAccessible::CalculateStates();
   auto self = Toolkit::Button::DownCast(Self());
 
   if(self.GetProperty<bool>(Toolkit::Button::Property::SELECTED))
index b172750..dbe2d35 100644 (file)
@@ -65,6 +65,11 @@ private: // From Button
   void OnInitialize() override;
 
   /**
+   * @copydoc Toolkit::Internal::Control::CreateAccessibleObject()
+   */
+  DevelControl::ControlAccessible* CreateAccessibleObject() override;
+
+  /**
    * @copydoc Toolkit::Internal::Button::OnStateChange
    */
   void OnStateChange(State newState) override;
@@ -82,10 +87,14 @@ private:
   RadioButton& operator=(const RadioButton& origin);
 
 protected:
-  struct AccessibleImpl : public Button::AccessibleImpl
+  class RadioButtonAccessible : public Button::ButtonAccessible
   {
-    using Button::AccessibleImpl::AccessibleImpl;
+  public:
+    using Button::ButtonAccessible::ButtonAccessible;
 
+    /**
+     * @copydoc Dali::Toolkit::DevelControl::ControlAccessible::CalculateStates()
+     */
     Dali::Accessibility::States CalculateStates() override;
   };
 };
index 3010e69..1b6ef02 100644 (file)
@@ -106,10 +106,12 @@ void ToggleButton::OnInitialize()
   Actor self = Self();
   self.SetProperty(Actor::Property::LEAVE_REQUIRED, true);
 
-  DevelControl::SetAccessibilityConstructor(Self(), [](Dali::Actor actor) {
-    return std::unique_ptr<Dali::Accessibility::Accessible>(
-      new AccessibleImpl(actor, Dali::Accessibility::Role::TOGGLE_BUTTON));
-  });
+  self.SetProperty(DevelControl::Property::ACCESSIBILITY_ROLE, Dali::Accessibility::Role::TOGGLE_BUTTON);
+}
+
+DevelControl::ControlAccessible* ToggleButton::CreateAccessibleObject()
+{
+  return new ToggleButtonAccessible(Self());
 }
 
 void ToggleButton::SetProperty(BaseObject* object, Property::Index propertyIndex, const Property::Value& value)
@@ -372,9 +374,9 @@ void ToggleButton::OnPressed()
   RelayoutRequest();
 }
 
-Dali::Accessibility::States ToggleButton::AccessibleImpl::CalculateStates()
+Dali::Accessibility::States ToggleButton::ToggleButtonAccessible::CalculateStates()
 {
-  auto states = Button::AccessibleImpl::CalculateStates();
+  auto states = Button::ButtonAccessible::CalculateStates();
   auto button = Toolkit::ToggleButton::DownCast(Self());
   if(button.GetProperty<int>(Toolkit::ToggleButton::Property::CURRENT_STATE_INDEX))
   {
@@ -383,7 +385,7 @@ Dali::Accessibility::States ToggleButton::AccessibleImpl::CalculateStates()
   return states;
 }
 
-std::string ToggleButton::AccessibleImpl::GetDescriptionRaw() const
+std::string ToggleButton::ToggleButtonAccessible::GetDescriptionRaw() const
 {
   auto button   = Toolkit::ToggleButton::DownCast(Self());
   auto index    = button.GetProperty<int>(Toolkit::ToggleButton::Property::CURRENT_STATE_INDEX);
@@ -392,7 +394,7 @@ std::string ToggleButton::AccessibleImpl::GetDescriptionRaw() const
   return tooltips[index].Get<std::string>();
 }
 
-Property::Index ToggleButton::AccessibleImpl::GetDescriptionPropertyIndex()
+Property::Index ToggleButton::ToggleButtonAccessible::GetDescriptionPropertyIndex()
 {
   return Toolkit::ToggleButton::Property::TOOLTIPS;
 }
@@ -400,11 +402,12 @@ Property::Index ToggleButton::AccessibleImpl::GetDescriptionPropertyIndex()
 void ToggleButton::OnStateChange(State newState)
 {
   // TODO: replace it with OnPropertySet hook once Button::Property::SELECTED will be consistently used
-  if(Dali::Accessibility::IsUp() && (Self() == Dali::Accessibility::Accessible::GetCurrentlyHighlightedActor())
-     && (newState == SELECTED_STATE || newState == UNSELECTED_STATE))
+  if((Self() == Dali::Accessibility::Accessible::GetCurrentlyHighlightedActor()) && (newState == SELECTED_STATE || newState == UNSELECTED_STATE))
   {
-    Dali::Accessibility::Accessible::Get(Self())->EmitStateChanged(Dali::Accessibility::State::CHECKED, mCurrentToggleIndex ? 1 : 0, 0);
-    Dali::Accessibility::Accessible::Get(Self())->Emit(Dali::Accessibility::ObjectPropertyChangeEvent::DESCRIPTION);
+    auto* accessible = GetAccessibleObject();
+
+    accessible->EmitStateChanged(Dali::Accessibility::State::CHECKED, mCurrentToggleIndex ? 1 : 0, 0);
+    accessible->Emit(Dali::Accessibility::ObjectPropertyChangeEvent::DESCRIPTION);
   }
 }
 
index 6629d40..c6652a5 100644 (file)
@@ -128,6 +128,11 @@ private: // From Button
   void OnInitialize() override;
 
   /**
+   * @copydoc Toolkit::Internal::Control::CreateAccessibleObject()
+   */
+  DevelControl::ControlAccessible* CreateAccessibleObject() override;
+
+  /**
    * @copydoc Toolkit::Internal::Button::OnRelayout
    */
   void OnRelayout(const Vector2& size, RelayoutContainer& container) override;
@@ -152,15 +157,29 @@ private:
   std::vector<Toolkit::Visual::Base> mToggleDisabledSelectedVisuals; ///< Save all disabled selected visuals.
   std::vector<std::string>           mToggleTooltips;                ///< Toggle tooltips.
   unsigned int                       mCurrentToggleIndex;            ///< The index of state.
+
 protected:
-  struct AccessibleImpl : public Button::AccessibleImpl
+  class ToggleButtonAccessible : public Button::ButtonAccessible
   {
-    using Button::AccessibleImpl::AccessibleImpl;
+  public:
+    using Button::ButtonAccessible::ButtonAccessible;
 
+    /**
+     * @copydoc Dali::Toolkit::DevelControl::ControlAccessible::CalculateStates()
+     */
     Dali::Accessibility::States CalculateStates() override;
-    std::string                 GetDescriptionRaw() const override;
-    Property::Index             GetDescriptionPropertyIndex() override;
+
+    /**
+     * @copydoc Dali::Toolkit::DevelControl::ControlAccessible::GetDescriptionRaw()
+     */
+    std::string GetDescriptionRaw() const override;
+
+    /**
+     * @copydoc Dali::Toolkit::DevelControl::ControlAccessible::GetDescriptionPropertyIndex()
+     */
+    Property::Index GetDescriptionPropertyIndex() override;
   };
+
   void OnStateChange(State newState) override;
 };
 
index 6ec6fc9..39253d0 100644 (file)
@@ -97,10 +97,7 @@ void CanvasView::OnInitialize()
   // CanvasView can relayout in the OnImageReady, alternative to a signal would be to have a upcall from the Control to CanvasView
   Dali::Toolkit::Control handle(GetOwner());
 
-  DevelControl::SetAccessibilityConstructor(Self(), [](Dali::Actor actor) {
-    return std::unique_ptr<Dali::Accessibility::Accessible>(
-      new DevelControl::ControlAccessible(actor, Dali::Accessibility::Role::IMAGE));
-  });
+  Self().SetProperty(DevelControl::Property::ACCESSIBILITY_ROLE, Dali::Accessibility::Role::IMAGE);
 
   Adaptor::Get().RegisterProcessor(*this, true);
 }
index 3d71f4d..c1618f3 100644 (file)
@@ -445,6 +445,19 @@ static bool IsShowingGeometryOnScreen(Dali::Rect<> rect)
   return rect.width > 0 && rect.height > 0;
 }
 
+Dali::Accessibility::Accessible* ExternalAccessibleGetter(Dali::Actor actor)
+{
+  auto control = Toolkit::Control::DownCast(actor);
+  if (!control)
+  {
+    return nullptr;
+  }
+
+  auto& controlImpl = Toolkit::Internal::GetImplementation(control);
+
+  return controlImpl.GetAccessibleObject();
+}
+
 } // unnamed namespace
 
 // clang-format off
@@ -508,14 +521,7 @@ Control::Impl::Impl(Control& controlImpl)
   mNeedToEmitResourceReady(false),
   mDispatchKeyEvents(true)
 {
-  Dali::Accessibility::Accessible::RegisterExternalAccessibleGetter(
-    [](Dali::Actor actor) -> Dali::Accessibility::Accessible* {
-      return Control::Impl::GetAccessibilityObject(actor);
-    });
-
-  mAccessibilityConstructor = [](Dali::Actor actor) -> std::unique_ptr<Dali::Accessibility::Accessible> {
-    return std::unique_ptr<Dali::Accessibility::Accessible>(new DevelControl::ControlAccessible(actor, Dali::Accessibility::Role::UNKNOWN));
-  };
+  Dali::Accessibility::Accessible::RegisterExternalAccessibleGetter(&ExternalAccessibleGetter);
 }
 
 Control::Impl::~Impl()
@@ -552,13 +558,7 @@ const Control::Impl& Control::Impl::Get(const Internal::Control& internalControl
 
 void Control::Impl::CheckHighlightedObjectGeometry()
 {
-  auto accessible = dynamic_cast<Dali::Toolkit::DevelControl::ControlAccessible*>(mAccessibilityObject.get());
-  if(!accessible)
-  {
-    DALI_LOG_ERROR("accessible is not a pointer to a DevelControl::ControlAccessible type");
-    return;
-  }
-
+  auto accessible     = GetAccessibleObject();
   auto lastPosition   = accessible->GetLastPosition();
   auto accessibleRect = accessible->GetExtents(Dali::Accessibility::CoordinateType::WINDOW);
   auto rect = GetShowingGeometry(accessibleRect, accessible);
@@ -586,7 +586,7 @@ void Control::Impl::CheckHighlightedObjectGeometry()
       // notify AT-clients on outgoing moves only
       if(mAccessibilityLastScreenRelativeMoveType != Dali::Accessibility::ScreenRelativeMoveType::INSIDE)
       {
-        mAccessibilityObject.get()->EmitMovedOutOfScreen(mAccessibilityLastScreenRelativeMoveType);
+        accessible->EmitMovedOutOfScreen(mAccessibilityLastScreenRelativeMoveType);
       }
       break;
     }
@@ -1358,7 +1358,7 @@ void Control::Impl::SetProperty(BaseObject* object, Property::Index index, const
         {
           controlImpl.mImpl->mAccessibilityHidden = hidden;
 
-          auto* accessible = controlImpl.mImpl->GetAccessibilityObject();
+          auto* accessible = controlImpl.GetAccessibleObject();
           auto* parent     = dynamic_cast<Dali::Accessibility::ActorAccessible*>(accessible->GetParent());
           if (parent)
           {
@@ -2051,27 +2051,14 @@ void Control::Impl::OnIdleCallback()
   mIdleCallback = nullptr;
 }
 
-Dali::Accessibility::Accessible* Control::Impl::GetAccessibilityObject()
+Toolkit::DevelControl::ControlAccessible* Control::Impl::GetAccessibleObject()
 {
-  if(!mAccessibilityObject)
+  if(!mAccessibleObject)
   {
-    mAccessibilityObject = mAccessibilityConstructor(mControlImpl.Self());
+    mAccessibleObject.reset(mControlImpl.CreateAccessibleObject());
   }
-  return mAccessibilityObject.get();
-}
 
-Dali::Accessibility::Accessible* Control::Impl::GetAccessibilityObject(Dali::Actor actor)
-{
-  if(actor)
-  {
-    auto control = Dali::Toolkit::Control::DownCast(actor);
-    if(control)
-    {
-      auto controlImpl = static_cast<Internal::Control*>(&control.GetImplementation());
-      return controlImpl->mImpl->GetAccessibilityObject();
-    }
-  }
-  return nullptr;
+  return mAccessibleObject.get();
 }
 
 } // namespace Internal
index 1321a10..13ee7de 100644 (file)
@@ -423,20 +423,9 @@ public:
   void UpdateVisualProperties(const std::vector<std::pair<Dali::Property::Index, Dali::Property::Map>>& properties);
 
   /**
-   * @brief Gets the current control's accessible object.
-   *
-   * @return The handle to Accessible object
-   */
-  Dali::Accessibility::Accessible* GetAccessibilityObject();
-
-  /**
-   * @brief Gets Accessible object handle.
-   *
-   * The method acquires Accessible handle from Actor object
-   * @param  actor Actor object
-   * @return The handle to Accessible object
+   * @copydoc Dali::Toolkit::Internal::Control::GetAccessibleObject()
    */
-  static Dali::Accessibility::Accessible* GetAccessibilityObject(Dali::Actor actor);
+  Toolkit::DevelControl::ControlAccessible* GetAccessibleObject();
 
 private:
   /**
@@ -546,8 +535,7 @@ public:
   Dali::Accessibility::Role mAccessibilityRole = Dali::Accessibility::Role::UNKNOWN;
 
   std::map<Dali::Accessibility::RelationType, std::set<Accessibility::Accessible*>> mAccessibilityRelations;
-  std::function<std::unique_ptr<Dali::Accessibility::Accessible>(Actor)>            mAccessibilityConstructor;
-  std::unique_ptr<Dali::Accessibility::Accessible>                                  mAccessibilityObject;
+  std::unique_ptr<Toolkit::DevelControl::ControlAccessible>                         mAccessibleObject;
 
   // Gesture Detection
   PinchGestureDetector     mPinchGestureDetector;
index 0f3e141..5f132c7 100644 (file)
@@ -234,10 +234,7 @@ void EffectsView::OnInitialize()
   mChildrenRoot.SetProperty(Actor::Property::PARENT_ORIGIN, ParentOrigin::CENTER);
   self.Add(mChildrenRoot);
 
-  DevelControl::SetAccessibilityConstructor(self, [](Dali::Actor actor) {
-    return std::unique_ptr<Dali::Accessibility::Accessible>(
-      new DevelControl::ControlAccessible(actor, Dali::Accessibility::Role::FILLER));
-  });
+  self.SetProperty(DevelControl::Property::ACCESSIBILITY_ROLE, Dali::Accessibility::Role::FILLER);
 }
 
 void EffectsView::OnSizeSet(const Vector3& targetSize)
index 964afe2..b220445 100644 (file)
@@ -835,10 +835,7 @@ void FlexContainer::OnInitialize()
   self.SetProperty(Actor::Property::KEYBOARD_FOCUSABLE, true);
   SetAsKeyboardFocusGroup(true);
 
-  DevelControl::SetAccessibilityConstructor(self, [](Dali::Actor actor) {
-    return std::unique_ptr<Dali::Accessibility::Accessible>(
-      new DevelControl::ControlAccessible(actor, Dali::Accessibility::Role::FILLER));
-  });
+  self.SetProperty(DevelControl::Property::ACCESSIBILITY_ROLE, Dali::Accessibility::Role::FILLER);
 }
 
 } // namespace Internal
index 64d5ecb..31b7c61 100644 (file)
@@ -295,10 +295,7 @@ void GaussianBlurView::OnInitialize()
   mInternalRoot.Add(mVertBlurActor);
   mInternalRoot.Add(mRenderDownsampledCamera);
 
-  DevelControl::SetAccessibilityConstructor(Self(), [](Dali::Actor actor) {
-    return std::unique_ptr<Dali::Accessibility::Accessible>(
-      new DevelControl::ControlAccessible(actor, Dali::Accessibility::Role::FILLER));
-  });
+  Self().SetProperty(DevelControl::Property::ACCESSIBILITY_ROLE, Dali::Accessibility::Role::FILLER);
 }
 
 void GaussianBlurView::OnSizeSet(const Vector3& targetSize)
index 46c9e11..f769b44 100644 (file)
@@ -94,10 +94,7 @@ void ImageView::OnInitialize()
   Dali::Toolkit::Control handle(GetOwner());
   handle.ResourceReadySignal().Connect(this, &ImageView::OnResourceReady);
 
-  DevelControl::SetAccessibilityConstructor(Self(), [](Dali::Actor actor) {
-    return std::unique_ptr<Dali::Accessibility::Accessible>(
-      new DevelControl::ControlAccessible(actor, Dali::Accessibility::Role::IMAGE));
-  });
+  Self().SetProperty(DevelControl::Property::ACCESSIBILITY_ROLE, Dali::Accessibility::Role::IMAGE);
 }
 
 void ImageView::SetImage(const Property::Map& map)
index 6da7915..671551b 100644 (file)
@@ -218,10 +218,7 @@ void Magnifier::Initialize()
   constraint.AddSource(Source(self, Actor::Property::WORLD_SCALE));
   constraint.Apply();
 
-  DevelControl::SetAccessibilityConstructor(self, [](Dali::Actor actor) {
-    return std::unique_ptr<Dali::Accessibility::Accessible>(
-      new DevelControl::ControlAccessible(actor, Dali::Accessibility::Role::FILLER));
-  });
+  self.SetProperty(DevelControl::Property::ACCESSIBILITY_ROLE, Dali::Accessibility::Role::FILLER);
 }
 
 Magnifier::~Magnifier()
index b9ee873..1384a15 100644 (file)
@@ -280,10 +280,7 @@ void Model3dView::OnInitialize()
   Shader   shader = Shader::New(SHADER_MODEL3D_VIEW_SIMPLE_SHADER_VERT, SHADER_MODEL3D_VIEW_SIMPLE_SHADER_FRAG);
   mRenderer       = Renderer::New(mesh, shader);
 
-  DevelControl::SetAccessibilityConstructor(Self(), [](Dali::Actor actor) {
-    return std::unique_ptr<Dali::Accessibility::Accessible>(
-      new DevelControl::ControlAccessible(actor, Dali::Accessibility::Role::IMAGE));
-  });
+  Self().SetProperty(DevelControl::Property::ACCESSIBILITY_ROLE, Dali::Accessibility::Role::IMAGE);
 }
 
 void Model3dView::LoadGeometry()
index 9eab290..f140e3e 100644 (file)
@@ -70,10 +70,7 @@ Toolkit::NavigationView NavigationView::New()
 
 void NavigationView::OnInitialize()
 {
-  DevelControl::SetAccessibilityConstructor(Self(), [](Dali::Actor actor) {
-    return std::unique_ptr<Dali::Accessibility::Accessible>(
-      new DevelControl::ControlAccessible(actor, Dali::Accessibility::Role::FILLER));
-  });
+  Self().SetProperty(DevelControl::Property::ACCESSIBILITY_ROLE, Dali::Accessibility::Role::FILLER);
 }
 
 void NavigationView::OnSceneConnection(int depth)
index 69369de..a5e9e95 100644 (file)
@@ -414,10 +414,7 @@ void PageTurnView::OnInitialize()
   // enable the pan gesture which is attached to the control
   EnableGestureDetection(GestureType::Value(GestureType::PAN));
 
-  DevelControl::SetAccessibilityConstructor(Self(), [](Dali::Actor actor) {
-    return std::unique_ptr<Dali::Accessibility::Accessible>(
-      new DevelControl::ControlAccessible(actor, Dali::Accessibility::Role::PAGE_TAB_LIST));
-  });
+  Self().SetProperty(DevelControl::Property::ACCESSIBILITY_ROLE, Dali::Accessibility::Role::PAGE_TAB_LIST);
 }
 
 Shader PageTurnView::CreateShader(const Property::Map& shaderMap)
index f811812..f7ebcf4 100644 (file)
@@ -345,9 +345,12 @@ void Popup::OnInitialize()
 
   DevelControl::AppendAccessibilityAttribute(Toolkit::Control::DownCast(self), "sub-role", "Alert");
 
-  DevelControl::SetAccessibilityConstructor(self, [](Dali::Actor actor) {
-    return std::unique_ptr<Dali::Accessibility::Accessible>(new AccessibleImpl(actor, Dali::Accessibility::Role::DIALOG, true));
-  });
+  self.SetProperty(DevelControl::Property::ACCESSIBILITY_ROLE, Dali::Accessibility::Role::DIALOG);
+}
+
+DevelControl::ControlAccessible* Popup::CreateAccessibleObject()
+{
+  return new PopupAccessible(Self());
 }
 
 Popup::~Popup()
@@ -1994,7 +1997,7 @@ void Popup::SetupTouch()
   }
 }
 
-std::string Popup::AccessibleImpl::GetNameRaw() const
+std::string Popup::PopupAccessible::GetNameRaw() const
 {
   auto        popup = Toolkit::Popup::DownCast(Self());
   std::string title;
@@ -2016,13 +2019,14 @@ std::string Popup::AccessibleImpl::GetNameRaw() const
   return title;
 }
 
-Dali::Accessibility::States Popup::AccessibleImpl::CalculateStates()
+Dali::Accessibility::States Popup::PopupAccessible::CalculateStates()
 {
   auto states       = DevelControl::ControlAccessible::CalculateStates();
   auto popup        = Toolkit::Popup::DownCast(Self());
   auto displayState = popup.GetProperty<std::string>(Toolkit::Popup::Property::DISPLAY_STATE);
 
   states[Dali::Accessibility::State::SHOWING] = (displayState == "SHOWN" || displayState == "SHOWING");
+  states[Dali::Accessibility::State::MODAL]   = true;
 
   return states;
 }
index 50a2fd6..8f4aef0 100644 (file)
@@ -241,11 +241,19 @@ public:
   static Property::Value GetProperty(BaseObject* object, Property::Index propertyIndex);
 
 protected:
-  struct AccessibleImpl : public DevelControl::ControlAccessible
+  class PopupAccessible : public DevelControl::ControlAccessible
   {
+  public:
     using DevelControl::ControlAccessible::ControlAccessible;
 
-    std::string                 GetNameRaw() const override;
+    /**
+     * @copydoc Dali::Toolkit::DevelControl::ControlAccessible::GetNameRaw()
+     */
+    std::string GetNameRaw() const override;
+
+    /**
+     * @copydoc Dali::Toolkit::DevelControl::ControlAccessible::CalculateStates()
+     */
     Dali::Accessibility::States CalculateStates() override;
   };
 
@@ -429,6 +437,11 @@ private:
   void OnInitialize() override;
 
   /**
+   * @copydoc Toolkit::Internal::Control::CreateAccessibleObject()
+   */
+  DevelControl::ControlAccessible* CreateAccessibleObject() override;
+
+  /**
    * Called whenever the popup layout is re-set up.
    * Normally due to a change in contents.
    * Note: This is only done when the popup is shown.
index 1a243a2..f98ece7 100644 (file)
@@ -165,12 +165,14 @@ ProgressBar::~ProgressBar()
 
 void ProgressBar::OnInitialize()
 {
-  DevelControl::SetAccessibilityConstructor(Self(), [](Dali::Actor actor) {
-    return std::unique_ptr<Dali::Accessibility::Accessible>(
-      new AccessibleImpl(actor, Dali::Accessibility::Role::PROGRESS_BAR));
-  });
-  //Enable highightability
-  Self().SetProperty(Toolkit::DevelControl::Property::ACCESSIBILITY_HIGHLIGHTABLE, true);
+  // Accessibility
+  Self().SetProperty(DevelControl::Property::ACCESSIBILITY_ROLE, Dali::Accessibility::Role::PROGRESS_BAR);
+  Self().SetProperty(DevelControl::Property::ACCESSIBILITY_HIGHLIGHTABLE, true);
+}
+
+DevelControl::ControlAccessible* ProgressBar::CreateAccessibleObject()
+{
+  return new ProgressBarAccessible(Self());
 }
 
 void ProgressBar::OnRelayout(const Vector2& size, RelayoutContainer& container)
@@ -271,7 +273,7 @@ void ProgressBar::SetProgressValue(float value)
     mValueChangedSignal.Emit(self, mProgressValue, mSecondaryProgressValue);
     if(Self() == Dali::Accessibility::Accessible::GetCurrentlyHighlightedActor())
     {
-      Control::Impl::GetAccessibilityObject(Self())->Emit(Dali::Accessibility::ObjectPropertyChangeEvent::VALUE);
+      GetAccessibleObject()->Emit(Dali::Accessibility::ObjectPropertyChangeEvent::VALUE);
     }
     RelayoutRequest();
   }
@@ -676,23 +678,23 @@ void ProgressBar::OnSceneConnection(int depth)
   }
 }
 
-double ProgressBar::AccessibleImpl::GetMinimum() const
+double ProgressBar::ProgressBarAccessible::GetMinimum() const
 {
   return DEFAULT_LOWER_BOUND;
 }
 
-double ProgressBar::AccessibleImpl::GetCurrent() const
+double ProgressBar::ProgressBarAccessible::GetCurrent() const
 {
   auto self = Toolkit::ProgressBar::DownCast(Self());
   return self.GetProperty(Toolkit::ProgressBar::Property::PROGRESS_VALUE).Get<float>();
 }
 
-double ProgressBar::AccessibleImpl::GetMaximum() const
+double ProgressBar::ProgressBarAccessible::GetMaximum() const
 {
   return DEFAULT_UPPER_BOUND;
 }
 
-bool ProgressBar::AccessibleImpl::SetCurrent(double current)
+bool ProgressBar::ProgressBarAccessible::SetCurrent(double current)
 {
   if(current < GetMinimum() || current > GetMaximum())
   {
@@ -704,7 +706,7 @@ bool ProgressBar::AccessibleImpl::SetCurrent(double current)
   return true;
 }
 
-double ProgressBar::AccessibleImpl::GetMinimumIncrement() const
+double ProgressBar::ProgressBarAccessible::GetMinimumIncrement() const
 {
   return 0.0;
 }
index 96540d2..13c9cb3 100644 (file)
@@ -201,6 +201,11 @@ private:
   void OnInitialize() override;
 
   /**
+   * @copydoc Toolkit::Internal::Control::CreateAccessibleObject()
+   */
+  DevelControl::ControlAccessible* CreateAccessibleObject() override;
+
+  /**
    * Get the range of the valid values the ProgressBar handle can move between
    *
    * @param[in] currentSize The current size of the ProgressBar
@@ -265,15 +270,35 @@ private:
   Property::Map           mSecondaryProgressVisualMap;    ///< To backup visual properties when switching determinate/indeterminate.
 
 protected:
-  struct AccessibleImpl : public DevelControl::ControlAccessible,
-                          public virtual Dali::Accessibility::Value
+  class ProgressBarAccessible : public DevelControl::ControlAccessible,
+                                public virtual Dali::Accessibility::Value
   {
+  public:
     using DevelControl::ControlAccessible::ControlAccessible;
 
+    /**
+     * @copydoc Dali::Accessibility::Value::GetMinimum()
+     */
     double GetMinimum() const override;
+
+    /**
+     * @copydoc Dali::Accessibility::Value::GetCurrent()
+     */
     double GetCurrent() const override;
+
+    /**
+     * @copydoc Dali::Accessibility::Value::GetMaximum()
+     */
     double GetMaximum() const override;
-    bool   SetCurrent(double) override;
+
+    /**
+     * @copydoc Dali::Accessibility::Value::SetCurrent()
+     */
+    bool SetCurrent(double) override;
+
+    /**
+     * @copydoc Dali::Accessibility::Value::GetMinimumIncrement()
+     */
     double GetMinimumIncrement() const override;
   };
 };
index 1fef71b..88fdf6b 100644 (file)
@@ -209,13 +209,17 @@ ScrollBar::~ScrollBar()
 
 void ScrollBar::OnInitialize()
 {
+  auto self = Self();
+
   CreateDefaultIndicatorActor();
-  Self().SetProperty(Actor::Property::DRAW_MODE, DrawMode::OVERLAY_2D);
+  self.SetProperty(Actor::Property::DRAW_MODE, DrawMode::OVERLAY_2D);
+
+  self.SetProperty(DevelControl::Property::ACCESSIBILITY_ROLE, Dali::Accessibility::Role::SCROLL_BAR);
+}
 
-  DevelControl::SetAccessibilityConstructor(Self(), [](Dali::Actor actor) {
-    return std::unique_ptr<Dali::Accessibility::Accessible>(
-      new AccessibleImpl(actor, Dali::Accessibility::Role::SCROLL_BAR));
-  });
+DevelControl::ControlAccessible* ScrollBar::CreateAccessibleObject()
+{
+  return new ScrollBarAccessible(Self());
 }
 
 void ScrollBar::SetScrollPropertySource(Handle handle, Property::Index propertyScrollPosition, Property::Index propertyMinScrollPosition, Property::Index propertyMaxScrollPosition, Property::Index propertyScrollContentSize)
@@ -360,7 +364,7 @@ void ScrollBar::OnScrollPositionIntervalReached(PropertyNotification& source)
     mScrollPositionIntervalReachedSignal.Emit(scrollableHandle.GetCurrentProperty<float>(mPropertyScrollPosition));
     if(Self() == Dali::Accessibility::Accessible::GetCurrentlyHighlightedActor())
     {
-      Control::Impl::GetAccessibilityObject(Self())->Emit(Dali::Accessibility::ObjectPropertyChangeEvent::VALUE);
+      GetAccessibleObject()->Emit(Dali::Accessibility::ObjectPropertyChangeEvent::VALUE);
     }
   }
 }
@@ -861,28 +865,28 @@ Toolkit::ScrollBar ScrollBar::New(Toolkit::ScrollBar::Direction direction)
   return handle;
 }
 
-double ScrollBar::AccessibleImpl::GetMinimum() const
+double ScrollBar::ScrollBarAccessible::GetMinimum() const
 {
   auto self = Toolkit::ScrollBar::DownCast(Self());
   Handle scrollableHandle = GetImpl(self).mScrollableObject.GetHandle();
   return scrollableHandle ? scrollableHandle.GetCurrentProperty<float>(GetImpl(self).mPropertyMinScrollPosition) : 0.0f;
 }
 
-double ScrollBar::AccessibleImpl::GetCurrent() const
+double ScrollBar::ScrollBarAccessible::GetCurrent() const
 {
   auto self = Toolkit::ScrollBar::DownCast(Self());
   Handle scrollableHandle = GetImpl(self).mScrollableObject.GetHandle();
   return scrollableHandle ? scrollableHandle.GetCurrentProperty<float>(GetImpl(self).mPropertyScrollPosition) : 0.0f;
 }
 
-double ScrollBar::AccessibleImpl::GetMaximum() const
+double ScrollBar::ScrollBarAccessible::GetMaximum() const
 {
   auto self = Toolkit::ScrollBar::DownCast(Self());
   Handle scrollableHandle = GetImpl(self).mScrollableObject.GetHandle();
   return scrollableHandle ? scrollableHandle.GetCurrentProperty<float>(GetImpl(self).mPropertyMaxScrollPosition) : 1.0f;
 }
 
-bool ScrollBar::AccessibleImpl::SetCurrent(double current)
+bool ScrollBar::ScrollBarAccessible::SetCurrent(double current)
 {
   if(current < GetMinimum() || current > GetMaximum())
   {
@@ -910,7 +914,7 @@ bool ScrollBar::AccessibleImpl::SetCurrent(double current)
   return true;
 }
 
-double ScrollBar::AccessibleImpl::GetMinimumIncrement() const
+double ScrollBar::ScrollBarAccessible::GetMinimumIncrement() const
 {
   return 1.0;
 }
index 97a7daa..57def7f 100644 (file)
@@ -211,6 +211,11 @@ private: // from Control
   void OnInitialize() override;
 
   /**
+   * @copydoc Toolkit::Internal::Control::CreateAccessibleObject()
+   */
+  DevelControl::ControlAccessible* CreateAccessibleObject() override;
+
+  /**
    * @copydoc Toolkit::Control::OnPan
    */
   void OnPan(const PanGesture& gesture) override;
@@ -314,15 +319,35 @@ private:
   bool mIndicatorFirstShow : 1; ///< True if the indicator has never been shown
 
 protected:
-  struct AccessibleImpl : public DevelControl::ControlAccessible,
-                          public virtual Dali::Accessibility::Value
+  class ScrollBarAccessible : public DevelControl::ControlAccessible,
+                              public virtual Dali::Accessibility::Value
   {
+  public:
     using DevelControl::ControlAccessible::ControlAccessible;
 
+    /**
+     * @copydoc Dali::Accessibility::Value::GetMinimum()
+     */
     double GetMinimum() const override;
+
+    /**
+     * @copydoc Dali::Accessibility::Value::GetCurrent()
+     */
     double GetCurrent() const override;
+
+    /**
+     * @copydoc Dali::Accessibility::Value::GetMaximum()
+     */
     double GetMaximum() const override;
-    bool   SetCurrent(double) override;
+
+    /**
+     * @copydoc Dali::Accessibility::Value::SetCurrent()
+     */
+    bool SetCurrent(double) override;
+
+    /**
+     * @copydoc Dali::Accessibility::Value::GetMinimumIncrement()
+     */
     double GetMinimumIncrement() const override;
   };
 };
index e9b58c8..6d6e211 100644 (file)
@@ -367,9 +367,12 @@ void ItemView::OnInitialize()
   // Connect wheel event
   self.WheelEventSignal().Connect(this, &ItemView::OnWheelEvent);
 
-  DevelControl::SetAccessibilityConstructor(self, [](Dali::Actor actor) {
-    return std::unique_ptr<Dali::Accessibility::Accessible>(new AccessibleImpl(actor, Dali::Accessibility::Role::SCROLL_PANE));
-  });
+  self.SetProperty(DevelControl::Property::ACCESSIBILITY_ROLE, Dali::Accessibility::Role::SCROLL_PANE);
+}
+
+DevelControl::ControlAccessible* ItemView::CreateAccessibleObject()
+{
+  return new ItemViewAccessible(Self());
 }
 
 ItemView::~ItemView()
@@ -1345,7 +1348,7 @@ void ItemView::OnKeyboardFocusChangeCommitted(Actor commitedFocusableActor)
   }
 }
 
-bool ItemView::AccessibleImpl::ScrollToChild(Actor child)
+bool ItemView::ItemViewAccessible::ScrollToChild(Actor child)
 {
   auto itemView = Dali::Toolkit::ItemView::DownCast(Self());
   Toolkit::GetImpl(itemView).OnKeyboardFocusChangeCommitted(child);
index 7e3d8c1..b388e22 100644 (file)
@@ -419,6 +419,11 @@ private: // From Control
   void OnInitialize() override;
 
   /**
+   * @copydoc Toolkit::Internal::Control::CreateAccessibleObject()
+   */
+  DevelControl::ControlAccessible* CreateAccessibleObject() override;
+
+  /**
    * @copydoc Toolkit::Control::OnAccessibilityPan()
    */
   bool OnAccessibilityPan(PanGesture gesture) override;
@@ -434,10 +439,14 @@ private: // From Control
   void OnKeyboardFocusChangeCommitted(Actor commitedFocusableActor) override;
 
 protected:
-  struct AccessibleImpl : public Scrollable::AccessibleImpl
+  class ItemViewAccessible : public Scrollable::ScrollableAccessible
   {
-    using Scrollable::AccessibleImpl::AccessibleImpl;
+  public:
+    using Scrollable::ScrollableAccessible::ScrollableAccessible;
 
+    /**
+     * @copydoc Dali::Toolkit::DevelControl::ControlAccessible::ScrollToChild()
+     */
     bool ScrollToChild(Actor child) override;
   };
 
index 218f6ae..0dceb47 100644 (file)
@@ -680,10 +680,12 @@ void ScrollView::OnInitialize()
   // Connect wheel event
   self.WheelEventSignal().Connect(this, &ScrollView::OnWheelEvent);
 
-  DevelControl::SetAccessibilityConstructor(Self(), [](Dali::Actor actor) {
-    return std::unique_ptr<Dali::Accessibility::Accessible>(
-      new AccessibleImpl(actor, Dali::Accessibility::Role::SCROLL_PANE));
-  });
+  self.SetProperty(DevelControl::Property::ACCESSIBILITY_ROLE, Dali::Accessibility::Role::SCROLL_PANE);
+}
+
+DevelControl::ControlAccessible* ScrollView::CreateAccessibleObject()
+{
+  return new ScrollViewAccessible(Self());
 }
 
 void ScrollView::OnSceneConnection(int depth)
@@ -1262,7 +1264,7 @@ Toolkit::ScrollView::SnapStartedSignalType& ScrollView::SnapStartedSignal()
   return mSnapStartedSignal;
 }
 
-bool ScrollView::AccessibleImpl::ScrollToChild(Actor child)
+bool ScrollView::ScrollViewAccessible::ScrollToChild(Actor child)
 {
   auto scrollView = Dali::Toolkit::ScrollView::DownCast(Self());
   if(Toolkit::GetImpl(scrollView).FindClosestActor() == child)
index 4061727..d9dddfc 100644 (file)
@@ -661,6 +661,11 @@ private: // private overridden functions from CustomActorImpl and Controls
   void OnInitialize() override;
 
   /**
+   * @copydoc Toolkit::Internal::Control::CreateAccessibleObject()
+   */
+  DevelControl::ControlAccessible* CreateAccessibleObject() override;
+
+  /**
    * @copydoc CustomActorImpl::OnSceneConnection()
    */
   void OnSceneConnection(int depth) override;
@@ -841,10 +846,14 @@ private:
   void WrapPosition(Vector2& position) const;
 
 protected:
-  struct AccessibleImpl : public Scrollable::AccessibleImpl
+  class ScrollViewAccessible : public Scrollable::ScrollableAccessible
   {
-    using Scrollable::AccessibleImpl::AccessibleImpl;
+  public:
+    using Scrollable::ScrollableAccessible::ScrollableAccessible;
 
+    /**
+     * @copydoc Dali::Toolkit::DevelControl::ControlAccessible::ScrollToChild()
+     */
     bool ScrollToChild(Actor child) override;
   };
 
index ea3240f..7c12348 100644 (file)
@@ -92,17 +92,19 @@ Scrollable::~Scrollable()
 {
 }
 
-bool Scrollable::AccessibleImpl::IsScrollable() const
+bool Scrollable::ScrollableAccessible::IsScrollable() const
 {
   return true;
 }
 
 void Scrollable::OnInitialize()
 {
-  DevelControl::SetAccessibilityConstructor(Self(), [](Dali::Actor actor) {
-    return std::unique_ptr<Dali::Accessibility::Accessible>(
-      new AccessibleImpl(actor, Dali::Accessibility::Role::SCROLL_PANE));
-  });
+  Self().SetProperty(DevelControl::Property::ACCESSIBILITY_ROLE, Dali::Accessibility::Role::SCROLL_PANE);
+}
+
+DevelControl::ControlAccessible* Scrollable::CreateAccessibleObject()
+{
+  return new ScrollableAccessible(Self());
 }
 
 bool Scrollable::IsOvershootEnabled() const
index 44d9a33..5e30b86 100644 (file)
@@ -117,10 +117,14 @@ public:
   virtual void SetOvershootSize(const Vector2& size) = 0;
 
 protected: // From Control
-  struct AccessibleImpl : public DevelControl::ControlAccessible
+  class ScrollableAccessible : public DevelControl::ControlAccessible
   {
+  public:
     using DevelControl::ControlAccessible::ControlAccessible;
 
+    /**
+     * @copydoc Dali::Accessibility::Component::IsScrollable()
+     */
     bool IsScrollable() const override;
   };
 
@@ -129,6 +133,11 @@ protected: // From Control
    */
   virtual void OnInitialize() override;
 
+  /**
+   * @copydoc Toolkit::Internal::Control::CreateAccessibleObject()
+   */
+  DevelControl::ControlAccessible* CreateAccessibleObject() override;
+
 private:
   /**
    * Temporary function to override EnableScrollOvershoot functionality for overshoot
index 1197a46..9140b97 100644 (file)
@@ -256,10 +256,7 @@ void ShadowView::OnInitialize()
   blurStrengthConstraint.AddSource(Source(self, mBlurStrengthPropertyIndex));
   blurStrengthConstraint.Apply();
 
-  DevelControl::SetAccessibilityConstructor(Self(), [](Dali::Actor actor) {
-    return std::unique_ptr<Dali::Accessibility::Accessible>(
-      new DevelControl::ControlAccessible(actor, Dali::Accessibility::Role::FILLER));
-  });
+  Self().SetProperty(DevelControl::Property::ACCESSIBILITY_ROLE, Dali::Accessibility::Role::FILLER);
 }
 
 void ShadowView::OnChildAdd(Actor& child)
index 7e6370d..a48ddbe 100644 (file)
@@ -202,16 +202,17 @@ void Slider::OnInitialize()
   // Size the Slider actor to a default
   self.SetProperty(Actor::Property::SIZE, Vector2(DEFAULT_HIT_REGION.x, DEFAULT_HIT_REGION.y));
 
-  // Set the Slider to be highlightable in Screen Reader mode
-  self.SetProperty(Toolkit::DevelControl::Property::ACCESSIBILITY_HIGHLIGHTABLE, true);
-
   // Connect to the touch signal
   self.TouchedSignal().Connect(this, &Slider::OnTouch);
 
-  DevelControl::SetAccessibilityConstructor(self, [](Dali::Actor actor) {
-    return std::unique_ptr<Dali::Accessibility::Accessible>(
-      new AccessibleImpl(actor, Dali::Accessibility::Role::SLIDER));
-  });
+  // Accessibility
+  self.SetProperty(DevelControl::Property::ACCESSIBILITY_ROLE, Dali::Accessibility::Role::SLIDER);
+  self.SetProperty(DevelControl::Property::ACCESSIBILITY_HIGHLIGHTABLE, true);
+}
+
+DevelControl::ControlAccessible* Slider::CreateAccessibleObject()
+{
+  return new SliderAccessible(Self());
 }
 
 void Slider::OnRelayout(const Vector2& size, RelayoutContainer& container)
@@ -950,7 +951,7 @@ void Slider::SetValue(float value)
   DisplayValue(mValue, true);
   if(Self() == Dali::Accessibility::Accessible::GetCurrentlyHighlightedActor())
   {
-    Control::Impl::GetAccessibilityObject(Self())->Emit(Dali::Accessibility::ObjectPropertyChangeEvent::VALUE);
+    GetAccessibleObject()->Emit(Dali::Accessibility::ObjectPropertyChangeEvent::VALUE);
   }
 }
 
@@ -1411,25 +1412,25 @@ Property::Value Slider::GetProperty(BaseObject* object, Property::Index property
   return value;
 }
 
-double Slider::AccessibleImpl::GetMinimum() const
+double Slider::SliderAccessible::GetMinimum() const
 {
   auto self = Toolkit::Slider::DownCast(Self());
   return self.GetProperty(Toolkit::Slider::Property::LOWER_BOUND).Get<float>();
 }
 
-double Slider::AccessibleImpl::GetCurrent() const
+double Slider::SliderAccessible::GetCurrent() const
 {
   auto self = Toolkit::Slider::DownCast(Self());
   return self.GetProperty(Toolkit::Slider::Property::VALUE).Get<float>();
 }
 
-double Slider::AccessibleImpl::GetMaximum() const
+double Slider::SliderAccessible::GetMaximum() const
 {
   auto self = Toolkit::Slider::DownCast(Self());
   return self.GetProperty(Toolkit::Slider::Property::UPPER_BOUND).Get<float>();
 }
 
-bool Slider::AccessibleImpl::SetCurrent(double current)
+bool Slider::SliderAccessible::SetCurrent(double current)
 {
   if(current < GetMinimum() || current > GetMaximum())
     return false;
@@ -1477,7 +1478,7 @@ bool Slider::AccessibleImpl::SetCurrent(double current)
   return true;
 }
 
-double Slider::AccessibleImpl::GetMinimumIncrement() const
+double Slider::SliderAccessible::GetMinimumIncrement() const
 {
   auto self = Toolkit::Slider::DownCast(Self());
 
index 7385953..7bf3e2a 100644 (file)
@@ -319,6 +319,11 @@ private:
   void OnInitialize() override;
 
   /**
+   * @copydoc Toolkit::Internal::Control::CreateAccessibleObject()
+   */
+  DevelControl::ControlAccessible* CreateAccessibleObject() override;
+
+  /**
    * Hit region touch
    *
    * @param[in] actor The actor the event is raised for
@@ -749,15 +754,35 @@ private:
     mSnapToMarks : 1;  ///< Turn on or off snapping to marks
 
 protected:
-  struct AccessibleImpl : public DevelControl::ControlAccessible,
-                          public virtual Dali::Accessibility::Value
+  class SliderAccessible : public DevelControl::ControlAccessible,
+                           public virtual Dali::Accessibility::Value
   {
+  public:
     using DevelControl::ControlAccessible::ControlAccessible;
 
+    /**
+     * @copydoc Dali::Accessibility::Value::GetMinimum()
+     */
     double GetMinimum() const override;
+
+    /**
+     * @copydoc Dali::Accessibility::Value::GetCurrent()
+     */
     double GetCurrent() const override;
+
+    /**
+     * @copydoc Dali::Accessibility::Value::GetMaximum()
+     */
     double GetMaximum() const override;
-    bool   SetCurrent(double) override;
+
+    /**
+     * @copydoc Dali::Accessibility::Value::SetCurrent()
+     */
+    bool SetCurrent(double) override;
+
+    /**
+     * @copydoc Dali::Accessibility::Value::GetMinimumIncrement()
+     */
     double GetMinimumIncrement() const override;
   };
 };
index ad90105..7ea1492 100644 (file)
@@ -149,10 +149,7 @@ void SuperBlurView::OnInitialize()
 
   mBlurStrengthPropertyIndex = self.RegisterUniqueProperty("blurStrength", 0.f);
 
-  DevelControl::SetAccessibilityConstructor(self, [](Dali::Actor actor) {
-    return std::unique_ptr<Dali::Accessibility::Accessible>(
-      new DevelControl::ControlAccessible(actor, Dali::Accessibility::Role::FILLER));
-  });
+  self.SetProperty(DevelControl::Property::ACCESSIBILITY_ROLE, Dali::Accessibility::Role::FILLER);
 }
 
 void SuperBlurView::SetTexture(Texture texture)
index 2426775..2afc0da 100644 (file)
@@ -1119,10 +1119,7 @@ void TableView::OnInitialize()
   self.SetProperty(Actor::Property::KEYBOARD_FOCUSABLE, true);
   SetAsKeyboardFocusGroup(true);
 
-  DevelControl::SetAccessibilityConstructor(self, [](Dali::Actor actor) {
-    return std::unique_ptr<Dali::Accessibility::Accessible>(
-      new DevelControl::ControlAccessible(actor, Dali::Accessibility::Role::TABLE));
-  });
+  self.SetProperty(DevelControl::Property::ACCESSIBILITY_ROLE, Dali::Accessibility::Role::TABLE);
 }
 
 void TableView::ResizeContainers(unsigned int rows, unsigned int columns)
index 696b44a..833b81b 100644 (file)
  * limitations under the License.
  */
 
+// EXTERNAL INCLUDES
 #include <dali/public-api/actors/layer.h>
 
+// INTERNAL INCLUDES
 #include <dali-toolkit/devel-api/controls/control-depth-index-ranges.h>
 #include <dali-toolkit/devel-api/controls/control-devel.h>
+#include <dali-toolkit/devel-api/focus-manager/keyinput-focus-manager.h>
 #include <dali-toolkit/internal/controls/text-controls/common-text-utils.h>
+#include <dali-toolkit/internal/text/character-set-conversion.h>
+#include <dali-toolkit/internal/text/hidden-text.h>
 #include <dali-toolkit/internal/text/text-view.h>
 
 namespace Dali::Toolkit::Internal
@@ -151,4 +156,344 @@ void CommonTextUtils::RenderText(
   }
 }
 
+std::size_t TextControlAccessible::GetCharacterCount() const
+{
+  return GetWholeText().size();
+}
+
+std::size_t TextControlAccessible::GetCursorOffset() const
+{
+  return 0u;
+}
+
+Rect<> TextControlAccessible::GetRangeExtents(std::size_t startOffset, std::size_t endOffset, Accessibility::CoordinateType type)
+{
+  if(!ValidateRange(GetWholeText(), startOffset, endOffset))
+  {
+    return {0, 0, 0, 0};
+  }
+
+  auto rect    = GetTextController()->GetTextBoundingRectangle(startOffset, endOffset - 1);
+  auto extents = GetExtents(type);
+
+  rect.x += extents.x;
+  rect.y += extents.y;
+
+  return rect;
+}
+
+Accessibility::Range TextControlAccessible::GetRangeOfSelection(std::size_t selectionIndex) const
+{
+  // Since DALi supports only one selection, indices other than 0 are ignored
+  if(selectionIndex > 0)
+  {
+    return {};
+  }
+
+  auto indices     = GetTextController()->GetSelectionIndexes();
+  auto startOffset = static_cast<std::size_t>(indices.first);
+  auto endOffset   = static_cast<std::size_t>(indices.second);
+  auto text        = GetText(startOffset, endOffset);
+
+  return {startOffset, endOffset, text};
+}
+
+std::string TextControlAccessible::GetText(std::size_t startOffset, std::size_t endOffset) const
+{
+  auto text = GetWholeText();
+
+  if(!ValidateRange(text, startOffset, endOffset))
+  {
+    return {};
+  }
+
+  if(IsHiddenInput())
+  {
+    std::uint32_t substituteCharacterUtf32 = GetSubstituteCharacter();
+    std::string   substituteCharacterUtf8;
+    std::string   substituteText;
+
+    Toolkit::Text::Utf32ToUtf8(&substituteCharacterUtf32, 1, substituteCharacterUtf8);
+
+    while(substituteText.length() < endOffset - startOffset)
+    {
+      substituteText.append(substituteCharacterUtf8);
+    }
+
+    return substituteText;
+  }
+
+  return text.substr(startOffset, endOffset - startOffset);
+}
+
+Accessibility::Range TextControlAccessible::GetTextAtOffset(std::size_t offset, Accessibility::TextBoundary boundary) const
+{
+  Accessibility::Range range{};
+
+  if(IsHiddenInput())
+  {
+    // Returning empty object, as there is no possibility to parse the textfield
+    // when its content is hidden.
+    return range;
+  }
+
+  auto text     = GetWholeText();
+  auto textSize = text.size();
+
+  switch(boundary)
+  {
+    case Dali::Accessibility::TextBoundary::CHARACTER:
+    {
+      if(offset < textSize)
+      {
+        range.content     = text[offset];
+        range.startOffset = offset;
+        range.endOffset   = offset + 1;
+      }
+      break;
+    }
+
+    case Dali::Accessibility::TextBoundary::WORD:
+    case Dali::Accessibility::TextBoundary::LINE:
+    {
+      std::vector<char> breaks(textSize, '\0');
+
+      if(boundary == Dali::Accessibility::TextBoundary::WORD)
+      {
+        Accessibility::Accessible::FindWordSeparationsUtf8(reinterpret_cast<const utf8_t*>(text.c_str()), textSize, "", breaks.data());
+      }
+      else
+      {
+        Accessibility::Accessible::FindLineSeparationsUtf8(reinterpret_cast<const utf8_t*>(text.c_str()), textSize, "", breaks.data());
+      }
+
+      std::size_t index   = 0u;
+      std::size_t counter = 0u;
+
+      while(index < textSize && counter <= offset)
+      {
+        auto start = index;
+        if(breaks[index])
+        {
+          while(breaks[index])
+          {
+            index++;
+          }
+          counter++;
+        }
+        else
+        {
+          if(boundary == Dali::Accessibility::TextBoundary::WORD)
+          {
+            index++;
+          }
+          if(boundary == Dali::Accessibility::TextBoundary::LINE)
+          {
+            counter++;
+          }
+        }
+
+        if((counter > 0) && ((counter - 1) == offset))
+        {
+          range.content     = text.substr(start, index - start + 1);
+          range.startOffset = start;
+          range.endOffset   = index + 1;
+        }
+
+        if(boundary == Dali::Accessibility::TextBoundary::LINE)
+        {
+          index++;
+        }
+      }
+      break;
+    }
+
+    case Dali::Accessibility::TextBoundary::SENTENCE: // Not supported by default
+    case Dali::Accessibility::TextBoundary::PARAGRAPH: // Not supported by libunibreak library
+    default:
+    {
+      break;
+    }
+  }
+
+  return range;
+}
+
+bool TextControlAccessible::RemoveSelection(std::size_t selectionIndex)
+{
+  // Since DALi supports only one selection, indices other than 0 are ignored
+  if(selectionIndex > 0)
+  {
+    return false;
+  }
+
+  GetTextController()->SetSelection(0, 0);
+
+  return true;
+}
+
+bool TextControlAccessible::SetCursorOffset(std::size_t offset)
+{
+  return false;
+}
+
+bool TextControlAccessible::SetRangeOfSelection(std::size_t selectionIndex, std::size_t startOffset, std::size_t endOffset)
+{
+  // Since DALi supports only one selection, indices other than 0 are ignored
+  if(selectionIndex > 0)
+  {
+    return false;
+  }
+
+  // Lack of ValidateRange() is intentional
+
+  GetTextController()->SetSelection(startOffset, endOffset);
+
+  return true;
+}
+
+Accessibility::Hyperlink* TextControlAccessible::GetLink(std::int32_t linkIndex) const
+{
+  if(linkIndex < 0 || linkIndex >= GetLinkCount())
+  {
+    return nullptr;
+  }
+
+  auto anchor = GetTextAnchors()[linkIndex];
+
+  return Accessibility::Hyperlink::DownCast(Accessibility::Accessible::Get(anchor));
+}
+
+std::int32_t TextControlAccessible::GetLinkCount() const
+{
+  return static_cast<std::int32_t>(GetTextAnchors().size());
+}
+
+std::int32_t TextControlAccessible::GetLinkIndex(std::int32_t characterOffset) const
+{
+  return GetTextController()->GetAnchorIndex(static_cast<std::size_t>(characterOffset));
+}
+
+std::string TextControlAccessible::GetWholeText() const
+{
+  std::string text;
+
+  GetTextController()->GetText(text);
+
+  return text;
+}
+
+std::uint32_t TextControlAccessible::GetSubstituteCharacter() const
+{
+  return Toolkit::Text::STAR;
+}
+
+bool TextControlAccessible::IsHiddenInput() const
+{
+  return false;
+}
+
+bool TextControlAccessible::ValidateRange(const std::string& string, std::size_t begin, std::size_t end)
+{
+  auto size = string.size();
+
+  if(end <= begin || begin >= size || end > size)
+  {
+    return false;
+  }
+
+  // TODO: Check whether the range [begin, end) describes a valid substring:
+  // 1. It does not break multi-byte UTF-8 sequences.
+  // 2. It does not break graphemes (compound emojis, glyphs with combining characters etc.).
+
+  return true;
+}
+
+Accessibility::States EditableTextControlAccessible::CalculateStates()
+{
+  using Dali::Accessibility::State;
+
+  auto states       = DevelControl::ControlAccessible::CalculateStates();
+  auto focusControl = Toolkit::KeyInputFocusManager::Get().GetCurrentFocusControl();
+
+  states[State::EDITABLE]  = true;
+  states[State::FOCUSABLE] = true;
+  states[State::FOCUSED]   = (Self() == focusControl);
+
+  return states;
+}
+
+std::size_t EditableTextControlAccessible::GetCursorOffset() const
+{
+  return GetTextController()->GetCursorPosition();
+}
+
+bool EditableTextControlAccessible::SetCursorOffset(std::size_t offset)
+{
+  if(offset > GetCharacterCount())
+  {
+    return false;
+  }
+
+  GetTextController()->ResetCursorPosition(offset);
+  RequestTextRelayout();
+
+  return true;
+}
+
+bool EditableTextControlAccessible::CopyText(std::size_t startPosition, std::size_t endPosition)
+{
+  auto text = GetWholeText();
+
+  if(!ValidateRange(text, startPosition, endPosition))
+  {
+    return false;
+  }
+
+  GetTextController()->CopyStringToClipboard(text.substr(startPosition, endPosition - startPosition));
+
+  return true;
+}
+
+bool EditableTextControlAccessible::CutText(std::size_t startPosition, std::size_t endPosition)
+{
+  if(!CopyText(startPosition, endPosition))
+  {
+    return false;
+  }
+
+  return DeleteText(startPosition, endPosition);
+}
+
+bool EditableTextControlAccessible::DeleteText(std::size_t startPosition, std::size_t endPosition)
+{
+  auto text = GetWholeText();
+
+  if(!ValidateRange(text, startPosition, endPosition))
+  {
+    return false;
+  }
+
+  return SetTextContents(text.erase(startPosition, endPosition - startPosition));
+}
+
+bool EditableTextControlAccessible::InsertText(std::size_t startPosition, std::string newText)
+{
+  auto text = GetWholeText();
+
+  if(!ValidateRange(text, startPosition, startPosition + 1))
+  {
+    return false;
+  }
+
+  return SetTextContents(text.insert(startPosition, std::move(newText)));
+}
+
+bool EditableTextControlAccessible::SetTextContents(std::string newContents)
+{
+  GetTextController()->SetText(std::move(newContents));
+
+  return true;
+}
+
 } // namespace Dali::Toolkit::Internal
index 212f162..f6a9a2f 100644 (file)
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+
+// EXTERNAL INCLUDES
+#include <dali/devel-api/atspi-interfaces/editable-text.h>
+#include <dali/devel-api/atspi-interfaces/hypertext.h>
+#include <dali/devel-api/atspi-interfaces/text.h>
+#include <dali/public-api/actors/actor.h>
+#include <dali/public-api/common/vector-wrapper.h>
+
+// INTERNAL INCLUDES
+#include <dali-toolkit/devel-api/controls/control-accessible.h>
 #include <dali-toolkit/devel-api/controls/text-controls/text-anchor-devel.h>
 #include <dali-toolkit/internal/text/decorator/text-decorator.h>
 #include <dali-toolkit/internal/text/rendering/text-renderer.h>
 #include <dali-toolkit/internal/text/text-controller.h>
 #include <dali-toolkit/public-api/controls/control.h>
 #include <dali-toolkit/public-api/controls/text-controls/text-editor.h>
-#include <dali/public-api/actors/actor.h>
-
-#include <dali/public-api/common/vector-wrapper.h>
 
 namespace Dali::Toolkit::Internal
 {
@@ -70,6 +77,181 @@ public:
     std::vector<Toolkit::TextAnchor>& anchorActors);
 };
 
+class TextControlAccessible : public DevelControl::ControlAccessible,
+                              public virtual Dali::Accessibility::Text,
+                              public virtual Dali::Accessibility::Hypertext
+{
+public:
+  using DevelControl::ControlAccessible::ControlAccessible;
+
+  // Text
+
+  /**
+   * @copydoc Dali::Accessibility::Text::GetCharacterCount()
+   */
+  std::size_t GetCharacterCount() const override;
+
+  /**
+   * @copydoc Dali::Accessibility::Text::GetCursorOffset()
+   */
+  std::size_t GetCursorOffset() const override;
+
+  /**
+   * @copydoc Dali::Accessibility::Text::GetRangeExtents()
+   */
+  Rect<> GetRangeExtents(std::size_t startOffset, std::size_t endOffset, Accessibility::CoordinateType type) override;
+
+  /**
+   * @copydoc Dali::Accessibility::Text::GetRangeOfSelection()
+   */
+  Accessibility::Range GetRangeOfSelection(std::size_t selectionIndex) const override;
+
+  /**
+   * @copydoc Dali::Accessibility::Text::GetText()
+   */
+  std::string GetText(std::size_t startOffset, std::size_t endOffset) const override;
+
+  /**
+   * @copydoc Dali::Accessibility::Text::GetTextAtOffset()
+   */
+  Accessibility::Range GetTextAtOffset(std::size_t offset, Accessibility::TextBoundary boundary) const override;
+
+  /**
+   * @copydoc Dali::Accessibility::Text::RemoveSelection()
+   */
+  bool RemoveSelection(std::size_t selectionIndex) override;
+
+  /**
+   * @copydoc Dali::Accessibility::Text::SetCursorOffset()
+   */
+  bool SetCursorOffset(std::size_t offset) override;
+
+  /**
+   * @copydoc Dali::Accessibility::Text::SetRangeOfSelection()
+   */
+  bool SetRangeOfSelection(std::size_t selectionIndex, std::size_t startOffset, std::size_t endOffset) override;
+
+  // Hypertext
+
+  /**
+   * @copydoc Dali::Accessibility::Hypertext::GetLink()
+   */
+  Accessibility::Hyperlink* GetLink(std::int32_t linkIndex) const override;
+
+  /**
+   * @copydoc Dali::Accessibility::Hypertext::GetLinkCount()
+   */
+  std::int32_t GetLinkCount() const override;
+
+  /**
+   * @copydoc Dali::Accessibility::Hypertext::GetLinkIndex()
+   */
+  std::int32_t GetLinkIndex(std::int32_t characterOffset) const override;
+
+protected:
+  /**
+   * @brief Gets whole text.
+   *
+   * @return The text
+   */
+  std::string GetWholeText() const;
+
+  /**
+   * @brief Gets text anchors.
+   *
+   * @return Text anchors
+   */
+  virtual const std::vector<Toolkit::TextAnchor>& GetTextAnchors() const = 0;
+
+  /**
+   * @brief Gets text controller.
+   *
+   * @return The text controller
+   */
+  virtual Toolkit::Text::ControllerPtr GetTextController() const = 0;
+
+  /**
+   * @brief Get substitute character for hidden text.
+   *
+   * @return The substitute character (Unicode codepoint)
+   */
+  virtual std::uint32_t GetSubstituteCharacter() const;
+
+  /**
+   * @brief Checks whether text should be hidden (replaced with substitute characters).
+   *
+   * @return True if text should be hidden, false otherwise
+   */
+  virtual bool IsHiddenInput() const;
+
+  /**
+   * @brief Checks whether [startPosition, endPosition) is a valid, non-empty range within a given string.
+   *
+   * @param string Source string
+   * @param begin Start index (inclusive)
+   * @param end End index (exclusive)
+   * @return true if the range is valid, false otherwise
+   */
+  static bool ValidateRange(const std::string& string, std::size_t begin, std::size_t end);
+};
+
+class EditableTextControlAccessible : public TextControlAccessible,
+                                      public virtual Dali::Accessibility::EditableText
+{
+public:
+  using TextControlAccessible::TextControlAccessible;
+
+  /**
+   * @copydoc Dali::Toolkit::DevelControl::ControlAccessible::CalculateStates()
+   */
+  Accessibility::States CalculateStates() override;
+
+  // Text
+
+  /**
+   * @copydoc Dali::Accessibility::Text::GetCursorOffset()
+   */
+  std::size_t GetCursorOffset() const override;
+
+  /**
+   * @copydoc Dali::Accessibility::Text::SetCursorOffset()
+   */
+  bool SetCursorOffset(std::size_t offset) override;
+
+  // EditableText
+
+  /**
+   * @copydoc Dali::Accessibility::EditableText::CopyText()
+   */
+  bool CopyText(size_t startPosition, size_t endPosition) override;
+
+  /**
+   * @copydoc Dali::Accessibility::EditableText::CutText()
+   */
+  bool CutText(size_t startPosition, size_t endPosition) override;
+
+  /**
+   * @copydoc Dali::Accessibility::EditableText::DeleteText()
+   */
+  bool DeleteText(size_t startPosition, size_t endPosition) override;
+
+  /**
+   * @copydoc Dali::Accessibility::EditableText::InsertText()
+   */
+  bool InsertText(size_t startPosition, std::string text) override;
+
+  /**
+   * @copydoc Dali::Accessibility::EditableText::SetTextContents()
+   */
+  bool SetTextContents(std::string newContents) override;
+
+protected:
+  /**
+   * @brief Requests text relayout.
+   */
+  virtual void RequestTextRelayout() = 0;
+};
+
 } // namespace Dali::Toolkit::Internal
 
 #endif //DALI_TOOLKIT_INTERNAL_TEXT_CONTROLS_COMMON_TEXT_UTILS_H
index 37831ea..8abb0ae 100644 (file)
@@ -145,13 +145,14 @@ void TextAnchor::OnInitialize()
 {
   Actor self = Self();
 
-  // Enable highlightability
-  self.SetProperty(Toolkit::DevelControl::Property::ACCESSIBILITY_HIGHLIGHTABLE, true);
+  // Accessibility
+  self.SetProperty(DevelControl::Property::ACCESSIBILITY_ROLE, Dali::Accessibility::Role::LINK);
+  self.SetProperty(DevelControl::Property::ACCESSIBILITY_HIGHLIGHTABLE, true);
+}
 
-  DevelControl::SetAccessibilityConstructor(self, [](Dali::Actor actor) {
-    return std::unique_ptr<Dali::Accessibility::Accessible>(
-      new AccessibleImpl(actor, Dali::Accessibility::Role::LINK));
-  });
+DevelControl::ControlAccessible* TextAnchor::CreateAccessibleObject()
+{
+  return new TextAnchorAccessible(Self());
 }
 
 TextAnchor::TextAnchor()
@@ -166,35 +167,35 @@ TextAnchor::~TextAnchor()
 {
 }
 
-int32_t TextAnchor::AccessibleImpl::GetEndIndex() const
+int32_t TextAnchor::TextAnchorAccessible::GetEndIndex() const
 {
   auto self = Toolkit::TextAnchor::DownCast(Self());
   return self.GetProperty(Toolkit::TextAnchor::Property::END_CHARACTER_INDEX).Get<int>();
 }
 
-int32_t TextAnchor::AccessibleImpl::GetStartIndex() const
+int32_t TextAnchor::TextAnchorAccessible::GetStartIndex() const
 {
   auto self = Toolkit::TextAnchor::DownCast(Self());
   return self.GetProperty(Toolkit::TextAnchor::Property::START_CHARACTER_INDEX).Get<int>();
 }
 
-int32_t TextAnchor::AccessibleImpl::GetAnchorCount() const
+int32_t TextAnchor::TextAnchorAccessible::GetAnchorCount() const
 {
   return 1;
 }
 
-Dali::Accessibility::Accessible* TextAnchor::AccessibleImpl::GetAnchorAccessible(int32_t anchorIndex) const
+Dali::Accessibility::Accessible* TextAnchor::TextAnchorAccessible::GetAnchorAccessible(int32_t anchorIndex) const
 {
-  return Control::Impl::GetAccessibilityObject(Self());
+  return const_cast<TextAnchorAccessible*>(this);
 }
 
-std::string TextAnchor::AccessibleImpl::GetAnchorUri(int32_t anchorIndex) const
+std::string TextAnchor::TextAnchorAccessible::GetAnchorUri(int32_t anchorIndex) const
 {
   auto self = Toolkit::TextAnchor::DownCast(Self());
   return self.GetProperty(Toolkit::TextAnchor::Property::URI).Get<std::string>();
 }
 
-bool TextAnchor::AccessibleImpl::IsValid() const
+bool TextAnchor::TextAnchorAccessible::IsValid() const
 {
   return !GetAnchorUri(0).empty();
 }
index e26006d..8b32bdd 100644 (file)
@@ -71,6 +71,11 @@ private: // From Control
   void OnInitialize() override;
 
   /**
+   * @copydoc Toolkit::Internal::Control::CreateAccessibleObject()
+   */
+  DevelControl::ControlAccessible* CreateAccessibleObject() override;
+
+  /**
    * @copydoc Control::OnPropertySet()
    */
   // void OnPropertySet(Property::Index index, const Property::Value& propertyValue) override;
@@ -105,10 +110,12 @@ protected:
   /**
    * @brief This structure is to connect TextAnchor with Accessible functions.
    */
-  struct AccessibleImpl : public DevelControl::ControlAccessible,
-                          public virtual Dali::Accessibility::Hyperlink
+  class TextAnchorAccessible : public DevelControl::ControlAccessible,
+                               public virtual Dali::Accessibility::Hyperlink
   {
+  public:
     using DevelControl::ControlAccessible::ControlAccessible;
+
     /**
      * @copydoc Dali::Accessibility::Hyperlink::GetEndIndex()
      */
index 6202c8f..d3c0154 100644 (file)
@@ -33,7 +33,6 @@
 
 // INTERNAL INCLUDES
 #include <dali-toolkit/devel-api/controls/control-devel.h>
-#include <dali-toolkit/devel-api/focus-manager/keyinput-focus-manager.h>
 #include <dali-toolkit/devel-api/text/rendering-backend.h>
 #include <dali-toolkit/internal/controls/control/control-data-impl.h>
 #include <dali-toolkit/internal/controls/text-controls/common-text-utils.h>
@@ -583,9 +582,6 @@ void TextEditor::OnInitialize()
   self.SetResizePolicy(ResizePolicy::FILL_TO_PARENT, Dimension::HEIGHT);
   self.OnSceneSignal().Connect(this, &TextEditor::OnSceneConnect);
 
-  //Enable highightability
-  self.SetProperty(Toolkit::DevelControl::Property::ACCESSIBILITY_HIGHLIGHTABLE, true);
-
   DevelControl::SetInputMethodContext(*this, mInputMethodContext);
 
   // Creates an extra control to be used as stencil buffer.
@@ -603,15 +599,19 @@ void TextEditor::OnInitialize()
 
   self.Add(mStencil);
 
-  DevelControl::SetAccessibilityConstructor(self, [](Dali::Actor actor) {
-    return std::unique_ptr<Dali::Accessibility::Accessible>(
-      new AccessibleImpl(actor, Dali::Accessibility::Role::ENTRY));
-  });
+  // Accessibility
+  self.SetProperty(DevelControl::Property::ACCESSIBILITY_ROLE, Dali::Accessibility::Role::ENTRY);
+  self.SetProperty(DevelControl::Property::ACCESSIBILITY_HIGHLIGHTABLE, true);
 
   Accessibility::Bridge::EnabledSignal().Connect(this, &TextEditor::OnAccessibilityStatusChanged);
   Accessibility::Bridge::DisabledSignal().Connect(this, &TextEditor::OnAccessibilityStatusChanged);
 }
 
+DevelControl::ControlAccessible* TextEditor::CreateAccessibleObject()
+{
+  return new TextEditorAccessible(Self());
+}
+
 void TextEditor::OnStyleChange(Toolkit::StyleManager styleManager, StyleChange::Type change)
 {
   DALI_LOG_INFO(gTextEditorLogFilter, Debug::Verbose, "TextEditor::OnStyleChange\n");
@@ -909,26 +909,17 @@ void TextEditor::RequestTextRelayout()
 
 void TextEditor::TextInserted(unsigned int position, unsigned int length, const std::string& content)
 {
-  if(Accessibility::IsUp())
-  {
-    Control::Impl::GetAccessibilityObject(Self())->EmitTextInserted(position, length, content);
-  }
+  GetAccessibleObject()->EmitTextInserted(position, length, content);
 }
 
 void TextEditor::TextDeleted(unsigned int position, unsigned int length, const std::string& content)
 {
-  if(Accessibility::IsUp())
-  {
-    Control::Impl::GetAccessibilityObject(Self())->EmitTextDeleted(position, length, content);
-  }
+  GetAccessibleObject()->EmitTextDeleted(position, length, content);
 }
 
 void TextEditor::CursorPositionChanged(unsigned int oldPosition, unsigned int newPosition)
 {
-  if(Accessibility::IsUp())
-  {
-    Control::Impl::GetAccessibilityObject(Self())->EmitTextCursorMoved(newPosition);
-  }
+  GetAccessibleObject()->EmitTextCursorMoved(newPosition);
 
   if((oldPosition != newPosition) && !mCursorPositionChanged)
   {
@@ -1349,315 +1340,31 @@ TextEditor::~TextEditor()
   }
 }
 
-std::string TextEditor::AccessibleImpl::GetName() const
-{
-  auto self = Toolkit::TextEditor::DownCast(Self());
-  return self.GetProperty(Toolkit::TextEditor::Property::TEXT).Get<std::string>();
-}
-
-std::string TextEditor::AccessibleImpl::GetText(size_t startOffset, size_t endOffset) const
-{
-  if(endOffset <= startOffset)
-  {
-    return {};
-  }
-
-  auto self = Toolkit::TextEditor::DownCast(Self());
-  auto text = self.GetProperty(Toolkit::TextEditor::Property::TEXT).Get<std::string>();
-
-  if(startOffset > text.size() || endOffset > text.size())
-  {
-    return {};
-  }
-
-  return text.substr(startOffset, endOffset - startOffset);
-}
-
-size_t TextEditor::AccessibleImpl::GetCharacterCount() const
-{
-  auto self = Toolkit::TextEditor::DownCast(Self());
-  auto text = self.GetProperty(Toolkit::TextEditor::Property::TEXT).Get<std::string>();
-
-  return text.size();
-}
-
-size_t TextEditor::AccessibleImpl::GetCursorOffset() const
-{
-  auto slf = Toolkit::TextEditor::DownCast(Self());
-  return Dali::Toolkit::GetImpl(slf).GetTextController()->GetCursorPosition();
-}
-
-bool TextEditor::AccessibleImpl::SetCursorOffset(size_t offset)
-{
-  auto slf = Toolkit::TextEditor::DownCast(Self());
-  auto txt = slf.GetProperty(Toolkit::TextEditor::Property::TEXT).Get<std::string>();
-  if(offset > txt.size())
-  {
-    return false;
-  }
-
-  auto& slfImpl = Dali::Toolkit::GetImpl(slf);
-  slfImpl.GetTextController()->ResetCursorPosition(offset);
-  slfImpl.RequestTextRelayout();
-
-  return true;
-}
-
-Dali::Accessibility::Range TextEditor::AccessibleImpl::GetTextAtOffset(size_t offset, Dali::Accessibility::TextBoundary boundary) const
-{
-  auto self     = Toolkit::TextEditor::DownCast(Self());
-  auto text     = self.GetProperty(Toolkit::TextEditor::Property::TEXT).Get<std::string>();
-  auto textSize = text.size();
-
-  auto range = Dali::Accessibility::Range{};
-
-  switch(boundary)
-  {
-    case Dali::Accessibility::TextBoundary::CHARACTER:
-    {
-      if(offset < textSize)
-      {
-        range.content     = text[offset];
-        range.startOffset = offset;
-        range.endOffset   = offset + 1;
-      }
-      break;
-    }
-    case Dali::Accessibility::TextBoundary::WORD:
-    case Dali::Accessibility::TextBoundary::LINE:
-    {
-      auto textString = text.c_str();
-      auto breaks     = std::vector<char>(textSize, 0);
-
-      if(boundary == Dali::Accessibility::TextBoundary::WORD)
-      {
-        Accessibility::Accessible::FindWordSeparationsUtf8(reinterpret_cast<const utf8_t*>(textString), textSize, "", breaks.data());
-      }
-      else
-      {
-        Accessibility::Accessible::FindLineSeparationsUtf8(reinterpret_cast<const utf8_t*>(textString), textSize, "", breaks.data());
-      }
-
-      auto index   = 0u;
-      auto counter = 0u;
-      while(index < textSize && counter <= offset)
-      {
-        auto start = index;
-        if(breaks[index])
-        {
-          while(breaks[index])
-          {
-            index++;
-          }
-          counter++;
-        }
-        else
-        {
-          if(boundary == Dali::Accessibility::TextBoundary::WORD)
-          {
-            index++;
-          }
-          if(boundary == Dali::Accessibility::TextBoundary::LINE)
-          {
-            counter++;
-          }
-        }
-
-        if((counter > 0) && ((counter - 1) == offset))
-        {
-          range.content     = text.substr(start, index - start + 1);
-          range.startOffset = start;
-          range.endOffset   = index + 1;
-        }
-
-        if(boundary == Dali::Accessibility::TextBoundary::LINE)
-        {
-          index++;
-        }
-      }
-      break;
-    }
-    case Dali::Accessibility::TextBoundary::SENTENCE:
-    {
-      /* not supported by default */
-      break;
-    }
-    case Dali::Accessibility::TextBoundary::PARAGRAPH:
-    {
-      /* Paragraph is not supported by libunibreak library */
-      break;
-    }
-    default:
-      break;
-  }
-
-  return range;
-}
-
-Dali::Accessibility::Range TextEditor::AccessibleImpl::GetRangeOfSelection(size_t selectionIndex) const
-{
-  // Since DALi supports only one selection indexes higher than 0 are ignored
-  if(selectionIndex > 0)
-  {
-    return {};
-  }
-
-  auto        self       = Toolkit::TextEditor::DownCast(Self());
-  auto        controller = Dali::Toolkit::GetImpl(self).GetTextController();
-  std::string value{};
-  controller->RetrieveSelection(value);
-  auto indices = controller->GetSelectionIndexes();
-
-  return {static_cast<size_t>(indices.first), static_cast<size_t>(indices.second), value};
-}
-
-bool TextEditor::AccessibleImpl::RemoveSelection(size_t selectionIndex)
+std::string TextEditor::TextEditorAccessible::GetName() const
 {
-  // Since DALi supports only one selection indexes higher than 0 are ignored
-  if(selectionIndex > 0)
-  {
-    return false;
-  }
-
-  auto self = Toolkit::TextEditor::DownCast(Self());
-  Dali::Toolkit::GetImpl(self).GetTextController()->SetSelection(0, 0);
-  return true;
+  return GetWholeText();
 }
 
-bool TextEditor::AccessibleImpl::SetRangeOfSelection(size_t selectionIndex, size_t startOffset, size_t endOffset)
+const std::vector<Toolkit::TextAnchor>& TextEditor::TextEditorAccessible::GetTextAnchors() const
 {
-  // Since DALi supports only one selection indexes higher than 0 are ignored
-  if(selectionIndex > 0)
-  {
-    return false;
-  }
-
-  auto self = Toolkit::TextEditor::DownCast(Self());
-  Dali::Toolkit::GetImpl(self).GetTextController()->SetSelection(startOffset, endOffset);
-  return true;
-}
-
-Rect<> TextEditor::AccessibleImpl::GetRangeExtents(size_t startOffset, size_t endOffset, Accessibility::CoordinateType type)
-{
-  if (endOffset <= startOffset || endOffset <= 0)
-  {
-    return {0, 0, 0, 0};
-  }
-
   auto self = Toolkit::TextEditor::DownCast(Self());
-  auto rect = Dali::Toolkit::GetImpl(self).GetTextController()->GetTextBoundingRectangle(startOffset, endOffset - 1);
-
-  auto componentExtents = this->GetExtents(type);
 
-  rect.x += componentExtents.x;
-  rect.y += componentExtents.y;
-
-  return rect;
+  return Toolkit::GetImpl(self).mAnchorActors;
 }
 
-bool TextEditor::AccessibleImpl::CopyText(size_t startPosition, size_t endPosition)
+Toolkit::Text::ControllerPtr TextEditor::TextEditorAccessible::GetTextController() const
 {
-  if(endPosition <= startPosition)
-  {
-    return false;
-  }
-
   auto self = Toolkit::TextEditor::DownCast(Self());
-  auto text = self.GetProperty(Toolkit::TextEditor::Property::TEXT).Get<std::string>();
-  Dali::Toolkit::GetImpl(self).GetTextController()->CopyStringToClipboard(text.substr(startPosition, endPosition - startPosition));
 
-  return true;
+  return Toolkit::GetImpl(self).GetTextController();
 }
 
-bool TextEditor::AccessibleImpl::CutText(size_t startPosition, size_t endPosition)
+void TextEditor::TextEditorAccessible::RequestTextRelayout()
 {
-  if(endPosition <= startPosition)
-  {
-    return false;
-  }
+  auto  self     = Toolkit::TextEditor::DownCast(Self());
+  auto& selfImpl = Toolkit::GetImpl(self);
 
-  auto self = Toolkit::TextEditor::DownCast(Self());
-  auto text = self.GetProperty(Toolkit::TextEditor::Property::TEXT).Get<std::string>();
-  Dali::Toolkit::GetImpl(self).GetTextController()->CopyStringToClipboard(text.substr(startPosition, endPosition - startPosition));
-
-  self.SetProperty(Toolkit::TextEditor::Property::TEXT, text.substr(0, startPosition) + text.substr(endPosition));
-
-  return true;
-}
-
-bool TextEditor::AccessibleImpl::DeleteText(size_t startPosition, size_t endPosition)
-{
-  if(endPosition <= startPosition)
-  {
-    return false;
-  }
-
-  auto self = Toolkit::TextEditor::DownCast(Self());
-  auto text = self.GetProperty(Toolkit::TextEditor::Property::TEXT).Get<std::string>();
-
-  self.SetProperty(Toolkit::TextEditor::Property::TEXT, text.substr(0, startPosition) + text.substr(endPosition));
-
-  return true;
-}
-
-Dali::Accessibility::States TextEditor::AccessibleImpl::CalculateStates()
-{
-  using namespace Dali::Accessibility;
-
-  auto states              = DevelControl::ControlAccessible::CalculateStates();
-  states[State::EDITABLE]  = true;
-  states[State::FOCUSABLE] = true;
-
-  Toolkit::Control focusControl = Toolkit::KeyInputFocusManager::Get().GetCurrentFocusControl();
-  if(Self() == focusControl)
-  {
-    states[State::FOCUSED] = true;
-  }
-
-  return states;
-}
-
-bool TextEditor::AccessibleImpl::InsertText(size_t startPosition, std::string text)
-{
-  auto self         = Toolkit::TextEditor::DownCast(Self());
-  auto insertedText = self.GetProperty(Toolkit::TextEditor::Property::TEXT).Get<std::string>();
-
-  insertedText.insert(startPosition, text);
-
-  self.SetProperty(Toolkit::TextEditor::Property::TEXT, std::move(insertedText));
-
-  return true;
-}
-
-bool TextEditor::AccessibleImpl::SetTextContents(std::string newContents)
-{
-  auto self = Toolkit::TextEditor::DownCast(Self());
-  self.SetProperty(Toolkit::TextEditor::Property::TEXT, std::move(newContents));
-  return true;
-}
-
-int32_t TextEditor::AccessibleImpl::GetLinkCount() const
-{
-  auto self = Toolkit::TextEditor::DownCast(Self());
-  return Dali::Toolkit::GetImpl(self).mAnchorActors.size();
-}
-
-Accessibility::Hyperlink* TextEditor::AccessibleImpl::GetLink(int32_t linkIndex) const
-{
-  if(linkIndex < 0 || linkIndex >= GetLinkCount())
-  {
-    return nullptr;
-  }
-  auto self        = Toolkit::TextEditor::DownCast(Self());
-  auto anchorActor = Dali::Toolkit::GetImpl(self).mAnchorActors[linkIndex];
-  return dynamic_cast<Accessibility::Hyperlink*>(Dali::Accessibility::Accessible::Get(anchorActor));
-}
-
-int32_t TextEditor::AccessibleImpl::GetLinkIndex(int32_t characterOffset) const
-{
-  auto self       = Toolkit::TextEditor::DownCast(Self());
-  auto controller = Dali::Toolkit::GetImpl(self).GetTextController();
-  return controller->GetAnchorIndex(static_cast<size_t>(characterOffset));
+  selfImpl.RequestTextRelayout();
 }
 
 } // namespace Internal
index 8a96a13..5739ac2 100644 (file)
@@ -32,6 +32,7 @@
 #include <dali-toolkit/devel-api/controls/scroll-bar/scroll-bar.h>
 #include <dali-toolkit/devel-api/controls/text-controls/text-editor-devel.h>
 #include <dali-toolkit/internal/controls/control/control-data-impl.h>
+#include <dali-toolkit/internal/controls/text-controls/common-text-utils.h>
 #include <dali-toolkit/internal/text/decorator/text-decorator.h>
 #include <dali-toolkit/internal/text/rendering/text-renderer.h>
 #include <dali-toolkit/internal/text/text-anchor-control-interface.h>
@@ -160,6 +161,11 @@ private: // From Control
   void OnInitialize() override;
 
   /**
+   * @copydoc Toolkit::Internal::Control::CreateAccessibleObject()
+   */
+  DevelControl::ControlAccessible* CreateAccessibleObject() override;
+
+  /**
    * @copydoc Control::OnStyleChange()
    */
   void OnStyleChange(Toolkit::StyleManager styleManager, StyleChange::Type change) override;
@@ -577,106 +583,31 @@ private: // Data
   /**
    * @brief This structure is to connect TextEditor with Accessible functions.
    */
-  struct AccessibleImpl : public DevelControl::ControlAccessible,
-                          public virtual Dali::Accessibility::EditableText,
-                          public virtual Dali::Accessibility::Hypertext
+  class TextEditorAccessible : public EditableTextControlAccessible
   {
-    using DevelControl::ControlAccessible::ControlAccessible;
+  public:
+    using EditableTextControlAccessible::EditableTextControlAccessible;
 
     /**
      * @copydoc Dali::Accessibility::Accessible::GetName()
      */
     std::string GetName() const override;
 
+  protected:
     /**
-     * @copydoc Dali::Accessibility::Text::GetText()
-     */
-    std::string GetText(size_t startOffset, size_t endOffset) const override;
-
-    /**
-     * @copydoc Dali::Accessibility::Text::GetCharacterCount()
-     */
-    size_t GetCharacterCount() const override;
-
-    /**
-     * @copydoc Dali::Accessibility::Text::GetCursorOffset()
-     */
-    size_t GetCursorOffset() const override;
-
-    /**
-     * @copydoc Dali::Accessibility::Text::SetCursorOffset()
-     */
-    bool SetCursorOffset(size_t offset) override;
-
-    /**
-     * @copydoc Dali::Accessibility::Text::GetTextAtOffset()
-     */
-    Accessibility::Range GetTextAtOffset(size_t offset, Accessibility::TextBoundary boundary) const override;
-
-    /**
-     * @copydoc Dali::Accessibility::Text::GetRangeOfSelection()
-     */
-    Accessibility::Range GetRangeOfSelection(size_t selectionIndex) const override;
-
-    /**
-     * @copydoc Dali::Accessibility::Text::RemoveSelection()
-     */
-    bool RemoveSelection(size_t selectionIndex) override;
-
-    /**
-     * @copydoc Dali::Accessibility::Text::SetRangeOfSelection()
-     */
-    bool SetRangeOfSelection(size_t selectionIndex, size_t startOffset, size_t endOffset) override;
-
-    /**
-     * @copydoc Dali::Accessibility::Text::GetRangeExtents()
-     */
-    Rect<> GetRangeExtents(size_t startOffset, size_t endOffset, Accessibility::CoordinateType type) override;
-
-    /**
-     * @copydoc Dali::Accessibility::EditableText::CopyText()
-     */
-    bool CopyText(size_t startPosition, size_t endPosition) override;
-
-    /**
-     * @copydoc Dali::Accessibility::EditableText::CutText()
-     */
-    bool CutText(size_t startPosition, size_t endPosition) override;
-
-    /**
-     * @copydoc Dali::Accessibility::Accessible::GetStates()
-     */
-    Accessibility::States CalculateStates() override;
-
-    /**
-     * @copydoc Dali::Accessibility::EditableText::InsertText()
-     */
-    bool InsertText(size_t startPosition, std::string text) override;
-
-    /**
-     * @copydoc Dali::Accessibility::EditableText::SetTextContents()
-     */
-    bool SetTextContents(std::string newContents) override;
-
-    /**
-     * @copydoc Dali::Accessibility::EditableText::DeleteText()
-     */
-    bool DeleteText(size_t startPosition, size_t endPosition) override;
-
-    /**
-     * @copydoc Dali::Accessibility::Hypertext::GetLink()
+     * @copydoc Dali::Toolkit::Internal::TextControlAccessible::GetTextAnchors()
      */
-    Accessibility::Hyperlink* GetLink(int32_t linkIndex) const override;
+    const std::vector<Toolkit::TextAnchor>& GetTextAnchors() const override;
 
     /**
-     * @copydoc Dali::Accessibility::Hypertext::GetLinkIndex()
+     * @copydoc Dali::Toolkit::Internal::TextControlAccessible::GetTextController()
      */
-    int32_t GetLinkIndex(int32_t characterOffset) const override;
+    Toolkit::Text::ControllerPtr GetTextController() const override;
 
     /**
-     * @copydoc Dali::Accessibility::Hypertext::GetLinkCount()
+     * @copydoc Dali::Toolkit::Internal::EditableTextControlAccessible::RequestTextRelayout()
      */
-    int32_t GetLinkCount() const override;
+    void RequestTextRelayout() override;
   };
 };
 
index 35d06ea..b1ea8e7 100644 (file)
@@ -33,7 +33,6 @@
 // INTERNAL INCLUDES
 #include <dali-toolkit/devel-api/controls/control-devel.h>
 #include <dali-toolkit/devel-api/controls/text-controls/text-field-devel.h>
-#include <dali-toolkit/devel-api/focus-manager/keyinput-focus-manager.h>
 #include <dali-toolkit/devel-api/text/rendering-backend.h>
 #include <dali-toolkit/internal/controls/text-controls/common-text-utils.h>
 #include <dali-toolkit/internal/controls/text-controls/text-field-property-handler.h>
@@ -206,28 +205,6 @@ Toolkit::TextField::InputStyle::Mask ConvertInputStyle(Text::InputStyle::Mask in
   return fieldInputStyleMask;
 }
 
-bool IsHiddenInput(Toolkit::TextField textField)
-{
-  Property::Map hiddenInputSettings = textField.GetProperty<Property::Map>(Toolkit::TextField::Property::HIDDEN_INPUT_SETTINGS);
-  auto          mode                = hiddenInputSettings.Find(Toolkit::HiddenInput::Property::MODE);
-  if(mode && (mode->Get<int>() != Toolkit::HiddenInput::Mode::HIDE_NONE))
-  {
-    return true;
-  }
-  return false;
-}
-
-char GetSubstituteCharacter(Toolkit::TextField textField)
-{
-  Property::Map hiddenInputSettings = textField.GetProperty<Property::Map>(Toolkit::TextField::Property::HIDDEN_INPUT_SETTINGS);
-  auto          substChar           = hiddenInputSettings.Find(Toolkit::HiddenInput::Property::SUBSTITUTE_CHARACTER);
-  if(substChar)
-  {
-    return static_cast<char>(substChar->Get<int>());
-  }
-  return STAR;
-}
-
 } // namespace
 
 Toolkit::TextField TextField::New()
@@ -550,9 +527,6 @@ void TextField::OnInitialize()
   self.SetResizePolicy(ResizePolicy::FILL_TO_PARENT, Dimension::HEIGHT);
   self.OnSceneSignal().Connect(this, &TextField::OnSceneConnect);
 
-  //Enable highightability
-  self.SetProperty(Toolkit::DevelControl::Property::ACCESSIBILITY_HIGHLIGHTABLE, true);
-
   DevelControl::SetInputMethodContext(*this, mInputMethodContext);
 
   if(Dali::Toolkit::TextField::EXCEED_POLICY_CLIP == mExceedPolicy)
@@ -560,15 +534,19 @@ void TextField::OnInitialize()
     EnableClipping();
   }
 
-  DevelControl::SetAccessibilityConstructor(self, [](Dali::Actor actor) {
-    return std::unique_ptr<Dali::Accessibility::Accessible>(
-      new AccessibleImpl(actor, Dali::Accessibility::Role::ENTRY));
-  });
+  // Accessibility
+  self.SetProperty(DevelControl::Property::ACCESSIBILITY_ROLE, Dali::Accessibility::Role::ENTRY);
+  self.SetProperty(DevelControl::Property::ACCESSIBILITY_HIGHLIGHTABLE, true);
 
   Accessibility::Bridge::EnabledSignal().Connect(this, &TextField::OnAccessibilityStatusChanged);
   Accessibility::Bridge::DisabledSignal().Connect(this, &TextField::OnAccessibilityStatusChanged);
 }
 
+DevelControl::ControlAccessible* TextField::CreateAccessibleObject()
+{
+  return new TextFieldAccessible(Self());
+}
+
 void TextField::OnStyleChange(Toolkit::StyleManager styleManager, StyleChange::Type change)
 {
   DALI_LOG_INFO(gTextFieldLogFilter, Debug::Verbose, "TextField::OnStyleChange\n");
@@ -884,26 +862,17 @@ void TextField::SetEditable(bool editable)
 
 void TextField::TextInserted(unsigned int position, unsigned int length, const std::string& content)
 {
-  if(Accessibility::IsUp())
-  {
-    Control::Impl::GetAccessibilityObject(Self())->EmitTextInserted(position, length, content);
-  }
+  GetAccessibleObject()->EmitTextInserted(position, length, content);
 }
 
 void TextField::TextDeleted(unsigned int position, unsigned int length, const std::string& content)
 {
-  if(Accessibility::IsUp())
-  {
-    Control::Impl::GetAccessibilityObject(Self())->EmitTextDeleted(position, length, content);
-  }
+  GetAccessibleObject()->EmitTextDeleted(position, length, content);
 }
 
 void TextField::CursorPositionChanged(unsigned int oldPosition, unsigned int newPosition)
 {
-  if(Accessibility::IsUp())
-  {
-    Control::Impl::GetAccessibilityObject(Self())->EmitTextCursorMoved(newPosition);
-  }
+  GetAccessibleObject()->EmitTextCursorMoved(newPosition);
 
   if((oldPosition != newPosition) && !mCursorPositionChanged)
   {
@@ -1192,340 +1161,59 @@ Vector<Vector2> TextField::GetTextPosition(const uint32_t startIndex, const uint
   return mController->GetTextPosition(startIndex, endIndex);
 }
 
-std::string TextField::AccessibleImpl::GetName() const
+std::string TextField::TextFieldAccessible::GetName() const
 {
-  auto self = Toolkit::TextField::DownCast(Self());
-  if(IsHiddenInput(self))
+  if(IsHiddenInput())
   {
     return {};
   }
 
-  return self.GetProperty(Toolkit::TextField::Property::TEXT).Get<std::string>();
-}
-
-std::string TextField::AccessibleImpl::GetText(size_t startOffset, size_t endOffset) const
-{
-  if(endOffset <= startOffset)
-  {
-    return {};
-  }
-
-  auto self = Toolkit::TextField::DownCast(Self());
-  auto text = self.GetProperty(Toolkit::TextField::Property::TEXT).Get<std::string>();
-
-  if(startOffset > text.size() || endOffset > text.size())
-  {
-    return {};
-  }
-  if(IsHiddenInput(self))
-  {
-    return std::string(endOffset - startOffset, GetSubstituteCharacter(self));
-  }
-  return text.substr(startOffset, endOffset - startOffset);
+  return GetWholeText();
 }
 
-size_t TextField::AccessibleImpl::GetCharacterCount() const
+const std::vector<Toolkit::TextAnchor>& TextField::TextFieldAccessible::GetTextAnchors() const
 {
   auto self = Toolkit::TextField::DownCast(Self());
-  auto text = self.GetProperty(Toolkit::TextField::Property::TEXT).Get<std::string>();
 
-  return text.size();
+  return Toolkit::GetImpl(self).mAnchorActors;
 }
 
-size_t TextField::AccessibleImpl::GetCursorOffset() const
+Toolkit::Text::ControllerPtr TextField::TextFieldAccessible::GetTextController() const
 {
   auto self = Toolkit::TextField::DownCast(Self());
-  return Dali::Toolkit::GetImpl(self).GetTextController()->GetCursorPosition();
-}
-
-bool TextField::AccessibleImpl::SetCursorOffset(size_t offset)
-{
-  auto self = Toolkit::TextField::DownCast(Self());
-  auto text = self.GetProperty(Toolkit::TextField::Property::TEXT).Get<std::string>();
-  if(offset > text.size())
-  {
-    return false;
-  }
-
-  auto& selfImpl = Dali::Toolkit::GetImpl(self);
-  selfImpl.GetTextController()->ResetCursorPosition(offset);
-  selfImpl.RequestTextRelayout();
-
-  return true;
-}
-
-Dali::Accessibility::Range TextField::AccessibleImpl::GetTextAtOffset(
-  size_t offset, Dali::Accessibility::TextBoundary boundary) const
-{
-  auto self  = Toolkit::TextField::DownCast(Self());
-  auto range = Dali::Accessibility::Range{};
-
-  if(IsHiddenInput(self))
-  {
-    // Returning empty object, as there is no possibility to parse the textfield
-    // when its content is hidden.
-    return range;
-  }
-
-  auto text     = self.GetProperty(Toolkit::TextField::Property::TEXT).Get<std::string>();
-  auto textSize = text.size();
-
-  switch(boundary)
-  {
-    case Dali::Accessibility::TextBoundary::CHARACTER:
-    {
-      if(offset < textSize)
-      {
-        range.content     = text[offset];
-        range.startOffset = offset;
-        range.endOffset   = offset + 1;
-      }
-      break;
-    }
-    case Dali::Accessibility::TextBoundary::WORD:
-    case Dali::Accessibility::TextBoundary::LINE:
-    {
-      auto textString = text.c_str();
-      auto breaks     = std::vector<char>(textSize, 0);
-
-      if(boundary == Dali::Accessibility::TextBoundary::WORD)
-      {
-        Accessibility::Accessible::FindWordSeparationsUtf8(reinterpret_cast<const utf8_t*>(textString), textSize, "", breaks.data());
-      }
-      else
-      {
-        Accessibility::Accessible::FindLineSeparationsUtf8(reinterpret_cast<const utf8_t*>(textString), textSize, "", breaks.data());
-      }
-
-      auto index   = 0u;
-      auto counter = 0u;
-      while(index < textSize && counter <= offset)
-      {
-        auto start = index;
-        if(breaks[index])
-        {
-          while(breaks[index])
-          {
-            index++;
-          }
-          counter++;
-        }
-        else
-        {
-          if(boundary == Dali::Accessibility::TextBoundary::WORD)
-          {
-            index++;
-          }
-          if(boundary == Dali::Accessibility::TextBoundary::LINE)
-          {
-            counter++;
-          }
-        }
-
-        if((counter > 0) && ((counter - 1) == offset))
-        {
-          range.content     = text.substr(start, index - start + 1);
-          range.startOffset = start;
-          range.endOffset   = index + 1;
-        }
-
-        if(boundary == Dali::Accessibility::TextBoundary::LINE)
-        {
-          index++;
-        }
-      }
-      break;
-    }
-    case Dali::Accessibility::TextBoundary::SENTENCE:
-    {
-      /* not supported by default */
-      break;
-    }
-    case Dali::Accessibility::TextBoundary::PARAGRAPH:
-    {
-      /* Paragraph is not supported by libunibreak library */
-      break;
-    }
-    default:
-      break;
-  }
 
-  return range;
+  return Toolkit::GetImpl(self).GetTextController();
 }
 
-Dali::Accessibility::Range TextField::AccessibleImpl::GetRangeOfSelection(size_t selectionIndex) const
+std::uint32_t TextField::TextFieldAccessible::GetSubstituteCharacter() const
 {
-  // Since DALi supports only one selection indexes higher than 0 are ignored
-  if(selectionIndex > 0)
-  {
-    return {};
-  }
-
-  auto self       = Toolkit::TextField::DownCast(Self());
-  auto controller = Dali::Toolkit::GetImpl(self).GetTextController();
-  auto indices    = controller->GetSelectionIndexes();
-
-  auto startOffset = static_cast<size_t>(indices.first);
-  auto endOffset   = static_cast<size_t>(indices.second);
+  auto self                = Toolkit::TextField::DownCast(Self());
+  auto hiddenInputSettings = self.GetProperty<Property::Map>(Toolkit::TextField::Property::HIDDEN_INPUT_SETTINGS);
+  auto substChar           = hiddenInputSettings.Find(Toolkit::HiddenInput::Property::SUBSTITUTE_CHARACTER);
 
-  if(IsHiddenInput(self))
-  {
-    return {startOffset, endOffset, std::string(endOffset - startOffset, GetSubstituteCharacter(self))};
-  }
-
-  std::string value{};
-  controller->RetrieveSelection(value);
-  return {startOffset, endOffset, value};
-}
-
-bool TextField::AccessibleImpl::RemoveSelection(size_t selectionIndex)
-{
-  // Since DALi supports only one selection indexes higher than 0 are ignored
-  if(selectionIndex > 0)
-  {
-    return false;
-  }
-
-  auto self = Toolkit::TextField::DownCast(Self());
-  Dali::Toolkit::GetImpl(self).GetTextController()->SetSelection(0, 0);
-  return true;
-}
-
-bool TextField::AccessibleImpl::SetRangeOfSelection(size_t selectionIndex, size_t startOffset, size_t endOffset)
-{
-  // Since DALi supports only one selection indexes higher than 0 are ignored
-  if(selectionIndex > 0)
-  {
-    return false;
-  }
-
-  auto self = Toolkit::TextField::DownCast(Self());
-  Dali::Toolkit::GetImpl(self).GetTextController()->SetSelection(startOffset, endOffset);
-  return true;
-}
-
-Rect<> TextField::AccessibleImpl::GetRangeExtents(size_t startOffset, size_t endOffset, Accessibility::CoordinateType type)
-{
-  if (endOffset <= startOffset || endOffset <= 0)
-  {
-    return {0, 0, 0, 0};
-  }
-
-  auto self = Toolkit::TextField::DownCast(Self());
-  auto rect = Dali::Toolkit::GetImpl(self).GetTextController()->GetTextBoundingRectangle(startOffset, endOffset - 1);
-
-  auto componentExtents = this->GetExtents(type);
-
-  rect.x += componentExtents.x;
-  rect.y += componentExtents.y;
-
-  return rect;
-}
-
-bool TextField::AccessibleImpl::CopyText(size_t startPosition, size_t endPosition)
-{
-  if(endPosition <= startPosition)
-  {
-    return false;
-  }
-
-  auto self = Toolkit::TextField::DownCast(Self());
-  auto text = self.GetProperty(Toolkit::TextField::Property::TEXT).Get<std::string>();
-  Dali::Toolkit::GetImpl(self).GetTextController()->CopyStringToClipboard(text.substr(startPosition, endPosition - startPosition));
-
-  return true;
-}
-
-bool TextField::AccessibleImpl::CutText(size_t startPosition, size_t endPosition)
-{
-  if(endPosition <= startPosition)
-  {
-    return false;
-  }
-
-  auto self = Toolkit::TextField::DownCast(Self());
-  auto text = self.GetProperty(Toolkit::TextField::Property::TEXT).Get<std::string>();
-  Dali::Toolkit::GetImpl(self).GetTextController()->CopyStringToClipboard(text.substr(startPosition, endPosition - startPosition));
-
-  self.SetProperty(Toolkit::TextField::Property::TEXT, text.substr(0, startPosition) + text.substr(endPosition));
-
-  return true;
-}
-
-bool TextField::AccessibleImpl::DeleteText(size_t startPosition, size_t endPosition)
-{
-  if(endPosition <= startPosition)
-  {
-    return false;
-  }
-
-  auto self = Toolkit::TextField::DownCast(Self());
-  auto text = self.GetProperty(Toolkit::TextField::Property::TEXT).Get<std::string>();
-
-  self.SetProperty(Toolkit::TextField::Property::TEXT, text.substr(0, startPosition) + text.substr(endPosition));
-
-  return true;
-}
-
-Dali::Accessibility::States TextField::AccessibleImpl::CalculateStates()
-{
-  using namespace Dali::Accessibility;
-
-  auto states = DevelControl::ControlAccessible::CalculateStates();
-
-  states[State::EDITABLE]  = true;
-  states[State::FOCUSABLE] = true;
-
-  Toolkit::Control focusControl = Toolkit::KeyInputFocusManager::Get().GetCurrentFocusControl();
-  if(Self() == focusControl)
+  if(substChar)
   {
-    states[State::FOCUSED] = true;
+    return static_cast<std::uint32_t>(substChar->Get<int>());
   }
 
-  return states;
+  return TextControlAccessible::GetSubstituteCharacter();
 }
 
-bool TextField::AccessibleImpl::InsertText(size_t startPosition, std::string text)
+bool TextField::TextFieldAccessible::IsHiddenInput() const
 {
-  auto self         = Toolkit::TextField::DownCast(Self());
-  auto insertedText = self.GetProperty(Toolkit::TextField::Property::TEXT).Get<std::string>();
-
-  insertedText.insert(startPosition, text);
-
-  self.SetProperty(Toolkit::TextField::Property::TEXT, std::move(insertedText));
+  auto self                = Toolkit::TextField::DownCast(Self());
+  auto hiddenInputSettings = self.GetProperty<Property::Map>(Toolkit::TextField::Property::HIDDEN_INPUT_SETTINGS);
+  auto mode                = hiddenInputSettings.Find(Toolkit::HiddenInput::Property::MODE);
 
-  return true;
+  return (mode && (mode->Get<int>() != Toolkit::HiddenInput::Mode::HIDE_NONE));
 }
 
-bool TextField::AccessibleImpl::SetTextContents(std::string newContents)
+void TextField::TextFieldAccessible::RequestTextRelayout()
 {
-  auto self = Toolkit::TextField::DownCast(Self());
-  self.SetProperty(Toolkit::TextField::Property::TEXT, std::move(newContents));
-  return true;
-}
+  auto  self     = Toolkit::TextField::DownCast(Self());
+  auto& selfImpl = Toolkit::GetImpl(self);
 
-int32_t TextField::AccessibleImpl::GetLinkCount() const
-{
-  auto self = Toolkit::TextField::DownCast(Self());
-  return Dali::Toolkit::GetImpl(self).mAnchorActors.size();
-}
-
-Accessibility::Hyperlink* TextField::AccessibleImpl::GetLink(int32_t linkIndex) const
-{
-  if(linkIndex < 0 || linkIndex >= GetLinkCount())
-  {
-    return nullptr;
-  }
-  auto self        = Toolkit::TextField::DownCast(Self());
-  auto anchorActor = Dali::Toolkit::GetImpl(self).mAnchorActors[linkIndex];
-  return dynamic_cast<Accessibility::Hyperlink*>(Dali::Accessibility::Accessible::Get(anchorActor));
-}
-
-int32_t TextField::AccessibleImpl::GetLinkIndex(int32_t characterOffset) const
-{
-  auto self       = Toolkit::TextField::DownCast(Self());
-  auto controller = Dali::Toolkit::GetImpl(self).GetTextController();
-  return controller->GetAnchorIndex(static_cast<size_t>(characterOffset));
+  selfImpl.RequestTextRelayout();
 }
 
 } // namespace Internal
index c10dd51..d2d7fdf 100644 (file)
@@ -29,6 +29,7 @@
 #include <dali-toolkit/devel-api/controls/control-devel.h>
 #include <dali-toolkit/devel-api/controls/text-controls/text-field-devel.h>
 #include <dali-toolkit/internal/controls/control/control-data-impl.h>
+#include <dali-toolkit/internal/controls/text-controls/common-text-utils.h>
 #include <dali-toolkit/internal/text/decorator/text-decorator.h>
 #include <dali-toolkit/internal/text/rendering/text-renderer.h>
 #include <dali-toolkit/internal/text/text-anchor-control-interface.h>
@@ -151,6 +152,11 @@ private: // From Control
   void OnInitialize() override;
 
   /**
+   * @copydoc Toolkit::Internal::Control::CreateAccessibleObject()
+   */
+  DevelControl::ControlAccessible* CreateAccessibleObject() override;
+
+  /**
    * @copydoc Control::OnStyleChange()
    */
   void OnStyleChange(Toolkit::StyleManager styleManager, StyleChange::Type change) override;
@@ -526,106 +532,41 @@ protected:
   /**
    * @brief This structure is to connect TextField with Accessible functions.
    */
-  struct AccessibleImpl : public DevelControl::ControlAccessible,
-                          public virtual Dali::Accessibility::EditableText,
-                          public virtual Dali::Accessibility::Hypertext
+  class TextFieldAccessible : public EditableTextControlAccessible
   {
-    using DevelControl::ControlAccessible::ControlAccessible;
+  public:
+    using EditableTextControlAccessible::EditableTextControlAccessible;
 
     /**
      * @copydoc Dali::Accessibility::Accessible::GetName()
      */
     std::string GetName() const override;
 
+  protected:
     /**
-     * @copydoc Dali::Accessibility::Text::GetText()
-     */
-    std::string GetText(size_t startOffset, size_t endOffset) const override;
-
-    /**
-     * @copydoc Dali::Accessibility::Text::GetCharacterCount()
-     */
-    size_t GetCharacterCount() const override;
-
-    /**
-     * @copydoc Dali::Accessibility::Text::GetCursorOffset()
-     */
-    size_t GetCursorOffset() const override;
-
-    /**
-     * @copydoc Dali::Accessibility::Text::SetCursorOffset()
-     */
-    bool SetCursorOffset(size_t offset) override;
-
-    /**
-     * @copydoc Dali::Accessibility::Text::GetTextAtOffset()
-     */
-    Accessibility::Range GetTextAtOffset(size_t offset, Accessibility::TextBoundary boundary) const override;
-
-    /**
-     * @copydoc Dali::Accessibility::Text::GetRangeOfSelection()
-     */
-    Accessibility::Range GetRangeOfSelection(size_t selectionIndex) const override;
-
-    /**
-     * @copydoc Dali::Accessibility::Text::RemoveSelection()
-     */
-    bool RemoveSelection(size_t selectionIndex) override;
-
-    /**
-     * @copydoc Dali::Accessibility::Text::SetRangeOfSelection()
-     */
-    bool SetRangeOfSelection(size_t selectionIndex, size_t startOffset, size_t endOffset) override;
-
-    /**
-     * @copydoc Dali::Accessibility::Text::GetRangeExtents()
-     */
-    Rect<> GetRangeExtents(size_t startOffset, size_t endOffset, Accessibility::CoordinateType type) override;
-
-    /**
-     * @copydoc Dali::Accessibility::EditableText::CopyText()
-     */
-    bool CopyText(size_t startPosition, size_t endPosition) override;
-
-    /**
-     * @copydoc Dali::Accessibility::EditableText::CutText()
-     */
-    bool CutText(size_t startPosition, size_t endPosition) override;
-
-    /**
-     * @copydoc Dali::Accessibility::Accessible::GetStates()
-     */
-    Accessibility::States CalculateStates() override;
-
-    /**
-     * @copydoc Dali::Accessibility::EditableText::InsertText()
-     */
-    bool InsertText(size_t startPosition, std::string text) override;
-
-    /**
-     * @copydoc Dali::Accessibility::EditableText::SetTextContents()
+     * @copydoc Dali::Toolkit::Internal::TextControlAccessible::GetTextAnchors()
      */
-    bool SetTextContents(std::string newContents) override;
+    const std::vector<Toolkit::TextAnchor>& GetTextAnchors() const override;
 
     /**
-     * @copydoc Dali::Accessibility::EditableText::DeleteText()
+     * @copydoc Dali::Toolkit::Internal::TextControlAccessible::GetTextController()
      */
-    bool DeleteText(size_t startPosition, size_t endPosition) override;
+    Toolkit::Text::ControllerPtr GetTextController() const override;
 
     /**
-     * @copydoc Dali::Accessibility::Hypertext::GetLink()
+     * @copydoc Dali::Toolkit::Internal::TextControlAccessible::GetSubstituteCharacter()
      */
-    Accessibility::Hyperlink* GetLink(int32_t linkIndex) const override;
+    std::uint32_t GetSubstituteCharacter() const override;
 
     /**
-     * @copydoc Dali::Accessibility::Hypertext::GetLinkIndex()
+     * @copydoc Dali::Toolkit::Internal::TextControlAccessible::IsHiddenInput()
      */
-    int32_t GetLinkIndex(int32_t characterOffset) const override;
+    bool IsHiddenInput() const override;
 
     /**
-     * @copydoc Dali::Accessibility::Hypertext::GetLinkCount()
+     * @copydoc Dali::Toolkit::Internal::EditableTextControlAccessible::RequestTextRelayout()
      */
-    int32_t GetLinkCount() const override;
+    void RequestTextRelayout() override;
   };
 };
 
index fa9c6c0..76d0ee2 100644 (file)
@@ -883,9 +883,6 @@ void TextLabel::OnInitialize()
   self.SetResizePolicy(ResizePolicy::FILL_TO_PARENT, Dimension::WIDTH);
   self.SetResizePolicy(ResizePolicy::DIMENSION_DEPENDENCY, Dimension::HEIGHT);
 
-  // Enable highlightability
-  self.SetProperty(Toolkit::DevelControl::Property::ACCESSIBILITY_HIGHLIGHTABLE, true);
-
   // Enable the text ellipsis.
   mController->SetTextElideEnabled(true); // If false then text larger than control will overflow
 
@@ -899,15 +896,19 @@ void TextLabel::OnInitialize()
   Layout::Engine& engine = mController->GetLayoutEngine();
   engine.SetCursorWidth(0u); // Do not layout space for the cursor.
 
-  DevelControl::SetAccessibilityConstructor(self, [](Dali::Actor actor) {
-    return std::unique_ptr<Dali::Accessibility::Accessible>(
-      new AccessibleImpl(actor, Dali::Accessibility::Role::LABEL));
-  });
+  // Accessibility
+  self.SetProperty(DevelControl::Property::ACCESSIBILITY_ROLE, Dali::Accessibility::Role::LABEL);
+  self.SetProperty(DevelControl::Property::ACCESSIBILITY_HIGHLIGHTABLE, true);
 
   Accessibility::Bridge::EnabledSignal().Connect(this, &TextLabel::OnAccessibilityStatusChanged);
   Accessibility::Bridge::DisabledSignal().Connect(this, &TextLabel::OnAccessibilityStatusChanged);
 }
 
+DevelControl::ControlAccessible* TextLabel::CreateAccessibleObject()
+{
+  return new TextLabelAccessible(Self());
+}
+
 void TextLabel::OnStyleChange(Toolkit::StyleManager styleManager, StyleChange::Type change)
 {
   DALI_LOG_INFO(gLogFilter, Debug::Verbose, "TextLabel::OnStyleChange\n");
@@ -1198,227 +1199,28 @@ Vector<Vector2> TextLabel::GetTextPosition(const uint32_t startIndex, const uint
   return mController->GetTextPosition(startIndex, endIndex);
 }
 
-std::string TextLabel::AccessibleImpl::GetNameRaw() const
+std::string TextLabel::TextLabelAccessible::GetNameRaw() const
 {
-  auto self = Toolkit::TextLabel::DownCast(Self());
-  return self.GetProperty(Toolkit::TextLabel::Property::TEXT).Get<std::string>();
+  return GetWholeText();
 }
 
-Property::Index TextLabel::AccessibleImpl::GetNamePropertyIndex()
+Property::Index TextLabel::TextLabelAccessible::GetNamePropertyIndex()
 {
   return Toolkit::TextLabel::Property::TEXT;
 }
 
-std::string TextLabel::AccessibleImpl::GetText(size_t startOffset, size_t endOffset) const
+const std::vector<Toolkit::TextAnchor>& TextLabel::TextLabelAccessible::GetTextAnchors() const
 {
-  if(endOffset <= startOffset)
-  {
-    return {};
-  }
-
   auto self = Toolkit::TextLabel::DownCast(Self());
-  auto text = self.GetProperty(Toolkit::TextLabel::Property::TEXT).Get<std::string>();
-
-  if(startOffset > text.size() || endOffset > text.size())
-  {
-    return {};
-  }
 
-  return text.substr(startOffset, endOffset - startOffset);
+  return Toolkit::GetImpl(self).mAnchorActors;
 }
 
-size_t TextLabel::AccessibleImpl::GetCharacterCount() const
+Toolkit::Text::ControllerPtr TextLabel::TextLabelAccessible::GetTextController() const
 {
   auto self = Toolkit::TextLabel::DownCast(Self());
-  auto text = self.GetProperty(Toolkit::TextLabel::Property::TEXT).Get<std::string>();
-
-  return text.size();
-}
-
-size_t TextLabel::AccessibleImpl::GetCursorOffset() const
-{
-  return {};
-}
-
-bool TextLabel::AccessibleImpl::SetCursorOffset(size_t offset)
-{
-  return {};
-}
-
-Dali::Accessibility::Range TextLabel::AccessibleImpl::GetTextAtOffset(size_t offset, Dali::Accessibility::TextBoundary boundary) const
-{
-  auto self     = Toolkit::TextLabel::DownCast(Self());
-  auto text     = self.GetProperty(Toolkit::TextLabel::Property::TEXT).Get<std::string>();
-  auto textSize = text.size();
 
-  auto range = Dali::Accessibility::Range{};
-
-  switch(boundary)
-  {
-    case Dali::Accessibility::TextBoundary::CHARACTER:
-    {
-      if(offset < textSize)
-      {
-        range.content     = text[offset];
-        range.startOffset = offset;
-        range.endOffset   = offset + 1;
-      }
-      break;
-    }
-    case Dali::Accessibility::TextBoundary::WORD:
-    case Dali::Accessibility::TextBoundary::LINE:
-    {
-      auto textString = text.c_str();
-      auto breaks     = std::vector<char>(textSize, 0);
-
-      if(boundary == Dali::Accessibility::TextBoundary::WORD)
-      {
-        Accessibility::Accessible::FindWordSeparationsUtf8(reinterpret_cast<const utf8_t*>(textString), textSize, "", breaks.data());
-      }
-      else
-      {
-        Accessibility::Accessible::FindLineSeparationsUtf8(reinterpret_cast<const utf8_t*>(textString), textSize, "", breaks.data());
-      }
-
-      auto index   = 0u;
-      auto counter = 0u;
-      while(index < textSize && counter <= offset)
-      {
-        auto start = index;
-        if(breaks[index])
-        {
-          while(breaks[index])
-          {
-            index++;
-          }
-          counter++;
-        }
-        else
-        {
-          if(boundary == Dali::Accessibility::TextBoundary::WORD)
-          {
-            index++;
-          }
-          if(boundary == Dali::Accessibility::TextBoundary::LINE)
-          {
-            counter++;
-          }
-        }
-
-        if((counter > 0) && ((counter - 1) == offset))
-        {
-          range.content     = text.substr(start, index - start + 1);
-          range.startOffset = start;
-          range.endOffset   = index + 1;
-        }
-
-        if(boundary == Dali::Accessibility::TextBoundary::LINE)
-        {
-          index++;
-        }
-      }
-      break;
-    }
-    case Dali::Accessibility::TextBoundary::SENTENCE:
-    {
-      /* not supported by default */
-      break;
-    }
-    case Dali::Accessibility::TextBoundary::PARAGRAPH:
-    {
-      /* Paragraph is not supported by libunibreak library */
-      break;
-    }
-    default:
-      break;
-  }
-
-  return range;
-}
-
-Dali::Accessibility::Range TextLabel::AccessibleImpl::GetRangeOfSelection(size_t selectionIndex) const
-{
-  // Since DALi supports only one selection indexes higher than 0 are ignored
-  if(selectionIndex > 0)
-  {
-    return {};
-  }
-
-  auto        self       = Toolkit::TextLabel::DownCast(Self());
-  auto        controller = Dali::Toolkit::GetImpl(self).GetTextController();
-  std::string value{};
-  controller->RetrieveSelection(value);
-  auto indices = controller->GetSelectionIndexes();
-
-  return {static_cast<size_t>(indices.first), static_cast<size_t>(indices.second), value};
-}
-
-bool TextLabel::AccessibleImpl::RemoveSelection(size_t selectionIndex)
-{
-  // Since DALi supports only one selection indexes higher than 0 are ignored
-  if(selectionIndex > 0)
-  {
-    return false;
-  }
-
-  auto self = Toolkit::TextLabel::DownCast(Self());
-  Dali::Toolkit::GetImpl(self).GetTextController()->SetSelection(0, 0);
-  return true;
-}
-
-bool TextLabel::AccessibleImpl::SetRangeOfSelection(size_t selectionIndex, size_t startOffset, size_t endOffset)
-{
-  // Since DALi supports only one selection indexes higher than 0 are ignored
-  if(selectionIndex > 0)
-  {
-    return false;
-  }
-
-  auto self = Toolkit::TextLabel::DownCast(Self());
-  Dali::Toolkit::GetImpl(self).GetTextController()->SetSelection(startOffset, endOffset);
-  return true;
-}
-
-Rect<> TextLabel::AccessibleImpl::GetRangeExtents(size_t startOffset, size_t endOffset, Accessibility::CoordinateType type)
-{
-  if (endOffset <= startOffset || endOffset <= 0)
-  {
-    return {0, 0, 0, 0};
-  }
-
-  auto self = Toolkit::TextLabel::DownCast(Self());
-  auto rect = Dali::Toolkit::GetImpl(self).GetTextController()->GetTextBoundingRectangle(startOffset, endOffset - 1);
-
-  auto componentExtents = this->GetExtents(type);
-
-  rect.x += componentExtents.x;
-  rect.y += componentExtents.y;
-
-  return rect;
-}
-
-int32_t TextLabel::AccessibleImpl::GetLinkCount() const
-{
-  auto self = Toolkit::TextLabel::DownCast(Self());
-  return Dali::Toolkit::GetImpl(self).mAnchorActors.size();
-}
-
-Accessibility::Hyperlink* TextLabel::AccessibleImpl::GetLink(int32_t linkIndex) const
-{
-  if(linkIndex < 0 || linkIndex >= GetLinkCount())
-  {
-    return nullptr;
-  }
-  auto self        = Toolkit::TextLabel::DownCast(Self());
-  auto anchorActor = Dali::Toolkit::GetImpl(self).mAnchorActors[linkIndex];
-  return dynamic_cast<Accessibility::Hyperlink*>(Dali::Accessibility::Accessible::Get(anchorActor));
-}
-
-int32_t TextLabel::AccessibleImpl::GetLinkIndex(int32_t characterOffset) const
-{
-  auto self       = Toolkit::TextLabel::DownCast(Self());
-  auto controller = Dali::Toolkit::GetImpl(self).GetTextController();
-  return controller->GetAnchorIndex(static_cast<size_t>(characterOffset));
+  return Toolkit::GetImpl(self).GetTextController();
 }
 
 } // namespace Internal
index 9cba1c4..49f9197 100644 (file)
@@ -25,6 +25,7 @@
 
 // INTERNAL INCLUDES
 #include <dali-toolkit/internal/controls/control/control-data-impl.h>
+#include <dali-toolkit/internal/controls/text-controls/common-text-utils.h>
 #include <dali-toolkit/internal/text/rendering/text-renderer.h>
 #include <dali-toolkit/internal/text/text-anchor-control-interface.h>
 #include <dali-toolkit/internal/text/text-control-interface.h>
@@ -130,6 +131,11 @@ private: // From Control
   void OnInitialize() override;
 
   /**
+   * @copydoc Toolkit::Internal::Control::CreateAccessibleObject()
+   */
+  DevelControl::ControlAccessible* CreateAccessibleObject() override;
+
+  /**
    * @copydoc Control::OnStyleChange()
    */
   void OnStyleChange(Toolkit::StyleManager styleManager, StyleChange::Type change) override;
@@ -246,56 +252,10 @@ protected:
   /**
    * @brief This structure is to connect TextLabel with Accessible functions.
    */
-  struct AccessibleImpl : public DevelControl::ControlAccessible,
-                          public virtual Dali::Accessibility::Text,
-                          public virtual Dali::Accessibility::Hypertext
+  class TextLabelAccessible : public TextControlAccessible
   {
-    using DevelControl::ControlAccessible::ControlAccessible;
-
-    /**
-     * @copydoc Dali::Accessibility::Text::GetText()
-     */
-    std::string GetText(size_t startOffset, size_t endOffset) const override;
-
-    /**
-     * @copydoc Dali::Accessibility::Text::GetCharacterCount()
-     */
-    size_t GetCharacterCount() const override;
-
-    /**
-     * @copydoc Dali::Accessibility::Text::GetCursorOffset()
-     */
-    size_t GetCursorOffset() const override;
-
-    /**
-     * @copydoc Dali::Accessibility::Text::SetCursorOffset()
-     */
-    bool SetCursorOffset(size_t offset) override;
-
-    /**
-     * @copydoc Dali::Accessibility::Text::GetTextAtOffset()
-     */
-    Accessibility::Range GetTextAtOffset(size_t offset, Accessibility::TextBoundary boundary) const override;
-
-    /**
-     * @copydoc Dali::Accessibility::Text::GetRangeOfSelection()
-     */
-    Accessibility::Range GetRangeOfSelection(size_t selectionIndex) const override;
-
-    /**
-     * @copydoc Dali::Accessibility::Text::RemoveSelection()
-     */
-    bool RemoveSelection(size_t selectionIndex) override;
-
-    /**
-     * @copydoc Dali::Accessibility::Text::SetRangeOfSelection()
-     */
-    bool SetRangeOfSelection(size_t selectionIndex, size_t startOffset, size_t endOffset) override;
-
-    /**
-     * @copydoc Dali::Accessibility::Text::GetRangeExtents()
-     */
-    Rect<> GetRangeExtents(size_t startOffset, size_t endOffset, Accessibility::CoordinateType type) override;
+  public:
+    using TextControlAccessible::TextControlAccessible;
 
     /**
      * @copydoc Dali::Accessibility::Text::GetNameRaw()
@@ -307,20 +267,16 @@ protected:
      */
     Property::Index GetNamePropertyIndex() override;
 
+  protected:
     /**
-     * @copydoc Dali::Accessibility::Hypertext::GetLink()
-     */
-    Accessibility::Hyperlink* GetLink(int32_t linkIndex) const override;
-
-    /**
-     * @copydoc Dali::Accessibility::Hypertext::GetLinkIndex()
+     * @copydoc Dali::Toolkit::Internal::TextControlAccessible::GetTextAnchors()
      */
-    int32_t GetLinkIndex(int32_t characterOffset) const override;
+    const std::vector<Toolkit::TextAnchor>& GetTextAnchors() const override;
 
     /**
-     * @copydoc Dali::Accessibility::Hypertext::GetLinkCount()
+     * @copydoc Dali::Toolkit::Internal::TextControlAccessible::GetTextController()
      */
-    int32_t GetLinkCount() const override;
+    Toolkit::Text::ControllerPtr GetTextController() const override;
   };
 };
 
index 2ff1bd4..5d41058 100644 (file)
@@ -397,13 +397,23 @@ void TextSelectionPopup::OnInitialize()
   self.SetResizePolicy(ResizePolicy::FIT_TO_CHILDREN, Dimension::ALL_DIMENSIONS);
   self.SetProperty(Actor::Property::COLOR_ALPHA, 0.0f);
 
-  DevelControl::SetAccessibilityConstructor(Self(), [](Dali::Actor actor) {
-    return std::unique_ptr<Dali::Accessibility::Accessible>(
-      new DevelControl::ControlAccessible(actor, Dali::Accessibility::Role::DIALOG, true));
-  });
-
-  //Enable highightability
+  // Accessibility
   self.SetProperty(Toolkit::DevelControl::Property::ACCESSIBILITY_HIGHLIGHTABLE, true);
+  self.SetProperty(Toolkit::DevelControl::Property::ACCESSIBILITY_ROLE, Dali::Accessibility::Role::DIALOG);
+}
+
+DevelControl::ControlAccessible* TextSelectionPopup::CreateAccessibleObject()
+{
+  return new TextSelectionPopupAccessible(Self());
+}
+
+Dali::Accessibility::States TextSelectionPopup::TextSelectionPopupAccessible::CalculateStates()
+{
+  auto states = ControlAccessible::CalculateStates();
+
+  states[Dali::Accessibility::State::MODAL] = true;
+
+  return states;
 }
 
 void TextSelectionPopup::HideAnimationFinished(Animation& animation)
index 64130e1..41686ee 100644 (file)
@@ -24,6 +24,7 @@
 #include <string>
 
 // INTERNAL INCLUDES
+#include <dali-toolkit/devel-api/controls/control-devel.h>
 #include <dali-toolkit/devel-api/controls/table-view/table-view.h>
 #include <dali-toolkit/devel-api/controls/text-controls/text-selection-popup.h>
 #include <dali-toolkit/devel-api/controls/text-controls/text-selection-toolbar.h>
@@ -139,6 +140,11 @@ private: // From Control
    */
   void OnInitialize() override;
 
+  /**
+   * @copydoc Toolkit::Internal::Control::CreateAccessibleObject()
+   */
+  DevelControl::ControlAccessible* CreateAccessibleObject() override;
+
 private: // Implementation
   void HideAnimationFinished(Animation& animation);
 
@@ -266,6 +272,18 @@ private: // Implementation
    */
   virtual ~TextSelectionPopup();
 
+protected:
+  class TextSelectionPopupAccessible : public DevelControl::ControlAccessible
+  {
+  public:
+    using DevelControl::ControlAccessible::ControlAccessible;
+
+    /**
+     * @copydoc DevelControl::ControlAccessible::CalculateStates()
+     */
+    Dali::Accessibility::States CalculateStates() override;
+  };
+
 private:
   // Undefined copy constructor and assignment operators
   TextSelectionPopup(const TextSelectionPopup&);
index 3220328..f28f92b 100644 (file)
@@ -164,10 +164,7 @@ void TextSelectionToolbar::OnInitialize()
 {
   SetUp();
 
-  DevelControl::SetAccessibilityConstructor(Self(), [](Dali::Actor actor) {
-    return std::unique_ptr<Dali::Accessibility::Accessible>(
-      new DevelControl::ControlAccessible(actor, Dali::Accessibility::Role::TOOL_BAR));
-  });
+  Self().SetProperty(DevelControl::Property::ACCESSIBILITY_ROLE, Dali::Accessibility::Role::TOOL_BAR);
 }
 
 void TextSelectionToolbar::OnRelayout(const Vector2& size, RelayoutContainer& container)
index 0e894df..19cb548 100644 (file)
@@ -311,10 +311,7 @@ void ToolBar::OnInitialize()
   mLayout.SetRelativeWidth(0, mLeftRelativeSpace);
   mLayout.SetRelativeWidth(1, mRightRelativeSpace);
 
-  DevelControl::SetAccessibilityConstructor(Self(), [](Dali::Actor actor) {
-    return std::unique_ptr<Dali::Accessibility::Accessible>(
-      new DevelControl::ControlAccessible(actor, Dali::Accessibility::Role::TOOL_BAR));
-  });
+  Self().SetProperty(DevelControl::Property::ACCESSIBILITY_ROLE, Dali::Accessibility::Role::TOOL_BAR);
 }
 
 void ToolBar::OnChildAdd(Actor& child)
index c08625f..154caac 100644 (file)
@@ -118,13 +118,9 @@ void VideoView::OnInitialize()
   Actor self = Self();
   mVideoPlayer.FinishedSignal().Connect(this, &VideoView::EmitSignalFinish);
 
-  DevelControl::SetAccessibilityConstructor(self, [](Dali::Actor actor) {
-    return std::unique_ptr<Dali::Accessibility::Accessible>(
-      new DevelControl::ControlAccessible(actor, Dali::Accessibility::Role::VIDEO));
-  });
-
-  //Enable highightability
-  Self().SetProperty(Toolkit::DevelControl::Property::ACCESSIBILITY_HIGHLIGHTABLE, true);
+  // Accessibility
+  self.SetProperty(DevelControl::Property::ACCESSIBILITY_ROLE, Dali::Accessibility::Role::VIDEO);
+  self.SetProperty(DevelControl::Property::ACCESSIBILITY_HIGHLIGHTABLE, true);
 
   //update self property
   self.RegisterProperty(IS_VIDEO_VIEW_PROPERTY_NAME, true, Property::READ_WRITE);
index afb2bf9..271b826 100644 (file)
@@ -167,6 +167,11 @@ void Control::ClearBackground()
   RelayoutRequest();
 }
 
+Toolkit::DevelControl::ControlAccessible* Control::GetAccessibleObject()
+{
+  return mImpl->GetAccessibleObject();
+}
+
 void Control::EnableGestureDetection(GestureType::Value type)
 {
   if((type & GestureType::PINCH) && !mImpl->mPinchGestureDetector)
@@ -340,6 +345,11 @@ bool Control::OnAccessibilityZoom()
   return false; // Accessibility zoom action is not handled by default
 }
 
+DevelControl::ControlAccessible* Control::CreateAccessibleObject()
+{
+  return new DevelControl::ControlAccessible(Self());
+}
+
 Actor Control::GetNextKeyboardFocusableActor(Actor currentFocusedActor, Toolkit::Control::KeyboardFocus::Direction direction, bool loopEnabled)
 {
   return Actor();
@@ -484,7 +494,7 @@ void Control::EmitKeyInputFocusSignal(bool focusGained)
 
   if(Accessibility::IsUp())
   {
-    auto self = mImpl->GetAccessibilityObject(Self());
+    auto self = GetAccessibleObject();
     self->EmitFocused(focusGained);
     auto parent = self->GetParent();
     if(parent && !self->GetStates()[Dali::Accessibility::State::MANAGES_DESCENDANTS])
@@ -571,10 +581,7 @@ void Control::OnPropertySet(Property::Index index, const Property::Value& proper
     }
     case Actor::Property::VISIBLE:
     {
-      if(Dali::Accessibility::IsUp() && !Self().GetProperty<bool>(Toolkit::DevelControl::Property::ACCESSIBILITY_HIDDEN))
-      {
-        Dali::Accessibility::Accessible::Get(Self())->EmitVisible(Self().GetProperty(Actor::Property::VISIBLE).Get<bool>());
-      }
+      GetAccessibleObject()->EmitVisible(Self().GetProperty<bool>(Actor::Property::VISIBLE));
       break;
     }
   }
index e2d1ca4..9ccb533 100644 (file)
@@ -43,6 +43,12 @@ namespace Toolkit
 
 class StyleManager;
 
+namespace DevelControl
+{
+class ControlAccessible;
+
+} // namespace DevelControl
+
 namespace Internal
 {
 
@@ -109,6 +115,19 @@ public:
    */
   void ClearBackground();
 
+  // Accessibility
+
+  /**
+   * @brief Gets the Accessible object that represents this control.
+   *
+   * This method calls CreateAccessibleObject() if necessary, so a non-null return is expected.
+   *
+   * @return The Accessible object
+   *
+   * @see CreateAccessibleObject()
+   */
+  Toolkit::DevelControl::ControlAccessible* GetAccessibleObject();
+
   // Gesture Detection
 
   /**
@@ -488,6 +507,24 @@ public: // API for derived classes to override
    */
   virtual bool OnAccessibilityZoom();
 
+  /**
+   * @brief This method should be overriden by deriving classes when they wish to be
+   * represented by a custom Accessible object implementation.
+   *
+   * The AT-SPI infrastructure is responsible for destroying the returned object.
+   *
+   * Currently, this method is called at most once in a given Control's lifetime, when
+   * GetAccessibleObject() is called for the first time. A future version of the
+   * AT-SPI infrastructure, however, may delete the Accessible object and request a new
+   * one to be created (by calling this method) multiple times, for example during
+   * scene connection and disconnection.
+   *
+   * @return The newly created Accessible object
+   *
+   * @see GetAccessibleObject()
+   */
+  virtual DevelControl::ControlAccessible* CreateAccessibleObject();
+
   // Keyboard focus
 
   /**