X-Git-Url: http://review.tizen.org/git/?p=platform%2Fcore%2Fuifw%2Fdali-toolkit.git;a=blobdiff_plain;f=dali-toolkit%2Finternal%2Ffocus-manager%2Fkeyinput-focus-manager-impl.cpp;h=2549e52c9d5c7128755575b43aa3dd56d40dcb8f;hp=5d7d4be85b8f287594540afc26efe0e8893b1c42;hb=29540fc153880d6949c85786b78b8583ae8f1d37;hpb=1b1e10a3f4e486553200d8ddeb57d953c2284579 diff --git a/dali-toolkit/internal/focus-manager/keyinput-focus-manager-impl.cpp b/dali-toolkit/internal/focus-manager/keyinput-focus-manager-impl.cpp index 5d7d4be..2549e52 100644 --- a/dali-toolkit/internal/focus-manager/keyinput-focus-manager-impl.cpp +++ b/dali-toolkit/internal/focus-manager/keyinput-focus-manager-impl.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014 Samsung Electronics Co., Ltd. + * Copyright (c) 2020 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,12 +19,12 @@ #include "keyinput-focus-manager-impl.h" // EXTERNAL INCLUDES +#include // for strcmp #include -#include - -// INTERNAL INCLUDES #include #include +#include +#include namespace Dali { @@ -40,23 +40,34 @@ namespace // Signals -const char* const SIGNAL_KEY_INPUT_FOCUS_CHANGED = "key-input-focus-changed"; -const char* const SIGNAL_UNHANDLED_KEY_EVENT = "unhandled-key-event"; +const char* const SIGNAL_KEY_INPUT_FOCUS_CHANGED = "keyInputFocusChanged"; } KeyInputFocusManager::KeyInputFocusManager() -: mSlotDelegate( this ) +: mSlotDelegate( this ), + mCurrentFocusControl() { - Stage::GetCurrent().KeyEventSignal().Connect(mSlotDelegate, &KeyInputFocusManager::OnKeyEvent); - mObjectRegistry = Dali::Stage::GetCurrent().GetObjectRegistry(); - mObjectRegistry.ObjectDestroyedSignal().Connect( this, &KeyInputFocusManager::OnObjectDestroyed ); + // Retrieve all the existing widnows + Dali::SceneHolderList sceneHolders = Adaptor::Get().GetSceneHolders(); + for( auto iter = sceneHolders.begin(); iter != sceneHolders.end(); ++iter ) + { + ( *iter ).KeyEventGeneratedSignal().Connect( mSlotDelegate, &KeyInputFocusManager::OnKeyEvent ); + } + + // Get notified when any new scene holder is created afterwards + Adaptor::Get().WindowCreatedSignal().Connect( mSlotDelegate, &KeyInputFocusManager::OnSceneHolderCreated ); } KeyInputFocusManager::~KeyInputFocusManager() { } +void KeyInputFocusManager::OnSceneHolderCreated( Dali::Integration::SceneHolder& sceneHolder ) +{ + sceneHolder.KeyEventGeneratedSignal().Connect( mSlotDelegate, &KeyInputFocusManager::OnKeyEvent ); +} + void KeyInputFocusManager::SetFocus( Toolkit::Control control ) { if( !control ) @@ -65,35 +76,26 @@ void KeyInputFocusManager::SetFocus( Toolkit::Control control ) return; } - FocusStackIterator pos = FindFocusControlInStack( control ); - - if( ( mFocusStack.Count() != 0 ) && ( pos == mFocusStack.End()-1 ) ) + if( control == mCurrentFocusControl ) { - // Control already in front, so No-op + // Control already has focus return; } - if( pos != mFocusStack.End() ) - { - // A previously focused control wants to regain focus - mFocusStack.Erase( pos ); - } - else - { - control.OffStageSignal().Connect( mSlotDelegate, &KeyInputFocusManager::OnFocusControlStageDisconnection ); - } + control.OffSceneSignal().Connect( mSlotDelegate, &KeyInputFocusManager::OnFocusControlSceneDisconnection ); Dali::Toolkit::Control previousFocusControl = GetCurrentFocusControl(); if( previousFocusControl ) { // Notify the control that it has lost key input focus - previousFocusControl.GetImplementation().OnKeyInputFocusLost(); + GetImplementation( previousFocusControl ).OnKeyInputFocusLost(); } - mFocusStack.PushBack( &control.GetBaseObject() ); + // Set control to currentFocusControl + mCurrentFocusControl = control; // Tell the new actor that it has gained focus. - control.GetImplementation().OnKeyInputFocusGained(); + GetImplementation( control ).OnKeyInputFocusGained(); // Emit the signal to inform focus change to the application. if ( !mKeyInputFocusChangedSignal.Empty() ) @@ -104,61 +106,20 @@ void KeyInputFocusManager::SetFocus( Toolkit::Control control ) void KeyInputFocusManager::RemoveFocus( Toolkit::Control control ) { - if( control ) + if( control == mCurrentFocusControl ) { - FocusStackIterator pos = FindFocusControlInStack( control ); - if( pos != mFocusStack.End() ) - { - control.OffStageSignal().Disconnect( mSlotDelegate, &KeyInputFocusManager::OnFocusControlStageDisconnection ); + control.OffSceneSignal().Disconnect( mSlotDelegate, &KeyInputFocusManager::OnFocusControlSceneDisconnection ); - // Notify the control that it has lost key input focus - control.GetImplementation().OnKeyInputFocusLost(); + // Notify the control that it has lost key input focus + GetImplementation( control ).OnKeyInputFocusLost(); - // If this is the top-most actor, pop it and change focus to the previous control - if( pos == mFocusStack.End() - 1 ) - { - mFocusStack.Erase( pos ); - - Toolkit::Control previouslyFocusedControl = GetCurrentFocusControl(); - if( previouslyFocusedControl ) - { - // Tell the control that it has gained focus. - previouslyFocusedControl.GetImplementation().OnKeyInputFocusGained(); - } - } - else - { - // If the removed control is not currently focused, then no need to emit signal. - mFocusStack.Erase( pos ); - } - } + mCurrentFocusControl.Reset(); } } Toolkit::Control KeyInputFocusManager::GetCurrentFocusControl() const { - Toolkit::Control currentControl; - - FocusStack::SizeType count = mFocusStack.Count(); - if( count != 0 ) - { - BaseObject* object = mFocusStack[ count - 1 ]; - BaseHandle handle( object ); - currentControl = Dali::Toolkit::Control::DownCast( handle ); - } - return currentControl; -} - -bool KeyInputFocusManager::IsKeyboardListener( Toolkit::Control control ) const -{ - bool result = false; - - if( FindFocusControlInStack( control ) != mFocusStack.End() ) - { - result = true; - } - - return result; + return mCurrentFocusControl; } Toolkit::KeyInputFocusManager::KeyInputFocusChangedSignalType& KeyInputFocusManager::KeyInputFocusChangedSignal() @@ -166,84 +127,65 @@ Toolkit::KeyInputFocusManager::KeyInputFocusChangedSignalType& KeyInputFocusMana return mKeyInputFocusChangedSignal; } -Toolkit::KeyInputFocusManager::UnhandledKeyEventSignalType& KeyInputFocusManager::UnhandledKeyEventSignal() +bool KeyInputFocusManager::OnKeyEvent( const KeyEvent& event ) { - return mUnhandledKeyEventSignal; -} + bool consumed = false; -KeyInputFocusManager::FocusStackIterator KeyInputFocusManager::FindFocusControlInStack( Toolkit::Control control ) const -{ - BaseObject* controlObject = &control.GetBaseObject(); - return std::find( mFocusStack.Begin(), mFocusStack.End(), controlObject ); + Toolkit::Control control = GetCurrentFocusControl(); + if( control ) + { + // Notify the control about the key event + consumed = EmitKeyEventSignal( control, event ); + } + + return consumed; } -void KeyInputFocusManager::OnKeyEvent( const KeyEvent& event ) +bool KeyInputFocusManager::EmitKeyEventSignal( Toolkit::Control control, const KeyEvent& event ) { bool consumed = false; - if( mFocusStack.Count() > 0 ) + if( control ) { - FocusStack::SizeType index = mFocusStack.Count(); - while( mFocusStack.Count() != 0 && !consumed && index > 0 ) + consumed = GetImplementation( control ).EmitKeyEventSignal( event ); + + // if control doesn't consume KeyEvent, give KeyEvent to its parent. + if( !consumed ) { - --index; - BaseObject* object = mFocusStack[ index ]; - BaseHandle handle( object ); - Toolkit::Control control = Toolkit::Control::DownCast( object ); - if( control ) + Toolkit::Control parent = Toolkit::Control::DownCast( control.GetParent() ); + + if( parent ) { - // Notify the control about the key event - consumed = control.GetImplementation().EmitKeyEventSignal( event ); + consumed = EmitKeyEventSignal( parent, event ); } } } - if( !consumed ) - { - // Emit signal to inform that a key event is not consumed. - if( !mUnhandledKeyEventSignal.Empty() ) - { - mUnhandledKeyEventSignal.Emit(event); - } - } + return consumed; } -void KeyInputFocusManager::OnFocusControlStageDisconnection( Dali::Actor actor ) +void KeyInputFocusManager::OnFocusControlSceneDisconnection( Dali::Actor actor ) { RemoveFocus( Dali::Toolkit::Control::DownCast( actor ) ); } -void KeyInputFocusManager::OnObjectDestroyed( const Dali::RefObject* object ) -{ - // The object is already destroyed. Don't create handles to it, or try sending - // signals to it. Remove it's pointer from the stack. - const BaseObject* baseObject = static_cast( object ); - FocusStackIterator pos = std::find( mFocusStack.Begin(), mFocusStack.End(), baseObject ); - if( pos != mFocusStack.End() ) - { - mFocusStack.Erase( pos ); - } -} bool KeyInputFocusManager::DoConnectSignal( BaseObject* object, ConnectionTrackerInterface* tracker, const std::string& signalName, FunctorDelegate* functor ) { - Dali::BaseHandle handle( object ); - bool connected( true ); KeyInputFocusManager* manager = dynamic_cast( object ); - if( 0 == strcmp( signalName.c_str(), SIGNAL_KEY_INPUT_FOCUS_CHANGED ) ) - { - manager->KeyInputFocusChangedSignal().Connect( tracker, functor ); - } - else if( 0 == strcmp( signalName.c_str(), SIGNAL_UNHANDLED_KEY_EVENT ) ) - { - manager->UnhandledKeyEventSignal().Connect( tracker, functor ); - } - else + if( manager ) { - // signalName does not match any signal - connected = false; + if( 0 == strcmp( signalName.c_str(), SIGNAL_KEY_INPUT_FOCUS_CHANGED ) ) + { + manager->KeyInputFocusChangedSignal().Connect( tracker, functor ); + } + else + { + // signalName does not match any signal + connected = false; + } } return connected;