11644e7c5108e6b7a2f36dfdb594a172f584b589
[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   Constraint constraint = Constraint::New<Vector3>(Actor::SIZE,
472                                                    ParentSource(Actor::SIZE),
473                                                    EqualToConstraint());
474   focusIndicator.ApplyConstraint(constraint);
475
476   SetFocusIndicatorActor(focusIndicator);
477 }
478
479 void KeyboardFocusManager::OnPhysicalKeyboardStatusChanged(PhysicalKeyboard keyboard)
480 {
481   mIsKeyboardFocusEnabled = keyboard.IsAttached();
482
483   if(mIsKeyboardFocusEnabled)
484   {
485     // Show indicator when keyboard focus turned on if there is focused actor.
486     Actor actor = GetCurrentFocusActor();
487     if(actor)
488     {
489       if(mFocusIndicatorActor)
490       {
491         actor.Add(mFocusIndicatorActor);
492       }
493     }
494     mIsFocusIndicatorEnabled = true;
495   }
496   else
497   {
498     // Hide indicator when keyboard focus turned off
499     Actor actor = GetCurrentFocusActor();
500     if(actor)
501     {
502       actor.Remove(mFocusIndicatorActor);
503     }
504     mIsFocusIndicatorEnabled = false;
505   }
506 }
507
508 void KeyboardFocusManager::OnKeyEvent(const KeyEvent& event)
509 {
510   if(!mIsKeyboardFocusEnabled)
511   {
512     return;
513   }
514
515   AccessibilityManager accessibilityManager = AccessibilityManager::Get();
516   bool isAccessibilityEnabled = accessibilityManager.IsEnabled();
517
518   Toolkit::FocusManager accessibilityFocusManager = Toolkit::FocusManager::Get();
519
520   std::string keyName = event.keyPressedName;
521
522   bool isFocusStartableKey = false;
523
524   if(event.state == KeyEvent::Down)
525   {
526     if (keyName == "Left")
527     {
528       if(!isAccessibilityEnabled)
529       {
530         if(!mIsFocusIndicatorEnabled)
531         {
532           // Show focus indicator
533           mIsFocusIndicatorEnabled = true;
534         }
535         else
536         {
537           // Move the focus towards left
538           MoveFocus(Toolkit::Control::Left);
539         }
540
541         isFocusStartableKey = true;
542       }
543       else
544       {
545         // Move the accessibility focus backward
546         accessibilityFocusManager.MoveFocusBackward();
547       }
548     }
549     else if (keyName == "Right")
550     {
551       if(!isAccessibilityEnabled)
552       {
553         if(!mIsFocusIndicatorEnabled)
554         {
555           // Show focus indicator
556           mIsFocusIndicatorEnabled = true;
557         }
558         else
559         {
560           // Move the focus towards right
561           MoveFocus(Toolkit::Control::Right);
562         }
563       }
564       else
565       {
566         // Move the accessibility focus forward
567         accessibilityFocusManager.MoveFocusForward();
568       }
569
570       isFocusStartableKey = true;
571     }
572     else if (keyName == "Up" && !isAccessibilityEnabled)
573     {
574       if(!mIsFocusIndicatorEnabled)
575       {
576         // Show focus indicator
577         mIsFocusIndicatorEnabled = true;
578       }
579       else
580       {
581         // Move the focus towards up
582         MoveFocus(Toolkit::Control::Up);
583       }
584
585       isFocusStartableKey = true;
586     }
587     else if (keyName == "Down" && !isAccessibilityEnabled)
588     {
589       if(!mIsFocusIndicatorEnabled)
590       {
591         // Show focus indicator
592         mIsFocusIndicatorEnabled = true;
593       }
594       else
595       {
596         // Move the focus towards down
597         MoveFocus(Toolkit::Control::Down);
598       }
599
600       isFocusStartableKey = true;
601     }
602     else if (keyName == "Tab" && !isAccessibilityEnabled)
603     {
604       if(!mIsFocusIndicatorEnabled)
605       {
606         // Show focus indicator
607         mIsFocusIndicatorEnabled = true;
608       }
609       else
610       {
611         // "Tab" key changes the focus group in the forward direction and
612         // "Shift-Tab" key changes it in the backward direction.
613         DoMoveFocusToNextFocusGroup(!event.IsShiftModifier());
614       }
615
616       isFocusStartableKey = true;
617     }
618     else if (keyName == "space" && !isAccessibilityEnabled)
619     {
620       if(!mIsFocusIndicatorEnabled)
621       {
622         // Show focus indicator
623         mIsFocusIndicatorEnabled = true;
624       }
625
626       isFocusStartableKey = true;
627     }
628     else if (keyName == "" && !isAccessibilityEnabled)
629     {
630       // Check the fake key event for evas-plugin case
631       if(!mIsFocusIndicatorEnabled)
632       {
633         // Show focus indicator
634         mIsFocusIndicatorEnabled = true;
635       }
636
637       isFocusStartableKey = true;
638     }
639     else if (keyName == "Backspace" && !isAccessibilityEnabled)
640     {
641       // Emit signal to go back to the previous view???
642     }
643   }
644   else if(event.state == KeyEvent::Up)
645   {
646     if (keyName == "Return")
647     {
648       if(!mIsFocusIndicatorEnabled && !isAccessibilityEnabled)
649       {
650         // Show focus indicator
651         mIsFocusIndicatorEnabled = true;
652       }
653       else
654       {
655         // Activate the focused actor
656         Actor actor;
657         if(!isAccessibilityEnabled)
658         {
659           actor = GetCurrentFocusActor();
660         }
661         else
662         {
663           actor = accessibilityFocusManager.GetCurrentFocusActor();
664         }
665
666         if(actor)
667         {
668           DoActivate(actor);
669         }
670       }
671
672       isFocusStartableKey = true;
673     }
674   }
675
676   if(isFocusStartableKey && mIsFocusIndicatorEnabled && !isAccessibilityEnabled)
677   {
678     Actor actor = GetCurrentFocusActor();
679     if( !actor )
680     {
681       // No actor is focused but keyboard focus is activated by the key press
682       // Let's try to move the initial focus
683       MoveFocus(Toolkit::Control::Right);
684     }
685     else if(mFocusIndicatorActor)
686     {
687       // Make sure the focused actor is highlighted
688       actor.Add(mFocusIndicatorActor);
689     }
690   }
691 }
692
693 void KeyboardFocusManager::OnTouched(const TouchEvent& touchEvent)
694 {
695   // Clear the focus when user touch the screen
696   ClearFocus();
697 }
698
699 Toolkit::KeyboardFocusManager::PreFocusChangeSignalType& KeyboardFocusManager::PreFocusChangeSignal()
700 {
701   return mPreFocusChangeSignal;
702 }
703
704 Toolkit::KeyboardFocusManager::FocusChangedSignalType& KeyboardFocusManager::FocusChangedSignal()
705 {
706   return mFocusChangedSignal;
707 }
708
709 Toolkit::KeyboardFocusManager::FocusGroupChangedSignalType& KeyboardFocusManager::FocusGroupChangedSignal()
710 {
711   return mFocusGroupChangedSignal;
712 }
713
714 Toolkit::KeyboardFocusManager::FocusedActorActivatedSignalType& KeyboardFocusManager::FocusedActorActivatedSignal()
715 {
716   return mFocusedActorActivatedSignal;
717 }
718
719 bool KeyboardFocusManager::DoConnectSignal( BaseObject* object, ConnectionTrackerInterface* tracker, const std::string& signalName, FunctorDelegate* functor )
720 {
721   Dali::BaseHandle handle( object );
722
723   bool connected( true );
724   KeyboardFocusManager* manager = dynamic_cast<KeyboardFocusManager*>(object);
725
726   if( Dali::Toolkit::KeyboardFocusManager::SIGNAL_PRE_FOCUS_CHANGE == signalName )
727   {
728     manager->PreFocusChangeSignal().Connect( tracker, functor );
729   }
730   if( Dali::Toolkit::KeyboardFocusManager::SIGNAL_FOCUS_CHANGED == signalName )
731   {
732     manager->FocusChangedSignal().Connect( tracker, functor );
733   }
734   if( Dali::Toolkit::KeyboardFocusManager::SIGNAL_FOCUS_GROUP_CHANGED == signalName )
735   {
736     manager->FocusGroupChangedSignal().Connect( tracker, functor );
737   }
738   else if( Dali::Toolkit::KeyboardFocusManager::SIGNAL_FOCUSED_ACTOR_ACTIVATED== signalName )
739   {
740     manager->FocusedActorActivatedSignal().Connect( tracker, functor );
741   }
742   else
743   {
744     // signalName does not match any signal
745     connected = false;
746   }
747
748   return connected;
749 }
750
751 } // namespace Internal
752
753 } // namespace Toolkit
754
755 } // namespace Dali