Fix InputMethodContext to work well in multi-window env
[platform/core/uifw/dali-toolkit.git] / dali-toolkit / internal / focus-manager / keyboard-focus-manager-impl.cpp
1 /*
2  * Copyright (c) 2019 Samsung Electronics Co., Ltd.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  *
16  */
17
18 // CLASS HEADER
19 #include "keyboard-focus-manager-impl.h"
20
21 // EXTERNAL INCLUDES
22 #include <cstring> // for strcmp
23 #include <dali/public-api/actors/layer.h>
24 #include <dali/devel-api/adaptor-framework/accessibility-adaptor.h>
25 #include <dali/devel-api/adaptor-framework/singleton-service.h>
26 #include <dali/devel-api/adaptor-framework/window-devel.h>
27 #include <dali/devel-api/adaptor-framework/lifecycle-controller.h>
28 #include <dali/public-api/animation/constraints.h>
29 #include <dali/public-api/common/stage.h>
30 #include <dali/public-api/events/key-event.h>
31 #include <dali/public-api/events/touch-data.h>
32 #include <dali/public-api/object/type-registry.h>
33 #include <dali/public-api/object/type-registry-helper.h>
34 #include <dali/public-api/object/property-map.h>
35 #include <dali/public-api/images/resource-image.h>
36 #include <dali/integration-api/adaptors/adaptor.h>
37 #include <dali/integration-api/adaptors/scene-holder.h>
38 #include <dali/integration-api/debug.h>
39
40 // INTERNAL INCLUDES
41 #include <dali-toolkit/public-api/controls/control.h>
42 #include <dali-toolkit/public-api/controls/control-impl.h>
43 #include <dali-toolkit/public-api/controls/image-view/image-view.h>
44 #include <dali-toolkit/public-api/accessibility-manager/accessibility-manager.h>
45 #include <dali-toolkit/devel-api/controls/control-devel.h>
46 #include <dali-toolkit/public-api/styling/style-manager.h>
47 #include <dali-toolkit/devel-api/styling/style-manager-devel.h>
48
49 namespace Dali
50 {
51
52 namespace Toolkit
53 {
54
55 namespace Internal
56 {
57
58 namespace // Unnamed namespace
59 {
60
61 #if defined(DEBUG_ENABLED)
62 Debug::Filter* gLogFilter = Debug::Filter::New(Debug::NoLogging, false, "LOG_KEYBOARD_FOCUS_MANAGER");
63 #endif
64
65 const char* const IS_FOCUS_GROUP_PROPERTY_NAME = "isKeyboardFocusGroup"; // This property will be replaced by a flag in Control.
66
67 const char* const FOCUS_BORDER_IMAGE_PATH = DALI_IMAGE_DIR "keyboard_focus.9.png";
68
69 BaseHandle Create()
70 {
71   BaseHandle handle = KeyboardFocusManager::Get();
72
73   if ( !handle )
74   {
75     SingletonService singletonService( SingletonService::Get() );
76     if ( singletonService )
77     {
78       Toolkit::KeyboardFocusManager manager = Toolkit::KeyboardFocusManager( new Internal::KeyboardFocusManager() );
79       singletonService.Register( typeid( manager ), manager );
80       handle = manager;
81     }
82   }
83
84   return handle;
85 }
86
87 DALI_TYPE_REGISTRATION_BEGIN_CREATE( Toolkit::KeyboardFocusManager, Dali::BaseHandle, Create, true )
88
89 DALI_SIGNAL_REGISTRATION( Toolkit, KeyboardFocusManager, "keyboardPreFocusChange",           SIGNAL_PRE_FOCUS_CHANGE )
90 DALI_SIGNAL_REGISTRATION( Toolkit, KeyboardFocusManager, "keyboardFocusChanged",             SIGNAL_FOCUS_CHANGED )
91 DALI_SIGNAL_REGISTRATION( Toolkit, KeyboardFocusManager, "keyboardFocusGroupChanged",        SIGNAL_FOCUS_GROUP_CHANGED )
92 DALI_SIGNAL_REGISTRATION( Toolkit, KeyboardFocusManager, "keyboardFocusedActorEnterKey",     SIGNAL_FOCUSED_ACTOR_ENTER_KEY )
93
94 DALI_TYPE_REGISTRATION_END()
95
96 const unsigned int MAX_HISTORY_AMOUNT = 30; ///< Max length of focus history stack
97
98 } // unnamed namespace
99
100 Toolkit::KeyboardFocusManager KeyboardFocusManager::Get()
101 {
102   Toolkit::KeyboardFocusManager manager;
103
104   SingletonService singletonService( SingletonService::Get() );
105   if ( singletonService )
106   {
107     // Check whether the keyboard focus manager is already created
108     Dali::BaseHandle handle = singletonService.GetSingleton( typeid( Toolkit::KeyboardFocusManager ) );
109     if(handle)
110     {
111       // If so, downcast the handle of singleton to keyboard focus manager
112       manager = Toolkit::KeyboardFocusManager( dynamic_cast< KeyboardFocusManager* >( handle.GetObjectPtr() ) );
113     }
114   }
115
116   return manager;
117 }
118
119 KeyboardFocusManager::KeyboardFocusManager()
120 : mPreFocusChangeSignal(),
121   mFocusChangedSignal(),
122   mFocusGroupChangedSignal(),
123   mFocusedActorEnterKeySignal(),
124   mCurrentFocusActor(),
125   mFocusIndicatorActor(),
126   mIsFocusIndicatorShown( -1 ),
127   mFocusGroupLoopEnabled( false ),
128   mIsWaitingKeyboardFocusChangeCommit( false ),
129   mClearFocusOnTouch( true ),
130   mEnableFocusIndicator( true ),
131   mAlwaysShowIndicator( true ),
132   mFocusHistory(),
133   mSlotDelegate( this ),
134   mCustomAlgorithmInterface(NULL)
135 {
136   // TODO: Get FocusIndicatorEnable constant from stylesheet to set mIsFocusIndicatorShown.
137
138   LifecycleController::Get().InitSignal().Connect( mSlotDelegate, &KeyboardFocusManager::OnAdaptorInit );
139 }
140
141 void KeyboardFocusManager::OnAdaptorInit()
142 {
143   if( Adaptor::IsAvailable() )
144   {
145     // Retrieve all the existing widnows
146     Dali::WindowContainer windows = Adaptor::Get().GetWindows();
147     for ( auto iter = windows.begin(); iter != windows.end(); ++iter )
148     {
149       DevelWindow::KeyEventSignal( *iter ).Connect( mSlotDelegate, &KeyboardFocusManager::OnKeyEvent);
150       DevelWindow::TouchSignal( *iter ).Connect( mSlotDelegate, &KeyboardFocusManager::OnTouch);
151     }
152
153     // Get notified when any new window is created afterwards
154     Adaptor::Get().WindowCreatedSignal().Connect( mSlotDelegate, &KeyboardFocusManager::OnWindowCreated);
155   }
156 }
157
158 void KeyboardFocusManager::OnWindowCreated( Dali::Window& window )
159 {
160   DevelWindow::KeyEventSignal( window ).Connect( mSlotDelegate, &KeyboardFocusManager::OnKeyEvent);
161   DevelWindow::TouchSignal( window ).Connect( mSlotDelegate, &KeyboardFocusManager::OnTouch);
162 }
163
164 KeyboardFocusManager::~KeyboardFocusManager()
165 {
166 }
167
168 void KeyboardFocusManager::GetConfigurationFromStyleManger()
169 {
170     Toolkit::StyleManager styleManager = Toolkit::StyleManager::Get();
171     if( styleManager )
172     {
173       Property::Map config = Toolkit::DevelStyleManager::GetConfigurations( styleManager );
174       mAlwaysShowIndicator = config["alwaysShowFocus"].Get<bool>();
175       mIsFocusIndicatorShown = static_cast<int>(mAlwaysShowIndicator);
176       mClearFocusOnTouch = mIsFocusIndicatorShown ? false : true;
177     }
178 }
179
180 bool KeyboardFocusManager::SetCurrentFocusActor( Actor actor )
181 {
182   DALI_ASSERT_DEBUG( !mIsWaitingKeyboardFocusChangeCommit && "Calling this function in the PreFocusChangeSignal callback?" );
183
184   if( mIsFocusIndicatorShown == -1 )
185   {
186     GetConfigurationFromStyleManger();
187   }
188
189   return DoSetCurrentFocusActor( actor );
190 }
191
192 bool KeyboardFocusManager::DoSetCurrentFocusActor( Actor actor )
193 {
194   bool success = false;
195
196   Actor currentFocusedActor = GetCurrentFocusActor();
197
198   // If developer set focus on same actor, doing nothing
199   if( actor == currentFocusedActor )
200   {
201     if( !actor )
202     {
203       return false;
204     }
205     return true;
206   }
207
208   // Check whether the actor is in the stage and is keyboard focusable.
209   if( actor && actor.IsKeyboardFocusable() && actor.OnStage() )
210   {
211     if( mIsFocusIndicatorShown && mEnableFocusIndicator )
212     {
213       actor.Add( GetFocusIndicatorActor() );
214     }
215
216     // Send notification for the change of focus actor
217     if( !mFocusChangedSignal.Empty() )
218     {
219       mFocusChangedSignal.Emit(currentFocusedActor, actor);
220     }
221
222     Toolkit::Control currentlyFocusedControl = Toolkit::Control::DownCast(currentFocusedActor);
223     if( currentlyFocusedControl )
224     {
225       // Do we need it to remember if it was previously DISABLED?
226       currentlyFocusedControl.SetProperty(DevelControl::Property::STATE, DevelControl::NORMAL );
227       currentlyFocusedControl.ClearKeyInputFocus();
228     }
229
230     DALI_LOG_INFO( gLogFilter, Debug::General, "[%s:%d] Focus Changed\n", __FUNCTION__, __LINE__);
231
232     // Save the current focused actor
233     mCurrentFocusActor = actor;
234
235     Toolkit::Control newlyFocusedControl = Toolkit::Control::DownCast(actor);
236     if( newlyFocusedControl )
237     {
238       newlyFocusedControl.SetProperty(DevelControl::Property::STATE, DevelControl::FOCUSED );
239       newlyFocusedControl.SetKeyInputFocus();
240     }
241
242     // Push Current Focused Actor to FocusHistory
243     mFocusHistory.push_back( actor );
244
245     // Delete first element before add new element when Stack is full.
246     if( mFocusHistory.size() > MAX_HISTORY_AMOUNT )
247     {
248        FocusStackIterator beginPos = mFocusHistory.begin();
249        mFocusHistory.erase( beginPos );
250     }
251
252     DALI_LOG_INFO( gLogFilter, Debug::General, "[%s:%d] SUCCEED\n", __FUNCTION__, __LINE__);
253     success = true;
254   }
255   else
256   {
257     DALI_LOG_WARNING("[%s:%d] FAILED\n", __FUNCTION__, __LINE__);
258   }
259
260   return success;
261 }
262
263 Actor KeyboardFocusManager::GetCurrentFocusActor()
264 {
265   Actor actor = mCurrentFocusActor.GetHandle();
266   if( actor && ! actor.OnStage() )
267   {
268     // If the actor has been removed from the stage, then it should not be focused
269
270     actor.Reset();
271     mCurrentFocusActor.Reset();
272   }
273   return actor;
274 }
275
276 Actor KeyboardFocusManager::GetCurrentFocusGroup()
277 {
278   return GetFocusGroup(GetCurrentFocusActor());
279 }
280
281 void KeyboardFocusManager::MoveFocusBackward()
282 {
283   // Find Pre Focused Actor when the list size is more than 1
284   if( mFocusHistory.size() > 1 )
285   {
286     // Delete current focused actor in history
287     mFocusHistory.pop_back();
288
289     // If pre-focused actors are not on stage or deleted, remove them in stack
290     while( mFocusHistory.size() > 0 )
291     {
292       // Get pre focused actor
293       Actor target = mFocusHistory[ mFocusHistory.size() -1 ].GetHandle();
294
295       // Impl of Actor is not null
296       if( target && target.OnStage() )
297       {
298         // Delete pre focused actor in history because it will pushed again by SetCurrentFocusActor()
299         mFocusHistory.pop_back();
300         SetCurrentFocusActor( target );
301         break;
302       }
303       else
304       {
305         // Target is empty handle or off stage. Erase from queue
306         mFocusHistory.pop_back();
307       }
308     }
309
310     // if there is no actor which can get focus, then push current focus actor in stack again
311     if( mFocusHistory.size() == 0 )
312     {
313       Actor currentFocusedActor = GetCurrentFocusActor();
314       mFocusHistory.push_back( currentFocusedActor );
315     }
316   }
317 }
318
319 bool KeyboardFocusManager::IsLayoutControl(Actor actor) const
320 {
321   Toolkit::Control control = Toolkit::Control::DownCast(actor);
322   return control && GetImplementation( control ).IsKeyboardNavigationSupported();
323 }
324
325 Toolkit::Control KeyboardFocusManager::GetParentLayoutControl(Actor actor) const
326 {
327   // Get the actor's parent layout control that supports two dimensional keyboard navigation
328   Actor rootActor;
329   Actor parent;
330   if(actor)
331   {
332     rootActor = Integration::SceneHolder::Get( actor ).GetRootLayer();
333     parent = actor.GetParent();
334   }
335
336   while( parent && !IsLayoutControl(parent) && parent != rootActor )
337   {
338     parent = parent.GetParent();
339   }
340
341   return Toolkit::Control::DownCast(parent);
342 }
343
344 bool KeyboardFocusManager::MoveFocus(Toolkit::Control::KeyboardFocus::Direction direction)
345 {
346   Actor currentFocusActor = GetCurrentFocusActor();
347
348   bool succeed = false;
349
350   // Go through the actor's hierarchy until we find a layout control that knows how to move the focus
351   Toolkit::Control parentLayoutControl = GetParentLayoutControl( currentFocusActor );
352   while( parentLayoutControl && !succeed )
353   {
354     succeed = DoMoveFocusWithinLayoutControl( parentLayoutControl, currentFocusActor, direction );
355     parentLayoutControl = GetParentLayoutControl( parentLayoutControl );
356   }
357
358   if( !succeed )
359   {
360     Actor nextFocusableActor;
361
362     Toolkit::Control currentFocusControl = Toolkit::Control::DownCast(currentFocusActor);
363
364     // If the current focused actor is a control, then find the next focusable actor via the focusable properties.
365     if( currentFocusControl )
366     {
367       int actorId = -1;
368       Property::Index index = Property::INVALID_INDEX;
369       Property::Value value;
370
371       // Find property index based upon focus direction
372       switch ( direction )
373       {
374         case Toolkit::Control::KeyboardFocus::LEFT:
375         {
376           index = Toolkit::DevelControl::Property::LEFT_FOCUSABLE_ACTOR_ID;
377           break;
378         }
379         case Toolkit::Control::KeyboardFocus::RIGHT:
380         {
381           index = Toolkit::DevelControl::Property::RIGHT_FOCUSABLE_ACTOR_ID;
382           break;
383         }
384         case Toolkit::Control::KeyboardFocus::UP:
385         {
386           index = Toolkit::DevelControl::Property::UP_FOCUSABLE_ACTOR_ID;
387           break;
388         }
389         case Toolkit::Control::KeyboardFocus::DOWN:
390         {
391           index = Toolkit::DevelControl::Property::DOWN_FOCUSABLE_ACTOR_ID;
392           break;
393         }
394         default:
395           break;
396       }
397
398       // If the focusable property is set then determine next focusable actor
399       if( index != Property::INVALID_INDEX)
400       {
401         value = currentFocusActor.GetProperty( index );
402         actorId = value.Get<int>();
403
404         // If actor's id is valid then find actor form actor's id. The actor should be on the stage.
405         if( actorId != -1 )
406         {
407           if( currentFocusActor.GetParent() )
408           {
409             nextFocusableActor = currentFocusActor.GetParent().FindChildById( actorId );
410           }
411
412           if( !nextFocusableActor )
413           {
414             nextFocusableActor = Integration::SceneHolder::Get( currentFocusActor ).GetRootLayer().FindChildById( actorId );
415           }
416         }
417       }
418     }
419
420     if( !nextFocusableActor )
421     {
422       // If the implementation of CustomAlgorithmInterface is provided then the PreFocusChangeSignal is no longer emitted.
423       if( mCustomAlgorithmInterface )
424       {
425         mIsWaitingKeyboardFocusChangeCommit = true;
426         nextFocusableActor = mCustomAlgorithmInterface->GetNextFocusableActor( currentFocusActor, Actor(), direction );
427         mIsWaitingKeyboardFocusChangeCommit = false;
428       }
429       else if( !mPreFocusChangeSignal.Empty() )
430       {
431         // Don't know how to move the focus further. The application needs to tell us which actor to move the focus to
432         mIsWaitingKeyboardFocusChangeCommit = true;
433         nextFocusableActor = mPreFocusChangeSignal.Emit( currentFocusActor, Actor(), direction );
434         mIsWaitingKeyboardFocusChangeCommit = false;
435       }
436     }
437
438     if( nextFocusableActor && nextFocusableActor.IsKeyboardFocusable() )
439     {
440       // Whether the next focusable actor is a layout control
441       if( IsLayoutControl( nextFocusableActor ) )
442       {
443         // If so, move the focus inside it.
444         Toolkit::Control layoutControl = Toolkit::Control::DownCast( nextFocusableActor) ;
445         succeed = DoMoveFocusWithinLayoutControl( layoutControl, currentFocusActor, direction );
446       }
447       else
448       {
449         // Otherwise, just set focus to the next focusable actor
450         succeed = SetCurrentFocusActor( nextFocusableActor );
451       }
452     }
453   }
454
455   return succeed;
456 }
457
458 bool KeyboardFocusManager::DoMoveFocusWithinLayoutControl(Toolkit::Control control, Actor actor, Toolkit::Control::KeyboardFocus::Direction direction)
459 {
460   // Ask the control for the next actor to focus
461   Actor nextFocusableActor = GetImplementation( control ).GetNextKeyboardFocusableActor(actor, direction, mFocusGroupLoopEnabled);
462   if(nextFocusableActor)
463   {
464     if(!nextFocusableActor.IsKeyboardFocusable())
465     {
466       // If the actor is not focusable, ask the same layout control for the next actor to focus
467       return DoMoveFocusWithinLayoutControl(control, nextFocusableActor, direction);
468     }
469     else
470     {
471       Actor currentFocusActor = GetCurrentFocusActor();
472       Actor committedFocusActor = nextFocusableActor;
473
474       // We will try to move the focus to the actor. Emit a signal to notify the proposed actor to focus
475       // Signal handler can check the proposed actor and return a different actor if it wishes.
476       if( !mPreFocusChangeSignal.Empty() )
477       {
478         mIsWaitingKeyboardFocusChangeCommit = true;
479         committedFocusActor = mPreFocusChangeSignal.Emit(currentFocusActor, nextFocusableActor, direction);
480         mIsWaitingKeyboardFocusChangeCommit = false;
481       }
482
483       if (committedFocusActor && committedFocusActor.IsKeyboardFocusable())
484       {
485         // Whether the commited focusable actor is a layout control
486         if(IsLayoutControl(committedFocusActor))
487         {
488           // If so, move the focus inside it.
489           Toolkit::Control layoutControl = Toolkit::Control::DownCast(committedFocusActor);
490           return DoMoveFocusWithinLayoutControl(layoutControl, currentFocusActor, direction);
491         }
492         else
493         {
494           // Otherwise, just set focus to the next focusable actor
495           if(committedFocusActor == nextFocusableActor)
496           {
497             // If the application hasn't changed our proposed actor, we informs the layout control we will
498             // move the focus to what the control returns. The control might wish to perform some actions
499             // before the focus is actually moved.
500             GetImplementation( control ).OnKeyboardFocusChangeCommitted( committedFocusActor );
501           }
502
503           return SetCurrentFocusActor(committedFocusActor);
504         }
505       }
506       else
507       {
508         return false;
509       }
510     }
511   }
512   else
513   {
514     // No more actor can be focused in the given direction within the same layout control.
515     return false;
516   }
517 }
518
519 bool KeyboardFocusManager::DoMoveFocusToNextFocusGroup(bool forward)
520 {
521   bool succeed = false;
522
523   // Get the parent layout control of the current focus group
524   Toolkit::Control parentLayoutControl = GetParentLayoutControl(GetCurrentFocusGroup());
525
526   while(parentLayoutControl && !succeed)
527   {
528     // If the current focus group has a parent layout control, we can probably automatically
529     // move the focus to the next focus group in the forward or backward direction.
530     Toolkit::Control::KeyboardFocus::Direction direction = forward ? Toolkit::Control::KeyboardFocus::RIGHT : Toolkit::Control::KeyboardFocus::LEFT;
531     succeed = DoMoveFocusWithinLayoutControl(parentLayoutControl, GetCurrentFocusActor(), direction);
532     parentLayoutControl = GetParentLayoutControl(parentLayoutControl);
533   }
534
535   if(!mFocusGroupChangedSignal.Empty())
536   {
537     // Emit a focus group changed signal. The applicaton can move the focus to a new focus group
538     mFocusGroupChangedSignal.Emit(GetCurrentFocusActor(), forward);
539   }
540
541   return succeed;
542 }
543
544 void KeyboardFocusManager::DoKeyboardEnter(Actor actor)
545 {
546   if( actor )
547   {
548     Toolkit::Control control = Toolkit::Control::DownCast( actor );
549     if( control )
550     {
551       // Notify the control that enter has been pressed on it.
552       GetImplementation( control ).KeyboardEnter();
553     }
554
555     // Send a notification for the actor.
556     if( !mFocusedActorEnterKeySignal.Empty() )
557     {
558       mFocusedActorEnterKeySignal.Emit( actor );
559     }
560   }
561 }
562
563 void KeyboardFocusManager::ClearFocus()
564 {
565   Actor actor = GetCurrentFocusActor();
566   if( actor )
567   {
568     if( mFocusIndicatorActor )
569     {
570       actor.Remove( mFocusIndicatorActor );
571     }
572
573     // Send notification for the change of focus actor
574     if( !mFocusChangedSignal.Empty() )
575     {
576       mFocusChangedSignal.Emit( actor, Actor() );
577     }
578
579     Toolkit::Control currentlyFocusedControl = Toolkit::Control::DownCast( actor );
580     if( currentlyFocusedControl )
581     {
582       currentlyFocusedControl.SetProperty( DevelControl::Property::STATE, DevelControl::NORMAL );
583       currentlyFocusedControl.ClearKeyInputFocus();
584     }
585   }
586
587   mCurrentFocusActor.Reset();
588   mIsFocusIndicatorShown = static_cast<int>(mAlwaysShowIndicator);
589 }
590
591 void KeyboardFocusManager::SetFocusGroupLoop(bool enabled)
592 {
593   mFocusGroupLoopEnabled = enabled;
594 }
595
596 bool KeyboardFocusManager::GetFocusGroupLoop() const
597 {
598   return mFocusGroupLoopEnabled;
599 }
600
601 void KeyboardFocusManager::SetAsFocusGroup(Actor actor, bool isFocusGroup)
602 {
603   if(actor)
604   {
605     // Create/Set focus group property.
606     actor.RegisterProperty( IS_FOCUS_GROUP_PROPERTY_NAME, isFocusGroup, Property::READ_WRITE );
607   }
608 }
609
610 bool KeyboardFocusManager::IsFocusGroup(Actor actor) const
611 {
612   // Check whether the actor is a focus group
613   bool isFocusGroup = false;
614
615   if(actor)
616   {
617     Property::Index propertyIsFocusGroup = actor.GetPropertyIndex(IS_FOCUS_GROUP_PROPERTY_NAME);
618     if(propertyIsFocusGroup != Property::INVALID_INDEX)
619     {
620       isFocusGroup = actor.GetProperty<bool>(propertyIsFocusGroup);
621     }
622   }
623
624   return isFocusGroup;
625 }
626
627 Actor KeyboardFocusManager::GetFocusGroup(Actor actor)
628 {
629   // Go through the actor's hierarchy to check which focus group the actor belongs to
630   while (actor && !IsFocusGroup(actor))
631   {
632     actor = actor.GetParent();
633   }
634
635   return actor;
636 }
637
638 void KeyboardFocusManager::SetFocusIndicatorActor(Actor indicator)
639 {
640   if(mFocusIndicatorActor != indicator)
641   {
642     Actor currentFocusActor = GetCurrentFocusActor();
643     if(currentFocusActor)
644     {
645       // The new focus indicator should be added to the current focused actor immediately
646       if(mFocusIndicatorActor)
647       {
648         currentFocusActor.Remove(mFocusIndicatorActor);
649       }
650
651       if(indicator)
652       {
653         currentFocusActor.Add(indicator);
654       }
655     }
656
657     mFocusIndicatorActor = indicator;
658   }
659 }
660
661 Actor KeyboardFocusManager::GetFocusIndicatorActor()
662 {
663   if( ! mFocusIndicatorActor )
664   {
665     // Create the default if it hasn't been set and one that's shared by all the keyboard focusable actors
666     mFocusIndicatorActor = Toolkit::ImageView::New( FOCUS_BORDER_IMAGE_PATH );
667
668     // Apply size constraint to the focus indicator
669     mFocusIndicatorActor.SetResizePolicy( ResizePolicy::FILL_TO_PARENT, Dimension::ALL_DIMENSIONS );
670   }
671
672   mFocusIndicatorActor.SetParentOrigin( ParentOrigin::CENTER );
673   mFocusIndicatorActor.SetAnchorPoint( AnchorPoint::CENTER );
674   mFocusIndicatorActor.SetPosition(0.0f, 0.0f);
675
676   return mFocusIndicatorActor;
677 }
678
679 void KeyboardFocusManager::OnKeyEvent(const KeyEvent& event)
680 {
681   AccessibilityAdaptor accessibilityAdaptor = AccessibilityAdaptor::Get();
682   bool isAccessibilityEnabled = accessibilityAdaptor.IsEnabled();
683
684   Toolkit::AccessibilityManager accessibilityManager = Toolkit::AccessibilityManager::Get();
685
686   std::string keyName = event.keyPressedName;
687
688   if( mIsFocusIndicatorShown == -1 )
689   {
690     GetConfigurationFromStyleManger();
691   }
692
693   bool isFocusStartableKey = false;
694
695   if(event.state == KeyEvent::Down)
696   {
697     if (keyName == "Left")
698     {
699       if(!isAccessibilityEnabled)
700       {
701         if(!mIsFocusIndicatorShown)
702         {
703           // Show focus indicator
704           mIsFocusIndicatorShown = 1;
705         }
706         else
707         {
708           // Move the focus towards left
709           MoveFocus(Toolkit::Control::KeyboardFocus::LEFT);
710         }
711
712         isFocusStartableKey = true;
713       }
714       else
715       {
716         // Move the accessibility focus backward
717         accessibilityManager.MoveFocusBackward();
718       }
719     }
720     else if (keyName == "Right")
721     {
722       if(!isAccessibilityEnabled)
723       {
724         if(!mIsFocusIndicatorShown)
725         {
726           // Show focus indicator
727           mIsFocusIndicatorShown = 1;
728         }
729         else
730         {
731           // Move the focus towards right
732           MoveFocus(Toolkit::Control::KeyboardFocus::RIGHT);
733         }
734       }
735       else
736       {
737         // Move the accessibility focus forward
738         accessibilityManager.MoveFocusForward();
739       }
740
741       isFocusStartableKey = true;
742     }
743     else if (keyName == "Up" && !isAccessibilityEnabled)
744     {
745       if(!mIsFocusIndicatorShown)
746       {
747         // Show focus indicator
748         mIsFocusIndicatorShown = 1;
749       }
750       else
751       {
752         // Move the focus towards up
753         MoveFocus(Toolkit::Control::KeyboardFocus::UP);
754       }
755
756       isFocusStartableKey = true;
757     }
758     else if (keyName == "Down" && !isAccessibilityEnabled)
759     {
760       if(!mIsFocusIndicatorShown)
761       {
762         // Show focus indicator
763         mIsFocusIndicatorShown = 1;
764       }
765       else
766       {
767         // Move the focus towards down
768         MoveFocus(Toolkit::Control::KeyboardFocus::DOWN);
769       }
770
771       isFocusStartableKey = true;
772     }
773     else if (keyName == "Prior" && !isAccessibilityEnabled)
774     {
775       if(!mIsFocusIndicatorShown)
776       {
777         // Show focus indicator
778         mIsFocusIndicatorShown = 1;
779       }
780       else
781       {
782         // Move the focus towards the previous page
783         MoveFocus(Toolkit::Control::KeyboardFocus::PAGE_UP);
784       }
785
786       isFocusStartableKey = true;
787     }
788     else if (keyName == "Next" && !isAccessibilityEnabled)
789     {
790       if(!mIsFocusIndicatorShown)
791       {
792         // Show focus indicator
793         mIsFocusIndicatorShown = 1;
794       }
795       else
796       {
797         // Move the focus towards the next page
798         MoveFocus(Toolkit::Control::KeyboardFocus::PAGE_DOWN);
799       }
800
801       isFocusStartableKey = true;
802     }
803     else if (keyName == "Tab" && !isAccessibilityEnabled)
804     {
805       if(!mIsFocusIndicatorShown)
806       {
807         // Show focus indicator
808         mIsFocusIndicatorShown = 1;
809       }
810       else
811       {
812         // "Tab" key changes the focus group in the forward direction and
813         // "Shift-Tab" key changes it in the backward direction.
814         DoMoveFocusToNextFocusGroup(!event.IsShiftModifier());
815       }
816
817       isFocusStartableKey = true;
818     }
819     else if (keyName == "space" && !isAccessibilityEnabled)
820     {
821       if(!mIsFocusIndicatorShown)
822       {
823         // Show focus indicator
824         mIsFocusIndicatorShown = 1;
825       }
826
827       isFocusStartableKey = true;
828     }
829     else if (keyName == "" && !isAccessibilityEnabled)
830     {
831       // Check the fake key event for evas-plugin case
832       if(!mIsFocusIndicatorShown)
833       {
834         // Show focus indicator
835         mIsFocusIndicatorShown = 1;
836       }
837
838       isFocusStartableKey = true;
839     }
840     else if (keyName == "Backspace" && !isAccessibilityEnabled)
841     {
842       // Emit signal to go back to the previous view???
843     }
844     else if (keyName == "Escape" && !isAccessibilityEnabled)
845     {
846     }
847   }
848   else if(event.state == KeyEvent::Up)
849   {
850     if (keyName == "Return")
851     {
852       if(!mIsFocusIndicatorShown && !isAccessibilityEnabled)
853       {
854         // Show focus indicator
855         mIsFocusIndicatorShown = 1;
856       }
857       else
858       {
859         // The focused actor has enter pressed on it
860         Actor actor;
861         if( !isAccessibilityEnabled )
862         {
863           actor = GetCurrentFocusActor();
864         }
865         else
866         {
867           actor = accessibilityManager.GetCurrentFocusActor();
868         }
869
870         if( actor )
871         {
872           DoKeyboardEnter( actor );
873         }
874       }
875
876       isFocusStartableKey = true;
877     }
878   }
879
880   if(isFocusStartableKey && mIsFocusIndicatorShown && !isAccessibilityEnabled)
881   {
882     Actor actor = GetCurrentFocusActor();
883     if( actor )
884     {
885       if( mEnableFocusIndicator )
886       {
887         // Make sure the focused actor is highlighted
888         actor.Add( GetFocusIndicatorActor() );
889       }
890     }
891     else
892     {
893       // No actor is focused but keyboard focus is activated by the key press
894       // Let's try to move the initial focus
895       MoveFocus(Toolkit::Control::KeyboardFocus::RIGHT);
896     }
897   }
898 }
899
900 void KeyboardFocusManager::OnTouch(const TouchData& touch)
901 {
902   // if mIsFocusIndicatorShown is -1, it means Configuration is not loaded.
903   // Try to load configuration.
904   if( mIsFocusIndicatorShown == -1 )
905   {
906     GetConfigurationFromStyleManger();
907   }
908
909   // Clear the focus when user touch the screen.
910   // We only do this on a Down event, otherwise the clear action may override a manually focused actor.
911   // If mClearFocusOnTouch is false, do not clear the focus even if user touch the screen.
912   if( (( touch.GetPointCount() < 1 ) || ( touch.GetState( 0 ) == PointState::DOWN )) && mClearFocusOnTouch )
913   {
914     ClearFocus();
915   }
916 }
917
918 Toolkit::KeyboardFocusManager::PreFocusChangeSignalType& KeyboardFocusManager::PreFocusChangeSignal()
919 {
920   return mPreFocusChangeSignal;
921 }
922
923 Toolkit::KeyboardFocusManager::FocusChangedSignalType& KeyboardFocusManager::FocusChangedSignal()
924 {
925   return mFocusChangedSignal;
926 }
927
928 Toolkit::KeyboardFocusManager::FocusGroupChangedSignalType& KeyboardFocusManager::FocusGroupChangedSignal()
929 {
930   return mFocusGroupChangedSignal;
931 }
932
933 Toolkit::KeyboardFocusManager::FocusedActorEnterKeySignalType& KeyboardFocusManager::FocusedActorEnterKeySignal()
934 {
935   return mFocusedActorEnterKeySignal;
936 }
937
938 bool KeyboardFocusManager::DoConnectSignal( BaseObject* object, ConnectionTrackerInterface* tracker, const std::string& signalName, FunctorDelegate* functor )
939 {
940   Dali::BaseHandle handle( object );
941
942   bool connected( true );
943   KeyboardFocusManager* manager = static_cast< KeyboardFocusManager* >( object ); // TypeRegistry guarantees that this is the correct type.
944
945   if( 0 == strcmp( signalName.c_str(), SIGNAL_PRE_FOCUS_CHANGE ) )
946   {
947     manager->PreFocusChangeSignal().Connect( tracker, functor );
948   }
949   else if( 0 == strcmp( signalName.c_str(), SIGNAL_FOCUS_CHANGED ) )
950   {
951     manager->FocusChangedSignal().Connect( tracker, functor );
952   }
953   else if( 0 == strcmp( signalName.c_str(), SIGNAL_FOCUS_GROUP_CHANGED ) )
954   {
955     manager->FocusGroupChangedSignal().Connect( tracker, functor );
956   }
957   else if( 0 == strcmp( signalName.c_str(), SIGNAL_FOCUSED_ACTOR_ENTER_KEY ) )
958   {
959     manager->FocusedActorEnterKeySignal().Connect( tracker, functor );
960   }
961   else
962   {
963     // signalName does not match any signal
964     connected = false;
965   }
966
967   return connected;
968 }
969
970 void KeyboardFocusManager::SetCustomAlgorithm(CustomAlgorithmInterface& interface)
971 {
972   mCustomAlgorithmInterface = &interface;
973 }
974
975 void KeyboardFocusManager::EnableFocusIndicator(bool enable)
976 {
977   if( !enable && mFocusIndicatorActor )
978   {
979     mFocusIndicatorActor.Unparent();
980   }
981
982   mEnableFocusIndicator = enable;
983 }
984
985 bool KeyboardFocusManager::IsFocusIndicatorEnabled() const
986 {
987   return mEnableFocusIndicator;
988 }
989
990 } // namespace Internal
991
992 } // namespace Toolkit
993
994 } // namespace Dali