Allows you to specify the root when calculating the focus movement algorithm. 22/274422/5
authorjoogab.yun <joogab.yun@samsung.com>
Thu, 28 Apr 2022 01:55:01 +0000 (10:55 +0900)
committerjoogab.yun <joogab.yun@samsung.com>
Tue, 3 May 2022 02:32:04 +0000 (11:32 +0900)
Change-Id: Id0b1a191301008c979cc00258a75d380e25ca99e

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

index 05ae1c4..9a40691 100644 (file)
@@ -2350,4 +2350,134 @@ int UtcDaliKeyboardFocusManagerWithVisible(void)
   DALI_TEST_CHECK(manager.GetCurrentFocusActor() == second);
 
   END_TEST;
+}
+
+int UtcDaliKeyboardFocusManagerFocusFinderRootActor(void)
+{
+  ToolkitTestApplication application;
+
+  tet_infoline(" UtcDaliKeyboardFocusManagerFocusFinderRootActor");
+
+  // Register Type
+  TypeInfo type;
+  type = TypeRegistry::Get().GetTypeInfo("KeyboardFocusManager");
+  DALI_TEST_CHECK(type);
+  BaseHandle handle = type.CreateInstance();
+  DALI_TEST_CHECK(handle);
+
+  KeyboardFocusManager manager = KeyboardFocusManager::Get();
+  DALI_TEST_CHECK(manager);
+
+  bool                 focusChangedSignalVerified = false;
+  FocusChangedCallback focusChangedCallback(focusChangedSignalVerified);
+  manager.FocusChangedSignal().Connect(&focusChangedCallback, &FocusChangedCallback::Callback);
+
+  PushButton button1 = PushButton::New();
+  PushButton button2 = PushButton::New();
+
+  button1.SetProperty(Actor::Property::SIZE, Vector2(50, 50));
+  button2.SetProperty(Actor::Property::SIZE, Vector2(50, 50));
+
+  button1.SetProperty(Actor::Property::KEYBOARD_FOCUSABLE, true);
+  button2.SetProperty(Actor::Property::KEYBOARD_FOCUSABLE, true);
+
+  application.GetScene().Add(button1);
+  application.GetScene().Add(button2);
+
+  Actor actor = Actor::New();
+  actor.SetProperty(Actor::Property::KEYBOARD_FOCUSABLE, true);
+  application.GetScene().Add(actor);
+
+  PushButton buttonA = PushButton::New();
+  PushButton buttonB = PushButton::New();
+
+  buttonA.SetProperty(Actor::Property::SIZE, Vector2(50, 50));
+  buttonB.SetProperty(Actor::Property::SIZE, Vector2(50, 50));
+
+  buttonA.SetProperty(Actor::Property::KEYBOARD_FOCUSABLE, true);
+  buttonB.SetProperty(Actor::Property::KEYBOARD_FOCUSABLE, true);
+
+  actor.Add(buttonA);
+  actor.Add(buttonB);
+
+  // set position
+  // button1 -- button2
+  button1.SetProperty(Actor::Property::POSITION, Vector2(0.0f, 0.0f));
+  button2.SetProperty(Actor::Property::POSITION, Vector2(100.0f, 0.0f));
+  button1.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
+  button2.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
+
+  // buttonA -- buttonB
+  buttonA.SetProperty(Actor::Property::POSITION, Vector2(0.0f, 50.0f));
+  buttonB.SetProperty(Actor::Property::POSITION, Vector2(100.0f, 50.0f));
+  buttonA.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
+  buttonB.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
+
+  // flush the queue and render once
+  application.SendNotification();
+  application.Render();
+
+  // Set the focus to the button1
+  // [button1] -- button2
+  DALI_TEST_CHECK(manager.SetCurrentFocusActor(button1) == true);
+  DALI_TEST_CHECK(manager.GetCurrentFocusActor() == button1);
+  DALI_TEST_CHECK(focusChangedCallback.mSignalVerified);
+  DALI_TEST_CHECK(focusChangedCallback.mOriginalFocusedActor == Actor());
+  DALI_TEST_CHECK(focusChangedCallback.mCurrentFocusedActor == button1);
+  focusChangedCallback.Reset();
+
+  // without set the navigation properties, but we can focus move
+  // enable the default algorithm
+  Dali::Toolkit::DevelKeyboardFocusManager::EnableDefaultAlgorithm(manager, true);
+  DALI_TEST_CHECK(Dali::Toolkit::DevelKeyboardFocusManager::IsDefaultAlgorithmEnabled(manager));
+
+  // Move the focus towards right
+  // button1 -- [button2]
+  DALI_TEST_CHECK(manager.MoveFocus(Control::KeyboardFocus::RIGHT) == true);
+
+  // Confirm whether focus is moved to button2
+  DALI_TEST_EQUALS(button2.GetProperty<int>(DevelControl::Property::STATE), (int)DevelControl::FOCUSED, TEST_LOCATION);
+  DALI_TEST_CHECK(focusChangedCallback.mSignalVerified);
+  DALI_TEST_CHECK(focusChangedCallback.mOriginalFocusedActor == button1);
+  DALI_TEST_CHECK(focusChangedCallback.mCurrentFocusedActor == button2);
+  focusChangedCallback.Reset();
+
+  // Clears focus.
+  manager.ClearFocus();
+
+  // There is no actor focused.
+  // button1 -- button2
+  // buttonA -- buttonB
+  DALI_TEST_CHECK(manager.GetCurrentFocusActor() == Actor());
+
+  // Sets the actor to root.
+  Dali::Toolkit::DevelKeyboardFocusManager::SetFocusFinderRootActor(manager, actor);
+
+  // Move the focus towards right
+  // [buttonA] -- buttonB
+  DALI_TEST_CHECK(manager.MoveFocus(Control::KeyboardFocus::RIGHT) == true);
+
+  // Confirm whether focus is moved to buttonA
+  // Because the root is an actor, the focus is moved to buttonA, a child of the actor.
+  DALI_TEST_EQUALS(buttonA.GetProperty<int>(DevelControl::Property::STATE), (int)DevelControl::FOCUSED, TEST_LOCATION);
+  DALI_TEST_CHECK(focusChangedCallback.mSignalVerified);
+  DALI_TEST_CHECK(focusChangedCallback.mOriginalFocusedActor == Actor());
+  DALI_TEST_CHECK(focusChangedCallback.mCurrentFocusedActor == buttonA);
+  focusChangedCallback.Reset();
+
+
+  // Move the focus towards right, The focus move will success.
+  // buttonA -- [buttonB]
+  DALI_TEST_CHECK(manager.MoveFocus(Control::KeyboardFocus::RIGHT) == true);
+  // Confirm whether focus is moved to buttonB
+  DALI_TEST_EQUALS(buttonB.GetProperty<int>(DevelControl::Property::STATE), (int)DevelControl::FOCUSED, TEST_LOCATION);
+  DALI_TEST_CHECK(focusChangedCallback.mSignalVerified);
+  DALI_TEST_CHECK(focusChangedCallback.mOriginalFocusedActor == buttonA);
+  DALI_TEST_CHECK(focusChangedCallback.mCurrentFocusedActor == buttonB);
+  focusChangedCallback.Reset();
+
+  // reset
+  Dali::Toolkit::DevelKeyboardFocusManager::ResetFocusFinderRootActor(manager);
+
+  END_TEST;
 }
\ No newline at end of file
index a3ed473..20fc10e 100644 (file)
@@ -55,6 +55,16 @@ bool MoveFocus(KeyboardFocusManager keyboardFocusManager, Control::KeyboardFocus
   return GetImpl(keyboardFocusManager).MoveFocus(direction, deviceName);
 }
 
+void SetFocusFinderRootActor(KeyboardFocusManager keyboardFocusManager, Actor actor)
+{
+  GetImpl(keyboardFocusManager).SetFocusFinderRootActor(actor);
+}
+
+void ResetFocusFinderRootActor(KeyboardFocusManager keyboardFocusManager)
+{
+  GetImpl(keyboardFocusManager).ResetFocusFinderRootActor();
+}
+
 } // namespace DevelKeyboardFocusManager
 
 } // namespace Toolkit
index b830445..98faca9 100644 (file)
@@ -115,6 +115,21 @@ DALI_TOOLKIT_API bool IsDefaultAlgorithmEnabled(KeyboardFocusManager keyboardFoc
  */
 DALI_TOOLKIT_API bool MoveFocus(KeyboardFocusManager keyboardFocusManager, Control::KeyboardFocus::Direction direction, const std::string& deviceName);
 
+/**
+ * @brief Sets the root actor to start moving focus when DefaultAlgorithm is enabled.
+ *
+ * @param[in] keyboardFocusManager The instance of KeyboardFocusManager
+ * @param[in] actor The root actor
+ */
+DALI_TOOLKIT_API void SetFocusFinderRootActor(KeyboardFocusManager keyboardFocusManager, Actor actor);
+
+/**
+ * @brief Resets the root actor that starts moving focus when DefaultAlgorithm is enabled.
+ * When reset, the window becomes root.
+ *
+ * @param[in] keyboardFocusManager The instance of KeyboardFocusManager
+ */
+DALI_TOOLKIT_API void ResetFocusFinderRootActor(KeyboardFocusManager keyboardFocusManager);
 
 } // namespace DevelKeyboardFocusManager
 
index d0daa9f..b77b2b8 100644 (file)
@@ -119,6 +119,7 @@ KeyboardFocusManager::KeyboardFocusManager()
   mFocusedActorEnterKeySignal(),
   mCurrentFocusActor(),
   mFocusIndicatorActor(),
+  mFocusFinderRootActor(),
   mFocusHistory(),
   mSlotDelegate(this),
   mCustomAlgorithmInterface(NULL),
@@ -520,25 +521,28 @@ bool KeyboardFocusManager::MoveFocus(Toolkit::Control::KeyboardFocus::Direction
       }
       else if (mEnableDefaultAlgorithm)
       {
-        Layer rootLayer;
-        if (currentFocusActor)
+        Actor rootActor = mFocusFinderRootActor.GetHandle();
+        if(!rootActor)
         {
-          // Find the window of the focused actor.
-          Integration::SceneHolder window = Integration::SceneHolder::Get(currentFocusActor);
-          if (window)
+          if (currentFocusActor)
           {
-            rootLayer = window.GetRootLayer();
+            // Find the window of the focused actor.
+            Integration::SceneHolder window = Integration::SceneHolder::Get(currentFocusActor);
+            if (window)
+            {
+              rootActor = window.GetRootLayer();
+            }
+          }
+          else
+          {
+            // Searches from the currently focused window.
+            rootActor = mCurrentFocusedWindow.GetHandle();
           }
         }
-        else
-        {
-          // Searches from the currently focused window.
-          rootLayer = mCurrentFocusedWindow.GetHandle();
-        }
-        if (rootLayer)
+        if(rootActor)
         {
           // We should find it among the actors nearby.
-          nextFocusableActor = Toolkit::FocusFinder::GetNearestFocusableActor(rootLayer, currentFocusActor, direction);
+          nextFocusableActor = Toolkit::FocusFinder::GetNearestFocusableActor(rootActor, currentFocusActor, direction);
         }
       }
     }
@@ -1184,6 +1188,16 @@ bool KeyboardFocusManager::IsDefaultAlgorithmEnabled() const
   return mEnableDefaultAlgorithm;
 }
 
+void KeyboardFocusManager::SetFocusFinderRootActor(Actor actor)
+{
+  mFocusFinderRootActor = actor;
+}
+
+void KeyboardFocusManager::ResetFocusFinderRootActor()
+{
+  mFocusFinderRootActor.Reset();
+}
+
 } // namespace Internal
 
 } // namespace Toolkit
index ae06097..31b0601 100644 (file)
@@ -162,6 +162,16 @@ public:
    */
   bool IsDefaultAlgorithmEnabled() const;
 
+  /**
+   * @copydoc Toolkit::DevelKeyboardFocusManager::SetFocusFinderRootActor
+   */
+  void SetFocusFinderRootActor(Actor actor);
+
+  /**
+   * @copydoc Toolkit::DevelKeyboardFocusManager::ResetFocusFinderRootActor
+   */
+  void ResetFocusFinderRootActor();
+
 public:
   /**
    * @copydoc Toolkit::KeyboardFocusManager::PreFocusChangeSignal()
@@ -344,6 +354,8 @@ private:
 
   Actor mFocusIndicatorActor; ///< The focus indicator actor shared by all the keyboard focusable actors for highlight
 
+  WeakHandle<Actor> mFocusFinderRootActor; ///<The root actor from which the focus finder is started.
+
   FocusStack mFocusHistory; ///< Stack to contain pre-focused actor's BaseObject*
 
   SlotDelegate<KeyboardFocusManager> mSlotDelegate;
@@ -369,6 +381,7 @@ private:
   bool mClearFocusOnTouch : 1; ///< Whether clear focus on touch.
 
   bool mEnableDefaultAlgorithm : 1; ///< Whether use default algorithm focus
+
 };
 
 } // namespace Internal