e6aae876f77553ce4f647c9dd97b7adeb65a46bc
[platform/core/uifw/dali-toolkit.git] / dali-toolkit / internal / focus-manager / keyboard-focus-manager-impl.cpp
1 /*
2  * Copyright (c) 2017 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 <cstring> // for strcmp
23 #include <dali/public-api/actors/layer.h>
24 #include <dali/devel-api/adaptor-framework/accessibility-adaptor.h>
25 #include <dali/devel-api/adaptor-framework/singleton-service.h>
26 #include <dali/public-api/animation/constraints.h>
27 #include <dali/public-api/common/stage.h>
28 #include <dali/public-api/events/key-event.h>
29 #include <dali/public-api/events/touch-data.h>
30 #include <dali/public-api/object/type-registry.h>
31 #include <dali/public-api/object/type-registry-helper.h>
32 #include <dali/public-api/images/resource-image.h>
33 #include <dali/integration-api/debug.h>
34
35 // INTERNAL INCLUDES
36 #include <dali-toolkit/public-api/controls/control.h>
37 #include <dali-toolkit/public-api/controls/control-impl.h>
38 #include <dali-toolkit/public-api/controls/image-view/image-view.h>
39 #include <dali-toolkit/public-api/accessibility-manager/accessibility-manager.h>
40 #include <dali-toolkit/devel-api/controls/control-devel.h>
41
42 namespace Dali
43 {
44
45 namespace Toolkit
46 {
47
48 namespace Internal
49 {
50
51 namespace // Unnamed namespace
52 {
53
54 #if defined(DEBUG_ENABLED)
55 Debug::Filter* gLogFilter = Debug::Filter::New(Debug::NoLogging, false, "LOG_KEYBOARD_FOCUS_MANAGER");
56 #endif
57
58 const char* const IS_FOCUS_GROUP_PROPERTY_NAME = "isKeyboardFocusGroup"; // This property will be replaced by a flag in Control.
59
60 const char* const FOCUS_BORDER_IMAGE_PATH = DALI_IMAGE_DIR "keyboard_focus.9.png";
61
62 BaseHandle Create()
63 {
64   BaseHandle handle = KeyboardFocusManager::Get();
65
66   if ( !handle )
67   {
68     SingletonService singletonService( SingletonService::Get() );
69     if ( singletonService )
70     {
71       Toolkit::KeyboardFocusManager manager = Toolkit::KeyboardFocusManager( new Internal::KeyboardFocusManager() );
72       singletonService.Register( typeid( manager ), manager );
73       handle = manager;
74     }
75   }
76
77   return handle;
78 }
79
80 DALI_TYPE_REGISTRATION_BEGIN_CREATE( Toolkit::KeyboardFocusManager, Dali::BaseHandle, Create, true )
81
82 DALI_SIGNAL_REGISTRATION( Toolkit, KeyboardFocusManager, "keyboardPreFocusChange",           SIGNAL_PRE_FOCUS_CHANGE )
83 DALI_SIGNAL_REGISTRATION( Toolkit, KeyboardFocusManager, "keyboardFocusChanged",             SIGNAL_FOCUS_CHANGED )
84 DALI_SIGNAL_REGISTRATION( Toolkit, KeyboardFocusManager, "keyboardFocusGroupChanged",        SIGNAL_FOCUS_GROUP_CHANGED )
85 DALI_SIGNAL_REGISTRATION( Toolkit, KeyboardFocusManager, "keyboardFocusedActorEnterKey",     SIGNAL_FOCUSED_ACTOR_ENTER_KEY )
86
87 DALI_TYPE_REGISTRATION_END()
88
89 const unsigned int MAX_HISTORY_AMOUNT = 30; ///< Max length of focus history stack
90
91 } // unnamed namespace
92
93 Toolkit::KeyboardFocusManager KeyboardFocusManager::Get()
94 {
95   Toolkit::KeyboardFocusManager manager;
96
97   SingletonService singletonService( SingletonService::Get() );
98   if ( singletonService )
99   {
100     // Check whether the keyboard focus manager is already created
101     Dali::BaseHandle handle = singletonService.GetSingleton( typeid( Toolkit::KeyboardFocusManager ) );
102     if(handle)
103     {
104       // If so, downcast the handle of singleton to keyboard focus manager
105       manager = Toolkit::KeyboardFocusManager( dynamic_cast< KeyboardFocusManager* >( handle.GetObjectPtr() ) );
106     }
107   }
108
109   return manager;
110 }
111
112 KeyboardFocusManager::KeyboardFocusManager()
113 : mPreFocusChangeSignal(),
114   mFocusChangedSignal(),
115   mFocusGroupChangedSignal(),
116   mFocusedActorEnterKeySignal(),
117   mCurrentFocusActor(),
118   mFocusIndicatorActor(),
119   mFocusGroupLoopEnabled( false ),
120   mIsFocusIndicatorEnabled( false ),
121   mIsWaitingKeyboardFocusChangeCommit( false ),
122   mFocusHistory(),
123   mSlotDelegate( this ),
124   mCustomAlgorithmInterface(NULL)
125 {
126   // TODO: Get FocusIndicatorEnable constant from stylesheet to set mIsFocusIndicatorEnabled.
127   Stage::GetCurrent().KeyEventSignal().Connect( mSlotDelegate, &KeyboardFocusManager::OnKeyEvent);
128   Stage::GetCurrent().TouchSignal().Connect( mSlotDelegate, &KeyboardFocusManager::OnTouch );
129 }
130
131 KeyboardFocusManager::~KeyboardFocusManager()
132 {
133 }
134
135 bool KeyboardFocusManager::SetCurrentFocusActor( Actor actor )
136 {
137   DALI_ASSERT_DEBUG( !mIsWaitingKeyboardFocusChangeCommit && "Calling this function in the PreFocusChangeSignal callback?" );
138
139   return DoSetCurrentFocusActor( actor );
140 }
141
142 bool KeyboardFocusManager::DoSetCurrentFocusActor( Actor actor )
143 {
144   bool success = false;
145
146   // Check whether the actor is in the stage and is keyboard focusable.
147   if( actor && actor.IsKeyboardFocusable() && actor.OnStage() )
148   {
149     if( mIsFocusIndicatorEnabled )
150     {
151       actor.Add( GetFocusIndicatorActor() );
152     }
153     // Send notification for the change of focus actor
154     Actor currentFocusedActor = GetCurrentFocusActor();
155
156     if( !mFocusChangedSignal.Empty() )
157     {
158       mFocusChangedSignal.Emit(currentFocusedActor, actor);
159     }
160
161     Toolkit::Control currentlyFocusedControl = Toolkit::Control::DownCast(currentFocusedActor);
162     if( currentlyFocusedControl )
163     {
164       // Do we need it to remember if it was previously DISABLED?
165       currentlyFocusedControl.SetProperty(DevelControl::Property::STATE, DevelControl::NORMAL );
166       currentlyFocusedControl.ClearKeyInputFocus();
167     }
168
169     DALI_LOG_INFO( gLogFilter, Debug::General, "[%s:%d] Focus Changed\n", __FUNCTION__, __LINE__);
170
171     // Save the current focused actor
172     mCurrentFocusActor = actor;
173
174     Toolkit::Control newlyFocusedControl = Toolkit::Control::DownCast(actor);
175     if( newlyFocusedControl )
176     {
177       newlyFocusedControl.SetProperty(DevelControl::Property::STATE, DevelControl::FOCUSED );
178       newlyFocusedControl.SetKeyInputFocus();
179     }
180
181     // Push Current Focused Actor to FocusHistory
182     mFocusHistory.PushBack( &actor.GetBaseObject() );
183
184     // Delete first element before add new element when Stack is full.
185     if( mFocusHistory.Count() > MAX_HISTORY_AMOUNT )
186     {
187        FocusStackIterator beginPos = mFocusHistory.Begin();
188        mFocusHistory.Erase( beginPos );
189     }
190
191     DALI_LOG_INFO( gLogFilter, Debug::General, "[%s:%d] SUCCEED\n", __FUNCTION__, __LINE__);
192     success = true;
193   }
194   else
195   {
196     DALI_LOG_WARNING("[%s:%d] FAILED\n", __FUNCTION__, __LINE__);
197   }
198
199   return success;
200 }
201
202 Actor KeyboardFocusManager::GetCurrentFocusActor()
203 {
204   Actor actor = mCurrentFocusActor.GetHandle();
205   if( actor && ! actor.OnStage() )
206   {
207     // If the actor has been removed from the stage, then it should not be focused
208
209     actor.Reset();
210     mCurrentFocusActor.Reset();
211   }
212   return actor;
213 }
214
215 Actor KeyboardFocusManager::GetCurrentFocusGroup()
216 {
217   return GetFocusGroup(GetCurrentFocusActor());
218 }
219
220 void KeyboardFocusManager::MoveFocusBackward()
221 {
222   // Find Pre Focused Actor when the list size is more than 1
223   if( mFocusHistory.Count() > 1 )
224   {
225     // Delete current focused actor in history
226     FocusStackIterator endPos = mFocusHistory.End();
227     endPos = mFocusHistory.Erase( --endPos );
228
229     // If pre-focused actors are not on stage, remove them in stack
230     while( !Dali::Actor::DownCast(BaseHandle(mFocusHistory[ mFocusHistory.Count() - 1 ])).OnStage() )
231     {
232       endPos = mFocusHistory.Erase( --endPos );
233     }
234
235     // Get pre focused actor
236     BaseObject* object = mFocusHistory[ mFocusHistory.Count() - 1 ];
237     BaseHandle handle( object );
238     Actor preFocusedActor = Dali::Actor::DownCast( handle );
239
240     // Delete pre focused actor in history because it will pushed again by SetCurrentFocusActor()
241     mFocusHistory.Erase( --endPos );
242
243     SetCurrentFocusActor( preFocusedActor );
244  }
245 }
246
247 bool KeyboardFocusManager::IsLayoutControl(Actor actor) const
248 {
249   Toolkit::Control control = Toolkit::Control::DownCast(actor);
250   return control && GetImplementation( control ).IsKeyboardNavigationSupported();
251 }
252
253 Toolkit::Control KeyboardFocusManager::GetParentLayoutControl(Actor actor) const
254 {
255   // Get the actor's parent layout control that supports two dimensional keyboard navigation
256   Actor rootActor = Stage::GetCurrent().GetRootLayer();
257   Actor parent;
258   if(actor)
259   {
260     parent = actor.GetParent();
261   }
262
263   while( parent && !IsLayoutControl(parent) && parent != rootActor )
264   {
265     parent = parent.GetParent();
266   }
267
268   return Toolkit::Control::DownCast(parent);
269 }
270
271 bool KeyboardFocusManager::MoveFocus(Toolkit::Control::KeyboardFocus::Direction direction)
272 {
273   Actor currentFocusActor = GetCurrentFocusActor();
274
275   bool succeed = false;
276
277   // Go through the actor's hierarchy until we find a layout control that knows how to move the focus
278   Toolkit::Control parentLayoutControl = GetParentLayoutControl( currentFocusActor );
279   while( parentLayoutControl && !succeed )
280   {
281     succeed = DoMoveFocusWithinLayoutControl( parentLayoutControl, currentFocusActor, direction );
282     parentLayoutControl = GetParentLayoutControl( parentLayoutControl );
283   }
284
285   if( !succeed )
286   {
287     Actor nextFocusableActor;
288
289     Toolkit::Control currentFocusControl = Toolkit::Control::DownCast(currentFocusActor);
290
291     // If the current focused actor is a control, then find the next focusable actor via the focusable properties.
292     if( currentFocusControl )
293     {
294       int actorId = -1;
295       Property::Index index = Property::INVALID_INDEX;
296       Property::Value value;
297
298       // Find property index based upon focus direction
299       switch ( direction )
300       {
301         case Toolkit::Control::KeyboardFocus::LEFT:
302         {
303           index = Toolkit::DevelControl::Property::LEFT_FOCUSABLE_ACTOR_ID;
304           break;
305         }
306         case Toolkit::Control::KeyboardFocus::RIGHT:
307         {
308           index = Toolkit::DevelControl::Property::RIGHT_FOCUSABLE_ACTOR_ID;
309           break;
310         }
311         case Toolkit::Control::KeyboardFocus::UP:
312         {
313           index = Toolkit::DevelControl::Property::UP_FOCUSABLE_ACTOR_ID;
314           break;
315         }
316         case Toolkit::Control::KeyboardFocus::DOWN:
317         {
318           index = Toolkit::DevelControl::Property::DOWN_FOCUSABLE_ACTOR_ID;
319           break;
320         }
321         default:
322           break;
323       }
324
325       // If the focusable property is set then determine next focusable actor
326       if( index != Property::INVALID_INDEX)
327       {
328         value = currentFocusActor.GetProperty( index );
329         actorId = value.Get<int>();
330
331         // If actor's id is valid then find actor form actor's id. The actor should be on the stage.
332         if( actorId != -1 )
333         {
334           if( currentFocusActor.GetParent() )
335           {
336             nextFocusableActor = currentFocusActor.GetParent().FindChildById( actorId );
337           }
338
339           if( !nextFocusableActor )
340           {
341             nextFocusableActor = Stage::GetCurrent().GetRootLayer().FindChildById( actorId );
342           }
343         }
344       }
345     }
346
347     if( !nextFocusableActor )
348     {
349       // If the implementation of CustomAlgorithmInterface is provided then the PreFocusChangeSignal is no longer emitted.
350       if( mCustomAlgorithmInterface )
351       {
352         mIsWaitingKeyboardFocusChangeCommit = true;
353         nextFocusableActor = mCustomAlgorithmInterface->GetNextFocusableActor( currentFocusActor, Actor(), direction );
354         mIsWaitingKeyboardFocusChangeCommit = false;
355       }
356       else if( !mPreFocusChangeSignal.Empty() )
357       {
358         // Don't know how to move the focus further. The application needs to tell us which actor to move the focus to
359         mIsWaitingKeyboardFocusChangeCommit = true;
360         nextFocusableActor = mPreFocusChangeSignal.Emit( currentFocusActor, Actor(), direction );
361         mIsWaitingKeyboardFocusChangeCommit = false;
362       }
363     }
364
365     if( nextFocusableActor && nextFocusableActor.IsKeyboardFocusable() )
366     {
367       // Whether the next focusable actor is a layout control
368       if( IsLayoutControl( nextFocusableActor ) )
369       {
370         // If so, move the focus inside it.
371         Toolkit::Control layoutControl = Toolkit::Control::DownCast( nextFocusableActor) ;
372         succeed = DoMoveFocusWithinLayoutControl( layoutControl, currentFocusActor, direction );
373       }
374       else
375       {
376         // Otherwise, just set focus to the next focusable actor
377         succeed = SetCurrentFocusActor( nextFocusableActor );
378       }
379     }
380   }
381
382   return succeed;
383 }
384
385 bool KeyboardFocusManager::DoMoveFocusWithinLayoutControl(Toolkit::Control control, Actor actor, Toolkit::Control::KeyboardFocus::Direction direction)
386 {
387   // Ask the control for the next actor to focus
388   Actor nextFocusableActor = GetImplementation( control ).GetNextKeyboardFocusableActor(actor, direction, mFocusGroupLoopEnabled);
389   if(nextFocusableActor)
390   {
391     if(!nextFocusableActor.IsKeyboardFocusable())
392     {
393       // If the actor is not focusable, ask the same layout control for the next actor to focus
394       return DoMoveFocusWithinLayoutControl(control, nextFocusableActor, direction);
395     }
396     else
397     {
398       Actor currentFocusActor = GetCurrentFocusActor();
399       Actor committedFocusActor = nextFocusableActor;
400
401       // We will try to move the focus to the actor. Emit a signal to notify the proposed actor to focus
402       // Signal handler can check the proposed actor and return a different actor if it wishes.
403       if( !mPreFocusChangeSignal.Empty() )
404       {
405         mIsWaitingKeyboardFocusChangeCommit = true;
406         committedFocusActor = mPreFocusChangeSignal.Emit(currentFocusActor, nextFocusableActor, direction);
407         mIsWaitingKeyboardFocusChangeCommit = false;
408       }
409
410       if (committedFocusActor && committedFocusActor.IsKeyboardFocusable())
411       {
412         // Whether the commited focusable actor is a layout control
413         if(IsLayoutControl(committedFocusActor))
414         {
415           // If so, move the focus inside it.
416           Toolkit::Control layoutControl = Toolkit::Control::DownCast(committedFocusActor);
417           return DoMoveFocusWithinLayoutControl(layoutControl, currentFocusActor, direction);
418         }
419         else
420         {
421           // Otherwise, just set focus to the next focusable actor
422           if(committedFocusActor == nextFocusableActor)
423           {
424             // If the application hasn't changed our proposed actor, we informs the layout control we will
425             // move the focus to what the control returns. The control might wish to perform some actions
426             // before the focus is actually moved.
427             GetImplementation( control ).OnKeyboardFocusChangeCommitted( committedFocusActor );
428           }
429
430           return SetCurrentFocusActor(committedFocusActor);
431         }
432       }
433       else
434       {
435         return false;
436       }
437     }
438   }
439   else
440   {
441     // No more actor can be focused in the given direction within the same layout control.
442     return false;
443   }
444 }
445
446 bool KeyboardFocusManager::DoMoveFocusToNextFocusGroup(bool forward)
447 {
448   bool succeed = false;
449
450   // Get the parent layout control of the current focus group
451   Toolkit::Control parentLayoutControl = GetParentLayoutControl(GetCurrentFocusGroup());
452
453   while(parentLayoutControl && !succeed)
454   {
455     // If the current focus group has a parent layout control, we can probably automatically
456     // move the focus to the next focus group in the forward or backward direction.
457     Toolkit::Control::KeyboardFocus::Direction direction = forward ? Toolkit::Control::KeyboardFocus::RIGHT : Toolkit::Control::KeyboardFocus::LEFT;
458     succeed = DoMoveFocusWithinLayoutControl(parentLayoutControl, GetCurrentFocusActor(), direction);
459     parentLayoutControl = GetParentLayoutControl(parentLayoutControl);
460   }
461
462   if(!mFocusGroupChangedSignal.Empty())
463   {
464     // Emit a focus group changed signal. The applicaton can move the focus to a new focus group
465     mFocusGroupChangedSignal.Emit(GetCurrentFocusActor(), forward);
466   }
467
468   return succeed;
469 }
470
471 void KeyboardFocusManager::DoKeyboardEnter(Actor actor)
472 {
473   if( actor )
474   {
475     Toolkit::Control control = Toolkit::Control::DownCast( actor );
476     if( control )
477     {
478       // Notify the control that enter has been pressed on it.
479       GetImplementation( control ).KeyboardEnter();
480     }
481
482     // Send a notification for the actor.
483     if( !mFocusedActorEnterKeySignal.Empty() )
484     {
485       mFocusedActorEnterKeySignal.Emit( actor );
486     }
487   }
488 }
489
490 void KeyboardFocusManager::ClearFocus()
491 {
492   Actor actor = GetCurrentFocusActor();
493   if( actor )
494   {
495     if( mFocusIndicatorActor )
496     {
497       actor.Remove( mFocusIndicatorActor );
498     }
499
500     // Send notification for the change of focus actor
501     if( !mFocusChangedSignal.Empty() )
502     {
503       mFocusChangedSignal.Emit( actor, Actor() );
504     }
505
506     Toolkit::Control currentlyFocusedControl = Toolkit::Control::DownCast( actor );
507     if( currentlyFocusedControl )
508     {
509       currentlyFocusedControl.SetProperty( DevelControl::Property::STATE, DevelControl::NORMAL );
510       currentlyFocusedControl.ClearKeyInputFocus();
511     }
512   }
513
514   mCurrentFocusActor.Reset();
515   mIsFocusIndicatorEnabled = false;
516 }
517
518 void KeyboardFocusManager::SetFocusGroupLoop(bool enabled)
519 {
520   mFocusGroupLoopEnabled = enabled;
521 }
522
523 bool KeyboardFocusManager::GetFocusGroupLoop() const
524 {
525   return mFocusGroupLoopEnabled;
526 }
527
528 void KeyboardFocusManager::SetAsFocusGroup(Actor actor, bool isFocusGroup)
529 {
530   if(actor)
531   {
532     // Create/Set focus group property.
533     actor.RegisterProperty( IS_FOCUS_GROUP_PROPERTY_NAME, isFocusGroup, Property::READ_WRITE );
534   }
535 }
536
537 bool KeyboardFocusManager::IsFocusGroup(Actor actor) const
538 {
539   // Check whether the actor is a focus group
540   bool isFocusGroup = false;
541
542   if(actor)
543   {
544     Property::Index propertyIsFocusGroup = actor.GetPropertyIndex(IS_FOCUS_GROUP_PROPERTY_NAME);
545     if(propertyIsFocusGroup != Property::INVALID_INDEX)
546     {
547       isFocusGroup = actor.GetProperty<bool>(propertyIsFocusGroup);
548     }
549   }
550
551   return isFocusGroup;
552 }
553
554 Actor KeyboardFocusManager::GetFocusGroup(Actor actor)
555 {
556   // Go through the actor's hierarchy to check which focus group the actor belongs to
557   while (actor && !IsFocusGroup(actor))
558   {
559     actor = actor.GetParent();
560   }
561
562   return actor;
563 }
564
565 void KeyboardFocusManager::SetFocusIndicatorActor(Actor indicator)
566 {
567   if(mFocusIndicatorActor != indicator)
568   {
569     Actor currentFocusActor = GetCurrentFocusActor();
570     if(currentFocusActor)
571     {
572       // The new focus indicator should be added to the current focused actor immediately
573       if(mFocusIndicatorActor)
574       {
575         currentFocusActor.Remove(mFocusIndicatorActor);
576       }
577
578       if(indicator)
579       {
580         currentFocusActor.Add(indicator);
581       }
582     }
583
584     mFocusIndicatorActor = indicator;
585   }
586 }
587
588 Actor KeyboardFocusManager::GetFocusIndicatorActor()
589 {
590   if( ! mFocusIndicatorActor )
591   {
592     // Create the default if it hasn't been set and one that's shared by all the keyboard focusable actors
593     mFocusIndicatorActor = Toolkit::ImageView::New( FOCUS_BORDER_IMAGE_PATH );
594
595     // Apply size constraint to the focus indicator
596     mFocusIndicatorActor.SetResizePolicy( ResizePolicy::FILL_TO_PARENT, Dimension::ALL_DIMENSIONS );
597   }
598
599   mFocusIndicatorActor.SetParentOrigin( ParentOrigin::CENTER );
600   mFocusIndicatorActor.SetAnchorPoint( AnchorPoint::CENTER );
601   mFocusIndicatorActor.SetPosition(0.0f, 0.0f);
602
603   return mFocusIndicatorActor;
604 }
605
606 void KeyboardFocusManager::OnKeyEvent(const KeyEvent& event)
607 {
608   AccessibilityAdaptor accessibilityAdaptor = AccessibilityAdaptor::Get();
609   bool isAccessibilityEnabled = accessibilityAdaptor.IsEnabled();
610
611   Toolkit::AccessibilityManager accessibilityManager = Toolkit::AccessibilityManager::Get();
612
613   std::string keyName = event.keyPressedName;
614
615   bool isFocusStartableKey = false;
616
617   if(event.state == KeyEvent::Down)
618   {
619     if (keyName == "Left")
620     {
621       if(!isAccessibilityEnabled)
622       {
623         if(!mIsFocusIndicatorEnabled)
624         {
625           // Show focus indicator
626           mIsFocusIndicatorEnabled = true;
627         }
628         else
629         {
630           // Move the focus towards left
631           MoveFocus(Toolkit::Control::KeyboardFocus::LEFT);
632         }
633
634         isFocusStartableKey = true;
635       }
636       else
637       {
638         // Move the accessibility focus backward
639         accessibilityManager.MoveFocusBackward();
640       }
641     }
642     else if (keyName == "Right")
643     {
644       if(!isAccessibilityEnabled)
645       {
646         if(!mIsFocusIndicatorEnabled)
647         {
648           // Show focus indicator
649           mIsFocusIndicatorEnabled = true;
650         }
651         else
652         {
653           // Move the focus towards right
654           MoveFocus(Toolkit::Control::KeyboardFocus::RIGHT);
655         }
656       }
657       else
658       {
659         // Move the accessibility focus forward
660         accessibilityManager.MoveFocusForward();
661       }
662
663       isFocusStartableKey = true;
664     }
665     else if (keyName == "Up" && !isAccessibilityEnabled)
666     {
667       if(!mIsFocusIndicatorEnabled)
668       {
669         // Show focus indicator
670         mIsFocusIndicatorEnabled = true;
671       }
672       else
673       {
674         // Move the focus towards up
675         MoveFocus(Toolkit::Control::KeyboardFocus::UP);
676       }
677
678       isFocusStartableKey = true;
679     }
680     else if (keyName == "Down" && !isAccessibilityEnabled)
681     {
682       if(!mIsFocusIndicatorEnabled)
683       {
684         // Show focus indicator
685         mIsFocusIndicatorEnabled = true;
686       }
687       else
688       {
689         // Move the focus towards down
690         MoveFocus(Toolkit::Control::KeyboardFocus::DOWN);
691       }
692
693       isFocusStartableKey = true;
694     }
695     else if (keyName == "Prior" && !isAccessibilityEnabled)
696     {
697       if(!mIsFocusIndicatorEnabled)
698       {
699         // Show focus indicator
700         mIsFocusIndicatorEnabled = true;
701       }
702       else
703       {
704         // Move the focus towards the previous page
705         MoveFocus(Toolkit::Control::KeyboardFocus::PAGE_UP);
706       }
707
708       isFocusStartableKey = true;
709     }
710     else if (keyName == "Next" && !isAccessibilityEnabled)
711     {
712       if(!mIsFocusIndicatorEnabled)
713       {
714         // Show focus indicator
715         mIsFocusIndicatorEnabled = true;
716       }
717       else
718       {
719         // Move the focus towards the next page
720         MoveFocus(Toolkit::Control::KeyboardFocus::PAGE_DOWN);
721       }
722
723       isFocusStartableKey = true;
724     }
725     else if (keyName == "Tab" && !isAccessibilityEnabled)
726     {
727       if(!mIsFocusIndicatorEnabled)
728       {
729         // Show focus indicator
730         mIsFocusIndicatorEnabled = true;
731       }
732       else
733       {
734         // "Tab" key changes the focus group in the forward direction and
735         // "Shift-Tab" key changes it in the backward direction.
736         DoMoveFocusToNextFocusGroup(!event.IsShiftModifier());
737       }
738
739       isFocusStartableKey = true;
740     }
741     else if (keyName == "space" && !isAccessibilityEnabled)
742     {
743       if(!mIsFocusIndicatorEnabled)
744       {
745         // Show focus indicator
746         mIsFocusIndicatorEnabled = true;
747       }
748
749       isFocusStartableKey = true;
750     }
751     else if (keyName == "" && !isAccessibilityEnabled)
752     {
753       // Check the fake key event for evas-plugin case
754       if(!mIsFocusIndicatorEnabled)
755       {
756         // Show focus indicator
757         mIsFocusIndicatorEnabled = true;
758       }
759
760       isFocusStartableKey = true;
761     }
762     else if (keyName == "Backspace" && !isAccessibilityEnabled)
763     {
764       // Emit signal to go back to the previous view???
765     }
766     else if (keyName == "Escape" && !isAccessibilityEnabled)
767     {
768     }
769   }
770   else if(event.state == KeyEvent::Up)
771   {
772     if (keyName == "Return")
773     {
774       if(!mIsFocusIndicatorEnabled && !isAccessibilityEnabled)
775       {
776         // Show focus indicator
777         mIsFocusIndicatorEnabled = true;
778       }
779       else
780       {
781         // The focused actor has enter pressed on it
782         Actor actor;
783         if( !isAccessibilityEnabled )
784         {
785           actor = GetCurrentFocusActor();
786         }
787         else
788         {
789           actor = accessibilityManager.GetCurrentFocusActor();
790         }
791
792         if( actor )
793         {
794           DoKeyboardEnter( actor );
795         }
796       }
797
798       isFocusStartableKey = true;
799     }
800   }
801
802   if(isFocusStartableKey && mIsFocusIndicatorEnabled && !isAccessibilityEnabled)
803   {
804     Actor actor = GetCurrentFocusActor();
805     if( actor )
806     {
807       // Make sure the focused actor is highlighted
808       actor.Add( GetFocusIndicatorActor() );
809     }
810     else
811     {
812       // No actor is focused but keyboard focus is activated by the key press
813       // Let's try to move the initial focus
814       MoveFocus(Toolkit::Control::KeyboardFocus::RIGHT);
815     }
816   }
817 }
818
819 void KeyboardFocusManager::OnTouch(const TouchData& touch)
820 {
821   // Clear the focus when user touch the screen.
822   // We only do this on a Down event, otherwise the clear action may override a manually focused actor.
823   if( ( touch.GetPointCount() < 1 ) || ( touch.GetState( 0 ) == PointState::DOWN ) )
824   {
825     ClearFocus();
826   }
827 }
828
829 Toolkit::KeyboardFocusManager::PreFocusChangeSignalType& KeyboardFocusManager::PreFocusChangeSignal()
830 {
831   return mPreFocusChangeSignal;
832 }
833
834 Toolkit::KeyboardFocusManager::FocusChangedSignalType& KeyboardFocusManager::FocusChangedSignal()
835 {
836   return mFocusChangedSignal;
837 }
838
839 Toolkit::KeyboardFocusManager::FocusGroupChangedSignalType& KeyboardFocusManager::FocusGroupChangedSignal()
840 {
841   return mFocusGroupChangedSignal;
842 }
843
844 Toolkit::KeyboardFocusManager::FocusedActorEnterKeySignalType& KeyboardFocusManager::FocusedActorEnterKeySignal()
845 {
846   return mFocusedActorEnterKeySignal;
847 }
848
849 bool KeyboardFocusManager::DoConnectSignal( BaseObject* object, ConnectionTrackerInterface* tracker, const std::string& signalName, FunctorDelegate* functor )
850 {
851   Dali::BaseHandle handle( object );
852
853   bool connected( true );
854   KeyboardFocusManager* manager = static_cast< KeyboardFocusManager* >( object ); // TypeRegistry guarantees that this is the correct type.
855
856   if( 0 == strcmp( signalName.c_str(), SIGNAL_PRE_FOCUS_CHANGE ) )
857   {
858     manager->PreFocusChangeSignal().Connect( tracker, functor );
859   }
860   else if( 0 == strcmp( signalName.c_str(), SIGNAL_FOCUS_CHANGED ) )
861   {
862     manager->FocusChangedSignal().Connect( tracker, functor );
863   }
864   else if( 0 == strcmp( signalName.c_str(), SIGNAL_FOCUS_GROUP_CHANGED ) )
865   {
866     manager->FocusGroupChangedSignal().Connect( tracker, functor );
867   }
868   else if( 0 == strcmp( signalName.c_str(), SIGNAL_FOCUSED_ACTOR_ENTER_KEY ) )
869   {
870     manager->FocusedActorEnterKeySignal().Connect( tracker, functor );
871   }
872   else
873   {
874     // signalName does not match any signal
875     connected = false;
876   }
877
878   return connected;
879 }
880
881 void KeyboardFocusManager::SetCustomAlgorithm(CustomAlgorithmInterface& interface)
882 {
883   mCustomAlgorithmInterface = &interface;
884 }
885
886 } // namespace Internal
887
888 } // namespace Toolkit
889
890 } // namespace Dali