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