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