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