Merge "(Control) Remove virtual inlines, better arrange source file & remove one...
[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( !mFocusChangedSignalV2.Empty() )
151       {
152         mFocusChangedSignalV2.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 && !mPreFocusChangeSignalV2.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 = mPreFocusChangeSignalV2.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( !mPreFocusChangeSignalV2.Empty() )
268       {
269         mIsWaitingKeyboardFocusChangeCommit = true;
270         committedFocusActor = mPreFocusChangeSignalV2.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(!mFocusGroupChangedSignalV2.Empty())
327   {
328     // Emit a focus group changed signal. The applicaton can move the focus to a new focus group
329     mFocusGroupChangedSignalV2.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( !mFocusedActorActivatedSignalV2.Empty() )
348     {
349       mFocusedActorActivatedSignalV2.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( !mFocusChangedSignalV2.Empty() )
366     {
367       mFocusChangedSignalV2.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         isFocusStartableKey = true;
564       }
565       else
566       {
567         // Move the accessibility focus forward
568         accessibilityFocusManager.MoveFocusForward();
569       }
570
571       isFocusStartableKey = true;
572     }
573     else if (keyName == "Up" && !isAccessibilityEnabled)
574     {
575       if(!mIsFocusIndicatorEnabled)
576       {
577         // Show focus indicator
578         mIsFocusIndicatorEnabled = true;
579       }
580       else
581       {
582         // Move the focus towards up
583         MoveFocus(Toolkit::Control::Up);
584       }
585
586       isFocusStartableKey = true;
587     }
588     else if (keyName == "Down" && !isAccessibilityEnabled)
589     {
590       if(!mIsFocusIndicatorEnabled)
591       {
592         // Show focus indicator
593         mIsFocusIndicatorEnabled = true;
594       }
595       else
596       {
597         // Move the focus towards down
598         MoveFocus(Toolkit::Control::Down);
599       }
600
601       isFocusStartableKey = true;
602     }
603     else if (keyName == "Tab" && !isAccessibilityEnabled)
604     {
605       if(!mIsFocusIndicatorEnabled)
606       {
607         // Show focus indicator
608         mIsFocusIndicatorEnabled = true;
609       }
610       else
611       {
612         // "Tab" key changes the focus group in the forward direction and
613         // "Shift-Tab" key changes it in the backward direction.
614         DoMoveFocusToNextFocusGroup(!event.IsShiftModifier());
615       }
616
617       isFocusStartableKey = true;
618     }
619     else if (keyName == "space" && !isAccessibilityEnabled)
620     {
621       if(!mIsFocusIndicatorEnabled)
622       {
623         // Show focus indicator
624         mIsFocusIndicatorEnabled = true;
625       }
626
627       isFocusStartableKey = true;
628     }
629     else if (keyName == "" && !isAccessibilityEnabled)
630     {
631       // Check the fake key event for evas-plugin case
632       if(!mIsFocusIndicatorEnabled)
633       {
634         // Show focus indicator
635         mIsFocusIndicatorEnabled = true;
636       }
637
638       isFocusStartableKey = true;
639     }
640     else if (keyName == "Backspace" && !isAccessibilityEnabled)
641     {
642       // Emit signal to go back to the previous view???
643     }
644   }
645   else if(event.state == KeyEvent::Up)
646   {
647     if (keyName == "Return")
648     {
649       if(!mIsFocusIndicatorEnabled && !isAccessibilityEnabled)
650       {
651         // Show focus indicator
652         mIsFocusIndicatorEnabled = true;
653       }
654       else
655       {
656         // Activate the focused actor
657         Actor actor;
658         if(!isAccessibilityEnabled)
659         {
660           actor = GetCurrentFocusActor();
661         }
662         else
663         {
664           actor = accessibilityFocusManager.GetCurrentFocusActor();
665         }
666
667         if(actor)
668         {
669           DoActivate(actor);
670         }
671       }
672
673       isFocusStartableKey = true;
674     }
675   }
676
677   if(isFocusStartableKey && mIsFocusIndicatorEnabled && !isAccessibilityEnabled)
678   {
679     Actor actor = GetCurrentFocusActor();
680     if( !actor )
681     {
682       // No actor is focused but keyboard focus is activated by the key press
683       // Let's try to move the initial focus
684       MoveFocus(Toolkit::Control::Right);
685     }
686     else if(mFocusIndicatorActor)
687     {
688       // Make sure the focused actor is highlighted
689       actor.Add(mFocusIndicatorActor);
690     }
691   }
692 }
693
694 void KeyboardFocusManager::OnTouched(const TouchEvent& touchEvent)
695 {
696   // Clear the focus when user touch the screen
697   ClearFocus();
698 }
699
700 Toolkit::KeyboardFocusManager::PreFocusChangeSignalV2& KeyboardFocusManager::PreFocusChangeSignal()
701 {
702   return mPreFocusChangeSignalV2;
703 }
704
705 Toolkit::KeyboardFocusManager::FocusChangedSignalV2& KeyboardFocusManager::FocusChangedSignal()
706 {
707   return mFocusChangedSignalV2;
708 }
709
710 Toolkit::KeyboardFocusManager::FocusGroupChangedSignalV2& KeyboardFocusManager::FocusGroupChangedSignal()
711 {
712   return mFocusGroupChangedSignalV2;
713 }
714
715 Toolkit::KeyboardFocusManager::FocusedActorActivatedSignalV2& KeyboardFocusManager::FocusedActorActivatedSignal()
716 {
717   return mFocusedActorActivatedSignalV2;
718 }
719
720 bool KeyboardFocusManager::DoConnectSignal( BaseObject* object, ConnectionTrackerInterface* tracker, const std::string& signalName, FunctorDelegate* functor )
721 {
722   Dali::BaseHandle handle( object );
723
724   bool connected( true );
725   KeyboardFocusManager* manager = dynamic_cast<KeyboardFocusManager*>(object);
726
727   if( Dali::Toolkit::KeyboardFocusManager::SIGNAL_PRE_FOCUS_CHANGE == signalName )
728   {
729     manager->PreFocusChangeSignal().Connect( tracker, functor );
730   }
731   if( Dali::Toolkit::KeyboardFocusManager::SIGNAL_FOCUS_CHANGED == signalName )
732   {
733     manager->FocusChangedSignal().Connect( tracker, functor );
734   }
735   if( Dali::Toolkit::KeyboardFocusManager::SIGNAL_FOCUS_GROUP_CHANGED == signalName )
736   {
737     manager->FocusGroupChangedSignal().Connect( tracker, functor );
738   }
739   else if( Dali::Toolkit::KeyboardFocusManager::SIGNAL_FOCUSED_ACTOR_ACTIVATED== signalName )
740   {
741     manager->FocusedActorActivatedSignal().Connect( tracker, functor );
742   }
743   else
744   {
745     // signalName does not match any signal
746     connected = false;
747   }
748
749   return connected;
750 }
751
752 } // namespace Internal
753
754 } // namespace Toolkit
755
756 } // namespace Dali