(KeyboardFocusManager) Use weak handle instead of calling FindChildById repeatedly 64/129664/2
authorAdeel Kazmi <adeel.kazmi@samsung.com>
Wed, 17 May 2017 10:48:06 +0000 (11:48 +0100)
committerAdeel Kazmi <adeel.kazmi@samsung.com>
Wed, 17 May 2017 12:56:56 +0000 (13:56 +0100)
Change-Id: Idfd0b4fdafd7d2d844af560f5beaa4f0a68697ef

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

index 4c099e6..f1cccda 100644 (file)
@@ -1380,3 +1380,31 @@ int UtcDaliKeyboardFocusManagerMoveFocusTestStateChange(void)
 
   END_TEST;
 }
 
   END_TEST;
 }
+
+int UtcDaliKeyboardFocusManagerFocusedActorUnstaged(void)
+{
+  ToolkitTestApplication application;
+
+  tet_infoline( "Ensure we cannot set an actor to be focused if it is not staged and that we do not retrieve an actor if it has been unstaged" );
+
+  KeyboardFocusManager manager = KeyboardFocusManager::Get();
+  DALI_TEST_CHECK( ! manager.GetCurrentFocusActor() );
+
+  Actor actor = Actor::New();
+  actor.SetKeyboardFocusable( true );
+
+  tet_infoline( "Attempt to set unstaged actor, no actor should be returned from KeyboardFocusManager" );
+  manager.SetCurrentFocusActor( actor );
+  DALI_TEST_CHECK( ! manager.GetCurrentFocusActor() );
+
+  tet_infoline( "Add actor to stage and attempt to set, our actor should be returned from KeyboardFocusManager" );
+  Stage::GetCurrent().Add( actor );
+  manager.SetCurrentFocusActor( actor );
+  DALI_TEST_CHECK( manager.GetCurrentFocusActor() == actor );
+
+  tet_infoline( "Remove actor from stage and attempt to retrieve, no actor should be returned from KeyboardFocusManager" );
+  actor.Unparent();
+  DALI_TEST_CHECK( ! manager.GetCurrentFocusActor() );
+
+  END_TEST;
+}
index 57fe076..e6aae87 100644 (file)
@@ -114,7 +114,7 @@ KeyboardFocusManager::KeyboardFocusManager()
   mFocusChangedSignal(),
   mFocusGroupChangedSignal(),
   mFocusedActorEnterKeySignal(),
   mFocusChangedSignal(),
   mFocusGroupChangedSignal(),
   mFocusedActorEnterKeySignal(),
-  mCurrentFocusActor( 0 ),
+  mCurrentFocusActor(),
   mFocusIndicatorActor(),
   mFocusGroupLoopEnabled( false ),
   mIsFocusIndicatorEnabled( false ),
   mFocusIndicatorActor(),
   mFocusGroupLoopEnabled( false ),
   mIsFocusIndicatorEnabled( false ),
@@ -144,7 +144,7 @@ bool KeyboardFocusManager::DoSetCurrentFocusActor( Actor actor )
   bool success = false;
 
   // Check whether the actor is in the stage and is keyboard focusable.
   bool success = false;
 
   // Check whether the actor is in the stage and is keyboard focusable.
-  if( actor && actor.IsKeyboardFocusable() )
+  if( actor && actor.IsKeyboardFocusable() && actor.OnStage() )
   {
     if( mIsFocusIndicatorEnabled )
     {
   {
     if( mIsFocusIndicatorEnabled )
     {
@@ -169,7 +169,7 @@ bool KeyboardFocusManager::DoSetCurrentFocusActor( Actor actor )
     DALI_LOG_INFO( gLogFilter, Debug::General, "[%s:%d] Focus Changed\n", __FUNCTION__, __LINE__);
 
     // Save the current focused actor
     DALI_LOG_INFO( gLogFilter, Debug::General, "[%s:%d] Focus Changed\n", __FUNCTION__, __LINE__);
 
     // Save the current focused actor
-    mCurrentFocusActor = actor.GetId();
+    mCurrentFocusActor = actor;
 
     Toolkit::Control newlyFocusedControl = Toolkit::Control::DownCast(actor);
     if( newlyFocusedControl )
 
     Toolkit::Control newlyFocusedControl = Toolkit::Control::DownCast(actor);
     if( newlyFocusedControl )
@@ -201,8 +201,15 @@ bool KeyboardFocusManager::DoSetCurrentFocusActor( Actor actor )
 
 Actor KeyboardFocusManager::GetCurrentFocusActor()
 {
 
 Actor KeyboardFocusManager::GetCurrentFocusActor()
 {
-  Actor rootActor = Stage::GetCurrent().GetRootLayer();
-  return rootActor.FindChildById(mCurrentFocusActor);
+  Actor actor = mCurrentFocusActor.GetHandle();
+  if( actor && ! actor.OnStage() )
+  {
+    // If the actor has been removed from the stage, then it should not be focused
+
+    actor.Reset();
+    mCurrentFocusActor.Reset();
+  }
+  return actor;
 }
 
 Actor KeyboardFocusManager::GetCurrentFocusGroup()
 }
 
 Actor KeyboardFocusManager::GetCurrentFocusGroup()
@@ -504,7 +511,7 @@ void KeyboardFocusManager::ClearFocus()
     }
   }
 
     }
   }
 
-  mCurrentFocusActor = 0;
+  mCurrentFocusActor.Reset();
   mIsFocusIndicatorEnabled = false;
 }
 
   mIsFocusIndicatorEnabled = false;
 }
 
index 6816200..298b3a7 100644 (file)
@@ -2,7 +2,7 @@
 #define __DALI_TOOLKIT_INTERNAL_KEYBOARD_FOCUS_MANAGER_H__
 
 /*
 #define __DALI_TOOLKIT_INTERNAL_KEYBOARD_FOCUS_MANAGER_H__
 
 /*
- * Copyright (c) 2016 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2017 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.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -20,6 +20,7 @@
 
 // EXTERNAL INCLUDES
 #include <dali/public-api/object/base-object.h>
 
 // EXTERNAL INCLUDES
 #include <dali/public-api/object/base-object.h>
+#include <dali/devel-api/object/weak-handle.h>
 
 // INTERNAL INCLUDES
 #include <dali-toolkit/public-api/focus-manager/keyboard-focus-manager.h>
 
 // INTERNAL INCLUDES
 #include <dali-toolkit/public-api/focus-manager/keyboard-focus-manager.h>
@@ -248,7 +249,7 @@ private:
   Toolkit::KeyboardFocusManager::FocusGroupChangedSignalType mFocusGroupChangedSignal; ///< The signal to notify the focus group change
   Toolkit::KeyboardFocusManager::FocusedActorEnterKeySignalType mFocusedActorEnterKeySignal; ///< The signal to notify that enter has been pressed on the focused actor
 
   Toolkit::KeyboardFocusManager::FocusGroupChangedSignalType mFocusGroupChangedSignal; ///< The signal to notify the focus group change
   Toolkit::KeyboardFocusManager::FocusedActorEnterKeySignalType mFocusedActorEnterKeySignal; ///< The signal to notify that enter has been pressed on the focused actor
 
-  unsigned int mCurrentFocusActor; ///< The actor ID of current focused actor
+  WeakHandle< Actor > mCurrentFocusActor; ///< A weak handle to the current focused actor
 
   Actor mFocusIndicatorActor; ///< The focus indicator actor shared by all the keyboard focusable actors for highlight
 
 
   Actor mFocusIndicatorActor; ///< The focus indicator actor shared by all the keyboard focusable actors for highlight