Merge "Typo fixed in Control implementation doc." into tizen
[platform/core/uifw/dali-toolkit.git] / dali-toolkit / internal / focus-manager / keyboard-focus-manager-impl.cpp
1 /*
2  * Copyright (c) 2014 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 <dali/public-api/actors/layer.h>
23 #include <dali/public-api/adaptor-framework/accessibility-manager.h>
24 #include <dali/public-api/adaptor-framework/singleton-service.h>
25 #include <dali/public-api/animation/constraints.h>
26 #include <dali/public-api/common/stage.h>
27 #include <dali/public-api/events/key-event.h>
28 #include <dali/public-api/object/type-registry.h>
29 #include <dali/public-api/images/resource-image.h>
30
31 // INTERNAL INCLUDES
32 #include <dali-toolkit/public-api/controls/control.h>
33 #include <dali-toolkit/public-api/controls/control-impl.h>
34 #include <dali-toolkit/public-api/focus-manager/focus-manager.h>
35 #include <dali-toolkit/public-api/focus-manager/keyinput-focus-manager.h>
36 #include <dali/integration-api/debug.h>
37
38 namespace Dali
39 {
40
41 namespace Toolkit
42 {
43
44 namespace Internal
45 {
46
47 namespace // unnamed namespace
48 {
49
50 // Signals
51
52 const char* const SIGNAL_PRE_FOCUS_CHANGE =        "keyboard-pre-focus-change";
53 const char* const SIGNAL_FOCUS_CHANGED =           "keyboard-focus-changed";
54 const char* const SIGNAL_FOCUS_GROUP_CHANGED =     "keyboard-focus-group-changed";
55 const char* const SIGNAL_FOCUSED_ACTOR_ACTIVATED = "keyboard-focused-actor-activated";
56
57 #if defined(DEBUG_ENABLED)
58 Debug::Filter* gLogFilter = Debug::Filter::New(Debug::NoLogging, false, "LOG_KEYBOARD_FOCUS_MANAGER");
59 #endif
60
61 const std::string IS_FOCUS_GROUP_PROPERTY_NAME("is-keyboard-focus-group"); // This property will be replaced by a flag in Control.
62
63 const char* FOCUS_BORDER_IMAGE_PATH = DALI_IMAGE_DIR "keyboard_focus.png";
64 const Vector4 FOCUS_BORDER_IMAGE_BORDER = Vector4(7.0f, 7.0f, 7.0f, 7.0f);
65
66 BaseHandle Create()
67 {
68   BaseHandle handle = KeyboardFocusManager::Get();
69
70   if ( !handle )
71   {
72     SingletonService singletonService( SingletonService::Get() );
73     if ( singletonService )
74     {
75       Toolkit::KeyboardFocusManager manager = Toolkit::KeyboardFocusManager( new Internal::KeyboardFocusManager() );
76       singletonService.Register( typeid( manager ), manager );
77       handle = manager;
78     }
79   }
80
81   return handle;
82 }
83
84 TypeRegistration KEYBOARD_FOCUS_MANAGER_TYPE( typeid(Dali::Toolkit::KeyboardFocusManager), typeid(Dali::BaseHandle), Create, true /* Create instance at startup */ );
85
86 SignalConnectorType signalConnector1( KEYBOARD_FOCUS_MANAGER_TYPE, SIGNAL_PRE_FOCUS_CHANGE , &KeyboardFocusManager::DoConnectSignal );
87 SignalConnectorType signalConnector2( KEYBOARD_FOCUS_MANAGER_TYPE, SIGNAL_FOCUS_CHANGED , &KeyboardFocusManager::DoConnectSignal );
88 SignalConnectorType signalConnector3( KEYBOARD_FOCUS_MANAGER_TYPE, SIGNAL_FOCUS_GROUP_CHANGED , &KeyboardFocusManager::DoConnectSignal );
89 SignalConnectorType signalConnector4( KEYBOARD_FOCUS_MANAGER_TYPE, SIGNAL_FOCUSED_ACTOR_ACTIVATED , &KeyboardFocusManager::DoConnectSignal );
90
91 } // unnamed namespace
92
93 Toolkit::KeyboardFocusManager KeyboardFocusManager::Get()
94 {
95   Toolkit::KeyboardFocusManager manager;
96
97   SingletonService singletonService( SingletonService::Get() );
98   if ( singletonService )
99   {
100     // Check whether the keyboard focus manager is already created
101     Dali::BaseHandle handle = singletonService.GetSingleton( typeid( Toolkit::KeyboardFocusManager ) );
102     if(handle)
103     {
104       // If so, downcast the handle of singleton to keyboard focus manager
105       manager = Toolkit::KeyboardFocusManager( dynamic_cast< KeyboardFocusManager* >( handle.GetObjectPtr() ) );
106     }
107   }
108
109   return manager;
110 }
111
112 KeyboardFocusManager::KeyboardFocusManager()
113 : mCurrentFocusActor(0),
114   mFocusIndicatorActor(Actor()),
115   mFocusGroupLoopEnabled(false),
116   mIsKeyboardFocusEnabled(false),
117   mIsFocusIndicatorEnabled(false),
118   mIsWaitingKeyboardFocusChangeCommit(false),
119   mSlotDelegate(this)
120 {
121   CreateDefaultFocusIndicatorActor();
122
123   OnPhysicalKeyboardStatusChanged(PhysicalKeyboard::Get());
124
125   Toolkit::KeyInputFocusManager::Get().UnhandledKeyEventSignal().Connect(mSlotDelegate, &KeyboardFocusManager::OnKeyEvent);
126   Stage::GetCurrent().TouchedSignal().Connect(mSlotDelegate, &KeyboardFocusManager::OnTouched);
127   PhysicalKeyboard::Get().StatusChangedSignal().Connect(mSlotDelegate, &KeyboardFocusManager::OnPhysicalKeyboardStatusChanged);
128 }
129
130 KeyboardFocusManager::~KeyboardFocusManager()
131 {
132 }
133
134 bool KeyboardFocusManager::SetCurrentFocusActor(Actor actor)
135 {
136   DALI_ASSERT_DEBUG( !mIsWaitingKeyboardFocusChangeCommit && "Calling this function in the PreFocusChangeSignal callback?" );
137
138   if(actor)
139   {
140     return DoSetCurrentFocusActor(actor.GetId());
141   }
142
143   return false;
144 }
145
146 bool KeyboardFocusManager::DoSetCurrentFocusActor(const unsigned int actorID)
147 {
148   Actor rootActor = Stage::GetCurrent().GetRootLayer();
149   Actor actor = rootActor.FindChildById(actorID);
150
151   // Check whether the actor is in the stage
152   if(actor)
153   {
154     // Set the focus only when the actor is keyboard focusable
155     if(actor.IsKeyboardFocusable())
156     {
157       // Draw the focus indicator upon the focused actor
158       if(mIsFocusIndicatorEnabled && mFocusIndicatorActor)
159       {
160         actor.Add(mFocusIndicatorActor);
161       }
162
163       // Send notification for the change of focus actor
164       if( !mFocusChangedSignal.Empty() )
165       {
166         mFocusChangedSignal.Emit(GetCurrentFocusActor(), actor);
167       }
168
169       DALI_LOG_INFO( gLogFilter, Debug::General, "[%s:%d] Focus Changed\n", __FUNCTION__, __LINE__);
170
171       // Save the current focused actor
172       mCurrentFocusActor = actorID;
173
174       // Move the accessibility focus to the same actor
175 //      Toolkit::FocusManager focusManager = Toolkit::FocusManager::Get();
176 //      focusManager.SetCurrentFocusActor(actor);
177
178       DALI_LOG_INFO( gLogFilter, Debug::General, "[%s:%d] SUCCEED\n", __FUNCTION__, __LINE__);
179       return true;
180     }
181   }
182
183   DALI_LOG_WARNING("[%s:%d] FAILED\n", __FUNCTION__, __LINE__);
184   return false;
185 }
186
187 Actor KeyboardFocusManager::GetCurrentFocusActor()
188 {
189   Actor rootActor = Stage::GetCurrent().GetRootLayer();
190   return rootActor.FindChildById(mCurrentFocusActor);
191 }
192
193 Actor KeyboardFocusManager::GetCurrentFocusGroup()
194 {
195   return GetFocusGroup(GetCurrentFocusActor());
196 }
197
198 bool KeyboardFocusManager::IsLayoutControl(Actor actor) const
199 {
200   Toolkit::Control control = Toolkit::Control::DownCast(actor);
201   return control && control.GetImplementation().IsKeyboardNavigationSupported();
202 }
203
204 Toolkit::Control KeyboardFocusManager::GetParentLayoutControl(Actor actor) const
205 {
206   // Get the actor's parent layout control that supports two dimensional keyboard navigation
207   Actor rootActor = Stage::GetCurrent().GetRootLayer();
208   Actor parent;
209   if(actor)
210   {
211     parent = actor.GetParent();
212   }
213
214   while( parent && !IsLayoutControl(parent) && parent != rootActor )
215   {
216     parent = parent.GetParent();
217   }
218
219   return Toolkit::Control::DownCast(parent);
220 }
221
222 bool KeyboardFocusManager::MoveFocus(Toolkit::Control::KeyboardFocusNavigationDirection direction)
223 {
224   Actor currentFocusActor = GetCurrentFocusActor();
225
226   bool succeed = false;
227
228   // Go through the actor's hierarchy until we find a layout control that knows how to move the focus
229   Toolkit::Control parentLayoutControl = GetParentLayoutControl(currentFocusActor);
230   while(parentLayoutControl && !succeed)
231   {
232     succeed = DoMoveFocusWithinLayoutControl(parentLayoutControl, currentFocusActor, direction);
233     parentLayoutControl = GetParentLayoutControl(parentLayoutControl);
234   }
235
236   if(!succeed && !mPreFocusChangeSignal.Empty())
237   {
238     // Don't know how to move the focus further. The application needs to tell us which actor to move the focus to
239     mIsWaitingKeyboardFocusChangeCommit = true;
240     Actor nextFocusableActor = mPreFocusChangeSignal.Emit(currentFocusActor, Actor(), direction);
241     mIsWaitingKeyboardFocusChangeCommit = false;
242
243     if ( nextFocusableActor && nextFocusableActor.IsKeyboardFocusable() )
244     {
245       // Whether the next focusable actor is a layout control
246       if(IsLayoutControl(nextFocusableActor))
247       {
248         // If so, move the focus inside it.
249         Toolkit::Control layoutControl = Toolkit::Control::DownCast(nextFocusableActor);
250         succeed = DoMoveFocusWithinLayoutControl(layoutControl, currentFocusActor, direction);
251       }
252       else
253       {
254         // Otherwise, just set focus to the next focusable actor
255         succeed = SetCurrentFocusActor(nextFocusableActor);
256       }
257     }
258   }
259
260   return succeed;
261 }
262
263 bool KeyboardFocusManager::DoMoveFocusWithinLayoutControl(Toolkit::Control control, Actor actor, Toolkit::Control::KeyboardFocusNavigationDirection direction)
264 {
265   // Ask the control for the next actor to focus
266   Actor nextFocusableActor = control.GetImplementation().GetNextKeyboardFocusableActor(actor, direction, mFocusGroupLoopEnabled);
267   if(nextFocusableActor)
268   {
269     if(!nextFocusableActor.IsKeyboardFocusable())
270     {
271       // If the actor is not focusable, ask the same layout control for the next actor to focus
272       return DoMoveFocusWithinLayoutControl(control, nextFocusableActor, direction);
273     }
274     else
275     {
276       Actor currentFocusActor = GetCurrentFocusActor();
277       Actor committedFocusActor = nextFocusableActor;
278
279       // We will try to move the focus to the actor. Emit a signal to notify the proposed actor to focus
280       // Signal handler can check the proposed actor and return a different actor if it wishes.
281       if( !mPreFocusChangeSignal.Empty() )
282       {
283         mIsWaitingKeyboardFocusChangeCommit = true;
284         committedFocusActor = mPreFocusChangeSignal.Emit(currentFocusActor, nextFocusableActor, direction);
285         mIsWaitingKeyboardFocusChangeCommit = false;
286       }
287
288       if (committedFocusActor && committedFocusActor.IsKeyboardFocusable())
289       {
290         // Whether the commited focusable actor is a layout control
291         if(IsLayoutControl(committedFocusActor))
292         {
293           // If so, move the focus inside it.
294           Toolkit::Control layoutControl = Toolkit::Control::DownCast(committedFocusActor);
295           return DoMoveFocusWithinLayoutControl(layoutControl, currentFocusActor, direction);
296         }
297         else
298         {
299           // Otherwise, just set focus to the next focusable actor
300           if(committedFocusActor == nextFocusableActor)
301           {
302             // If the application hasn't changed our proposed actor, we informs the layout control we will
303             // move the focus to what the control returns. The control might wish to perform some actions
304             // before the focus is actually moved.
305             control.GetImplementation().OnKeyboardFocusChangeCommitted(committedFocusActor);
306           }
307
308           return SetCurrentFocusActor(committedFocusActor);
309         }
310       }
311       else
312       {
313         return false;
314       }
315     }
316   }
317   else
318   {
319     // No more actor can be focused in the given direction within the same layout control.
320     return false;
321   }
322 }
323
324 bool KeyboardFocusManager::DoMoveFocusToNextFocusGroup(bool forward)
325 {
326   bool succeed = false;
327
328   // Get the parent layout control of the current focus group
329   Toolkit::Control parentLayoutControl = GetParentLayoutControl(GetCurrentFocusGroup());
330
331   while(parentLayoutControl && !succeed)
332   {
333     // If the current focus group has a parent layout control, we can probably automatically
334     // move the focus to the next focus group in the forward or backward direction.
335     Toolkit::Control::KeyboardFocusNavigationDirection direction = forward ? Toolkit::Control::Right : Toolkit::Control::Left;
336     succeed = DoMoveFocusWithinLayoutControl(parentLayoutControl, GetCurrentFocusActor(), direction);
337     parentLayoutControl = GetParentLayoutControl(parentLayoutControl);
338   }
339
340   if(!mFocusGroupChangedSignal.Empty())
341   {
342     // Emit a focus group changed signal. The applicaton can move the focus to a new focus group
343     mFocusGroupChangedSignal.Emit(GetCurrentFocusActor(), forward);
344   }
345
346   return succeed;
347 }
348
349 void KeyboardFocusManager::DoActivate(Actor actor)
350 {
351   if(actor)
352   {
353     Toolkit::Control control = Toolkit::Control::DownCast(actor);
354     if(control)
355     {
356       // Notify the control that it is activated
357       control.GetImplementation().Activate();
358     }
359
360     // Send notification for the activation of focused actor
361     if( !mFocusedActorActivatedSignal.Empty() )
362     {
363       mFocusedActorActivatedSignal.Emit(actor);
364     }
365   }
366 }
367
368 void KeyboardFocusManager::ClearFocus()
369 {
370   Actor actor = GetCurrentFocusActor();
371   if(actor)
372   {
373     if(mFocusIndicatorActor)
374     {
375       actor.Remove(mFocusIndicatorActor);
376     }
377
378     // Send notification for the change of focus actor
379     if( !mFocusChangedSignal.Empty() )
380     {
381       mFocusChangedSignal.Emit(actor, Actor());
382     }
383   }
384
385   mCurrentFocusActor = 0;
386   mIsFocusIndicatorEnabled = false;
387 }
388
389 void KeyboardFocusManager::SetFocusGroupLoop(bool enabled)
390 {
391   mFocusGroupLoopEnabled = enabled;
392 }
393
394 bool KeyboardFocusManager::GetFocusGroupLoop() const
395 {
396   return mFocusGroupLoopEnabled;
397 }
398
399 void KeyboardFocusManager::SetAsFocusGroup(Actor actor, bool isFocusGroup)
400 {
401   if(actor)
402   {
403     // Create focus group property if not already created.
404     Property::Index propertyIsFocusGroup = actor.GetPropertyIndex(IS_FOCUS_GROUP_PROPERTY_NAME);
405     if(propertyIsFocusGroup == Property::INVALID_INDEX)
406     {
407       actor.RegisterProperty(IS_FOCUS_GROUP_PROPERTY_NAME, isFocusGroup);
408     }
409     else
410     {
411       actor.SetProperty(propertyIsFocusGroup, isFocusGroup);
412     }
413   }
414 }
415
416 bool KeyboardFocusManager::IsFocusGroup(Actor actor) const
417 {
418   // Check whether the actor is a focus group
419   bool isFocusGroup = false;
420
421   if(actor)
422   {
423     Property::Index propertyIsFocusGroup = actor.GetPropertyIndex(IS_FOCUS_GROUP_PROPERTY_NAME);
424     if(propertyIsFocusGroup != Property::INVALID_INDEX)
425     {
426       isFocusGroup = actor.GetProperty<bool>(propertyIsFocusGroup);
427     }
428   }
429
430   return isFocusGroup;
431 }
432
433 Actor KeyboardFocusManager::GetFocusGroup(Actor actor)
434 {
435   // Go through the actor's hierarchy to check which focus group the actor belongs to
436   while (actor && !IsFocusGroup(actor))
437   {
438     actor = actor.GetParent();
439   }
440
441   return actor;
442 }
443
444 void KeyboardFocusManager::SetFocusIndicatorActor(Actor indicator)
445 {
446   if(mFocusIndicatorActor != indicator)
447   {
448     Actor currentFocusActor = GetCurrentFocusActor();
449     if(currentFocusActor)
450     {
451       // The new focus indicator should be added to the current focused actor immediately
452       if(mFocusIndicatorActor)
453       {
454         currentFocusActor.Remove(mFocusIndicatorActor);
455       }
456
457       if(indicator)
458       {
459         currentFocusActor.Add(indicator);
460       }
461     }
462
463     mFocusIndicatorActor = indicator;
464   }
465 }
466
467 Actor KeyboardFocusManager::GetFocusIndicatorActor()
468 {
469   return mFocusIndicatorActor;
470 }
471
472 void KeyboardFocusManager::CreateDefaultFocusIndicatorActor()
473 {
474   // Create a focus indicator actor shared by all the keyboard focusable actors
475   Image borderImage = ResourceImage::New(FOCUS_BORDER_IMAGE_PATH);
476
477   ImageActor focusIndicator = ImageActor::New(borderImage);
478   focusIndicator.SetPositionInheritanceMode( Dali::USE_PARENT_POSITION_PLUS_LOCAL_POSITION );
479   focusIndicator.SetStyle( ImageActor::STYLE_NINE_PATCH );
480   focusIndicator.SetNinePatchBorder(FOCUS_BORDER_IMAGE_BORDER);
481   focusIndicator.SetPosition(Vector3(0.0f, 0.0f, 1.0f));
482
483   // Apply size constraint to the focus indicator
484   focusIndicator.SetSizeMode( SIZE_EQUAL_TO_PARENT );
485
486   SetFocusIndicatorActor(focusIndicator);
487 }
488
489 void KeyboardFocusManager::OnPhysicalKeyboardStatusChanged(PhysicalKeyboard keyboard)
490 {
491   mIsKeyboardFocusEnabled = keyboard.IsAttached();
492
493   if(mIsKeyboardFocusEnabled)
494   {
495     // Show indicator when keyboard focus turned on if there is focused actor.
496     Actor actor = GetCurrentFocusActor();
497     if(actor)
498     {
499       if(mFocusIndicatorActor)
500       {
501         actor.Add(mFocusIndicatorActor);
502       }
503     }
504     mIsFocusIndicatorEnabled = true;
505   }
506   else
507   {
508     // Hide indicator when keyboard focus turned off
509     Actor actor = GetCurrentFocusActor();
510     if(actor)
511     {
512       actor.Remove(mFocusIndicatorActor);
513     }
514     mIsFocusIndicatorEnabled = false;
515   }
516 }
517
518 void KeyboardFocusManager::OnKeyEvent(const KeyEvent& event)
519 {
520   if(!mIsKeyboardFocusEnabled)
521   {
522     return;
523   }
524
525   AccessibilityManager accessibilityManager = AccessibilityManager::Get();
526   bool isAccessibilityEnabled = accessibilityManager.IsEnabled();
527
528   Toolkit::FocusManager accessibilityFocusManager = Toolkit::FocusManager::Get();
529
530   std::string keyName = event.keyPressedName;
531
532   bool isFocusStartableKey = false;
533
534   if(event.state == KeyEvent::Down)
535   {
536     if (keyName == "Left")
537     {
538       if(!isAccessibilityEnabled)
539       {
540         if(!mIsFocusIndicatorEnabled)
541         {
542           // Show focus indicator
543           mIsFocusIndicatorEnabled = true;
544         }
545         else
546         {
547           // Move the focus towards left
548           MoveFocus(Toolkit::Control::Left);
549         }
550
551         isFocusStartableKey = true;
552       }
553       else
554       {
555         // Move the accessibility focus backward
556         accessibilityFocusManager.MoveFocusBackward();
557       }
558     }
559     else if (keyName == "Right")
560     {
561       if(!isAccessibilityEnabled)
562       {
563         if(!mIsFocusIndicatorEnabled)
564         {
565           // Show focus indicator
566           mIsFocusIndicatorEnabled = true;
567         }
568         else
569         {
570           // Move the focus towards right
571           MoveFocus(Toolkit::Control::Right);
572         }
573       }
574       else
575       {
576         // Move the accessibility focus forward
577         accessibilityFocusManager.MoveFocusForward();
578       }
579
580       isFocusStartableKey = true;
581     }
582     else if (keyName == "Up" && !isAccessibilityEnabled)
583     {
584       if(!mIsFocusIndicatorEnabled)
585       {
586         // Show focus indicator
587         mIsFocusIndicatorEnabled = true;
588       }
589       else
590       {
591         // Move the focus towards up
592         MoveFocus(Toolkit::Control::Up);
593       }
594
595       isFocusStartableKey = true;
596     }
597     else if (keyName == "Down" && !isAccessibilityEnabled)
598     {
599       if(!mIsFocusIndicatorEnabled)
600       {
601         // Show focus indicator
602         mIsFocusIndicatorEnabled = true;
603       }
604       else
605       {
606         // Move the focus towards down
607         MoveFocus(Toolkit::Control::Down);
608       }
609
610       isFocusStartableKey = true;
611     }
612     else if (keyName == "Tab" && !isAccessibilityEnabled)
613     {
614       if(!mIsFocusIndicatorEnabled)
615       {
616         // Show focus indicator
617         mIsFocusIndicatorEnabled = true;
618       }
619       else
620       {
621         // "Tab" key changes the focus group in the forward direction and
622         // "Shift-Tab" key changes it in the backward direction.
623         DoMoveFocusToNextFocusGroup(!event.IsShiftModifier());
624       }
625
626       isFocusStartableKey = true;
627     }
628     else if (keyName == "space" && !isAccessibilityEnabled)
629     {
630       if(!mIsFocusIndicatorEnabled)
631       {
632         // Show focus indicator
633         mIsFocusIndicatorEnabled = true;
634       }
635
636       isFocusStartableKey = true;
637     }
638     else if (keyName == "" && !isAccessibilityEnabled)
639     {
640       // Check the fake key event for evas-plugin case
641       if(!mIsFocusIndicatorEnabled)
642       {
643         // Show focus indicator
644         mIsFocusIndicatorEnabled = true;
645       }
646
647       isFocusStartableKey = true;
648     }
649     else if (keyName == "Backspace" && !isAccessibilityEnabled)
650     {
651       // Emit signal to go back to the previous view???
652     }
653   }
654   else if(event.state == KeyEvent::Up)
655   {
656     if (keyName == "Return")
657     {
658       if(!mIsFocusIndicatorEnabled && !isAccessibilityEnabled)
659       {
660         // Show focus indicator
661         mIsFocusIndicatorEnabled = true;
662       }
663       else
664       {
665         // Activate the focused actor
666         Actor actor;
667         if(!isAccessibilityEnabled)
668         {
669           actor = GetCurrentFocusActor();
670         }
671         else
672         {
673           actor = accessibilityFocusManager.GetCurrentFocusActor();
674         }
675
676         if(actor)
677         {
678           DoActivate(actor);
679         }
680       }
681
682       isFocusStartableKey = true;
683     }
684   }
685
686   if(isFocusStartableKey && mIsFocusIndicatorEnabled && !isAccessibilityEnabled)
687   {
688     Actor actor = GetCurrentFocusActor();
689     if( !actor )
690     {
691       // No actor is focused but keyboard focus is activated by the key press
692       // Let's try to move the initial focus
693       MoveFocus(Toolkit::Control::Right);
694     }
695     else if(mFocusIndicatorActor)
696     {
697       // Make sure the focused actor is highlighted
698       actor.Add(mFocusIndicatorActor);
699     }
700   }
701 }
702
703 void KeyboardFocusManager::OnTouched(const TouchEvent& touchEvent)
704 {
705   // Clear the focus when user touch the screen
706   ClearFocus();
707 }
708
709 Toolkit::KeyboardFocusManager::PreFocusChangeSignalType& KeyboardFocusManager::PreFocusChangeSignal()
710 {
711   return mPreFocusChangeSignal;
712 }
713
714 Toolkit::KeyboardFocusManager::FocusChangedSignalType& KeyboardFocusManager::FocusChangedSignal()
715 {
716   return mFocusChangedSignal;
717 }
718
719 Toolkit::KeyboardFocusManager::FocusGroupChangedSignalType& KeyboardFocusManager::FocusGroupChangedSignal()
720 {
721   return mFocusGroupChangedSignal;
722 }
723
724 Toolkit::KeyboardFocusManager::FocusedActorActivatedSignalType& KeyboardFocusManager::FocusedActorActivatedSignal()
725 {
726   return mFocusedActorActivatedSignal;
727 }
728
729 bool KeyboardFocusManager::DoConnectSignal( BaseObject* object, ConnectionTrackerInterface* tracker, const std::string& signalName, FunctorDelegate* functor )
730 {
731   Dali::BaseHandle handle( object );
732
733   bool connected( true );
734   KeyboardFocusManager* manager = dynamic_cast<KeyboardFocusManager*>( object );
735
736   if( 0 == strcmp( signalName.c_str(), SIGNAL_PRE_FOCUS_CHANGE ) )
737   {
738     manager->PreFocusChangeSignal().Connect( tracker, functor );
739   }
740   if( 0 == strcmp( signalName.c_str(), SIGNAL_FOCUS_CHANGED ) )
741   {
742     manager->FocusChangedSignal().Connect( tracker, functor );
743   }
744   if( 0 == strcmp( signalName.c_str(), SIGNAL_FOCUS_GROUP_CHANGED ) )
745   {
746     manager->FocusGroupChangedSignal().Connect( tracker, functor );
747   }
748   else if( 0 == strcmp( signalName.c_str(), SIGNAL_FOCUSED_ACTOR_ACTIVATED ) )
749   {
750     manager->FocusedActorActivatedSignal().Connect( tracker, functor );
751   }
752   else
753   {
754     // signalName does not match any signal
755     connected = false;
756   }
757
758   return connected;
759 }
760
761 } // namespace Internal
762
763 } // namespace Toolkit
764
765 } // namespace Dali