44041ba8dde25c3c048994a6f207584817727d4e
[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   Constraint constraint = Constraint::New<Vector3>(Actor::SIZE,
485                                                    ParentSource(Actor::SIZE),
486                                                    EqualToConstraint());
487   focusIndicator.ApplyConstraint(constraint);
488
489   SetFocusIndicatorActor(focusIndicator);
490 }
491
492 void KeyboardFocusManager::OnPhysicalKeyboardStatusChanged(PhysicalKeyboard keyboard)
493 {
494   mIsKeyboardFocusEnabled = keyboard.IsAttached();
495
496   if(mIsKeyboardFocusEnabled)
497   {
498     // Show indicator when keyboard focus turned on if there is focused actor.
499     Actor actor = GetCurrentFocusActor();
500     if(actor)
501     {
502       if(mFocusIndicatorActor)
503       {
504         actor.Add(mFocusIndicatorActor);
505       }
506     }
507     mIsFocusIndicatorEnabled = true;
508   }
509   else
510   {
511     // Hide indicator when keyboard focus turned off
512     Actor actor = GetCurrentFocusActor();
513     if(actor)
514     {
515       actor.Remove(mFocusIndicatorActor);
516     }
517     mIsFocusIndicatorEnabled = false;
518   }
519 }
520
521 void KeyboardFocusManager::OnKeyEvent(const KeyEvent& event)
522 {
523   if(!mIsKeyboardFocusEnabled)
524   {
525     return;
526   }
527
528   AccessibilityManager accessibilityManager = AccessibilityManager::Get();
529   bool isAccessibilityEnabled = accessibilityManager.IsEnabled();
530
531   Toolkit::FocusManager accessibilityFocusManager = Toolkit::FocusManager::Get();
532
533   std::string keyName = event.keyPressedName;
534
535   bool isFocusStartableKey = false;
536
537   if(event.state == KeyEvent::Down)
538   {
539     if (keyName == "Left")
540     {
541       if(!isAccessibilityEnabled)
542       {
543         if(!mIsFocusIndicatorEnabled)
544         {
545           // Show focus indicator
546           mIsFocusIndicatorEnabled = true;
547         }
548         else
549         {
550           // Move the focus towards left
551           MoveFocus(Toolkit::Control::Left);
552         }
553
554         isFocusStartableKey = true;
555       }
556       else
557       {
558         // Move the accessibility focus backward
559         accessibilityFocusManager.MoveFocusBackward();
560       }
561     }
562     else if (keyName == "Right")
563     {
564       if(!isAccessibilityEnabled)
565       {
566         if(!mIsFocusIndicatorEnabled)
567         {
568           // Show focus indicator
569           mIsFocusIndicatorEnabled = true;
570         }
571         else
572         {
573           // Move the focus towards right
574           MoveFocus(Toolkit::Control::Right);
575         }
576       }
577       else
578       {
579         // Move the accessibility focus forward
580         accessibilityFocusManager.MoveFocusForward();
581       }
582
583       isFocusStartableKey = true;
584     }
585     else if (keyName == "Up" && !isAccessibilityEnabled)
586     {
587       if(!mIsFocusIndicatorEnabled)
588       {
589         // Show focus indicator
590         mIsFocusIndicatorEnabled = true;
591       }
592       else
593       {
594         // Move the focus towards up
595         MoveFocus(Toolkit::Control::Up);
596       }
597
598       isFocusStartableKey = true;
599     }
600     else if (keyName == "Down" && !isAccessibilityEnabled)
601     {
602       if(!mIsFocusIndicatorEnabled)
603       {
604         // Show focus indicator
605         mIsFocusIndicatorEnabled = true;
606       }
607       else
608       {
609         // Move the focus towards down
610         MoveFocus(Toolkit::Control::Down);
611       }
612
613       isFocusStartableKey = true;
614     }
615     else if (keyName == "Tab" && !isAccessibilityEnabled)
616     {
617       if(!mIsFocusIndicatorEnabled)
618       {
619         // Show focus indicator
620         mIsFocusIndicatorEnabled = true;
621       }
622       else
623       {
624         // "Tab" key changes the focus group in the forward direction and
625         // "Shift-Tab" key changes it in the backward direction.
626         DoMoveFocusToNextFocusGroup(!event.IsShiftModifier());
627       }
628
629       isFocusStartableKey = true;
630     }
631     else if (keyName == "space" && !isAccessibilityEnabled)
632     {
633       if(!mIsFocusIndicatorEnabled)
634       {
635         // Show focus indicator
636         mIsFocusIndicatorEnabled = true;
637       }
638
639       isFocusStartableKey = true;
640     }
641     else if (keyName == "" && !isAccessibilityEnabled)
642     {
643       // Check the fake key event for evas-plugin case
644       if(!mIsFocusIndicatorEnabled)
645       {
646         // Show focus indicator
647         mIsFocusIndicatorEnabled = true;
648       }
649
650       isFocusStartableKey = true;
651     }
652     else if (keyName == "Backspace" && !isAccessibilityEnabled)
653     {
654       // Emit signal to go back to the previous view???
655     }
656   }
657   else if(event.state == KeyEvent::Up)
658   {
659     if (keyName == "Return")
660     {
661       if(!mIsFocusIndicatorEnabled && !isAccessibilityEnabled)
662       {
663         // Show focus indicator
664         mIsFocusIndicatorEnabled = true;
665       }
666       else
667       {
668         // Activate the focused actor
669         Actor actor;
670         if(!isAccessibilityEnabled)
671         {
672           actor = GetCurrentFocusActor();
673         }
674         else
675         {
676           actor = accessibilityFocusManager.GetCurrentFocusActor();
677         }
678
679         if(actor)
680         {
681           DoActivate(actor);
682         }
683       }
684
685       isFocusStartableKey = true;
686     }
687   }
688
689   if(isFocusStartableKey && mIsFocusIndicatorEnabled && !isAccessibilityEnabled)
690   {
691     Actor actor = GetCurrentFocusActor();
692     if( !actor )
693     {
694       // No actor is focused but keyboard focus is activated by the key press
695       // Let's try to move the initial focus
696       MoveFocus(Toolkit::Control::Right);
697     }
698     else if(mFocusIndicatorActor)
699     {
700       // Make sure the focused actor is highlighted
701       actor.Add(mFocusIndicatorActor);
702     }
703   }
704 }
705
706 void KeyboardFocusManager::OnTouched(const TouchEvent& touchEvent)
707 {
708   // Clear the focus when user touch the screen
709   ClearFocus();
710 }
711
712 Toolkit::KeyboardFocusManager::PreFocusChangeSignalType& KeyboardFocusManager::PreFocusChangeSignal()
713 {
714   return mPreFocusChangeSignal;
715 }
716
717 Toolkit::KeyboardFocusManager::FocusChangedSignalType& KeyboardFocusManager::FocusChangedSignal()
718 {
719   return mFocusChangedSignal;
720 }
721
722 Toolkit::KeyboardFocusManager::FocusGroupChangedSignalType& KeyboardFocusManager::FocusGroupChangedSignal()
723 {
724   return mFocusGroupChangedSignal;
725 }
726
727 Toolkit::KeyboardFocusManager::FocusedActorActivatedSignalType& KeyboardFocusManager::FocusedActorActivatedSignal()
728 {
729   return mFocusedActorActivatedSignal;
730 }
731
732 bool KeyboardFocusManager::DoConnectSignal( BaseObject* object, ConnectionTrackerInterface* tracker, const std::string& signalName, FunctorDelegate* functor )
733 {
734   Dali::BaseHandle handle( object );
735
736   bool connected( true );
737   KeyboardFocusManager* manager = dynamic_cast<KeyboardFocusManager*>( object );
738
739   if( 0 == strcmp( signalName.c_str(), SIGNAL_PRE_FOCUS_CHANGE ) )
740   {
741     manager->PreFocusChangeSignal().Connect( tracker, functor );
742   }
743   if( 0 == strcmp( signalName.c_str(), SIGNAL_FOCUS_CHANGED ) )
744   {
745     manager->FocusChangedSignal().Connect( tracker, functor );
746   }
747   if( 0 == strcmp( signalName.c_str(), SIGNAL_FOCUS_GROUP_CHANGED ) )
748   {
749     manager->FocusGroupChangedSignal().Connect( tracker, functor );
750   }
751   else if( 0 == strcmp( signalName.c_str(), SIGNAL_FOCUSED_ACTOR_ACTIVATED ) )
752   {
753     manager->FocusedActorActivatedSignal().Connect( tracker, functor );
754   }
755   else
756   {
757     // signalName does not match any signal
758     connected = false;
759   }
760
761   return connected;
762 }
763
764 } // namespace Internal
765
766 } // namespace Toolkit
767
768 } // namespace Dali