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