From: Artur Świgoń Date: Fri, 3 Dec 2021 12:45:05 +0000 (+0100) Subject: [AT-SPI] Add ActorAccessible X-Git-Tag: dali_2.1.4~3 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=a1284cb38c39e265010e0fe91db9e2f8d67a3239;p=platform%2Fcore%2Fuifw%2Fdali-adaptor.git [AT-SPI] Add ActorAccessible 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 --- diff --git a/dali/devel-api/adaptor-framework/accessibility.cpp b/dali/devel-api/adaptor-framework/accessibility.cpp index 7caed8e..cea55f3 100644 --- a/dali/devel-api/adaptor-framework/accessibility.cpp +++ b/dali/devel-api/adaptor-framework/accessibility.cpp @@ -22,12 +22,12 @@ #include #include #include -#include #include #include // INTERNAL INCLUDES #include +#include #include #include #include @@ -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 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(); - Vector3 size = actor.GetCurrentProperty(Actor::Property::SIZE) * actor.GetCurrentProperty(Actor::Property::WORLD_SCALE); - bool positionUsesAnchorPoint = actor.GetProperty(Actor::Property::POSITION_USES_ANCHOR_POINT).Get(); - Vector3 anchorPointOffSet = size * (positionUsesAnchorPoint ? actor.GetCurrentProperty(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(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(Self().GetChildCount()); - } - - Accessible* GetChildAtIndex(size_t index) override - { - auto numberOfChildren = static_cast(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(index))); - } - - size_t GetIndexInParent() override - { - auto parent = Self().GetParent(); - if(!parent) - { - return 0; - } - auto size = static_cast(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 >; @@ -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 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 index 0000000..82e4b18 --- /dev/null +++ b/dali/devel-api/adaptor-framework/actor-accessible.cpp @@ -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 + +// INTERNAL INCLUDES +#include + +namespace Dali::Accessibility +{ +ActorAccessible::ActorAccessible(Actor actor) +: mSelf(actor) +{ +} + +std::string ActorAccessible::GetName() const +{ + return Self().GetProperty(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(Self().GetChildCount()); +} + +std::vector ActorAccessible::GetChildren() +{ + std::vector 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(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(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(Actor::Property::SCREEN_POSITION); + Vector3 size = actor.GetCurrentProperty(Actor::Property::SIZE) * actor.GetCurrentProperty(Actor::Property::WORLD_SCALE); + bool positionUsesAnchorPoint = actor.GetProperty(Actor::Property::POSITION_USES_ANCHOR_POINT); + Vector3 anchorPointOffSet = size * (positionUsesAnchorPoint ? actor.GetCurrentProperty(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 index 0000000..1306229 --- /dev/null +++ b/dali/devel-api/adaptor-framework/actor-accessible.h @@ -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 +#include + +// INTERNAL INCLUDES +#include +#include +#include + +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 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 mSelf; +}; + +} // namespace Dali::Accessibility + +#endif // DALI_ADAPTOR_ACTOR_ACCESSIBLE_H diff --git a/dali/devel-api/atspi-interfaces/accessible.h b/dali/devel-api/atspi-interfaces/accessible.h index 91dc7ab..a81a34a 100644 --- a/dali/devel-api/atspi-interfaces/accessible.h +++ b/dali/devel-api/atspi-interfaces/accessible.h @@ -205,7 +205,7 @@ public: * * @return The collection of accessibility objects */ - virtual std::vector GetChildren(); + virtual std::vector GetChildren() = 0; /** * @brief Gets child of the index. diff --git a/dali/devel-api/atspi-interfaces/component.h b/dali/devel-api/atspi-interfaces/component.h index 5a0fa73..1853313 100644 --- a/dali/devel-api/atspi-interfaces/component.h +++ b/dali/devel-api/atspi-interfaces/component.h @@ -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. diff --git a/dali/devel-api/file.list b/dali/devel-api/file.list index b501e0c..1390bf9 100755 --- a/dali/devel-api/file.list +++ b/dali/devel-api/file.list @@ -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 diff --git a/dali/internal/accessibility/bridge/accessible.cpp b/dali/internal/accessibility/bridge/accessible.cpp index 08c57d3..d58bc20 100644 --- a/dali/internal/accessibility/bridge/accessible.cpp +++ b/dali/internal/accessibility/bridge/accessible.cpp @@ -195,16 +195,6 @@ void Accessible::EmitBoundsChanged(Rect<> rect) } } -std::vector Accessible::GetChildren() -{ - std::vector tmp(GetChildCount()); - for(auto i = 0u; i < tmp.size(); ++i) - { - tmp[i] = GetChildAtIndex(i); - } - return tmp; -} - std::shared_ptr Accessible::GetBridgeData() const { auto handle = mBridgeData.lock(); diff --git a/dali/internal/accessibility/bridge/bridge-base.h b/dali/internal/accessibility/bridge/bridge-base.h index 30917e2..cdffa9e 100644 --- a/dali/internal/accessibility/bridge/bridge-base.h +++ b/dali/internal/accessibility/bridge/bridge-base.h @@ -63,6 +63,11 @@ public: return mChildren.size(); } + std::vector GetChildren() override + { + return mChildren; + } + Dali::Accessibility::Accessible* GetChildAtIndex(size_t index) override { auto size = mChildren.size(); diff --git a/dali/internal/accessibility/bridge/component.cpp b/dali/internal/accessibility/bridge/component.cpp index 1a4c9c9..640f30f 100644 --- a/dali/internal/accessibility/bridge/component.cpp +++ b/dali/internal/accessibility/bridge/component.cpp @@ -45,8 +45,3 @@ Accessible* Component::GetAccessibleAtPoint(Point point, Dali::Accessibility::Co } return nullptr; } - -bool Component::IsScrollable() const -{ - return false; -}