[AT-SPI] Add ActorAccessible 55/267455/7
authorArtur Świgoń <a.swigon@samsung.com>
Fri, 3 Dec 2021 12:45:05 +0000 (13:45 +0100)
committerArtur Świgoń <a.swigon@samsung.com>
Mon, 3 Jan 2022 10:33:18 +0000 (11:33 +0100)
This change adds a new ActorAccessible class as a common ancestor for
both AdaptorAccessible and ControlAccessible. This will allow to reduce
code duplication between dali-adaptor and dali-toolkit. There are no
significant changes to methods moved from AdaptorAccessible to
ActorAccessible, as they will be reworked in a later change.

Change-Id: I61fb8c6610e761cd8d49f8cf67f61af35cfe8dda

dali/devel-api/adaptor-framework/accessibility.cpp
dali/devel-api/adaptor-framework/actor-accessible.cpp [new file with mode: 0644]
dali/devel-api/adaptor-framework/actor-accessible.h [new file with mode: 0644]
dali/devel-api/atspi-interfaces/accessible.h
dali/devel-api/atspi-interfaces/component.h
dali/devel-api/file.list
dali/internal/accessibility/bridge/accessible.cpp
dali/internal/accessibility/bridge/bridge-base.h
dali/internal/accessibility/bridge/component.cpp

index 7caed8e..cea55f3 100644 (file)
 #include <dali/public-api/object/object-registry.h>
 #include <dali/public-api/object/type-info.h>
 #include <dali/public-api/object/type-registry-helper.h>
-#include <dali/public-api/object/weak-handle.h>
 #include <string_view>
 #include <unordered_map>
 
 // INTERNAL INCLUDES
 #include <dali/devel-api/adaptor-framework/accessibility-bridge.h>
+#include <dali/devel-api/adaptor-framework/actor-accessible.h>
 #include <dali/devel-api/adaptor-framework/proxy-accessible.h>
 #include <dali/devel-api/adaptor-framework/window-devel.h>
 #include <dali/devel-api/atspi-interfaces/accessible.h>
@@ -232,66 +232,18 @@ void Bridge::SetIsOnRootLevel(Accessible* owner)
 
 namespace
 {
-class AdaptorAccessible : public virtual Accessible, public virtual Collection, public virtual Component
+class AdaptorAccessible : public ActorAccessible
 {
 protected:
-  Dali::WeakHandle<Dali::Actor> mSelf;
-  bool                          mRoot = false;
-
-  Dali::Actor Self() const
-  {
-    auto handle = mSelf.GetHandle();
-
-    // AdaptorAccessible is deleted on ObjectDestroyedSignal
-    // for the respective actor (see `nonControlAccessibles`).
-    DALI_ASSERT_ALWAYS(handle);
-
-    return handle;
-  }
+  bool mRoot = false;
 
 public:
   AdaptorAccessible(Dali::Actor actor, bool isRoot)
-  : mSelf(actor),
+  : ActorAccessible(actor),
     mRoot(isRoot)
   {
   }
 
-  Dali::Rect<> GetExtents(Dali::Accessibility::CoordinateType type) const override
-  {
-    Dali::Actor actor                   = Self();
-    Vector2     screenPosition          = actor.GetProperty(Actor::Property::SCREEN_POSITION).Get<Vector2>();
-    Vector3     size                    = actor.GetCurrentProperty<Vector3>(Actor::Property::SIZE) * actor.GetCurrentProperty<Vector3>(Actor::Property::WORLD_SCALE);
-    bool        positionUsesAnchorPoint = actor.GetProperty(Actor::Property::POSITION_USES_ANCHOR_POINT).Get<bool>();
-    Vector3     anchorPointOffSet       = size * (positionUsesAnchorPoint ? actor.GetCurrentProperty<Vector3>(Actor::Property::ANCHOR_POINT) : AnchorPoint::TOP_LEFT);
-    Vector2     position                = Vector2(screenPosition.x - anchorPointOffSet.x, screenPosition.y - anchorPointOffSet.y);
-
-    if(type == Dali::Accessibility::CoordinateType::WINDOW)
-    {
-      return {position.x, position.y, size.x, size.y};
-    }
-    else // Dali::Accessibility::CoordinateType::SCREEN
-    {
-      auto window         = Dali::DevelWindow::Get(actor);
-      auto windowPosition = window.GetPosition();
-      return {position.x + windowPosition.GetX(), position.y + windowPosition.GetY(), size.x, size.y};
-    }
-  }
-
-  Dali::Accessibility::ComponentLayer GetLayer() const override
-  {
-    return Dali::Accessibility::ComponentLayer::WINDOW;
-  }
-
-  int16_t GetMdiZOrder() const override
-  {
-    return 0;
-  }
-
-  double GetAlpha() const override
-  {
-    return 0;
-  }
-
   bool GrabFocus() override
   {
     return false;
@@ -307,64 +259,6 @@ public:
     return false;
   }
 
-  bool IsScrollable() const override
-  {
-    return false;
-  }
-
-  std::string GetName() const override
-  {
-    return Self().GetProperty<std::string>(Dali::Actor::Property::NAME);
-  }
-
-  std::string GetDescription() const override
-  {
-    return "";
-  }
-
-  Accessible* GetParent() override
-  {
-    if(IsOnRootLevel())
-    {
-      auto data = GetBridgeData();
-      return data->mBridge->GetApplication();
-    }
-    return Get(Self().GetParent());
-  }
-
-  size_t GetChildCount() const override
-  {
-    return static_cast<size_t>(Self().GetChildCount());
-  }
-
-  Accessible* GetChildAtIndex(size_t index) override
-  {
-    auto numberOfChildren = static_cast<size_t>(Self().GetChildCount());
-    if(index >= numberOfChildren)
-    {
-      throw std::domain_error{"invalid index " + std::to_string(index) + " for object with " + std::to_string(numberOfChildren) + " children"};
-    }
-    return Get(Self().GetChildAt(static_cast<unsigned int>(index)));
-  }
-
-  size_t GetIndexInParent() override
-  {
-    auto parent = Self().GetParent();
-    if(!parent)
-    {
-      return 0;
-    }
-    auto size = static_cast<size_t>(parent.GetChildCount());
-    for(auto i = 0u; i < size; ++i)
-    {
-      if(parent.GetChildAt(i) == Self())
-      {
-        return i;
-      }
-    }
-    throw std::domain_error{"actor is not a child of it's parent"};
-  }
-
   Role GetRole() const override
   {
     return mRoot ? Role::WINDOW : Role::REDUNDANT_OBJECT;
@@ -410,11 +304,6 @@ public:
   {
     return {};
   }
-
-  Dali::Actor GetInternalActor() override
-  {
-    return mSelf.GetHandle();
-  }
 }; // AdaptorAccessible
 
 using AdaptorAccessiblesType = std::unordered_map<const Dali::RefObject*, std::unique_ptr<AdaptorAccessible> >;
@@ -432,6 +321,9 @@ ObjectRegistry objectRegistry;
 void Accessible::SetObjectRegistry(ObjectRegistry registry)
 {
   objectRegistry = registry;
+  objectRegistry.ObjectDestroyedSignal().Connect([](const Dali::RefObject* obj) {
+    gAdaptorAccessibles.erase(obj);
+  });
 }
 
 void Accessible::RegisterExternalAccessibleGetter(std::function<Accessible*(Dali::Actor)> functor)
@@ -449,12 +341,6 @@ Accessible* Accessible::Get(Dali::Actor actor, bool isRoot)
   auto accessible = convertingFunctor(actor);
   if(!accessible)
   {
-    if(gAdaptorAccessibles.empty() && objectRegistry)
-    {
-      objectRegistry.ObjectDestroyedSignal().Connect([](const Dali::RefObject* obj) {
-        gAdaptorAccessibles.erase(obj);
-      });
-    }
     auto pair = gAdaptorAccessibles.emplace(&actor.GetBaseObject(), nullptr);
     if(pair.second)
     {
diff --git a/dali/devel-api/adaptor-framework/actor-accessible.cpp b/dali/devel-api/adaptor-framework/actor-accessible.cpp
new file mode 100644 (file)
index 0000000..82e4b18
--- /dev/null
@@ -0,0 +1,147 @@
+/*
+ * Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// CLASS HEADER
+#include <dali/devel-api/adaptor-framework/actor-accessible.h>
+
+// INTERNAL INCLUDES
+#include <dali/devel-api/adaptor-framework/window-devel.h>
+
+namespace Dali::Accessibility
+{
+ActorAccessible::ActorAccessible(Actor actor)
+: mSelf(actor)
+{
+}
+
+std::string ActorAccessible::GetName() const
+{
+  return Self().GetProperty<std::string>(Dali::Actor::Property::NAME);
+}
+
+std::string ActorAccessible::GetDescription() const
+{
+  return {};
+}
+
+Accessible* ActorAccessible::GetParent()
+{
+  if(IsOnRootLevel())
+  {
+    auto data = GetBridgeData();
+    return data->mBridge->GetApplication();
+  }
+
+  return Get(Self().GetParent());
+}
+
+std::size_t ActorAccessible::GetChildCount() const
+{
+  return static_cast<std::size_t>(Self().GetChildCount());
+}
+
+std::vector<Accessible*> ActorAccessible::GetChildren()
+{
+  std::vector<Accessible*> tmp(GetChildCount());
+  for(auto i = 0u; i < tmp.size(); ++i)
+  {
+    tmp[i] = GetChildAtIndex(i);
+  }
+
+  return tmp;
+}
+
+Accessible* ActorAccessible::GetChildAtIndex(std::size_t index)
+{
+  auto numberOfChildren = GetChildCount();
+  if(DALI_UNLIKELY(index >= numberOfChildren))
+  {
+    throw std::domain_error{"invalid index " + std::to_string(index) + " for object with " + std::to_string(numberOfChildren) + " children"};
+  }
+
+  return Get(Self().GetChildAt(static_cast<std::uint32_t>(index)));
+}
+
+std::size_t ActorAccessible::GetIndexInParent()
+{
+  auto self   = Self();
+  auto parent = self.GetParent();
+
+  if(DALI_UNLIKELY(!parent))
+  {
+    throw std::domain_error{"can't call GetIndexInParent on object without parent"};
+  }
+
+  auto size = static_cast<std::size_t>(parent.GetChildCount());
+  for(auto i = 0u; i < size; ++i)
+  {
+    if(parent.GetChildAt(i) == self)
+    {
+      return i;
+    }
+  }
+
+  throw std::domain_error{"actor is not a child of its parent"};
+}
+
+Dali::Actor ActorAccessible::GetInternalActor()
+{
+  return Self();
+}
+
+ComponentLayer ActorAccessible::GetLayer() const
+{
+  return ComponentLayer::WINDOW;
+}
+
+std::int16_t ActorAccessible::GetMdiZOrder() const
+{
+  return 0;
+}
+
+double ActorAccessible::GetAlpha() const
+{
+  return 0;
+}
+
+bool ActorAccessible::IsScrollable() const
+{
+  return false;
+}
+
+Dali::Rect<> ActorAccessible::GetExtents(CoordinateType type) const
+{
+  Dali::Actor actor                   = Self();
+  Vector2     screenPosition          = actor.GetProperty<Vector2>(Actor::Property::SCREEN_POSITION);
+  Vector3     size                    = actor.GetCurrentProperty<Vector3>(Actor::Property::SIZE) * actor.GetCurrentProperty<Vector3>(Actor::Property::WORLD_SCALE);
+  bool        positionUsesAnchorPoint = actor.GetProperty<bool>(Actor::Property::POSITION_USES_ANCHOR_POINT);
+  Vector3     anchorPointOffSet       = size * (positionUsesAnchorPoint ? actor.GetCurrentProperty<Vector3>(Actor::Property::ANCHOR_POINT) : AnchorPoint::TOP_LEFT);
+  Vector2     position                = Vector2(screenPosition.x - anchorPointOffSet.x, screenPosition.y - anchorPointOffSet.y);
+
+  if(type == CoordinateType::WINDOW)
+  {
+    return {position.x, position.y, size.x, size.y};
+  }
+  else // CoordinateType::SCREEN
+  {
+    auto window         = Dali::DevelWindow::Get(actor);
+    auto windowPosition = window.GetPosition();
+    return {position.x + windowPosition.GetX(), position.y + windowPosition.GetY(), size.x, size.y};
+  }
+}
+
+} // namespace Dali::Accessibility
diff --git a/dali/devel-api/adaptor-framework/actor-accessible.h b/dali/devel-api/adaptor-framework/actor-accessible.h
new file mode 100644 (file)
index 0000000..1306229
--- /dev/null
@@ -0,0 +1,120 @@
+#ifndef DALI_ADAPTOR_ACTOR_ACCESSIBLE_H
+#define DALI_ADAPTOR_ACTOR_ACCESSIBLE_H
+
+/*
+ * Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// EXTERNAL INCLUDES
+#include <dali/public-api/actors/actor.h>
+#include <dali/public-api/object/weak-handle.h>
+
+// INTERNAL INCLUDES
+#include <dali/devel-api/atspi-interfaces/accessible.h>
+#include <dali/devel-api/atspi-interfaces/collection.h>
+#include <dali/devel-api/atspi-interfaces/component.h>
+
+namespace Dali::Accessibility
+{
+class DALI_ADAPTOR_API ActorAccessible : public virtual Accessible, public virtual Collection, public virtual Component
+{
+public:
+  ActorAccessible() = delete;
+
+  ActorAccessible(Actor actor);
+
+  /**
+   * @copydoc Dali::Accessibility::Accessible::GetName()
+   */
+  std::string GetName() const override;
+
+  /**
+   * @copydoc Dali::Accessibility::Accessible::GetDescription()
+   */
+  std::string GetDescription() const override;
+
+  /**
+   * @copydoc Dali::Accessibility::Accessible::GetParent()
+   */
+  Accessible* GetParent() override;
+
+  /**
+   * @copydoc Dali::Accessibility::Accessible::GetChildCount()
+   */
+  std::size_t GetChildCount() const override;
+
+  /**
+   * @copydoc Dali::Accessibility::Accessible::GetChildren()
+   */
+  std::vector<Accessible*> GetChildren() override;
+
+  /**
+   * @copydoc Dali::Accessibility::Accessible::GetChildAtIndex()
+   */
+  Accessible* GetChildAtIndex(std::size_t index) override;
+
+  /**
+   * @copydoc Dali::Accessibility::Accessible::GetIndexInParent()
+   */
+  std::size_t GetIndexInParent() override;
+
+  /**
+   * @copydoc Dali::Accessibility::Accessible::GetInternalActor()
+   */
+  Dali::Actor GetInternalActor() override;
+
+  /**
+   * @copydoc Dali::Accessibility::Component::GetLayer()
+   */
+  ComponentLayer GetLayer() const override;
+
+  /**
+   * @copydoc Dali::Accessibility::Component::GetMdiZOrder()
+   */
+  std::int16_t GetMdiZOrder() const override;
+
+  /**
+   * @copydoc Dali::Accessibility::Component::GetAlpha()
+   */
+  double GetAlpha() const override;
+
+  /**
+   * @copydoc Dali::Accessibility::Component::IsScrollable()
+   */
+  bool IsScrollable() const override;
+
+  /**
+   * @copydoc Dali::Accessibility::Component::GetExtents()
+   */
+  Dali::Rect<> GetExtents(CoordinateType type) const override;
+
+protected:
+  Dali::Actor Self() const
+  {
+    auto handle = mSelf.GetHandle();
+
+    // It is a bug if the Accessible outlives its Actor
+    DALI_ASSERT_ALWAYS(handle);
+
+    return handle;
+  }
+
+private:
+  Dali::WeakHandle<Dali::Actor> mSelf;
+};
+
+} // namespace Dali::Accessibility
+
+#endif // DALI_ADAPTOR_ACTOR_ACCESSIBLE_H
index 91dc7ab..a81a34a 100644 (file)
@@ -205,7 +205,7 @@ public:
    *
    * @return The collection of accessibility objects
    */
-  virtual std::vector<Accessible*> GetChildren();
+  virtual std::vector<Accessible*> GetChildren() = 0;
 
   /**
    * @brief Gets child of the index.
index 5a0fa73..1853313 100644 (file)
@@ -105,7 +105,7 @@ public:
    *
    * @see Dali:Accessibility::State
    */
-  virtual bool IsScrollable() const;
+  virtual bool IsScrollable() const = 0;
 
   /**
    * @brief Gets Accessible object containing given point.
index b501e0c..1390bf9 100755 (executable)
@@ -2,6 +2,7 @@
 
 SET( devel_api_src_files
   ${adaptor_devel_api_dir}/adaptor-framework/accessibility.cpp
+  ${adaptor_devel_api_dir}/adaptor-framework/actor-accessible.cpp
   ${adaptor_devel_api_dir}/adaptor-framework/animated-image-loading.cpp
   ${adaptor_devel_api_dir}/adaptor-framework/application-devel.cpp
   ${adaptor_devel_api_dir}/adaptor-framework/atspi-accessibility.cpp
@@ -55,6 +56,7 @@ SET( devel_api_src_files
 SET( devel_api_adaptor_framework_header_files
   ${adaptor_devel_api_dir}/adaptor-framework/accessibility.h
   ${adaptor_devel_api_dir}/adaptor-framework/accessibility-bridge.h
+  ${adaptor_devel_api_dir}/adaptor-framework/actor-accessible.h
   ${adaptor_devel_api_dir}/adaptor-framework/animated-image-loading.h
   ${adaptor_devel_api_dir}/adaptor-framework/application-devel.h
   ${adaptor_devel_api_dir}/adaptor-framework/atspi-accessibility.h
index 08c57d3..d58bc20 100644 (file)
@@ -195,16 +195,6 @@ void Accessible::EmitBoundsChanged(Rect<> rect)
   }
 }
 
-std::vector<Accessible*> Accessible::GetChildren()
-{
-  std::vector<Accessible*> tmp(GetChildCount());
-  for(auto i = 0u; i < tmp.size(); ++i)
-  {
-    tmp[i] = GetChildAtIndex(i);
-  }
-  return tmp;
-}
-
 std::shared_ptr<Bridge::Data> Accessible::GetBridgeData() const
 {
   auto handle = mBridgeData.lock();
index 30917e2..cdffa9e 100644 (file)
@@ -63,6 +63,11 @@ public:
     return mChildren.size();
   }
 
+  std::vector<Dali::Accessibility::Accessible*> GetChildren() override
+  {
+    return mChildren;
+  }
+
   Dali::Accessibility::Accessible* GetChildAtIndex(size_t index) override
   {
     auto size = mChildren.size();
index 1a4c9c9..640f30f 100644 (file)
@@ -45,8 +45,3 @@ Accessible* Component::GetAccessibleAtPoint(Point point, Dali::Accessibility::Co
   }
   return nullptr;
 }
-
-bool Component::IsScrollable() const
-{
-  return false;
-}