From 297201263692ae5b876a4cd4a872de4adb74073d Mon Sep 17 00:00:00 2001 From: Adeel Kazmi Date: Wed, 17 May 2017 11:48:06 +0100 Subject: [PATCH 1/1] (KeyboardFocusManager) Use weak handle instead of calling FindChildById repeatedly Change-Id: Idfd0b4fdafd7d2d844af560f5beaa4f0a68697ef --- .../dali-toolkit/utc-Dali-KeyboardFocusManager.cpp | 28 ++++++++++++++++++++++ .../focus-manager/keyboard-focus-manager-impl.cpp | 19 ++++++++++----- .../focus-manager/keyboard-focus-manager-impl.h | 5 ++-- 3 files changed, 44 insertions(+), 8 deletions(-) diff --git a/automated-tests/src/dali-toolkit/utc-Dali-KeyboardFocusManager.cpp b/automated-tests/src/dali-toolkit/utc-Dali-KeyboardFocusManager.cpp index 4c099e6..f1cccda 100644 --- a/automated-tests/src/dali-toolkit/utc-Dali-KeyboardFocusManager.cpp +++ b/automated-tests/src/dali-toolkit/utc-Dali-KeyboardFocusManager.cpp @@ -1380,3 +1380,31 @@ int UtcDaliKeyboardFocusManagerMoveFocusTestStateChange(void) 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; +} diff --git a/dali-toolkit/internal/focus-manager/keyboard-focus-manager-impl.cpp b/dali-toolkit/internal/focus-manager/keyboard-focus-manager-impl.cpp index 57fe076..e6aae87 100644 --- a/dali-toolkit/internal/focus-manager/keyboard-focus-manager-impl.cpp +++ b/dali-toolkit/internal/focus-manager/keyboard-focus-manager-impl.cpp @@ -114,7 +114,7 @@ KeyboardFocusManager::KeyboardFocusManager() mFocusChangedSignal(), mFocusGroupChangedSignal(), mFocusedActorEnterKeySignal(), - mCurrentFocusActor( 0 ), + mCurrentFocusActor(), 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. - if( actor && actor.IsKeyboardFocusable() ) + if( actor && actor.IsKeyboardFocusable() && actor.OnStage() ) { 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 - mCurrentFocusActor = actor.GetId(); + mCurrentFocusActor = actor; Toolkit::Control newlyFocusedControl = Toolkit::Control::DownCast(actor); if( newlyFocusedControl ) @@ -201,8 +201,15 @@ bool KeyboardFocusManager::DoSetCurrentFocusActor( Actor actor ) 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() @@ -504,7 +511,7 @@ void KeyboardFocusManager::ClearFocus() } } - mCurrentFocusActor = 0; + mCurrentFocusActor.Reset(); mIsFocusIndicatorEnabled = false; } diff --git a/dali-toolkit/internal/focus-manager/keyboard-focus-manager-impl.h b/dali-toolkit/internal/focus-manager/keyboard-focus-manager-impl.h index 6816200..298b3a7 100644 --- a/dali-toolkit/internal/focus-manager/keyboard-focus-manager-impl.h +++ b/dali-toolkit/internal/focus-manager/keyboard-focus-manager-impl.h @@ -2,7 +2,7 @@ #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. @@ -20,6 +20,7 @@ // EXTERNAL INCLUDES #include +#include // INTERNAL INCLUDES #include @@ -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 - 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 -- 2.7.4