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