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