Add KEYBOARD_FOCUSABLE_CHILDREN property. 71/262771/8
authorjoogab.yun <joogab.yun@samsung.com>
Thu, 19 Aug 2021 08:20:24 +0000 (17:20 +0900)
committerjoogab.yun <joogab.yun@samsung.com>
Fri, 27 Aug 2021 04:24:48 +0000 (13:24 +0900)
Whether the children of this actor can be focusable by keyboard navigation.

Change-Id: I2b650cc485ead5805a019763d0897094c5bd2f9a

automated-tests/src/dali-toolkit/utc-Dali-KeyboardFocusManager.cpp
dali-toolkit/devel-api/focus-manager/focus-finder.cpp
dali-toolkit/internal/focus-manager/keyboard-focus-manager-impl.cpp
dali-toolkit/public-api/focus-manager/keyboard-focus-manager.h

index 37c6ded..6d0e8af 100644 (file)
@@ -1993,3 +1993,47 @@ int UtcDaliKeyboardFocusManagerEnableDefaultAlgorithm(void)
 
   END_TEST;
 }
 
   END_TEST;
 }
+
+
+int UtcDaliKeyboardFocusManagerWithKeyboardFocusableChildren(void)
+{
+  ToolkitTestApplication application;
+
+  tet_infoline(" UtcDaliKeyboardFocusManagerWithKeyboardFocusableChildren");
+
+  KeyboardFocusManager manager = KeyboardFocusManager::Get();
+  DALI_TEST_CHECK(manager);
+
+  // Create the first actor and add it to the stage
+  Actor first = Actor::New();
+  first.SetProperty( Actor::Property::KEYBOARD_FOCUSABLE, true);
+  application.GetScene().Add(first);
+
+  // Create the second actor and add it to the first actor.
+  Actor second = Actor::New();
+  second.SetProperty( Actor::Property::KEYBOARD_FOCUSABLE, true);
+  first.Add(second);
+
+  // Check that no actor is being focused yet.
+  DALI_TEST_CHECK(manager.GetCurrentFocusActor() == Actor());
+
+  // Check that the focus is set on the first actor
+  DALI_TEST_CHECK(manager.SetCurrentFocusActor(first) == true);
+  DALI_TEST_CHECK(manager.GetCurrentFocusActor() == first);
+
+  // Set KeyboardFocusableChildren false.
+  first.SetProperty( DevelActor::Property::KEYBOARD_FOCUSABLE_CHILDREN, false);
+
+  // Check that it will fail to set focus on the second actor as it's not focusable
+  DALI_TEST_CHECK(manager.SetCurrentFocusActor(second) == false);
+  DALI_TEST_CHECK(manager.GetCurrentFocusActor() == first);
+
+  // Set KeyboardFocusableChildren true.
+  first.SetProperty( DevelActor::Property::KEYBOARD_FOCUSABLE_CHILDREN, true);
+
+  // Check that the focus is set on the second actor
+  DALI_TEST_CHECK(manager.SetCurrentFocusActor(second) == true);
+  DALI_TEST_CHECK(manager.GetCurrentFocusActor() == second);
+
+  END_TEST;
+}
\ No newline at end of file
index 2679dda..ddd0360 100644 (file)
@@ -350,7 +350,7 @@ bool IsFocusable(Actor& actor)
 Actor FindNextFocus(Actor& actor, Actor& focusedActor, Rect<float>& focusedRect, Rect<float>& bestCandidateRect, Toolkit::Control::KeyboardFocus::Direction direction)\r
 {\r
   Actor nearestActor;\r
 Actor FindNextFocus(Actor& actor, Actor& focusedActor, Rect<float>& focusedRect, Rect<float>& bestCandidateRect, Toolkit::Control::KeyboardFocus::Direction direction)\r
 {\r
   Actor nearestActor;\r
-  if(actor && actor.GetProperty<bool>(Actor::Property::VISIBLE))\r
+  if(actor && actor.GetProperty<bool>(Actor::Property::VISIBLE) && actor.GetProperty<bool>(DevelActor::Property::KEYBOARD_FOCUSABLE_CHILDREN))\r
   {\r
     // Recursively children\r
     const auto childCount = actor.GetChildCount();\r
   {\r
     // Recursively children\r
     const auto childCount = actor.GetChildCount();\r
index b10ff63..745da15 100644 (file)
@@ -199,6 +199,22 @@ bool KeyboardFocusManager::SetCurrentFocusActor(Actor actor)
 bool KeyboardFocusManager::DoSetCurrentFocusActor(Actor actor)
 {
   bool success = false;
 bool KeyboardFocusManager::DoSetCurrentFocusActor(Actor actor)
 {
   bool success = false;
+
+  // If the parent's KEYBOARD_FOCUSABLE_CHILDREN is false, it cannot have focus.
+  if(actor)
+  {
+    Actor parent = actor.GetParent();
+    while(parent)
+    {
+      if(!parent.GetProperty<bool>(DevelActor::Property::KEYBOARD_FOCUSABLE_CHILDREN))
+      {
+        DALI_LOG_INFO(gLogFilter, Debug::General, "[%s:%d] Parent Actor has KEYBOARD_FOCUSABLE_CHILDREN false,\n", __FUNCTION__, __LINE__);
+        return false;
+      }
+      parent = parent.GetParent();
+    }
+  }
+
   if(actor && actor.GetProperty<bool>(Actor::Property::KEYBOARD_FOCUSABLE) && actor.GetProperty<bool>(Actor::Property::CONNECTED_TO_SCENE))
   {
     Integration::SceneHolder currentWindow = Integration::SceneHolder::Get(actor);
   if(actor && actor.GetProperty<bool>(Actor::Property::KEYBOARD_FOCUSABLE) && actor.GetProperty<bool>(Actor::Property::CONNECTED_TO_SCENE))
   {
     Integration::SceneHolder currentWindow = Integration::SceneHolder::Get(actor);
index d99844e..df934f1 100644 (file)
@@ -102,6 +102,7 @@ public:
    * @return Whether the focus is successful or not
    * @pre The KeyboardFocusManager has been initialized.
    * @pre The Actor has been initialized.
    * @return Whether the focus is successful or not
    * @pre The KeyboardFocusManager has been initialized.
    * @pre The Actor has been initialized.
+   * @note If the parent of this actor has the KEYBOARD FOCUSABLE CHILDREN property set to false, it will not be focused.
    */
   bool SetCurrentFocusActor(Actor actor);
 
    */
   bool SetCurrentFocusActor(Actor actor);