Add null check for currentFocusActor
[platform/core/uifw/dali-toolkit.git] / dali-toolkit / internal / focus-manager / keyboard-focus-manager-impl.cpp
index 0aa9ed1..b8b8a6d 100644 (file)
@@ -127,7 +127,8 @@ KeyboardFocusManager::KeyboardFocusManager()
   mAlwaysShowIndicator(ALWAYS_SHOW),
   mFocusGroupLoopEnabled(false),
   mIsWaitingKeyboardFocusChangeCommit(false),
-  mClearFocusOnTouch(true)
+  mClearFocusOnTouch(true),
+  mEnableDefaultAlgorithm(false)
 {
   // TODO: Get FocusIndicatorEnable constant from stylesheet to set mIsFocusIndicatorShown.
 
@@ -198,6 +199,22 @@ bool KeyboardFocusManager::SetCurrentFocusActor(Actor actor)
 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);
@@ -497,10 +514,14 @@ bool KeyboardFocusManager::MoveFocus(Toolkit::Control::KeyboardFocus::Direction
         nextFocusableActor                  = mPreFocusChangeSignal.Emit(currentFocusActor, Actor(), direction);
         mIsWaitingKeyboardFocusChangeCommit = false;
       }
-      else
+      else if(mEnableDefaultAlgorithm && currentFocusActor)
       {
         // We should find it among the actors nearby.
-        nextFocusableActor = Toolkit::FocusFinder::Get().GetNearestFocusableActor(currentFocusActor, direction);
+        Integration::SceneHolder window = Integration::SceneHolder::Get(currentFocusActor);
+        if(window)
+        {
+          nextFocusableActor = Toolkit::FocusFinder::GetNearestFocusableActor(window.GetRootLayer(), currentFocusActor, direction);
+        }
       }
     }
 
@@ -878,7 +899,15 @@ void KeyboardFocusManager::OnKeyEvent(const KeyEvent& event)
       {
         // "Tab" key changes the focus group in the forward direction and
         // "Shift-Tab" key changes it in the backward direction.
-        DoMoveFocusToNextFocusGroup(!event.IsShiftModifier());
+        if(!DoMoveFocusToNextFocusGroup(!event.IsShiftModifier()))
+        {
+          // If the focus group is not changed, Move the focus towards right, "Shift-Tap" key moves the focus towards left.
+          if(!MoveFocus(event.IsShiftModifier() ? Toolkit::Control::KeyboardFocus::LEFT : Toolkit::Control::KeyboardFocus::RIGHT))
+          {
+            // If the focus is not moved, Move the focus towards down, "Shift-Tap" key moves the focus towards up.
+            MoveFocus(event.IsShiftModifier() ? Toolkit::Control::KeyboardFocus::UP : Toolkit::Control::KeyboardFocus::DOWN);
+          }
+        }
       }
 
       isFocusStartableKey = true;
@@ -1076,6 +1105,16 @@ bool KeyboardFocusManager::IsFocusIndicatorEnabled() const
   return (mEnableFocusIndicator == ENABLE);
 }
 
+void KeyboardFocusManager::EnableDefaultAlgorithm(bool enable)
+{
+  mEnableDefaultAlgorithm = enable;
+}
+
+bool KeyboardFocusManager::IsDefaultAlgorithmEnabled() const
+{
+  return mEnableDefaultAlgorithm;
+}
+
 } // namespace Internal
 
 } // namespace Toolkit