[AT-SPI] Add Table and TableCell interfaces
[platform/core/uifw/dali-adaptor.git] / dali / devel-api / adaptor-framework / accessibility.cpp
index ddc4f20..bba8f1d 100644 (file)
@@ -40,6 +40,8 @@
 #include <dali/devel-api/atspi-interfaces/hypertext.h>
 #include <dali/devel-api/atspi-interfaces/selection.h>
 #include <dali/devel-api/atspi-interfaces/socket.h>
+#include <dali/devel-api/atspi-interfaces/table.h>
+#include <dali/devel-api/atspi-interfaces/table-cell.h>
 #include <dali/devel-api/atspi-interfaces/text.h>
 #include <dali/devel-api/atspi-interfaces/value.h>
 #include <dali/internal/adaptor/common/adaptor-impl.h>
@@ -241,6 +243,8 @@ AtspiInterfaces Accessible::DoGetInterfaces() const
   interfaces[AtspiInterface::HYPERTEXT]     = dynamic_cast<const Hypertext*>(this);
   interfaces[AtspiInterface::SELECTION]     = dynamic_cast<const Selection*>(this);
   interfaces[AtspiInterface::SOCKET]        = dynamic_cast<const Socket*>(this);
+  interfaces[AtspiInterface::TABLE]         = dynamic_cast<const Table*>(this);
+  interfaces[AtspiInterface::TABLE_CELL]    = dynamic_cast<const TableCell*>(this);
   interfaces[AtspiInterface::TEXT]          = dynamic_cast<const Text*>(this);
   interfaces[AtspiInterface::VALUE]         = dynamic_cast<const Value*>(this);
 
@@ -338,6 +342,9 @@ namespace
 {
 class AdaptorAccessible : public ActorAccessible
 {
+private:
+  std::unique_ptr<TriggerEventInterface> mRenderNotification = nullptr;
+
 protected:
   bool mRoot = false;
 
@@ -366,7 +373,7 @@ public:
       return false;
     }
 
-    auto self = Self();
+    auto self                = Self();
     auto oldHighlightedActor = GetCurrentlyHighlightedActor();
     if(self == oldHighlightedActor)
     {
@@ -385,7 +392,7 @@ public:
 
     SetCurrentlyHighlightedActor(self);
 
-    auto window                                 = Dali::DevelWindow::Get(self);
+    auto                             window     = Dali::DevelWindow::Get(self);
     Dali::Internal::Adaptor::Window& windowImpl = Dali::GetImplementation(window);
     windowImpl.EmitAccessibilityHighlightSignal(true);
 
@@ -413,7 +420,7 @@ public:
 
     SetCurrentlyHighlightedActor({});
 
-    auto window                                 = Dali::DevelWindow::Get(self);
+    auto                             window     = Dali::DevelWindow::Get(self);
     Dali::Internal::Adaptor::Window& windowImpl = Dali::GetImplementation(window);
     windowImpl.EmitAccessibilityHighlightSignal(false);
 
@@ -453,7 +460,7 @@ public:
 
     if(mRoot)
     {
-      Dali::Window window                         = Dali::DevelWindow::Get(Self());
+      Dali::Window                     window     = Dali::DevelWindow::Get(Self());
       Dali::Internal::Adaptor::Window& windowImpl = Dali::GetImplementation(window);
       attributes["resID"]                         = windowImpl.GetNativeResourceId();
     }
@@ -474,12 +481,48 @@ public:
   {
     return {};
   }
+
+  void SetListenPostRender(bool enabled) override
+  {
+    if (!mRoot)
+    {
+      return;
+    }
+
+    auto window                                 = Dali::DevelWindow::Get(Self());
+    Dali::Internal::Adaptor::Window& windowImpl = Dali::GetImplementation(window);
+
+    if(!mRenderNotification)
+    {
+      mRenderNotification = std::unique_ptr<TriggerEventInterface>(
+                                           TriggerEventFactory::CreateTriggerEvent(MakeCallback(this, &AdaptorAccessible::OnPostRender),
+                                           TriggerEventInterface::KEEP_ALIVE_AFTER_TRIGGER));
+    }
+
+    if (enabled)
+    {
+      windowImpl.SetRenderNotification(mRenderNotification.get());
+    }
+    else
+    {
+      windowImpl.SetRenderNotification(nullptr);
+    }
+  }
+
+  void OnPostRender()
+  {
+    Accessibility::Bridge::GetCurrentBridge()->EmitPostRender(this);
+  }
 }; // AdaptorAccessible
 
 using AdaptorAccessiblesType = std::unordered_map<const Dali::RefObject*, std::unique_ptr<AdaptorAccessible> >;
 
 // Save RefObject from an Actor in Accessible::Get()
-AdaptorAccessiblesType gAdaptorAccessibles;
+AdaptorAccessiblesType& GetAdaptorAccessibles()
+{
+  static AdaptorAccessiblesType gAdaptorAccessibles;
+  return gAdaptorAccessibles;
+}
 
 std::function<Accessible*(Dali::Actor)> convertingFunctor = [](Dali::Actor) -> Accessible* {
   return nullptr;
@@ -492,7 +535,7 @@ void Accessible::SetObjectRegistry(ObjectRegistry registry)
 {
   objectRegistry = registry;
   objectRegistry.ObjectDestroyedSignal().Connect([](const Dali::RefObject* obj) {
-    gAdaptorAccessibles.erase(obj);
+    GetAdaptorAccessibles().erase(obj);
   });
 }
 
@@ -501,7 +544,7 @@ void Accessible::RegisterExternalAccessibleGetter(std::function<Accessible*(Dali
   convertingFunctor = functor;
 }
 
-Accessible* Accessible::Get(Dali::Actor actor, bool isRoot)
+Accessible* Accessible::Get(Dali::Actor actor)
 {
   if(!actor)
   {
@@ -511,9 +554,15 @@ Accessible* Accessible::Get(Dali::Actor actor, bool isRoot)
   auto accessible = convertingFunctor(actor);
   if(!accessible)
   {
-    auto pair = gAdaptorAccessibles.emplace(&actor.GetBaseObject(), nullptr);
+    auto pair = GetAdaptorAccessibles().emplace(&actor.GetBaseObject(), nullptr);
     if(pair.second)
     {
+      bool                     isRoot = false;
+      Dali::Integration::Scene scene  = Dali::Integration::Scene::Get(actor);
+      if(scene)
+      {
+        isRoot = (actor == scene.GetRootLayer());
+      }
       pair.first->second.reset(new AdaptorAccessible(actor, isRoot));
     }
     accessible = pair.first->second.get();