Merge "(Vector) Support dynamic properties" into devel/master
[platform/core/uifw/dali-toolkit.git] / dali-toolkit / internal / controls / control / control-data-impl.cpp
index 9e69f95..4c74704 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2022 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.
@@ -40,6 +40,7 @@
 #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/controls/control-wrapper-impl.h>
+#include <dali-toolkit/devel-api/visuals/visual-actions-devel.h>
 #include <dali-toolkit/internal/styling/style-manager-impl.h>
 #include <dali-toolkit/internal/visuals/visual-base-impl.h>
 #include <dali-toolkit/internal/visuals/visual-string-constants.h>
@@ -222,44 +223,57 @@ static bool DoAction(BaseObject* object, const std::string& actionName, const Pr
 
   DALI_ASSERT_ALWAYS(control);
 
-  if(0 == strcmp(actionName.c_str(), ACTION_ACCESSIBILITY_ACTIVATED) ||
-     actionName == "activate")
+  if(0 == strcmp(actionName.c_str(), ACTION_ACCESSIBILITY_ACTIVATED) || actionName == "activate")
   {
     // if cast succeeds there is an implementation so no need to check
     if(!DevelControl::AccessibilityActivateSignal(control).Empty())
+    {
       DevelControl::AccessibilityActivateSignal(control).Emit();
+    }
     else
+    {
       ret = Internal::GetImplementation(control).OnAccessibilityActivated();
+    }
   }
   else if(0 == strcmp(actionName.c_str(), ACTION_ACCESSIBILITY_READING_SKIPPED))
   {
     // if cast succeeds there is an implementation so no need to check
     if(!DevelControl::AccessibilityReadingSkippedSignal(control).Empty())
+    {
       DevelControl::AccessibilityReadingSkippedSignal(control).Emit();
+    }
   }
   else if(0 == strcmp(actionName.c_str(), ACTION_ACCESSIBILITY_READING_PAUSED))
   {
     // if cast succeeds there is an implementation so no need to check
     if(!DevelControl::AccessibilityReadingPausedSignal(control).Empty())
+    {
       DevelControl::AccessibilityReadingPausedSignal(control).Emit();
+    }
   }
   else if(0 == strcmp(actionName.c_str(), ACTION_ACCESSIBILITY_READING_RESUMED))
   {
     // if cast succeeds there is an implementation so no need to check
     if(!DevelControl::AccessibilityReadingResumedSignal(control).Empty())
+    {
       DevelControl::AccessibilityReadingResumedSignal(control).Emit();
+    }
   }
   else if(0 == strcmp(actionName.c_str(), ACTION_ACCESSIBILITY_READING_CANCELLED))
   {
     // if cast succeeds there is an implementation so no need to check
     if(!DevelControl::AccessibilityReadingCancelledSignal(control).Empty())
+    {
       DevelControl::AccessibilityReadingCancelledSignal(control).Emit();
+    }
   }
   else if(0 == strcmp(actionName.c_str(), ACTION_ACCESSIBILITY_READING_STOPPED))
   {
     // if cast succeeds there is an implementation so no need to check
     if(!DevelControl::AccessibilityReadingStoppedSignal(control).Empty())
+    {
       DevelControl::AccessibilityReadingStoppedSignal(control).Emit();
+    }
   }
   else
   {
@@ -397,6 +411,53 @@ void SetVisualsOffScene(const RegisteredVisualContainer& container, Actor parent
   }
 }
 
+Dali::Rect<> GetShowingGeometry(Dali::Rect<> rect, Dali::Toolkit::DevelControl::ControlAccessible* accessible)
+{
+  Rect<>  parentRect;
+  Vector2 currentPosition;
+  auto    parent = dynamic_cast<Toolkit::DevelControl::ControlAccessible*>(accessible->GetParent());
+
+  while(parent)
+  {
+    parentRect = parent->GetExtents(Dali::Accessibility::CoordinateType::WINDOW);
+
+    currentPosition.x = rect.x;
+    currentPosition.y = rect.y;
+
+    rect.x      = rect.x > parentRect.x ? rect.x : parentRect.x;
+    rect.y      = rect.y > parentRect.y ? rect.y : parentRect.y;
+    rect.width  = currentPosition.x + rect.width < parentRect.x + parentRect.width ? currentPosition.x + rect.width - rect.x : parentRect.x + parentRect.width - rect.x;
+    rect.height = currentPosition.y + rect.height < parentRect.y + parentRect.height ? currentPosition.y + rect.height - rect.y : parentRect.y + parentRect.height - rect.y;
+
+    if(rect.width < 0 || rect.height < 0)
+    {
+      return rect;
+    }
+
+    parent = dynamic_cast<Toolkit::DevelControl::ControlAccessible*>(parent->GetParent());
+  }
+
+  return rect;
+}
+
+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
@@ -414,13 +475,18 @@ const PropertyRegistration Control::Impl::PROPERTY_12(typeRegistration, "rightFo
 const PropertyRegistration Control::Impl::PROPERTY_13(typeRegistration, "upFocusableActorId",             Toolkit::DevelControl::Property::UP_FOCUSABLE_ACTOR_ID,            Property::INTEGER, &Control::Impl::SetProperty, &Control::Impl::GetProperty);
 const PropertyRegistration Control::Impl::PROPERTY_14(typeRegistration, "downFocusableActorId",           Toolkit::DevelControl::Property::DOWN_FOCUSABLE_ACTOR_ID,          Property::INTEGER, &Control::Impl::SetProperty, &Control::Impl::GetProperty);
 const PropertyRegistration Control::Impl::PROPERTY_15(typeRegistration, "shadow",                         Toolkit::DevelControl::Property::SHADOW,                           Property::MAP,     &Control::Impl::SetProperty, &Control::Impl::GetProperty);
-const PropertyRegistration Control::Impl::PROPERTY_16(typeRegistration, "accessibilityAttributes",        Toolkit::DevelControl::Property::ACCESSIBILITY_ATTRIBUTES,         Property::MAP,     &Control::Impl::SetProperty, &Control::Impl::GetProperty);
-const PropertyRegistration Control::Impl::PROPERTY_17(typeRegistration, "accessibilityName",              Toolkit::DevelControl::Property::ACCESSIBILITY_NAME,               Property::STRING,  &Control::Impl::SetProperty, &Control::Impl::GetProperty);
-const PropertyRegistration Control::Impl::PROPERTY_18(typeRegistration, "accessibilityDescription",       Toolkit::DevelControl::Property::ACCESSIBILITY_DESCRIPTION,        Property::STRING,  &Control::Impl::SetProperty, &Control::Impl::GetProperty);
-const PropertyRegistration Control::Impl::PROPERTY_19(typeRegistration, "accessibilityTranslationDomain", Toolkit::DevelControl::Property::ACCESSIBILITY_TRANSLATION_DOMAIN, Property::STRING,  &Control::Impl::SetProperty, &Control::Impl::GetProperty);
-const PropertyRegistration Control::Impl::PROPERTY_20(typeRegistration, "accessibilityRole",              Toolkit::DevelControl::Property::ACCESSIBILITY_ROLE,               Property::INTEGER, &Control::Impl::SetProperty, &Control::Impl::GetProperty);
-const PropertyRegistration Control::Impl::PROPERTY_21(typeRegistration, "accessibilityHighlightable",     Toolkit::DevelControl::Property::ACCESSIBILITY_HIGHLIGHTABLE,      Property::BOOLEAN, &Control::Impl::SetProperty, &Control::Impl::GetProperty);
-const PropertyRegistration Control::Impl::PROPERTY_22(typeRegistration, "accessibilityAnimated",          Toolkit::DevelControl::Property::ACCESSIBILITY_ANIMATED,           Property::BOOLEAN, &Control::Impl::SetProperty, &Control::Impl::GetProperty);
+const PropertyRegistration Control::Impl::PROPERTY_16(typeRegistration, "accessibilityName",              Toolkit::DevelControl::Property::ACCESSIBILITY_NAME,               Property::STRING,  &Control::Impl::SetProperty, &Control::Impl::GetProperty);
+const PropertyRegistration Control::Impl::PROPERTY_17(typeRegistration, "accessibilityDescription",       Toolkit::DevelControl::Property::ACCESSIBILITY_DESCRIPTION,        Property::STRING,  &Control::Impl::SetProperty, &Control::Impl::GetProperty);
+const PropertyRegistration Control::Impl::PROPERTY_18(typeRegistration, "accessibilityTranslationDomain", Toolkit::DevelControl::Property::ACCESSIBILITY_TRANSLATION_DOMAIN, Property::STRING,  &Control::Impl::SetProperty, &Control::Impl::GetProperty);
+const PropertyRegistration Control::Impl::PROPERTY_19(typeRegistration, "accessibilityRole",              Toolkit::DevelControl::Property::ACCESSIBILITY_ROLE,               Property::INTEGER, &Control::Impl::SetProperty, &Control::Impl::GetProperty);
+const PropertyRegistration Control::Impl::PROPERTY_20(typeRegistration, "accessibilityHighlightable",     Toolkit::DevelControl::Property::ACCESSIBILITY_HIGHLIGHTABLE,      Property::BOOLEAN, &Control::Impl::SetProperty, &Control::Impl::GetProperty);
+const PropertyRegistration Control::Impl::PROPERTY_21(typeRegistration, "accessibilityAttributes",        Toolkit::DevelControl::Property::ACCESSIBILITY_ATTRIBUTES,         Property::MAP,     &Control::Impl::SetProperty, &Control::Impl::GetProperty);
+const PropertyRegistration Control::Impl::PROPERTY_22(typeRegistration, "dispatchKeyEvents",              Toolkit::DevelControl::Property::DISPATCH_KEY_EVENTS,              Property::BOOLEAN, &Control::Impl::SetProperty, &Control::Impl::GetProperty);
+const PropertyRegistration Control::Impl::PROPERTY_23(typeRegistration, "accessibilityHidden",            Toolkit::DevelControl::Property::ACCESSIBILITY_HIDDEN,             Property::BOOLEAN, &Control::Impl::SetProperty, &Control::Impl::GetProperty);
+const PropertyRegistration Control::Impl::PROPERTY_24(typeRegistration, "clockwiseFocusableActorId",      Toolkit::DevelControl::Property::CLOCKWISE_FOCUSABLE_ACTOR_ID,     Property::INTEGER, &Control::Impl::SetProperty, &Control::Impl::GetProperty);
+const PropertyRegistration Control::Impl::PROPERTY_25(typeRegistration, "counterClockwiseFocusableActorId", Toolkit::DevelControl::Property::COUNTER_CLOCKWISE_FOCUSABLE_ACTOR_ID, Property::INTEGER, &Control::Impl::SetProperty, &Control::Impl::GetProperty);
+const PropertyRegistration Control::Impl::PROPERTY_26(typeRegistration, "automationId",                   Toolkit::DevelControl::Property::AUTOMATION_ID,                    Property::STRING,  &Control::Impl::SetProperty, &Control::Impl::GetProperty);
+
 // clang-format on
 
 Control::Impl::Impl(Control& controlImpl)
@@ -431,6 +497,8 @@ Control::Impl::Impl(Control& controlImpl)
   mRightFocusableActorId(-1),
   mUpFocusableActorId(-1),
   mDownFocusableActorId(-1),
+  mClockwiseFocusableActorId(-1),
+  mCounterClockwiseFocusableActorId(-1),
   mStyleName(""),
   mBackgroundColor(Color::TRANSPARENT),
   mStartingPinchScale(nullptr),
@@ -455,24 +523,10 @@ Control::Impl::Impl(Control& controlImpl)
   mIsKeyboardNavigationSupported(false),
   mIsKeyboardFocusGroup(false),
   mIsEmittingResourceReadySignal(false),
-  mNeedToEmitResourceReady(false)
+  mNeedToEmitResourceReady(false),
+  mDispatchKeyEvents(true)
 {
-  Dali::Accessibility::Accessible::RegisterControlAccessibilityGetter(
-    [](Dali::Actor actor) -> Dali::Accessibility::Accessible* {
-      return Control::Impl::GetAccessibilityObject(actor);
-    });
-
-  accessibilityConstructor = [](Dali::Actor actor) -> std::unique_ptr<Dali::Accessibility::Accessible> {
-    return std::unique_ptr<Dali::Accessibility::Accessible>(new DevelControl::AccessibleImpl(actor,
-                                                                                             Dali::Accessibility::Role::UNKNOWN));
-  };
-
-  size_t len = static_cast<size_t>(Dali::Accessibility::RelationType::MAX_COUNT);
-  mAccessibilityRelations.reserve(len);
-  for(auto i = 0u; i < len; ++i)
-  {
-    mAccessibilityRelations.push_back({});
-  }
+  Dali::Accessibility::Accessible::RegisterExternalAccessibleGetter(&ExternalAccessibleGetter);
 }
 
 Control::Impl::~Impl()
@@ -507,6 +561,84 @@ const Control::Impl& Control::Impl::Get(const Internal::Control& internalControl
   return *internalControl.mImpl;
 }
 
+void Control::Impl::CheckHighlightedObjectGeometry()
+{
+  auto accessible     = GetAccessibleObject();
+  auto lastPosition   = accessible->GetLastPosition();
+  auto accessibleRect = accessible->GetExtents(Dali::Accessibility::CoordinateType::WINDOW);
+  auto rect           = GetShowingGeometry(accessibleRect, accessible);
+
+  switch(mAccessibilityLastScreenRelativeMoveType)
+  {
+    case Dali::Accessibility::ScreenRelativeMoveType::OUTSIDE:
+    {
+      if(IsShowingGeometryOnScreen(rect))
+      {
+        mAccessibilityLastScreenRelativeMoveType = Dali::Accessibility::ScreenRelativeMoveType::INSIDE;
+      }
+      break;
+    }
+    case Dali::Accessibility::ScreenRelativeMoveType::INSIDE:
+    {
+      if(rect.width < 0 && accessibleRect.x != lastPosition.x)
+      {
+        mAccessibilityLastScreenRelativeMoveType = (accessibleRect.x < lastPosition.x) ? Dali::Accessibility::ScreenRelativeMoveType::OUTGOING_TOP_LEFT : Dali::Accessibility::ScreenRelativeMoveType::OUTGOING_BOTTOM_RIGHT;
+      }
+      if(rect.height < 0 && accessibleRect.y != lastPosition.y)
+      {
+        mAccessibilityLastScreenRelativeMoveType = (accessibleRect.y < lastPosition.y) ? Dali::Accessibility::ScreenRelativeMoveType::OUTGOING_TOP_LEFT : Dali::Accessibility::ScreenRelativeMoveType::OUTGOING_BOTTOM_RIGHT;
+      }
+      // notify AT-clients on outgoing moves only
+      if(mAccessibilityLastScreenRelativeMoveType != Dali::Accessibility::ScreenRelativeMoveType::INSIDE)
+      {
+        accessible->EmitMovedOutOfScreen(mAccessibilityLastScreenRelativeMoveType);
+      }
+      break;
+    }
+    case Dali::Accessibility::ScreenRelativeMoveType::OUTGOING_TOP_LEFT:
+    case Dali::Accessibility::ScreenRelativeMoveType::OUTGOING_BOTTOM_RIGHT:
+    {
+      if(IsShowingGeometryOnScreen(rect))
+      {
+        mAccessibilityLastScreenRelativeMoveType = Dali::Accessibility::ScreenRelativeMoveType::INSIDE;
+      }
+      else
+      {
+        mAccessibilityLastScreenRelativeMoveType = Dali::Accessibility::ScreenRelativeMoveType::OUTSIDE;
+      }
+      break;
+    }
+    default:
+    {
+      break;
+    }
+  }
+
+  accessible->SetLastPosition(Vector2(accessibleRect.x, accessibleRect.y));
+}
+
+void Control::Impl::RegisterAccessibilityPositionPropertyNotification()
+{
+  if(mIsAccessibilityPositionPropertyNotificationSet)
+  {
+    return;
+  }
+  // set default value until first move of object is detected
+  mAccessibilityLastScreenRelativeMoveType = Dali::Accessibility::ScreenRelativeMoveType::OUTSIDE;
+  // recalculate mAccessibilityLastScreenRelativeMoveType accordingly to the initial position
+  CheckHighlightedObjectGeometry();
+  mAccessibilityPositionNotification = mControlImpl.Self().AddPropertyNotification(Actor::Property::WORLD_POSITION, StepCondition(1.0f, 1.0f));
+  mAccessibilityPositionNotification.SetNotifyMode(PropertyNotification::NOTIFY_ON_CHANGED);
+  mAccessibilityPositionNotification.NotifySignal().Connect(this, [this](PropertyNotification&) { CheckHighlightedObjectGeometry(); });
+  mIsAccessibilityPositionPropertyNotificationSet = true;
+}
+
+void Control::Impl::UnregisterAccessibilityPositionPropertyNotification()
+{
+  mControlImpl.Self().RemovePropertyNotification(mAccessibilityPositionNotification);
+  mIsAccessibilityPositionPropertyNotificationSet = false;
+}
+
 // Gesture Detection Methods
 void Control::Impl::PinchDetected(Actor actor, const PinchGesture& pinch)
 {
@@ -836,6 +968,11 @@ void Control::Impl::NotifyVisualEvent(Visual::Base& object, Property::Index sign
   }
 }
 
+void Control::Impl::RelayoutRequest(Visual::Base& object)
+{
+  mControlImpl.RelayoutRequest();
+}
+
 bool Control::Impl::IsResourceReady() const
 {
   // Iterate through and check all the enabled visuals are ready
@@ -959,11 +1096,19 @@ void Control::Impl::DoAction(Dali::Property::Index visualIndex, Dali::Property::
   }
 }
 
-void Control::Impl::AppendAccessibilityAttribute(const std::string& key,
-                                                 const std::string  value)
+void Control::Impl::DoActionExtension(Dali::Property::Index visualIndex, Dali::Property::Index actionId, Dali::Any attributes)
 {
-  Property::Value* val = mAccessibilityAttributes.Find(key);
-  if(val)
+  RegisteredVisualContainer::Iterator iter;
+  if(FindVisual(visualIndex, mVisuals, iter))
+  {
+    Toolkit::GetImplementation((*iter)->visual).DoActionExtension(actionId, attributes);
+  }
+}
+
+void Control::Impl::AppendAccessibilityAttribute(const std::string& key, const std::string value)
+{
+  Property::Value* checkedValue = mAccessibilityAttributes.Find(key);
+  if(checkedValue)
   {
     mAccessibilityAttributes[key] = Property::Value(value);
   }
@@ -1046,76 +1191,6 @@ void Control::Impl::SetProperty(BaseObject* object, Property::Index index, const
       }
       break;
 
-      case Toolkit::DevelControl::Property::ACCESSIBILITY_NAME:
-      {
-        std::string name;
-        if(value.Get(name))
-        {
-          controlImpl.mImpl->mAccessibilityName    = name;
-          controlImpl.mImpl->mAccessibilityNameSet = true;
-        }
-        else
-        {
-          controlImpl.mImpl->mAccessibilityNameSet = false;
-        }
-      }
-      break;
-
-      case Toolkit::DevelControl::Property::ACCESSIBILITY_DESCRIPTION:
-      {
-        std::string txt;
-        if(value.Get(txt))
-        {
-          controlImpl.mImpl->mAccessibilityDescription    = txt;
-          controlImpl.mImpl->mAccessibilityDescriptionSet = true;
-        }
-        else
-        {
-          controlImpl.mImpl->mAccessibilityDescriptionSet = false;
-        }
-      }
-      break;
-
-      case Toolkit::DevelControl::Property::ACCESSIBILITY_TRANSLATION_DOMAIN:
-      {
-        std::string txt;
-        if(value.Get(txt))
-        {
-          controlImpl.mImpl->mAccessibilityTranslationDomain    = txt;
-          controlImpl.mImpl->mAccessibilityTranslationDomainSet = true;
-        }
-        else
-        {
-          controlImpl.mImpl->mAccessibilityTranslationDomainSet = false;
-        }
-      }
-      break;
-
-      case Toolkit::DevelControl::Property::ACCESSIBILITY_HIGHLIGHTABLE:
-      {
-        bool highlightable;
-        if(value.Get(highlightable))
-        {
-          controlImpl.mImpl->mAccessibilityHighlightable    = highlightable;
-          controlImpl.mImpl->mAccessibilityHighlightableSet = true;
-        }
-        else
-        {
-          controlImpl.mImpl->mAccessibilityHighlightableSet = false;
-        }
-      }
-      break;
-
-      case Toolkit::DevelControl::Property::ACCESSIBILITY_ROLE:
-      {
-        Dali::Accessibility::Role val;
-        if(value.Get(val))
-        {
-          controlImpl.mImpl->mAccessibilityRole = val;
-        }
-      }
-      break;
-
       case Toolkit::DevelControl::Property::UP_FOCUSABLE_ACTOR_ID:
       {
         int focusId;
@@ -1225,6 +1300,56 @@ void Control::Impl::SetProperty(BaseObject* object, Property::Index index, const
         break;
       }
 
+      case Toolkit::DevelControl::Property::ACCESSIBILITY_NAME:
+      {
+        std::string name;
+        if(value.Get(name))
+        {
+          controlImpl.mImpl->mAccessibilityName = name;
+        }
+        break;
+      }
+
+      case Toolkit::DevelControl::Property::ACCESSIBILITY_DESCRIPTION:
+      {
+        std::string text;
+        if(value.Get(text))
+        {
+          controlImpl.mImpl->mAccessibilityDescription = text;
+        }
+        break;
+      }
+
+      case Toolkit::DevelControl::Property::ACCESSIBILITY_TRANSLATION_DOMAIN:
+      {
+        std::string text;
+        if(value.Get(text))
+        {
+          controlImpl.mImpl->mAccessibilityTranslationDomain = text;
+        }
+        break;
+      }
+
+      case Toolkit::DevelControl::Property::ACCESSIBILITY_ROLE:
+      {
+        Dali::Accessibility::Role role;
+        if(value.Get(role))
+        {
+          controlImpl.mImpl->mAccessibilityRole = role;
+        }
+        break;
+      }
+
+      case Toolkit::DevelControl::Property::ACCESSIBILITY_HIGHLIGHTABLE:
+      {
+        bool highlightable;
+        if(value.Get(highlightable))
+        {
+          controlImpl.mImpl->mAccessibilityHighlightable = highlightable;
+        }
+        break;
+      }
+
       case Toolkit::DevelControl::Property::ACCESSIBILITY_ATTRIBUTES:
       {
         const Property::Map* map = value.GetMap();
@@ -1235,12 +1360,57 @@ void Control::Impl::SetProperty(BaseObject* object, Property::Index index, const
         break;
       }
 
-      case Toolkit::DevelControl::Property::ACCESSIBILITY_ANIMATED:
+      case Toolkit::DevelControl::Property::DISPATCH_KEY_EVENTS:
+      {
+        bool dispatch;
+        if(value.Get(dispatch))
+        {
+          controlImpl.mImpl->mDispatchKeyEvents = dispatch;
+        }
+        break;
+      }
+
+      case Toolkit::DevelControl::Property::ACCESSIBILITY_HIDDEN:
+      {
+        bool hidden;
+        if(value.Get(hidden))
+        {
+          controlImpl.mImpl->mAccessibilityHidden = hidden;
+
+          auto* accessible = controlImpl.GetAccessibleObject();
+          auto* parent     = dynamic_cast<Dali::Accessibility::ActorAccessible*>(accessible->GetParent());
+          if(parent)
+          {
+            parent->OnChildrenChanged();
+          }
+        }
+        break;
+      }
+      case Toolkit::DevelControl::Property::CLOCKWISE_FOCUSABLE_ACTOR_ID:
+      {
+        int focusId;
+        if(value.Get(focusId))
+        {
+          controlImpl.mImpl->mClockwiseFocusableActorId = focusId;
+        }
+        break;
+      }
+      case Toolkit::DevelControl::Property::COUNTER_CLOCKWISE_FOCUSABLE_ACTOR_ID:
+      {
+        int focusId;
+        if(value.Get(focusId))
+        {
+          controlImpl.mImpl->mCounterClockwiseFocusableActorId = focusId;
+        }
+        break;
+      }
+
+      case Toolkit::DevelControl::Property::AUTOMATION_ID:
       {
-        bool animated;
-        if(value.Get(animated))
+        std::string automationId;
+        if(value.Get(automationId))
         {
-          controlImpl.mImpl->mAccessibilityAnimated = animated;
+          controlImpl.mImpl->mAutomationId = automationId;
         }
         break;
       }
@@ -1290,48 +1460,6 @@ Property::Value Control::Impl::GetProperty(BaseObject* object, Property::Index i
         break;
       }
 
-      case Toolkit::DevelControl::Property::ACCESSIBILITY_NAME:
-      {
-        if(controlImpl.mImpl->mAccessibilityNameSet)
-        {
-          value = controlImpl.mImpl->mAccessibilityName;
-        }
-        break;
-      }
-
-      case Toolkit::DevelControl::Property::ACCESSIBILITY_DESCRIPTION:
-      {
-        if(controlImpl.mImpl->mAccessibilityDescriptionSet)
-        {
-          value = controlImpl.mImpl->mAccessibilityDescription;
-        }
-        break;
-      }
-
-      case Toolkit::DevelControl::Property::ACCESSIBILITY_TRANSLATION_DOMAIN:
-      {
-        if(controlImpl.mImpl->mAccessibilityTranslationDomainSet)
-        {
-          value = controlImpl.mImpl->mAccessibilityTranslationDomain;
-        }
-        break;
-      }
-
-      case Toolkit::DevelControl::Property::ACCESSIBILITY_HIGHLIGHTABLE:
-      {
-        if(controlImpl.mImpl->mAccessibilityHighlightableSet)
-        {
-          value = controlImpl.mImpl->mAccessibilityHighlightable;
-        }
-        break;
-      }
-
-      case Toolkit::DevelControl::Property::ACCESSIBILITY_ROLE:
-      {
-        value = Property::Value(controlImpl.mImpl->mAccessibilityRole);
-        break;
-      }
-
       case Toolkit::DevelControl::Property::UP_FOCUSABLE_ACTOR_ID:
       {
         value = controlImpl.mImpl->mUpFocusableActorId;
@@ -1399,15 +1527,69 @@ Property::Value Control::Impl::GetProperty(BaseObject* object, Property::Index i
         break;
       }
 
+      case Toolkit::DevelControl::Property::ACCESSIBILITY_NAME:
+      {
+        value = controlImpl.mImpl->mAccessibilityName;
+        break;
+      }
+
+      case Toolkit::DevelControl::Property::ACCESSIBILITY_DESCRIPTION:
+      {
+        value = controlImpl.mImpl->mAccessibilityDescription;
+        break;
+      }
+
+      case Toolkit::DevelControl::Property::ACCESSIBILITY_TRANSLATION_DOMAIN:
+      {
+        value = controlImpl.mImpl->mAccessibilityTranslationDomain;
+        break;
+      }
+
+      case Toolkit::DevelControl::Property::ACCESSIBILITY_ROLE:
+      {
+        value = Property::Value(controlImpl.mImpl->mAccessibilityRole);
+        break;
+      }
+
+      case Toolkit::DevelControl::Property::ACCESSIBILITY_HIGHLIGHTABLE:
+      {
+        value = controlImpl.mImpl->mAccessibilityHighlightable;
+        break;
+      }
+
       case Toolkit::DevelControl::Property::ACCESSIBILITY_ATTRIBUTES:
       {
         value = controlImpl.mImpl->mAccessibilityAttributes;
         break;
       }
 
-      case Toolkit::DevelControl::Property::ACCESSIBILITY_ANIMATED:
+      case Toolkit::DevelControl::Property::DISPATCH_KEY_EVENTS:
+      {
+        value = controlImpl.mImpl->mDispatchKeyEvents;
+        break;
+      }
+
+      case Toolkit::DevelControl::Property::ACCESSIBILITY_HIDDEN:
       {
-        value = controlImpl.mImpl->mAccessibilityAnimated;
+        value = controlImpl.mImpl->mAccessibilityHidden;
+        break;
+      }
+
+      case Toolkit::DevelControl::Property::CLOCKWISE_FOCUSABLE_ACTOR_ID:
+      {
+        value = controlImpl.mImpl->mClockwiseFocusableActorId;
+        break;
+      }
+
+      case Toolkit::DevelControl::Property::COUNTER_CLOCKWISE_FOCUSABLE_ACTOR_ID:
+      {
+        value = controlImpl.mImpl->mCounterClockwiseFocusableActorId;
+        break;
+      }
+
+      case Toolkit::DevelControl::Property::AUTOMATION_ID:
+      {
+        value = controlImpl.mImpl->mAutomationId;
         break;
       }
     }
@@ -1418,9 +1600,11 @@ Property::Value Control::Impl::GetProperty(BaseObject* object, Property::Index i
 
 void Control::Impl::RemoveAccessibilityAttribute(const std::string& key)
 {
-  Property::Value* val = mAccessibilityAttributes.Find(key);
-  if(val)
+  Property::Value* value = mAccessibilityAttributes.Find(key);
+  if(value)
+  {
     mAccessibilityAttributes[key] = Property::Value();
+  }
 }
 
 void Control::Impl::ClearAccessibilityAttributes()
@@ -1430,7 +1614,7 @@ void Control::Impl::ClearAccessibilityAttributes()
 
 void Control::Impl::SetAccessibilityReadingInfoType(const Dali::Accessibility::ReadingInfoTypes types)
 {
-  std::string value;
+  std::string value{};
   if(types[Dali::Accessibility::ReadingInfoType::NAME])
   {
     value += READING_INFO_TYPE_NAME;
@@ -1464,7 +1648,7 @@ void Control::Impl::SetAccessibilityReadingInfoType(const Dali::Accessibility::R
 
 Dali::Accessibility::ReadingInfoTypes Control::Impl::GetAccessibilityReadingInfoType() const
 {
-  std::string value;
+  std::string value{};
   auto        place = mAccessibilityAttributes.Find(READING_INFO_TYPE_ATTRIBUTE_NAME);
   if(place)
   {
@@ -1473,10 +1657,10 @@ Dali::Accessibility::ReadingInfoTypes Control::Impl::GetAccessibilityReadingInfo
   else
   {
     Dali::Accessibility::ReadingInfoTypes types;
-    types[Dali::Accessibility::ReadingInfoType::NAME] = true;
-    types[Dali::Accessibility::ReadingInfoType::ROLE] = true;
+    types[Dali::Accessibility::ReadingInfoType::NAME]        = true;
+    types[Dali::Accessibility::ReadingInfoType::ROLE]        = true;
     types[Dali::Accessibility::ReadingInfoType::DESCRIPTION] = true;
-    types[Dali::Accessibility::ReadingInfoType::STATE] = true;
+    types[Dali::Accessibility::ReadingInfoType::STATE]       = true;
     return types;
   }
 
@@ -1838,6 +2022,49 @@ Dali::Property Control::Impl::GetVisualProperty(Dali::Property::Index index, Dal
   return Dali::Property(handle, Property::INVALID_INDEX);
 }
 
+void Control::Impl::CreateTransitions(std::vector<std::pair<Dali::Property::Index, Dali::Property::Map>>& sourceProperties,
+                                      std::vector<std::pair<Dali::Property::Index, Dali::Property::Map>>& destinationProperties,
+                                      Dali::Toolkit::Control                                              source,
+                                      Dali::Toolkit::Control                                              destination)
+{
+  // Retrieves background properties to be transitioned.
+  Dali::Property::Map backgroundSourcePropertyMap, backgroundDestinationPropertyMap;
+  mControlImpl.MakeVisualTransition(backgroundSourcePropertyMap, backgroundDestinationPropertyMap, source, destination, Toolkit::Control::Property::BACKGROUND);
+  if(backgroundSourcePropertyMap.Count() > 0)
+  {
+    sourceProperties.push_back(std::pair<Dali::Property::Index, Dali::Property::Map>(Toolkit::Control::Property::BACKGROUND, backgroundSourcePropertyMap));
+    destinationProperties.push_back(std::pair<Dali::Property::Index, Dali::Property::Map>(Toolkit::Control::Property::BACKGROUND, backgroundDestinationPropertyMap));
+  }
+
+  // Retrieves shadow properties to be transitioned.
+  Dali::Property::Map shadowSourcePropertyMap, shadowDestinationPropertyMap;
+  mControlImpl.MakeVisualTransition(shadowSourcePropertyMap, shadowDestinationPropertyMap, source, destination, Toolkit::DevelControl::Property::SHADOW);
+  if(shadowSourcePropertyMap.Count() > 0)
+  {
+    sourceProperties.push_back(std::pair<Dali::Property::Index, Dali::Property::Map>(Toolkit::DevelControl::Property::SHADOW, shadowSourcePropertyMap));
+    destinationProperties.push_back(std::pair<Dali::Property::Index, Dali::Property::Map>(Toolkit::DevelControl::Property::SHADOW, shadowDestinationPropertyMap));
+  }
+
+  // Retrieves transition from inherited class.
+  mControlImpl.OnCreateTransitions(sourceProperties, destinationProperties, source, destination);
+}
+
+void Control::Impl::UpdateVisualProperties(const std::vector<std::pair<Dali::Property::Index, Dali::Property::Map>>& properties)
+{
+  for(auto&& data : properties)
+  {
+    if(data.first == Toolkit::Control::Property::BACKGROUND)
+    {
+      DoAction(Toolkit::Control::Property::BACKGROUND, DevelVisual::Action::UPDATE_PROPERTY, data.second);
+    }
+    else if(data.first == Toolkit::DevelControl::Property::SHADOW)
+    {
+      DoAction(Toolkit::DevelControl::Property::SHADOW, DevelVisual::Action::UPDATE_PROPERTY, data.second);
+    }
+  }
+  mControlImpl.OnUpdateVisualProperties(properties);
+}
+
 void Control::Impl::EmitResourceReadySignal()
 {
   if(!mIsEmittingResourceReadySignal)
@@ -1890,95 +2117,14 @@ void Control::Impl::OnIdleCallback()
   mIdleCallback = nullptr;
 }
 
-Dali::Accessibility::Accessible* Control::Impl::GetAccessibilityObject()
-{
-  if(!accessibilityObject)
-    accessibilityObject = accessibilityConstructor(mControlImpl.Self());
-  return accessibilityObject.get();
-}
-
-Dali::Accessibility::Accessible* Control::Impl::GetAccessibilityObject(Dali::Actor actor)
+Toolkit::DevelControl::ControlAccessible* Control::Impl::GetAccessibleObject()
 {
-  if(actor)
+  if(!mAccessibleObject)
   {
-    auto q = Dali::Toolkit::Control::DownCast(actor);
-    if(q)
-    {
-      auto q2 = static_cast<Internal::Control*>(&q.GetImplementation());
-      return q2->mImpl->GetAccessibilityObject();
-    }
+    mAccessibleObject.reset(mControlImpl.CreateAccessibleObject());
   }
-  return nullptr;
-}
 
-void Control::Impl::PositionOrSizeChangedCallback(PropertyNotification& p)
-{
-  auto self = Dali::Actor::DownCast(p.GetTarget());
-  if(Dali::Accessibility::IsUp() && !self.GetProperty(Toolkit::DevelControl::Property::ACCESSIBILITY_ANIMATED).Get<bool>())
-  {
-    auto extents = DevelActor::CalculateScreenExtents(self);
-    Dali::Accessibility::Accessible::Get(self)->EmitBoundsChanged(extents);
-  }
-}
-
-void Control::Impl::CulledChangedCallback(PropertyNotification& p)
-{
-  if(Dali::Accessibility::IsUp())
-  {
-    auto self = Dali::Actor::DownCast(p.GetTarget());
-    Dali::Accessibility::Accessible::Get(self)->EmitShowing(!self.GetProperty(DevelActor::Property::CULLED).Get<bool>());
-  }
-}
-
-void Control::Impl::AccessibilityRegister()
-{
-  if(!accessibilityNotificationSet)
-  {
-    accessibilityNotificationPosition = mControlImpl.Self().AddPropertyNotification(Actor::Property::POSITION, StepCondition(0.01f));
-    accessibilityNotificationPosition.SetNotifyMode(PropertyNotification::NOTIFY_ON_CHANGED);
-    accessibilityNotificationPosition.NotifySignal().Connect(&Control::Impl::PositionOrSizeChangedCallback);
-
-    accessibilityNotificationSize = mControlImpl.Self().AddPropertyNotification(Actor::Property::SIZE, StepCondition(0.01f));
-    accessibilityNotificationSize.SetNotifyMode(PropertyNotification::NOTIFY_ON_CHANGED);
-    accessibilityNotificationSize.NotifySignal().Connect(&Control::Impl::PositionOrSizeChangedCallback);
-
-    accessibilityNotificationCulled = mControlImpl.Self().AddPropertyNotification(DevelActor::Property::CULLED, LessThanCondition(0.5f));
-    accessibilityNotificationCulled.SetNotifyMode(PropertyNotification::NOTIFY_ON_CHANGED);
-    accessibilityNotificationCulled.NotifySignal().Connect(&Control::Impl::CulledChangedCallback);
-
-    accessibilityNotificationSet = true;
-  }
-}
-
-void Control::Impl::AccessibilityDeregister(bool remove)
-{
-  if(accessibilityNotificationSet)
-  {
-    accessibilityNotificationPosition.NotifySignal().Disconnect(&Control::Impl::PositionOrSizeChangedCallback);
-    if(remove)
-    {
-      mControlImpl.Self().RemovePropertyNotification(accessibilityNotificationPosition);
-    }
-    accessibilityNotificationPosition.Reset();
-    accessibilityNotificationPosition = {};
-
-    accessibilityNotificationSize.NotifySignal().Disconnect(&Control::Impl::PositionOrSizeChangedCallback);
-    if(remove)
-    {
-      mControlImpl.Self().RemovePropertyNotification(accessibilityNotificationSize);
-    }
-    accessibilityNotificationSize.Reset();
-    accessibilityNotificationSize     = {};
-
-    accessibilityNotificationCulled.NotifySignal().Disconnect(&Control::Impl::CulledChangedCallback);
-    if(remove)
-    {
-      mControlImpl.Self().RemovePropertyNotification(accessibilityNotificationCulled);
-    }
-    accessibilityNotificationCulled.Reset();
-    accessibilityNotificationCulled   = {};
-    accessibilityNotificationSet      = false;
-  }
+  return mAccessibleObject.get();
 }
 
 } // namespace Internal