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