X-Git-Url: http://review.tizen.org/git/?p=platform%2Fcore%2Fuifw%2Fdali-toolkit.git;a=blobdiff_plain;f=dali-toolkit%2Finternal%2Ffocus-manager%2Fkeyboard-focus-manager-impl.cpp;h=07dc86dee4b907313f5b6215c855b59c22896f05;hp=5092cfef04079845dbfae3de793bb78ab8ca1891;hb=5b71f181969c17b67521ca3cb5a15308b1c10e55;hpb=e4a3c7b18f3a6168ec3967d4881663f7ed54f8d5 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 5092cfe..07dc86d 100644 --- a/dali-toolkit/internal/focus-manager/keyboard-focus-manager-impl.cpp +++ b/dali-toolkit/internal/focus-manager/keyboard-focus-manager-impl.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020 Samsung Electronics Co., Ltd. + * Copyright (c) 2022 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. @@ -19,43 +19,41 @@ #include "keyboard-focus-manager-impl.h" // EXTERNAL INCLUDES -#include // for strcmp -#include -#include -#include +#include #include +#include +#include +#include +#include +#include #include #include #include -#include -#include +#include #include -#include -#include -#include +#include +#include +#include // for strcmp // INTERNAL INCLUDES #include -#include +#include +#include +#include #include +#include #include -#include -#include #include -#include +#include namespace Dali { - namespace Toolkit { - namespace Internal { - namespace // Unnamed namespace { - #if defined(DEBUG_ENABLED) Debug::Filter* gLogFilter = Debug::Filter::New(Debug::NoLogging, false, "LOG_KEYBOARD_FOCUS_MANAGER"); #endif @@ -68,13 +66,13 @@ BaseHandle Create() { BaseHandle handle = KeyboardFocusManager::Get(); - if ( !handle ) + if(!handle) { - SingletonService singletonService( SingletonService::Get() ); - if ( singletonService ) + SingletonService singletonService(SingletonService::Get()); + if(singletonService) { - Toolkit::KeyboardFocusManager manager = Toolkit::KeyboardFocusManager( new Internal::KeyboardFocusManager() ); - singletonService.Register( typeid( manager ), manager ); + Toolkit::KeyboardFocusManager manager = Toolkit::KeyboardFocusManager(new Internal::KeyboardFocusManager()); + singletonService.Register(typeid(manager), manager); handle = manager; } } @@ -82,12 +80,12 @@ BaseHandle Create() return handle; } -DALI_TYPE_REGISTRATION_BEGIN_CREATE( Toolkit::KeyboardFocusManager, Dali::BaseHandle, Create, true ) +DALI_TYPE_REGISTRATION_BEGIN_CREATE(Toolkit::KeyboardFocusManager, Dali::BaseHandle, Create, true) -DALI_SIGNAL_REGISTRATION( Toolkit, KeyboardFocusManager, "keyboardPreFocusChange", SIGNAL_PRE_FOCUS_CHANGE ) -DALI_SIGNAL_REGISTRATION( Toolkit, KeyboardFocusManager, "keyboardFocusChanged", SIGNAL_FOCUS_CHANGED ) -DALI_SIGNAL_REGISTRATION( Toolkit, KeyboardFocusManager, "keyboardFocusGroupChanged", SIGNAL_FOCUS_GROUP_CHANGED ) -DALI_SIGNAL_REGISTRATION( Toolkit, KeyboardFocusManager, "keyboardFocusedActorEnterKey", SIGNAL_FOCUSED_ACTOR_ENTER_KEY ) +DALI_SIGNAL_REGISTRATION(Toolkit, KeyboardFocusManager, "keyboardPreFocusChange", SIGNAL_PRE_FOCUS_CHANGE) +DALI_SIGNAL_REGISTRATION(Toolkit, KeyboardFocusManager, "keyboardFocusChanged", SIGNAL_FOCUS_CHANGED) +DALI_SIGNAL_REGISTRATION(Toolkit, KeyboardFocusManager, "keyboardFocusGroupChanged", SIGNAL_FOCUS_GROUP_CHANGED) +DALI_SIGNAL_REGISTRATION(Toolkit, KeyboardFocusManager, "keyboardFocusedActorEnterKey", SIGNAL_FOCUSED_ACTOR_ENTER_KEY) DALI_TYPE_REGISTRATION_END() @@ -99,15 +97,15 @@ Toolkit::KeyboardFocusManager KeyboardFocusManager::Get() { Toolkit::KeyboardFocusManager manager; - SingletonService singletonService( SingletonService::Get() ); - if ( singletonService ) + SingletonService singletonService(SingletonService::Get()); + if(singletonService) { // Check whether the keyboard focus manager is already created - Dali::BaseHandle handle = singletonService.GetSingleton( typeid( Toolkit::KeyboardFocusManager ) ); + Dali::BaseHandle handle = singletonService.GetSingleton(typeid(Toolkit::KeyboardFocusManager)); if(handle) { // If so, downcast the handle of singleton to keyboard focus manager - manager = Toolkit::KeyboardFocusManager( dynamic_cast< KeyboardFocusManager* >( handle.GetObjectPtr() ) ); + manager = Toolkit::KeyboardFocusManager(dynamic_cast(handle.GetObjectPtr())); } } @@ -121,52 +119,58 @@ KeyboardFocusManager::KeyboardFocusManager() mFocusedActorEnterKeySignal(), mCurrentFocusActor(), mFocusIndicatorActor(), + mFocusFinderRootActor(), mFocusHistory(), - mSlotDelegate( this ), + mSlotDelegate(this), mCustomAlgorithmInterface(NULL), mCurrentFocusedWindow(), - mIsFocusIndicatorShown( UNKNOWN ), - mEnableFocusIndicator( ENABLE ), - mAlwaysShowIndicator( ALWAYS_SHOW ), - mFocusGroupLoopEnabled( false ), - mIsWaitingKeyboardFocusChangeCommit( false ), - mClearFocusOnTouch( true ) + mIsFocusIndicatorShown(UNKNOWN), + mEnableFocusIndicator(ENABLE), + mAlwaysShowIndicator(ALWAYS_SHOW), + mFocusGroupLoopEnabled(false), + mIsWaitingKeyboardFocusChangeCommit(false), + mClearFocusOnTouch(true), + mEnableDefaultAlgorithm(false) { // TODO: Get FocusIndicatorEnable constant from stylesheet to set mIsFocusIndicatorShown. - LifecycleController::Get().InitSignal().Connect( mSlotDelegate, &KeyboardFocusManager::OnAdaptorInit ); + LifecycleController::Get().InitSignal().Connect(mSlotDelegate, &KeyboardFocusManager::OnAdaptorInit); } void KeyboardFocusManager::OnAdaptorInit() { - if( Adaptor::IsAvailable() ) + if(Adaptor::IsAvailable()) { // Retrieve all the existing scene holders Dali::SceneHolderList sceneHolders = Adaptor::Get().GetSceneHolders(); - for( auto iter = sceneHolders.begin(); iter != sceneHolders.end(); ++iter ) + for(auto iter = sceneHolders.begin(); iter != sceneHolders.end(); ++iter) { - ( *iter ).KeyEventSignal().Connect( mSlotDelegate, &KeyboardFocusManager::OnKeyEvent ); - ( *iter ).TouchedSignal().Connect( mSlotDelegate, &KeyboardFocusManager::OnTouch ); - Dali::Window window = DevelWindow::DownCast( *iter ); - if( window ) + (*iter).KeyEventSignal().Connect(mSlotDelegate, &KeyboardFocusManager::OnKeyEvent); + (*iter).TouchedSignal().Connect(mSlotDelegate, &KeyboardFocusManager::OnTouch); + (*iter).WheelEventGeneratedSignal().Connect(mSlotDelegate, &KeyboardFocusManager::OnCustomWheelEvent); + (*iter).WheelEventSignal().Connect(mSlotDelegate, &KeyboardFocusManager::OnWheelEvent); + Dali::Window window = DevelWindow::DownCast(*iter); + if(window) { - window.FocusChangeSignal().Connect( mSlotDelegate, &KeyboardFocusManager::OnWindowFocusChanged); + window.FocusChangeSignal().Connect(mSlotDelegate, &KeyboardFocusManager::OnWindowFocusChanged); } } // Get notified when any new scene holder is created afterwards - Adaptor::Get().WindowCreatedSignal().Connect( mSlotDelegate, &KeyboardFocusManager::OnSceneHolderCreated ); + Adaptor::Get().WindowCreatedSignal().Connect(mSlotDelegate, &KeyboardFocusManager::OnSceneHolderCreated); } } -void KeyboardFocusManager::OnSceneHolderCreated( Dali::Integration::SceneHolder& sceneHolder ) +void KeyboardFocusManager::OnSceneHolderCreated(Dali::Integration::SceneHolder& sceneHolder) { - sceneHolder.KeyEventSignal().Connect( mSlotDelegate, &KeyboardFocusManager::OnKeyEvent ); - sceneHolder.TouchedSignal().Connect( mSlotDelegate, &KeyboardFocusManager::OnTouch ); - Dali::Window window = DevelWindow::DownCast( sceneHolder ); - if( window ) + sceneHolder.KeyEventSignal().Connect(mSlotDelegate, &KeyboardFocusManager::OnKeyEvent); + sceneHolder.TouchedSignal().Connect(mSlotDelegate, &KeyboardFocusManager::OnTouch); + sceneHolder.WheelEventGeneratedSignal().Connect(mSlotDelegate, &KeyboardFocusManager::OnCustomWheelEvent); + sceneHolder.WheelEventSignal().Connect(mSlotDelegate, &KeyboardFocusManager::OnWheelEvent); + Dali::Window window = DevelWindow::DownCast(sceneHolder); + if(window) { - window.FocusChangeSignal().Connect( mSlotDelegate, &KeyboardFocusManager::OnWindowFocusChanged); + window.FocusChangeSignal().Connect(mSlotDelegate, &KeyboardFocusManager::OnWindowFocusChanged); } } @@ -176,115 +180,123 @@ KeyboardFocusManager::~KeyboardFocusManager() void KeyboardFocusManager::GetConfigurationFromStyleManger() { - Toolkit::StyleManager styleManager = Toolkit::StyleManager::Get(); - if( styleManager ) - { - Property::Map config = Toolkit::DevelStyleManager::GetConfigurations( styleManager ); - mAlwaysShowIndicator = config["alwaysShowFocus"].Get() ? ALWAYS_SHOW : NONE; - mIsFocusIndicatorShown = ( mAlwaysShowIndicator == ALWAYS_SHOW )? SHOW : HIDE; - mClearFocusOnTouch = ( mIsFocusIndicatorShown == SHOW ) ? false : true; - } + Toolkit::StyleManager styleManager = Toolkit::StyleManager::Get(); + if(styleManager) + { + const Property::Map& config = Toolkit::DevelStyleManager::GetConfigurations(styleManager); + const auto alwaysShowFocusValue = config.Find("alwaysShowFocus", Property::Type::BOOLEAN); + + mAlwaysShowIndicator = (alwaysShowFocusValue && alwaysShowFocusValue->Get()) ? ALWAYS_SHOW : NONE; + mIsFocusIndicatorShown = (mAlwaysShowIndicator == ALWAYS_SHOW) ? SHOW : HIDE; + mClearFocusOnTouch = (mIsFocusIndicatorShown == SHOW) ? false : true; + } } -bool KeyboardFocusManager::SetCurrentFocusActor( Actor actor ) +bool KeyboardFocusManager::SetCurrentFocusActor(Actor actor) { - DALI_ASSERT_DEBUG( !mIsWaitingKeyboardFocusChangeCommit && "Calling this function in the PreFocusChangeSignal callback?" ); + DALI_ASSERT_DEBUG(!mIsWaitingKeyboardFocusChangeCommit && "Calling this function in the PreFocusChangeSignal callback?"); - if( mIsFocusIndicatorShown == UNKNOWN ) + if(mIsFocusIndicatorShown == UNKNOWN) { GetConfigurationFromStyleManger(); } - return DoSetCurrentFocusActor( actor ); + return DoSetCurrentFocusActor(actor); } -bool KeyboardFocusManager::DoSetCurrentFocusActor( Actor actor ) +bool KeyboardFocusManager::DoSetCurrentFocusActor(Actor actor) { bool success = false; - 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( currentWindow.GetRootLayer() != mCurrentFocusedWindow.GetHandle()) - { - Layer rootLayer = currentWindow.GetRootLayer(); - mCurrentFocusedWindow = rootLayer; - } - } - - Actor currentFocusedActor = GetCurrentFocusActor(); - // If developer set focus on same actor, doing nothing - if( actor == currentFocusedActor ) + // Check whether the actor is in the stage and is keyboard focusable. + if(actor && + actor.GetProperty(Actor::Property::KEYBOARD_FOCUSABLE) && + actor.GetProperty(DevelActor::Property::USER_INTERACTION_ENABLED) && + actor.GetProperty(Actor::Property::CONNECTED_TO_SCENE) && + actor.GetProperty(Actor::Property::VISIBLE)) { - if( !actor ) + // If the parent's KEYBOARD_FOCUSABLE_CHILDREN is false, it cannot have focus. + Actor parent = actor.GetParent(); + while(parent) { - return false; + if(!parent.GetProperty(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(); } - return true; - } - // Check whether the actor is in the stage and is keyboard focusable. - if( actor && actor.GetProperty< bool >( Actor::Property::KEYBOARD_FOCUSABLE ) && actor.GetProperty< bool >( Actor::Property::CONNECTED_TO_SCENE ) ) - { - if( ( mIsFocusIndicatorShown == SHOW ) && ( mEnableFocusIndicator == ENABLE ) ) + // If developer set focus on same actor, doing nothing + Actor currentFocusedActor = GetCurrentFocusActor(); + if(actor == currentFocusedActor) { - actor.Add( GetFocusIndicatorActor() ); + return true; } - // Send notification for the change of focus actor - if( !mFocusChangedSignal.Empty() ) + Integration::SceneHolder currentWindow = Integration::SceneHolder::Get(actor); + if(currentWindow.GetRootLayer() != mCurrentFocusedWindow.GetHandle()) { - mFocusChangedSignal.Emit(currentFocusedActor, actor); + Layer rootLayer = currentWindow.GetRootLayer(); + mCurrentFocusedWindow = rootLayer; } - Toolkit::Control currentlyFocusedControl = Toolkit::Control::DownCast(currentFocusedActor); - if( currentlyFocusedControl ) + if((mIsFocusIndicatorShown == SHOW) && (mEnableFocusIndicator == ENABLE)) { - // Do we need it to remember if it was previously DISABLED? - currentlyFocusedControl.SetProperty(DevelControl::Property::STATE, DevelControl::NORMAL ); - currentlyFocusedControl.ClearKeyInputFocus(); + actor.Add(GetFocusIndicatorActor()); } - DALI_LOG_INFO( gLogFilter, Debug::General, "[%s:%d] Focus Changed\n", __FUNCTION__, __LINE__); - // Save the current focused actor mCurrentFocusActor = actor; bool focusedWindowFound = false; - for( unsigned int i = 0; i < mCurrentFocusActors.size(); i++ ) + for(unsigned int i = 0; i < mCurrentFocusActors.size(); i++) { - if( mCurrentFocusActors[i].first == mCurrentFocusedWindow ) + if(mCurrentFocusActors[i].first == mCurrentFocusedWindow) { mCurrentFocusActors[i].second = actor; - focusedWindowFound = true; + focusedWindowFound = true; break; } } - if( !focusedWindowFound) + if(!focusedWindowFound) { // A new window gains the focus, so store the focused actor in that window. - mCurrentFocusActors.push_back( std::pair< WeakHandle< Layer>, WeakHandle< Actor > >( mCurrentFocusedWindow , actor )); + mCurrentFocusActors.push_back(std::pair, WeakHandle >(mCurrentFocusedWindow, actor)); + } + + // Send notification for the change of focus actor + if(!mFocusChangedSignal.Empty()) + { + mFocusChangedSignal.Emit(currentFocusedActor, actor); + } + + Toolkit::Control currentlyFocusedControl = Toolkit::Control::DownCast(currentFocusedActor); + if(currentlyFocusedControl) + { + // Do we need it to remember if it was previously DISABLED? + currentlyFocusedControl.SetProperty(DevelControl::Property::STATE, DevelControl::NORMAL); + currentlyFocusedControl.ClearKeyInputFocus(); } Toolkit::Control newlyFocusedControl = Toolkit::Control::DownCast(actor); - if( newlyFocusedControl ) + if(newlyFocusedControl) { - newlyFocusedControl.SetProperty(DevelControl::Property::STATE, DevelControl::FOCUSED ); + newlyFocusedControl.SetProperty(DevelControl::Property::STATE, DevelControl::FOCUSED); newlyFocusedControl.SetKeyInputFocus(); } // Push Current Focused Actor to FocusHistory - mFocusHistory.push_back( actor ); + mFocusHistory.push_back(actor); // Delete first element before add new element when Stack is full. - if( mFocusHistory.size() > MAX_HISTORY_AMOUNT ) + if(mFocusHistory.size() > MAX_HISTORY_AMOUNT) { - FocusStackIterator beginPos = mFocusHistory.begin(); - mFocusHistory.erase( beginPos ); + FocusStackIterator beginPos = mFocusHistory.begin(); + mFocusHistory.erase(beginPos); } - DALI_LOG_INFO( gLogFilter, Debug::General, "[%s:%d] SUCCEED\n", __FUNCTION__, __LINE__); + DALI_LOG_INFO(gLogFilter, Debug::General, "[%s:%d] SUCCEED\n", __FUNCTION__, __LINE__); success = true; } else @@ -299,7 +311,7 @@ Actor KeyboardFocusManager::GetCurrentFocusActor() { Actor actor = mCurrentFocusActor.GetHandle(); - if( actor && ! actor.GetProperty< bool >( Actor::Property::CONNECTED_TO_SCENE ) ) + if(actor && !actor.GetProperty(Actor::Property::CONNECTED_TO_SCENE)) { // If the actor has been removed from the stage, then it should not be focused actor.Reset(); @@ -310,22 +322,22 @@ Actor KeyboardFocusManager::GetCurrentFocusActor() Actor KeyboardFocusManager::GetFocusActorFromCurrentWindow() { - Actor actor; + Actor actor; unsigned int index; - for( index = 0; index < mCurrentFocusActors.size(); index++ ) + for(index = 0; index < mCurrentFocusActors.size(); index++) { - if( mCurrentFocusActors[index].first == mCurrentFocusedWindow ) + if(mCurrentFocusActors[index].first == mCurrentFocusedWindow) { actor = mCurrentFocusActors[index].second.GetHandle(); break; } } - if( actor && ! actor.GetProperty< bool >( Actor::Property::CONNECTED_TO_SCENE ) ) + if(actor && !actor.GetProperty(Actor::Property::CONNECTED_TO_SCENE)) { // If the actor has been removed from the window, then the window doesn't have any focused actor actor.Reset(); - mCurrentFocusActors.erase( mCurrentFocusActors.begin() + index ); + mCurrentFocusActors.erase(mCurrentFocusActors.begin() + index); } return actor; @@ -339,23 +351,23 @@ Actor KeyboardFocusManager::GetCurrentFocusGroup() void KeyboardFocusManager::MoveFocusBackward() { // Find Pre Focused Actor when the list size is more than 1 - if( mFocusHistory.size() > 1 ) + if(mFocusHistory.size() > 1) { // Delete current focused actor in history mFocusHistory.pop_back(); // If pre-focused actors are not on stage or deleted, remove them in stack - while( mFocusHistory.size() > 0 ) + while(mFocusHistory.size() > 0) { // Get pre focused actor - Actor target = mFocusHistory[ mFocusHistory.size() -1 ].GetHandle(); + Actor target = mFocusHistory[mFocusHistory.size() - 1].GetHandle(); // Impl of Actor is not null - if( target && target.GetProperty< bool >( Actor::Property::CONNECTED_TO_SCENE ) ) + if(target && target.GetProperty(Actor::Property::CONNECTED_TO_SCENE)) { // Delete pre focused actor in history because it will pushed again by SetCurrentFocusActor() mFocusHistory.pop_back(); - SetCurrentFocusActor( target ); + SetCurrentFocusActor(target); break; } else @@ -366,10 +378,10 @@ void KeyboardFocusManager::MoveFocusBackward() } // if there is no actor which can get focus, then push current focus actor in stack again - if( mFocusHistory.size() == 0 ) + if(mFocusHistory.size() == 0) { Actor currentFocusedActor = GetCurrentFocusActor(); - mFocusHistory.push_back( currentFocusedActor ); + mFocusHistory.push_back(currentFocusedActor); } } } @@ -377,7 +389,7 @@ void KeyboardFocusManager::MoveFocusBackward() bool KeyboardFocusManager::IsLayoutControl(Actor actor) const { Toolkit::Control control = Toolkit::Control::DownCast(actor); - return control && GetImplementation( control ).IsKeyboardNavigationSupported(); + return control && GetImplementation(control).IsKeyboardNavigationSupported(); } Toolkit::Control KeyboardFocusManager::GetParentLayoutControl(Actor actor) const @@ -387,8 +399,8 @@ Toolkit::Control KeyboardFocusManager::GetParentLayoutControl(Actor actor) const Actor parent; if(actor) { - Integration::SceneHolder window = Integration::SceneHolder::Get( actor ); - if ( window ) + Integration::SceneHolder window = Integration::SceneHolder::Get(actor); + if(window) { rootActor = window.GetRootLayer(); } @@ -396,7 +408,7 @@ Toolkit::Control KeyboardFocusManager::GetParentLayoutControl(Actor actor) const parent = actor.GetParent(); } - while( parent && !IsLayoutControl(parent) && parent != rootActor ) + while(parent && !IsLayoutControl(parent) && parent != rootActor) { parent = parent.GetParent(); } @@ -404,35 +416,35 @@ Toolkit::Control KeyboardFocusManager::GetParentLayoutControl(Actor actor) const return Toolkit::Control::DownCast(parent); } -bool KeyboardFocusManager::MoveFocus(Toolkit::Control::KeyboardFocus::Direction direction) +bool KeyboardFocusManager::MoveFocus(Toolkit::Control::KeyboardFocus::Direction direction, const std::string& deviceName) { Actor currentFocusActor = GetCurrentFocusActor(); bool succeed = false; // Go through the actor's hierarchy until we find a layout control that knows how to move the focus - Toolkit::Control parentLayoutControl = GetParentLayoutControl( currentFocusActor ); - while( parentLayoutControl && !succeed ) + Toolkit::Control layoutControl = IsLayoutControl(currentFocusActor) ? Toolkit::Control::DownCast(currentFocusActor) : GetParentLayoutControl(currentFocusActor); + while(layoutControl && !succeed) { - succeed = DoMoveFocusWithinLayoutControl( parentLayoutControl, currentFocusActor, direction ); - parentLayoutControl = GetParentLayoutControl( parentLayoutControl ); + succeed = DoMoveFocusWithinLayoutControl(layoutControl, currentFocusActor, direction); + layoutControl = GetParentLayoutControl(layoutControl); } - if( !succeed ) + if(!succeed) { Actor nextFocusableActor; Toolkit::Control currentFocusControl = Toolkit::Control::DownCast(currentFocusActor); // If the current focused actor is a control, then find the next focusable actor via the focusable properties. - if( currentFocusControl ) + if(currentFocusControl) { - int actorId = -1; - Property::Index index = Property::INVALID_INDEX; + int actorId = -1; + Property::Index index = Property::INVALID_INDEX; Property::Value value; // Find property index based upon focus direction - switch ( direction ) + switch(direction) { case Toolkit::Control::KeyboardFocus::LEFT: { @@ -454,67 +466,103 @@ bool KeyboardFocusManager::MoveFocus(Toolkit::Control::KeyboardFocus::Direction index = Toolkit::DevelControl::Property::DOWN_FOCUSABLE_ACTOR_ID; break; } + case Toolkit::Control::KeyboardFocus::CLOCKWISE: + { + index = Toolkit::DevelControl::Property::CLOCKWISE_FOCUSABLE_ACTOR_ID; + break; + } + case Toolkit::Control::KeyboardFocus::COUNTER_CLOCKWISE: + { + index = Toolkit::DevelControl::Property::COUNTER_CLOCKWISE_FOCUSABLE_ACTOR_ID; + break; + } default: break; } // If the focusable property is set then determine next focusable actor - if( index != Property::INVALID_INDEX) + if(index != Property::INVALID_INDEX) { - value = currentFocusActor.GetProperty( index ); + value = currentFocusActor.GetProperty(index); actorId = value.Get(); // If actor's id is valid then find actor form actor's id. The actor should be on the stage. - if( actorId != -1 ) + if(actorId != -1) { - if( currentFocusActor.GetParent() ) + if(currentFocusActor.GetParent()) { - nextFocusableActor = currentFocusActor.GetParent().FindChildById( actorId ); + nextFocusableActor = currentFocusActor.GetParent().FindChildById(actorId); } - if( !nextFocusableActor ) + if(!nextFocusableActor) { - Integration::SceneHolder window = Integration::SceneHolder::Get( currentFocusActor ); - if ( window ) + Integration::SceneHolder window = Integration::SceneHolder::Get(currentFocusActor); + if(window) { - nextFocusableActor = window.GetRootLayer().FindChildById( actorId ); + nextFocusableActor = window.GetRootLayer().FindChildById(actorId); } } } } } - if( !nextFocusableActor ) + if(!nextFocusableActor) { // If the implementation of CustomAlgorithmInterface is provided then the PreFocusChangeSignal is no longer emitted. - if( mCustomAlgorithmInterface ) + if(mCustomAlgorithmInterface) { mIsWaitingKeyboardFocusChangeCommit = true; - nextFocusableActor = mCustomAlgorithmInterface->GetNextFocusableActor( currentFocusActor, Actor(), direction ); + nextFocusableActor = mCustomAlgorithmInterface->GetNextFocusableActor(currentFocusActor, Actor(), direction, deviceName); mIsWaitingKeyboardFocusChangeCommit = false; } - else if( !mPreFocusChangeSignal.Empty() ) + else if(!mPreFocusChangeSignal.Empty()) { // Don't know how to move the focus further. The application needs to tell us which actor to move the focus to mIsWaitingKeyboardFocusChangeCommit = true; - nextFocusableActor = mPreFocusChangeSignal.Emit( currentFocusActor, Actor(), direction ); + nextFocusableActor = mPreFocusChangeSignal.Emit(currentFocusActor, Actor(), direction); mIsWaitingKeyboardFocusChangeCommit = false; } + else if(mEnableDefaultAlgorithm) + { + Actor rootActor = mFocusFinderRootActor.GetHandle(); + if(!rootActor) + { + if(currentFocusActor) + { + // 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(); + } + } + if(rootActor) + { + // We should find it among the actors nearby. + nextFocusableActor = Toolkit::FocusFinder::GetNearestFocusableActor(rootActor, currentFocusActor, direction); + } + } } - if( nextFocusableActor && nextFocusableActor.GetProperty< bool >( Actor::Property::KEYBOARD_FOCUSABLE ) ) + if(nextFocusableActor && nextFocusableActor.GetProperty(Actor::Property::KEYBOARD_FOCUSABLE) && nextFocusableActor.GetProperty(DevelActor::Property::USER_INTERACTION_ENABLED)) { // Whether the next focusable actor is a layout control - if( IsLayoutControl( nextFocusableActor ) ) + if(IsLayoutControl(nextFocusableActor)) { // If so, move the focus inside it. - Toolkit::Control layoutControl = Toolkit::Control::DownCast( nextFocusableActor) ; - succeed = DoMoveFocusWithinLayoutControl( layoutControl, currentFocusActor, direction ); + Toolkit::Control layoutControl = Toolkit::Control::DownCast(nextFocusableActor); + succeed = DoMoveFocusWithinLayoutControl(layoutControl, currentFocusActor, direction); } - else + if(!succeed) { - // Otherwise, just set focus to the next focusable actor - succeed = SetCurrentFocusActor( nextFocusableActor ); + // Just set focus to the next focusable actor + succeed = SetCurrentFocusActor(nextFocusableActor); } } } @@ -525,32 +573,32 @@ bool KeyboardFocusManager::MoveFocus(Toolkit::Control::KeyboardFocus::Direction bool KeyboardFocusManager::DoMoveFocusWithinLayoutControl(Toolkit::Control control, Actor actor, Toolkit::Control::KeyboardFocus::Direction direction) { // Ask the control for the next actor to focus - Actor nextFocusableActor = GetImplementation( control ).GetNextKeyboardFocusableActor(actor, direction, mFocusGroupLoopEnabled); + Actor nextFocusableActor = GetImplementation(control).GetNextKeyboardFocusableActor(actor, direction, mFocusGroupLoopEnabled); if(nextFocusableActor) { - if(!nextFocusableActor.GetProperty< bool >( Actor::Property::KEYBOARD_FOCUSABLE )) + if(!(nextFocusableActor.GetProperty(Actor::Property::KEYBOARD_FOCUSABLE) || nextFocusableActor.GetProperty(DevelActor::Property::USER_INTERACTION_ENABLED))) { // If the actor is not focusable, ask the same layout control for the next actor to focus return DoMoveFocusWithinLayoutControl(control, nextFocusableActor, direction); } else { - Actor currentFocusActor = GetCurrentFocusActor(); + Actor currentFocusActor = GetCurrentFocusActor(); Actor committedFocusActor = nextFocusableActor; // We will try to move the focus to the actor. Emit a signal to notify the proposed actor to focus // Signal handler can check the proposed actor and return a different actor if it wishes. - if( !mPreFocusChangeSignal.Empty() ) + if(!mPreFocusChangeSignal.Empty()) { mIsWaitingKeyboardFocusChangeCommit = true; - committedFocusActor = mPreFocusChangeSignal.Emit(currentFocusActor, nextFocusableActor, direction); + committedFocusActor = mPreFocusChangeSignal.Emit(currentFocusActor, nextFocusableActor, direction); mIsWaitingKeyboardFocusChangeCommit = false; } - if (committedFocusActor && committedFocusActor.GetProperty< bool >( Actor::Property::KEYBOARD_FOCUSABLE )) + if(committedFocusActor && committedFocusActor.GetProperty(Actor::Property::KEYBOARD_FOCUSABLE) && committedFocusActor.GetProperty(DevelActor::Property::USER_INTERACTION_ENABLED)) { // Whether the commited focusable actor is a layout control - if(IsLayoutControl(committedFocusActor)) + if(IsLayoutControl(committedFocusActor) && committedFocusActor != control) { // If so, move the focus inside it. Toolkit::Control layoutControl = Toolkit::Control::DownCast(committedFocusActor); @@ -564,7 +612,7 @@ bool KeyboardFocusManager::DoMoveFocusWithinLayoutControl(Toolkit::Control contr // If the application hasn't changed our proposed actor, we informs the layout control we will // move the focus to what the control returns. The control might wish to perform some actions // before the focus is actually moved. - GetImplementation( control ).OnKeyboardFocusChangeCommitted( committedFocusActor ); + GetImplementation(control).OnKeyboardFocusChangeCommitted(committedFocusActor); } return SetCurrentFocusActor(committedFocusActor); @@ -595,8 +643,8 @@ bool KeyboardFocusManager::DoMoveFocusToNextFocusGroup(bool forward) // If the current focus group has a parent layout control, we can probably automatically // move the focus to the next focus group in the forward or backward direction. Toolkit::Control::KeyboardFocus::Direction direction = forward ? Toolkit::Control::KeyboardFocus::RIGHT : Toolkit::Control::KeyboardFocus::LEFT; - succeed = DoMoveFocusWithinLayoutControl(parentLayoutControl, GetCurrentFocusActor(), direction); - parentLayoutControl = GetParentLayoutControl(parentLayoutControl); + succeed = DoMoveFocusWithinLayoutControl(parentLayoutControl, GetCurrentFocusActor(), direction); + parentLayoutControl = GetParentLayoutControl(parentLayoutControl); } if(!mFocusGroupChangedSignal.Empty()) @@ -610,49 +658,56 @@ bool KeyboardFocusManager::DoMoveFocusToNextFocusGroup(bool forward) void KeyboardFocusManager::DoKeyboardEnter(Actor actor) { - if( actor ) + if(actor) { - Toolkit::Control control = Toolkit::Control::DownCast( actor ); - if( control ) + Toolkit::Control control = Toolkit::Control::DownCast(actor); + if(control) { // Notify the control that enter has been pressed on it. - GetImplementation( control ).KeyboardEnter(); + GetImplementation(control).KeyboardEnter(); } // Send a notification for the actor. - if( !mFocusedActorEnterKeySignal.Empty() ) + if(!mFocusedActorEnterKeySignal.Empty()) { - mFocusedActorEnterKeySignal.Emit( actor ); + mFocusedActorEnterKeySignal.Emit(actor); } } } void KeyboardFocusManager::ClearFocus() { + ClearFocusIndicator(); Actor actor = GetCurrentFocusActor(); - if( actor ) + if(actor) { - if( mFocusIndicatorActor ) - { - actor.Remove( mFocusIndicatorActor ); - } - // Send notification for the change of focus actor - if( !mFocusChangedSignal.Empty() ) + if(!mFocusChangedSignal.Empty()) { - mFocusChangedSignal.Emit( actor, Actor() ); + mFocusChangedSignal.Emit(actor, Actor()); } - Toolkit::Control currentlyFocusedControl = Toolkit::Control::DownCast( actor ); - if( currentlyFocusedControl ) + Toolkit::Control currentlyFocusedControl = Toolkit::Control::DownCast(actor); + if(currentlyFocusedControl) { - currentlyFocusedControl.SetProperty( DevelControl::Property::STATE, DevelControl::NORMAL ); + currentlyFocusedControl.SetProperty(DevelControl::Property::STATE, DevelControl::NORMAL); currentlyFocusedControl.ClearKeyInputFocus(); } } - mCurrentFocusActor.Reset(); - mIsFocusIndicatorShown = ( mAlwaysShowIndicator == ALWAYS_SHOW ) ? SHOW : HIDE; +} + +void KeyboardFocusManager::ClearFocusIndicator() +{ + Actor actor = GetCurrentFocusActor(); + if(actor) + { + if(mFocusIndicatorActor) + { + actor.Remove(mFocusIndicatorActor); + } + } + mIsFocusIndicatorShown = (mAlwaysShowIndicator == ALWAYS_SHOW) ? SHOW : HIDE; } void KeyboardFocusManager::SetFocusGroupLoop(bool enabled) @@ -670,7 +725,7 @@ void KeyboardFocusManager::SetAsFocusGroup(Actor actor, bool isFocusGroup) if(actor) { // Create/Set focus group property. - actor.RegisterProperty( IS_FOCUS_GROUP_PROPERTY_NAME, isFocusGroup, Property::READ_WRITE ); + actor.RegisterProperty(IS_FOCUS_GROUP_PROPERTY_NAME, isFocusGroup, Property::READ_WRITE); } } @@ -694,7 +749,7 @@ bool KeyboardFocusManager::IsFocusGroup(Actor actor) const Actor KeyboardFocusManager::GetFocusGroup(Actor actor) { // Go through the actor's hierarchy to check which focus group the actor belongs to - while (actor && !IsFocusGroup(actor)) + while(actor && !IsFocusGroup(actor)) { actor = actor.GetParent(); } @@ -727,33 +782,29 @@ void KeyboardFocusManager::SetFocusIndicatorActor(Actor indicator) Actor KeyboardFocusManager::GetFocusIndicatorActor() { - if( ! mFocusIndicatorActor ) + if(!mFocusIndicatorActor) { // Create the default if it hasn't been set and one that's shared by all the keyboard focusable actors const std::string imageDirPath = AssetManager::GetDaliImagePath(); - mFocusIndicatorActor = Toolkit::ImageView::New( imageDirPath + FOCUS_BORDER_IMAGE_FILE_NAME ); + mFocusIndicatorActor = Toolkit::ImageView::New(imageDirPath + FOCUS_BORDER_IMAGE_FILE_NAME); // Apply size constraint to the focus indicator - mFocusIndicatorActor.SetResizePolicy( ResizePolicy::FILL_TO_PARENT, Dimension::ALL_DIMENSIONS ); + mFocusIndicatorActor.SetResizePolicy(ResizePolicy::FILL_TO_PARENT, Dimension::ALL_DIMENSIONS); } - mFocusIndicatorActor.SetProperty( Actor::Property::PARENT_ORIGIN, ParentOrigin::CENTER ); - mFocusIndicatorActor.SetProperty( Actor::Property::ANCHOR_POINT, AnchorPoint::CENTER ); - mFocusIndicatorActor.SetProperty( Actor::Property::POSITION, Vector2(0.0f, 0.0f)); + mFocusIndicatorActor.SetProperty(Actor::Property::PARENT_ORIGIN, ParentOrigin::CENTER); + mFocusIndicatorActor.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::CENTER); + mFocusIndicatorActor.SetProperty(Actor::Property::POSITION, Vector2(0.0f, 0.0f)); return mFocusIndicatorActor; } void KeyboardFocusManager::OnKeyEvent(const KeyEvent& event) { - AccessibilityAdaptor accessibilityAdaptor = AccessibilityAdaptor::Get(); - bool isAccessibilityEnabled = accessibilityAdaptor.IsEnabled(); - - Toolkit::AccessibilityManager accessibilityManager = Toolkit::AccessibilityManager::Get(); - - std::string keyName = event.GetKeyName(); + const std::string& keyName = event.GetKeyName(); + const std::string& deviceName = event.GetDeviceName(); - if( mIsFocusIndicatorShown == UNKNOWN ) + if(mIsFocusIndicatorShown == UNKNOWN) { GetConfigurationFromStyleManger(); } @@ -762,55 +813,39 @@ void KeyboardFocusManager::OnKeyEvent(const KeyEvent& event) if(event.GetState() == KeyEvent::DOWN) { - if (keyName == "Left") + if(keyName == "Left") { - if(!isAccessibilityEnabled) + if(mIsFocusIndicatorShown == HIDE) { - if(mIsFocusIndicatorShown == HIDE) - { - // Show focus indicator - mIsFocusIndicatorShown = SHOW; - } - else - { - // Move the focus towards left - MoveFocus(Toolkit::Control::KeyboardFocus::LEFT); - } - - isFocusStartableKey = true; + // Show focus indicator + mIsFocusIndicatorShown = SHOW; } else { - // Move the accessibility focus backward - accessibilityManager.MoveFocusBackward(); + // Move the focus towards left + MoveFocus(Toolkit::Control::KeyboardFocus::LEFT, deviceName); } + + isFocusStartableKey = true; } - else if (keyName == "Right") + else if(keyName == "Right") { - if(!isAccessibilityEnabled) + if(mIsFocusIndicatorShown == HIDE) { - if( mIsFocusIndicatorShown == HIDE ) - { - // Show focus indicator - mIsFocusIndicatorShown = SHOW; - } - else - { - // Move the focus towards right - MoveFocus(Toolkit::Control::KeyboardFocus::RIGHT); - } + // Show focus indicator + mIsFocusIndicatorShown = SHOW; } else { - // Move the accessibility focus forward - accessibilityManager.MoveFocusForward(); + // Move the focus towards right + MoveFocus(Toolkit::Control::KeyboardFocus::RIGHT, deviceName); } isFocusStartableKey = true; } - else if (keyName == "Up" && !isAccessibilityEnabled) + else if(keyName == "Up") { - if( mIsFocusIndicatorShown == HIDE ) + if(mIsFocusIndicatorShown == HIDE) { // Show focus indicator mIsFocusIndicatorShown = SHOW; @@ -818,14 +853,14 @@ void KeyboardFocusManager::OnKeyEvent(const KeyEvent& event) else { // Move the focus towards up - MoveFocus(Toolkit::Control::KeyboardFocus::UP); + MoveFocus(Toolkit::Control::KeyboardFocus::UP, deviceName); } isFocusStartableKey = true; } - else if (keyName == "Down" && !isAccessibilityEnabled) + else if(keyName == "Down") { - if( mIsFocusIndicatorShown == HIDE ) + if(mIsFocusIndicatorShown == HIDE) { // Show focus indicator mIsFocusIndicatorShown = SHOW; @@ -833,14 +868,14 @@ void KeyboardFocusManager::OnKeyEvent(const KeyEvent& event) else { // Move the focus towards down - MoveFocus(Toolkit::Control::KeyboardFocus::DOWN); + MoveFocus(Toolkit::Control::KeyboardFocus::DOWN, deviceName); } isFocusStartableKey = true; } - else if (keyName == "Prior" && !isAccessibilityEnabled) + else if(keyName == "Prior") { - if( mIsFocusIndicatorShown == HIDE ) + if(mIsFocusIndicatorShown == HIDE) { // Show focus indicator mIsFocusIndicatorShown = SHOW; @@ -848,14 +883,14 @@ void KeyboardFocusManager::OnKeyEvent(const KeyEvent& event) else { // Move the focus towards the previous page - MoveFocus(Toolkit::Control::KeyboardFocus::PAGE_UP); + MoveFocus(Toolkit::Control::KeyboardFocus::PAGE_UP, deviceName); } isFocusStartableKey = true; } - else if (keyName == "Next" && !isAccessibilityEnabled) + else if(keyName == "Next") { - if( mIsFocusIndicatorShown == HIDE ) + if(mIsFocusIndicatorShown == HIDE) { // Show focus indicator mIsFocusIndicatorShown = SHOW; @@ -863,14 +898,14 @@ void KeyboardFocusManager::OnKeyEvent(const KeyEvent& event) else { // Move the focus towards the next page - MoveFocus(Toolkit::Control::KeyboardFocus::PAGE_DOWN); + MoveFocus(Toolkit::Control::KeyboardFocus::PAGE_DOWN, deviceName); } isFocusStartableKey = true; } - else if (keyName == "Tab" && !isAccessibilityEnabled) + else if(keyName == "Tab") { - if( mIsFocusIndicatorShown == HIDE ) + if(mIsFocusIndicatorShown == HIDE) { // Show focus indicator mIsFocusIndicatorShown = SHOW; @@ -879,14 +914,18 @@ 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 forward, "Shift-Tap" key moves the focus towards backward. + MoveFocus(event.IsShiftModifier() ? Toolkit::Control::KeyboardFocus::BACKWARD : Toolkit::Control::KeyboardFocus::FORWARD, deviceName); + } } isFocusStartableKey = true; } - else if (keyName == "space" && !isAccessibilityEnabled) + else if(keyName == "space") { - if( mIsFocusIndicatorShown == HIDE ) + if(mIsFocusIndicatorShown == HIDE) { // Show focus indicator mIsFocusIndicatorShown = SHOW; @@ -894,10 +933,10 @@ void KeyboardFocusManager::OnKeyEvent(const KeyEvent& event) isFocusStartableKey = true; } - else if (keyName == "" && !isAccessibilityEnabled) + else if(keyName == "") { // Check the fake key event for evas-plugin case - if( mIsFocusIndicatorShown == HIDE ) + if(mIsFocusIndicatorShown == HIDE) { // Show focus indicator mIsFocusIndicatorShown = SHOW; @@ -905,19 +944,19 @@ void KeyboardFocusManager::OnKeyEvent(const KeyEvent& event) isFocusStartableKey = true; } - else if (keyName == "Backspace" && !isAccessibilityEnabled) + else if(keyName == "Backspace") { // Emit signal to go back to the previous view??? } - else if (keyName == "Escape" && !isAccessibilityEnabled) + else if(keyName == "Escape") { } } else if(event.GetState() == KeyEvent::UP) { - if (keyName == "Return") + if(keyName == "Return") { - if((mIsFocusIndicatorShown == HIDE) && !isAccessibilityEnabled) + if(mIsFocusIndicatorShown == HIDE) { // Show focus indicator mIsFocusIndicatorShown = SHOW; @@ -925,19 +964,10 @@ void KeyboardFocusManager::OnKeyEvent(const KeyEvent& event) else { // The focused actor has enter pressed on it - Actor actor; - if( !isAccessibilityEnabled ) - { - actor = GetCurrentFocusActor(); - } - else + Actor actor = GetCurrentFocusActor(); + if(actor) { - actor = accessibilityManager.GetCurrentFocusActor(); - } - - if( actor ) - { - DoKeyboardEnter( actor ); + DoKeyboardEnter(actor); } } @@ -945,22 +975,22 @@ void KeyboardFocusManager::OnKeyEvent(const KeyEvent& event) } } - if(isFocusStartableKey && ( mIsFocusIndicatorShown == SHOW ) && !isAccessibilityEnabled) + if(isFocusStartableKey && mIsFocusIndicatorShown == SHOW) { Actor actor = GetCurrentFocusActor(); - if( actor ) + if(actor) { - if( mEnableFocusIndicator == ENABLE ) + if(mEnableFocusIndicator == ENABLE) { // Make sure the focused actor is highlighted - actor.Add( GetFocusIndicatorActor() ); + actor.Add(GetFocusIndicatorActor()); } } - else + else if(!mEnableDefaultAlgorithm) { // No actor is focused but keyboard focus is activated by the key press // Let's try to move the initial focus - MoveFocus(Toolkit::Control::KeyboardFocus::RIGHT); + MoveFocus(Toolkit::Control::KeyboardFocus::RIGHT, deviceName); } } } @@ -969,36 +999,111 @@ void KeyboardFocusManager::OnTouch(const TouchEvent& touch) { // if mIsFocusIndicatorShown is UNKNOWN, it means Configuration is not loaded. // Try to load configuration. - if( mIsFocusIndicatorShown == UNKNOWN ) + if(mIsFocusIndicatorShown == UNKNOWN) { GetConfigurationFromStyleManger(); } // Clear the focus when user touch the screen. // We only do this on a Down event, otherwise the clear action may override a manually focused actor. - // If mClearFocusOnTouch is false, do not clear the focus even if user touch the screen. - if( (( touch.GetPointCount() < 1 ) || ( touch.GetState( 0 ) == PointState::DOWN )) && mClearFocusOnTouch ) + if(((touch.GetPointCount() < 1) || (touch.GetState(0) == PointState::DOWN))) + { + // If you touch the currently focused actor again, you don't need to do SetCurrentFocusActor again. + Actor hitActor = touch.GetHitActor(0); + if(hitActor && hitActor == GetCurrentFocusActor()) + { + return; + } + // If KEYBOARD_FOCUSABLE and TOUCH_FOCUSABLE is true, set focus actor + if(hitActor && hitActor.GetProperty(Actor::Property::KEYBOARD_FOCUSABLE) && hitActor.GetProperty(DevelActor::Property::TOUCH_FOCUSABLE)) + { + // If mClearFocusOnTouch is false, do not clear the focus + if(mClearFocusOnTouch) + { + ClearFocus(); + } + SetCurrentFocusActor(hitActor); + } + else + { + // If mClearFocusOnTouch is false, do not clear the focus indicator even if user touch the screen. + if(mClearFocusOnTouch) + { + ClearFocusIndicator(); + } + } + } +} + +void KeyboardFocusManager::OnWheelEvent(const WheelEvent& event) +{ + if(event.GetType() == Dali::WheelEvent::CUSTOM_WHEEL) + { + Toolkit::Control::KeyboardFocus::Direction direction = (event.GetDelta() > 0) ? Toolkit::Control::KeyboardFocus::CLOCKWISE : Toolkit::Control::KeyboardFocus::COUNTER_CLOCKWISE; + // Move the focus + MoveFocus(direction); + } +} + +bool KeyboardFocusManager::OnCustomWheelEvent(const WheelEvent& event) +{ + bool consumed = false; + Actor actor = GetCurrentFocusActor(); + if(actor) + { + // Notify the actor about the wheel event + consumed = EmitCustomWheelSignals(actor, event); + } + return consumed; +} + +bool KeyboardFocusManager::EmitCustomWheelSignals(Actor actor, const WheelEvent& event) +{ + bool consumed = false; + + if(actor) { - ClearFocus(); + Dali::Actor oldParent(actor.GetParent()); + + // Only do the conversion and emit the signal if the actor's wheel signal has connections. + if(!actor.WheelEventSignal().Empty()) + { + // Emit the signal to the parent + consumed = actor.WheelEventSignal().Emit(actor, event); + } + // if actor doesn't consume WheelEvent, give WheelEvent to its parent. + if(!consumed) + { + // The actor may have been removed/reparented during the signal callbacks. + Dali::Actor parent = actor.GetParent(); + + if(parent && + (parent == oldParent)) + { + consumed = EmitCustomWheelSignals(parent, event); + } + } } + + return consumed; } -void KeyboardFocusManager::OnWindowFocusChanged(Window window, bool focusIn ) +void KeyboardFocusManager::OnWindowFocusChanged(Window window, bool focusIn) { - if( focusIn && mCurrentFocusedWindow.GetHandle() != window.GetRootLayer() ) + if(focusIn && mCurrentFocusedWindow.GetHandle() != window.GetRootLayer()) { // Change Current Focused Window - Layer rootLayer = window.GetRootLayer(); + Layer rootLayer = window.GetRootLayer(); mCurrentFocusedWindow = rootLayer; // Get Current Focused Actor from window Actor currentFocusedActor = GetFocusActorFromCurrentWindow(); - SetCurrentFocusActor( currentFocusedActor ); + SetCurrentFocusActor(currentFocusedActor); - if( currentFocusedActor && ( mEnableFocusIndicator == ENABLE ) ) + if(currentFocusedActor && (mEnableFocusIndicator == ENABLE)) { // Make sure the focused actor is highlighted - currentFocusedActor.Add( GetFocusIndicatorActor() ); + currentFocusedActor.Add(GetFocusIndicatorActor()); mIsFocusIndicatorShown = SHOW; } } @@ -1024,28 +1129,28 @@ Toolkit::KeyboardFocusManager::FocusedActorEnterKeySignalType& KeyboardFocusMana return mFocusedActorEnterKeySignal; } -bool KeyboardFocusManager::DoConnectSignal( BaseObject* object, ConnectionTrackerInterface* tracker, const std::string& signalName, FunctorDelegate* functor ) +bool KeyboardFocusManager::DoConnectSignal(BaseObject* object, ConnectionTrackerInterface* tracker, const std::string& signalName, FunctorDelegate* functor) { - Dali::BaseHandle handle( object ); + Dali::BaseHandle handle(object); - bool connected( true ); - KeyboardFocusManager* manager = static_cast< KeyboardFocusManager* >( object ); // TypeRegistry guarantees that this is the correct type. + bool connected(true); + KeyboardFocusManager* manager = static_cast(object); // TypeRegistry guarantees that this is the correct type. - if( 0 == strcmp( signalName.c_str(), SIGNAL_PRE_FOCUS_CHANGE ) ) + if(0 == strcmp(signalName.c_str(), SIGNAL_PRE_FOCUS_CHANGE)) { - manager->PreFocusChangeSignal().Connect( tracker, functor ); + manager->PreFocusChangeSignal().Connect(tracker, functor); } - else if( 0 == strcmp( signalName.c_str(), SIGNAL_FOCUS_CHANGED ) ) + else if(0 == strcmp(signalName.c_str(), SIGNAL_FOCUS_CHANGED)) { - manager->FocusChangedSignal().Connect( tracker, functor ); + manager->FocusChangedSignal().Connect(tracker, functor); } - else if( 0 == strcmp( signalName.c_str(), SIGNAL_FOCUS_GROUP_CHANGED ) ) + else if(0 == strcmp(signalName.c_str(), SIGNAL_FOCUS_GROUP_CHANGED)) { - manager->FocusGroupChangedSignal().Connect( tracker, functor ); + manager->FocusGroupChangedSignal().Connect(tracker, functor); } - else if( 0 == strcmp( signalName.c_str(), SIGNAL_FOCUSED_ACTOR_ENTER_KEY ) ) + else if(0 == strcmp(signalName.c_str(), SIGNAL_FOCUSED_ACTOR_ENTER_KEY)) { - manager->FocusedActorEnterKeySignal().Connect( tracker, functor ); + manager->FocusedActorEnterKeySignal().Connect(tracker, functor); } else { @@ -1063,18 +1168,37 @@ void KeyboardFocusManager::SetCustomAlgorithm(CustomAlgorithmInterface& interfac void KeyboardFocusManager::EnableFocusIndicator(bool enable) { - if( !enable && mFocusIndicatorActor ) + if(!enable && mFocusIndicatorActor) { mFocusIndicatorActor.Unparent(); } - mEnableFocusIndicator = enable? ENABLE : DISABLE; - + mEnableFocusIndicator = enable ? ENABLE : DISABLE; } bool KeyboardFocusManager::IsFocusIndicatorEnabled() const { - return ( mEnableFocusIndicator == ENABLE ); + return (mEnableFocusIndicator == ENABLE); +} + +void KeyboardFocusManager::EnableDefaultAlgorithm(bool enable) +{ + mEnableDefaultAlgorithm = enable; +} + +bool KeyboardFocusManager::IsDefaultAlgorithmEnabled() const +{ + return mEnableDefaultAlgorithm; +} + +void KeyboardFocusManager::SetFocusFinderRootActor(Actor actor) +{ + mFocusFinderRootActor = actor; +} + +void KeyboardFocusManager::ResetFocusFinderRootActor() +{ + mFocusFinderRootActor.Reset(); } } // namespace Internal