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