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