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