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