License conversion from Flora to Apache 2.0
[platform/core/uifw/dali-toolkit.git] / base / dali-toolkit / internal / focus-manager / focus-manager-impl.cpp
1 /*
2  * Copyright (c) 2014 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 "focus-manager-impl.h"
20
21 // INTERNAL INCLUDES
22 #include <dali-toolkit/public-api/controls/control.h>
23 #include <dali-toolkit/public-api/controls/control-impl.h>
24 #include <dali/integration-api/debug.h>
25
26 namespace Dali
27 {
28
29 namespace Toolkit
30 {
31
32 namespace Internal
33 {
34
35 namespace // unnamed namespace
36 {
37
38 #if defined(DEBUG_ENABLED)
39 Debug::Filter* gLogFilter = Debug::Filter::New(Debug::NoLogging, false, "LOG_FOCUS_MANAGER");
40 #endif
41
42 const char * const ACTOR_FOCUSABLE("focusable");
43 const char * const IS_FOCUS_GROUP("is-focus-group");
44
45 const char* FOCUS_BORDER_IMAGE_PATH = DALI_IMAGE_DIR "B16-8_TTS_focus.png";
46 const Vector4 FOCUS_BORDER_IMAGE_BORDER = Vector4(7.0f, 7.0f, 7.0f, 7.0f);
47
48 /**
49  * The function to be used in the hit-test algorithm to check whether the actor is hittable.
50  */
51 bool IsActorFocusableFunction(Actor actor, Dali::HitTestAlgorithm::TraverseType type)
52 {
53   bool hittable = false;
54
55   switch (type)
56   {
57     case Dali::HitTestAlgorithm::CHECK_ACTOR:
58     {
59       // Check whether the actor is visible and not fully transparent.
60       if( actor.IsVisible()
61        && actor.GetCurrentWorldColor().a > 0.01f) // not FULLY_TRANSPARENT
62       {
63         // Check whether the actor is focusable
64         Property::Index propertyActorFocusable = actor.GetPropertyIndex(ACTOR_FOCUSABLE);
65         if(propertyActorFocusable != Property::INVALID_INDEX)
66         {
67           hittable = actor.GetProperty<bool>(propertyActorFocusable);
68         }
69       }
70       break;
71     }
72     case Dali::HitTestAlgorithm::DESCEND_ACTOR_TREE:
73     {
74       if( actor.IsVisible() ) // Actor is visible, if not visible then none of its children are visible.
75       {
76         hittable = true;
77       }
78       break;
79     }
80     default:
81     {
82       break;
83     }
84   }
85
86   return hittable;
87 };
88
89 }
90
91 FocusManager::FocusManager()
92 : mIsWrapped(false),
93   mIsFocusWithinGroup(false),
94   mCurrentFocusActor(FocusIDPair(0, 0)),
95   mFocusIndicatorActor(Actor()),
96   mRecursiveFocusMoveCounter(0),
97   mIsAccessibilityTtsEnabled(false),
98   mIsFocusIndicatorEnabled(false)
99 {
100   CreateDefaultFocusIndicatorActor();
101
102   AccessibilityManager manager = AccessibilityManager::Get();
103   manager.SetActionHandler(*this);
104   manager.SetGestureHandler(*this);
105
106   ChangeAccessibilityStatus();
107 }
108
109 FocusManager::~FocusManager()
110 {
111 }
112
113 FocusManager::ActorAdditionalInfo FocusManager::GetActorAdditionalInfo(const unsigned int actorID) const
114 {
115   ActorAdditionalInfo data;
116   IDAdditionalInfoConstIter iter = mIDAdditionalInfoContainer.find(actorID);
117   if(iter != mIDAdditionalInfoContainer.end())
118   {
119     data = (*iter).second;
120   }
121
122   return data;
123 }
124
125 void FocusManager::SynchronizeActorAdditionalInfo(const unsigned int actorID, const unsigned int order)
126 {
127   ActorAdditionalInfo actorInfo = GetActorAdditionalInfo(actorID);
128   actorInfo.mFocusOrder = order;
129   mIDAdditionalInfoContainer.erase(actorID);
130   mIDAdditionalInfoContainer.insert(IDAdditionalInfoPair(actorID, actorInfo));
131 }
132
133 void FocusManager::SetAccessibilityAttribute(Actor actor, Toolkit::FocusManager::AccessibilityAttribute type, const std::string& text)
134 {
135   if(actor)
136   {
137     unsigned int actorID = actor.GetId();
138
139     ActorAdditionalInfo info = GetActorAdditionalInfo(actorID);
140     info.mAccessibilityAttributes[type] = text;
141
142     mIDAdditionalInfoContainer.erase(actorID);
143     mIDAdditionalInfoContainer.insert(IDAdditionalInfoPair(actorID, info));
144   }
145 }
146
147 std::string FocusManager::GetAccessibilityAttribute(Actor actor, Toolkit::FocusManager::AccessibilityAttribute type) const
148 {
149   std::string text;
150
151   if(actor)
152   {
153     ActorAdditionalInfo data = GetActorAdditionalInfo(actor.GetId());
154     text = data.mAccessibilityAttributes[type];
155   }
156
157   return text;
158 }
159
160 void FocusManager::SetFocusOrder(Actor actor, const unsigned int order)
161 {
162   // Do nothing if the focus order of the actor is not changed.
163   if(actor && GetFocusOrder(actor) != order)
164   {
165     // Firstly delete the actor from the focus chain if it's already there with a different focus order.
166     mFocusIDContainer.erase(GetFocusOrder(actor));
167
168     // Create actor focusable property if not already created.
169     Property::Index propertyActorFocusable = actor.GetPropertyIndex(ACTOR_FOCUSABLE);
170     if(propertyActorFocusable == Property::INVALID_INDEX)
171     {
172       propertyActorFocusable = actor.RegisterProperty(ACTOR_FOCUSABLE, true);
173     }
174
175     if(order == 0)
176     {
177       // The actor is not focusable without a defined focus order.
178       actor.SetProperty(propertyActorFocusable, false);
179
180       // If the actor is currently being focused, it should clear the focus
181       if(actor == GetCurrentFocusActor())
182       {
183         ClearFocus();
184       }
185     }
186     else // Insert the actor to the focus chain
187     {
188       // Check whether there is another actor in the focus chain with the same focus order already.
189       FocusIDIter focusIDIter = mFocusIDContainer.find(order);
190       if(focusIDIter != mFocusIDContainer.end())
191       {
192         // We need to increase the focus order of that actor and all the actors followed it
193         // in the focus chain.
194         FocusIDIter lastIter = mFocusIDContainer.end();
195         --lastIter;//We want forward iterator to the last element here
196         mFocusIDContainer.insert(FocusIDPair((*lastIter).first + 1, (*lastIter).second));
197
198         // Update the actor's focus order in its additional data
199         SynchronizeActorAdditionalInfo((*lastIter).second, (*lastIter).first + 1);
200
201         for(FocusIDIter iter = lastIter; iter != focusIDIter; iter--)
202         {
203           FocusIDIter previousIter = iter;
204           --previousIter;//We want forward iterator to the previous element here
205           unsigned int actorID = (*previousIter).second;
206           (*iter).second = actorID;
207
208           // Update the actor's focus order in its additional data
209           SynchronizeActorAdditionalInfo(actorID, (*iter).first);
210         }
211
212         mFocusIDContainer.erase(order);
213       }
214
215       // The actor is focusable
216       actor.SetProperty(propertyActorFocusable, true);
217
218       // Now we insert the actor into the focus chain with the specified focus order
219       mFocusIDContainer.insert(FocusIDPair(order, actor.GetId()));
220     }
221
222     // Update the actor's focus order in its additional data
223     SynchronizeActorAdditionalInfo(actor.GetId(), order);
224   }
225 }
226
227 unsigned int FocusManager::GetFocusOrder(Actor actor) const
228 {
229   unsigned int focusOrder = 0;
230
231   if(actor)
232   {
233     ActorAdditionalInfo data = GetActorAdditionalInfo(actor.GetId());
234     focusOrder = data.mFocusOrder;
235   }
236
237   return focusOrder;
238 }
239
240 unsigned int FocusManager::GenerateNewFocusOrder() const
241 {
242   unsigned int order = 1;
243   FocusIDContainer::const_reverse_iterator iter = mFocusIDContainer.rbegin();
244
245   if(iter != mFocusIDContainer.rend())
246   {
247     order = (*iter).first + 1;
248   }
249
250   return order;
251 }
252
253 Actor FocusManager::GetActorByFocusOrder(const unsigned int order)
254 {
255   Actor actor = Actor();
256
257   FocusIDIter focusIDIter = mFocusIDContainer.find(order);
258   if(focusIDIter != mFocusIDContainer.end())
259   {
260     Actor rootActor = Stage::GetCurrent().GetRootLayer();
261     actor = rootActor.FindChildById(mFocusIDContainer[order]);
262   }
263
264   return actor;
265 }
266
267 bool FocusManager::SetCurrentFocusActor(Actor actor)
268 {
269   if(actor)
270   {
271     return DoSetCurrentFocusActor(actor.GetId());
272   }
273
274   return false;
275 }
276
277 bool FocusManager::DoSetCurrentFocusActor(const unsigned int actorID)
278 {
279   Actor rootActor = Stage::GetCurrent().GetRootLayer();
280
281   // If the group mode is enabled, check which focus group the current focused actor belongs to
282   Actor focusGroup;
283   if(mIsFocusWithinGroup)
284   {
285     focusGroup = GetFocusGroup(GetCurrentFocusActor());
286   }
287
288   if(!focusGroup)
289   {
290     focusGroup = rootActor;
291   }
292
293   Actor actor = focusGroup.FindChildById(actorID);
294
295   // Check whether the actor is in the stage
296   if(actor)
297   {
298     // Check whether the actor is focusable
299     bool actorFocusable = false;
300     Property::Index propertyActorFocusable = actor.GetPropertyIndex(ACTOR_FOCUSABLE);
301     if(propertyActorFocusable != Property::INVALID_INDEX)
302     {
303       actorFocusable = actor.GetProperty<bool>(propertyActorFocusable);
304     }
305
306     // Go through the actor's hierarchy to check whether the actor is visible
307     bool actorVisible = actor.IsVisible();
308     Actor parent = actor.GetParent();
309     while (actorVisible && parent && parent != rootActor)
310     {
311       actorVisible = parent.IsVisible();
312       parent = parent.GetParent();
313     }
314
315     // Check whether the actor is fully transparent
316     bool actorOpaque = actor.GetCurrentWorldColor().a > 0.01f;
317
318     // Set the focus only when the actor is focusable and visible and not fully transparent
319     if(actorVisible && actorFocusable && actorOpaque)
320     {
321       // Draw the focus indicator upon the focused actor
322       if(mIsFocusIndicatorEnabled && mFocusIndicatorActor)
323       {
324         actor.Add(mFocusIndicatorActor);
325       }
326
327       // Send notification for the change of focus actor
328       mFocusChangedSignalV2.Emit( GetCurrentFocusActor(), actor );
329
330       // Save the current focused actor
331       mCurrentFocusActor = FocusIDPair(GetFocusOrder(actor), actorID);
332
333       if(mIsAccessibilityTtsEnabled)
334       {
335         // Play the accessibility attributes with the TTS player.
336         Dali::TtsPlayer player = Dali::TtsPlayer::Get(Dali::TtsPlayer::SCREEN_READER);
337
338         // Combine attribute texts to one text
339         std::string informationText;
340         for(int i = 0; i < Toolkit::FocusManager::ACCESSIBILITY_ATTRIBUTE_NUM; i++)
341         {
342           if(!GetActorAdditionalInfo(actorID).mAccessibilityAttributes[i].empty())
343           {
344             if( i > 0 )
345             {
346               informationText += ", "; // for space time between each information
347             }
348             informationText += GetActorAdditionalInfo(actorID).mAccessibilityAttributes[i];
349           }
350         }
351         player.Play(informationText);
352       }
353
354       return true;
355     }
356   }
357
358   DALI_LOG_WARNING("[%s:%d] FAILED\n", __FUNCTION__, __LINE__);
359   return false;
360 }
361
362 Actor FocusManager::GetCurrentFocusActor()
363 {
364   Actor rootActor = Stage::GetCurrent().GetRootLayer();
365   return rootActor.FindChildById(mCurrentFocusActor.second);
366 }
367
368 Actor FocusManager::GetCurrentFocusGroup()
369 {
370   return GetFocusGroup(GetCurrentFocusActor());
371 }
372
373 unsigned int FocusManager::GetCurrentFocusOrder()
374 {
375   return mCurrentFocusActor.first;
376 }
377
378 bool FocusManager::MoveFocusForward()
379 {
380   bool ret = false;
381   mRecursiveFocusMoveCounter = 0;
382
383   FocusIDIter focusIDIter = mFocusIDContainer.find(mCurrentFocusActor.first);
384   if(focusIDIter != mFocusIDContainer.end())
385   {
386     DALI_LOG_INFO( gLogFilter, Debug::General, "[%s:%d] focus order : %d\n", __FUNCTION__, __LINE__, (*focusIDIter).first);
387     ret = DoMoveFocus(focusIDIter, true, mIsWrapped);
388   }
389   else
390   {
391     // TODO: if there is not focused actor, move first actor
392     if(!mFocusIDContainer.empty())
393     {
394       //if there is not focused actor, move 1st actor
395       focusIDIter = mFocusIDContainer.begin(); // TODO: I'm not sure it was sorted.
396       DALI_LOG_INFO( gLogFilter, Debug::General, "[%s:%d] focus order : %d\n", __FUNCTION__, __LINE__, (*focusIDIter).first);
397       ret = DoSetCurrentFocusActor((*focusIDIter).second);
398     }
399   }
400
401   DALI_LOG_INFO( gLogFilter, Debug::General, "[%s] %s\n", __FUNCTION__, ret?"SUCCEED!!!":"FAILED!!!");
402
403   return ret;
404 }
405
406 bool FocusManager::MoveFocusBackward()
407 {
408   bool ret = false;
409   mRecursiveFocusMoveCounter = 0;
410
411   FocusIDIter focusIDIter = mFocusIDContainer.find(mCurrentFocusActor.first);
412   if(focusIDIter != mFocusIDContainer.end())
413   {
414     DALI_LOG_INFO( gLogFilter, Debug::General, "[%s:%d] focus order : %d\n", __FUNCTION__, __LINE__, (*focusIDIter).first);
415     ret = DoMoveFocus(focusIDIter, false, mIsWrapped);
416   }
417   else
418   {
419     // TODO: if there is not focused actor, move last actor
420     if(!mFocusIDContainer.empty())
421     {
422       //if there is not focused actor, move last actor
423       focusIDIter = mFocusIDContainer.end();
424       --focusIDIter;//We want forward iterator to the last element here
425       DALI_LOG_INFO( gLogFilter, Debug::General, "[%s:%d] focus order : %d\n", __FUNCTION__, __LINE__, (*focusIDIter).first);
426       ret = DoSetCurrentFocusActor((*focusIDIter).second);
427     }
428   }
429
430   DALI_LOG_INFO( gLogFilter, Debug::General, "[%s] %s\n", __FUNCTION__, ret?"SUCCEED!!!":"FAILED!!!");
431
432   return ret;
433 }
434
435 void FocusManager::DoActivate(Actor actor)
436 {
437   if(actor)
438   {
439     Dali::Toolkit::Control control = Dali::Toolkit::Control::DownCast(actor);
440     if(control)
441     {
442       // Notify the control that it is activated
443       control.GetImplementation().OnActivated();
444     }
445
446     // Send notification for the activation of focused actor
447     mFocusedActorActivatedSignalV2.Emit(actor);
448   }
449 }
450
451 void FocusManager::ClearFocus()
452 {
453   Actor actor = GetCurrentFocusActor();
454   if(actor)
455   {
456     actor.Remove(mFocusIndicatorActor);
457   }
458
459   mCurrentFocusActor = FocusIDPair(0, 0);
460
461   // Send notification for the change of focus actor
462   mFocusChangedSignalV2.Emit(actor, Actor());
463
464   if(mIsAccessibilityTtsEnabled)
465   {
466     // Stop the TTS playing if any
467     Dali::TtsPlayer player = Dali::TtsPlayer::Get(Dali::TtsPlayer::SCREEN_READER);
468     player.Stop();
469   }
470 }
471
472 void FocusManager::Reset()
473 {
474   ClearFocus();
475   mFocusIDContainer.clear();
476   mIDAdditionalInfoContainer.clear();
477 }
478
479 void FocusManager::SetFocusGroup(Actor actor, bool isFocusGroup)
480 {
481   if(actor)
482   {
483     // Create focus group property if not already created.
484     Property::Index propertyIsFocusGroup = actor.GetPropertyIndex(IS_FOCUS_GROUP);
485     if(propertyIsFocusGroup == Property::INVALID_INDEX)
486     {
487       propertyIsFocusGroup = actor.RegisterProperty(IS_FOCUS_GROUP, isFocusGroup);
488     }
489     else
490     {
491       actor.SetProperty(propertyIsFocusGroup, isFocusGroup);
492     }
493   }
494 }
495
496 bool FocusManager::IsFocusGroup(Actor actor) const
497 {
498   // Check whether the actor is a focus group
499   bool isFocusGroup = false;
500
501   if(actor)
502   {
503     Property::Index propertyIsFocusGroup = actor.GetPropertyIndex(IS_FOCUS_GROUP);
504     if(propertyIsFocusGroup != Property::INVALID_INDEX)
505     {
506       isFocusGroup = actor.GetProperty<bool>(propertyIsFocusGroup);
507     }
508   }
509
510   return isFocusGroup;
511 }
512
513 Actor FocusManager::GetFocusGroup(Actor actor)
514 {
515   // Go through the actor's hierarchy to check which focus group the actor belongs to
516   while (actor && !IsFocusGroup(actor))
517   {
518     actor = actor.GetParent();
519   }
520
521   return actor;
522 }
523
524 void FocusManager::SetGroupMode(bool enabled)
525 {
526   mIsFocusWithinGroup = enabled;
527 }
528
529 bool FocusManager::GetGroupMode() const
530 {
531   return mIsFocusWithinGroup;
532 }
533
534 void FocusManager::SetWrapMode(bool wrapped)
535 {
536   mIsWrapped = wrapped;
537 }
538
539 bool FocusManager::GetWrapMode() const
540 {
541   return mIsWrapped;
542 }
543
544 void FocusManager::SetFocusIndicatorActor(Actor indicator)
545 {
546   mFocusIndicatorActor = indicator;
547 }
548
549 Actor FocusManager::GetFocusIndicatorActor()
550 {
551   return mFocusIndicatorActor;
552 }
553
554 bool FocusManager::DoMoveFocus(FocusIDIter focusIDIter, bool forward, bool wrapped)
555 {
556   DALI_LOG_INFO( gLogFilter, Debug::General, "[%s:%d] %d focusable actors\n", __FUNCTION__, __LINE__, mFocusIDContainer.size());
557   DALI_LOG_INFO( gLogFilter, Debug::General, "[%s:%d] focus order : %d\n", __FUNCTION__, __LINE__, (*focusIDIter).first);
558
559   if( (forward && ++focusIDIter == mFocusIDContainer.end())
560     || (!forward && focusIDIter-- == mFocusIDContainer.begin()) )
561   {
562     if(wrapped)
563     {
564       if(forward)
565       {
566         focusIDIter = mFocusIDContainer.begin();
567       }
568       else
569       {
570         focusIDIter = mFocusIDContainer.end();
571         --focusIDIter;//We want forward iterator to the last element here
572       }
573     }
574     else
575     {
576       DALI_LOG_INFO( gLogFilter, Debug::General, "[%s:%d] Overshot\n", __FUNCTION__, __LINE__);
577       // Send notification for handling overshooted situation
578       mFocusOvershotSignalV2.Emit(GetCurrentFocusActor(), forward ? Toolkit::FocusManager::OVERSHOT_NEXT : Toolkit::FocusManager::OVERSHOT_PREVIOUS);
579
580       return false; // Try to move the focus out of the scope
581     }
582   }
583
584   if((focusIDIter != mFocusIDContainer.end()) && !DoSetCurrentFocusActor((*focusIDIter).second))
585   {
586     mRecursiveFocusMoveCounter++;
587     if(mRecursiveFocusMoveCounter > mFocusIDContainer.size())
588     {
589       // We've attempted to focus all the actors in the whole focus chain and no actor
590       // can be focused successfully.
591
592       DALI_LOG_WARNING("[%s] There is no more focusable actor in %d focus chains\n", __FUNCTION__, mRecursiveFocusMoveCounter);
593
594       return false;
595     }
596     else
597     {
598       return DoMoveFocus(focusIDIter, forward, wrapped);
599     }
600   }
601
602   return true;
603 }
604
605 void FocusManager::SetFocusable(Actor actor, bool focusable)
606 {
607   if(actor)
608   {
609     // Create actor focusable property if not already created.
610     Property::Index propertyActorFocusable = actor.GetPropertyIndex(ACTOR_FOCUSABLE);
611     if(propertyActorFocusable == Property::INVALID_INDEX)
612     {
613       propertyActorFocusable = actor.RegisterProperty(ACTOR_FOCUSABLE, focusable);
614     }
615     else
616     {
617       actor.SetProperty(propertyActorFocusable, focusable);
618     }
619   }
620 }
621
622 void FocusManager::CreateDefaultFocusIndicatorActor()
623 {
624   // Create a focus indicator actor shared by all the focusable actors
625   Image borderImage = Image::New(FOCUS_BORDER_IMAGE_PATH);
626
627   ImageActor focusIndicator = ImageActor::New(borderImage);
628   focusIndicator.SetPositionInheritanceMode( Dali::USE_PARENT_POSITION_PLUS_LOCAL_POSITION );
629   focusIndicator.SetStyle( ImageActor::STYLE_NINE_PATCH );
630   focusIndicator.SetNinePatchBorder(FOCUS_BORDER_IMAGE_BORDER);
631   focusIndicator.SetPosition(Vector3(0.0f, 0.0f, 1.0f));
632
633   // Apply size constraint to the focus indicator
634   Constraint constraint = Constraint::New<Vector3>(Actor::SIZE,
635                                                    ParentSource(Actor::SIZE),
636                                                    EqualToConstraint());
637   focusIndicator.ApplyConstraint(constraint);
638
639   SetFocusIndicatorActor(focusIndicator);
640 }
641
642 bool FocusManager::ChangeAccessibilityStatus()
643 {
644   AccessibilityManager manager = AccessibilityManager::Get();
645   mIsAccessibilityTtsEnabled = manager.IsEnabled();
646
647   if(mIsAccessibilityTtsEnabled)
648   {
649     // Show indicator when tts turned on if there is focused actor.
650     Actor actor = GetCurrentFocusActor();
651     if(actor)
652     {
653       if(mFocusIndicatorActor)
654       {
655         actor.Add(mFocusIndicatorActor);
656       }
657     }
658     mIsFocusIndicatorEnabled = true;
659   }
660   else
661   {
662     // Hide indicator when tts turned off
663     Actor actor = GetCurrentFocusActor();
664     if(actor)
665     {
666       actor.Remove(mFocusIndicatorActor);
667     }
668     mIsFocusIndicatorEnabled = false;
669   }
670
671   return true;
672 }
673
674 bool FocusManager::AccessibilityActionNext()
675 {
676   if(mIsAccessibilityTtsEnabled)
677   {
678     return MoveFocusForward();
679   }
680   else
681   {
682     return false;
683   }
684 }
685
686 bool FocusManager::AccessibilityActionPrevious()
687 {
688   if(mIsAccessibilityTtsEnabled)
689   {
690     return MoveFocusBackward();
691   }
692   else
693   {
694     return false;
695   }
696 }
697
698 bool FocusManager::AccessibilityActionActivate()
699 {
700   bool ret = false;
701
702   Actor actor = GetCurrentFocusActor();
703   if(actor)
704   {
705     DoActivate(actor);
706     ret = true;
707   }
708
709   return ret;
710 }
711
712 bool FocusManager::AccessibilityActionRead(bool allowReadAgain)
713 {
714   bool ret = false;
715
716   if(mIsAccessibilityTtsEnabled)
717   {
718     // Find the focusable actor at the read position
719     AccessibilityManager manager = AccessibilityManager::Get();
720     Dali::HitTestAlgorithm::Results results;
721     Dali::HitTestAlgorithm::HitTest( Stage::GetCurrent(), manager.GetReadPosition(), results, IsActorFocusableFunction );
722
723     FocusIDIter focusIDIter = mFocusIDContainer.find(GetFocusOrder(results.actor));
724     if(focusIDIter != mFocusIDContainer.end())
725     {
726       if( allowReadAgain || (results.actor != GetCurrentFocusActor()) )
727       {
728         // Move the focus to the actor
729         ret = SetCurrentFocusActor(results.actor);
730         DALI_LOG_INFO( gLogFilter, Debug::General, "[%s:%d] SetCurrentFocusActor returns %s\n", __FUNCTION__, __LINE__, ret?"TRUE":"FALSE");
731       }
732     }
733   }
734
735   return ret;
736 }
737
738 bool FocusManager::AccessibilityActionReadNext()
739 {
740   if(mIsAccessibilityTtsEnabled)
741   {
742     return MoveFocusForward();
743   }
744   else
745   {
746     return false;
747   }
748 }
749
750 bool FocusManager::AccessibilityActionReadPrevious()
751 {
752   if(mIsAccessibilityTtsEnabled)
753   {
754     return MoveFocusBackward();
755   }
756   else
757   {
758     return false;
759   }
760 }
761
762 bool FocusManager::AccessibilityActionUp()
763 {
764   bool ret = false;
765
766   if(mIsAccessibilityTtsEnabled)
767   {
768     Actor actor = GetCurrentFocusActor();
769     if(actor)
770     {
771       Dali::Toolkit::Control control = Dali::Toolkit::Control::DownCast(actor);
772       if(control)
773       {
774         // Notify the control that it is activated
775         ret = control.GetImplementation().OnAccessibilityValueChange(true);
776       }
777     }
778   }
779
780   return ret;
781 }
782
783 bool FocusManager::AccessibilityActionDown()
784 {
785   bool ret = false;
786
787   if(mIsAccessibilityTtsEnabled)
788   {
789     Actor actor = GetCurrentFocusActor();
790     if(actor)
791     {
792       Dali::Toolkit::Control control = Dali::Toolkit::Control::DownCast(actor);
793       if(control)
794       {
795         // Notify the control that it is activated
796         ret = control.GetImplementation().OnAccessibilityValueChange(false);
797       }
798     }
799   }
800
801   return ret;
802 }
803
804 bool FocusManager::ClearAccessibilityFocus()
805 {
806   if(mIsAccessibilityTtsEnabled)
807   {
808     ClearFocus();
809     return true;
810   }
811   else
812   {
813     return false;
814   }
815 }
816
817 bool FocusManager::AccessibilityActionBack()
818 {
819   // TODO: Back to previous view
820
821   return mIsAccessibilityTtsEnabled;
822 }
823
824 bool FocusManager::HandlePanGesture(const Integration::PanGestureEvent& panEvent)
825 {
826   bool handled = false;
827
828   Actor currentGesturedActor = GetCurrentFocusActor();
829   Actor rootActor = Stage::GetCurrent().GetRootLayer();
830
831   Dali::PanGesture pan(panEvent.state);
832   pan.time = panEvent.time;
833   pan.numberOfTouches = panEvent.numberOfTouches;
834   pan.screenPosition = panEvent.currentPosition;
835   pan.screenDisplacement = panEvent.previousPosition - panEvent.currentPosition;
836   pan.screenVelocity.x = pan.screenDisplacement.x / panEvent.timeDelta;
837   pan.screenVelocity.y = pan.screenDisplacement.y / panEvent.timeDelta;
838
839   // Only handle the pan gesture when the current focused actor is scrollable or within a scrollable actor
840   while(currentGesturedActor && currentGesturedActor != rootActor && !handled)
841   {
842     Dali::Toolkit::Control control = Dali::Toolkit::Control::DownCast(currentGesturedActor);
843     if(control)
844     {
845       Vector2 localCurrent;
846       control.ScreenToLocal( localCurrent.x, localCurrent.y, panEvent.currentPosition.x, panEvent.currentPosition.y );
847       pan.position = localCurrent;
848
849       Vector2 localPrevious;
850       control.ScreenToLocal( localPrevious.x, localPrevious.y, panEvent.previousPosition.x, panEvent.previousPosition.y );
851
852       pan.displacement = localCurrent - localPrevious;
853       pan.velocity.x = pan.displacement.x / panEvent.timeDelta;
854       pan.velocity.y = pan.displacement.y / panEvent.timeDelta;
855
856       handled = control.GetImplementation().OnAccessibilityPan(pan);
857     }
858
859     // If the gesture is not handled by the control, check its parent
860     if(!handled)
861     {
862       currentGesturedActor = currentGesturedActor.GetParent();
863     }
864     else
865     {
866       // If handled, then update the pan gesture properties
867       PanGestureDetector::SetPanGestureProperties( pan );
868     }
869   }
870
871   return handled;
872 }
873
874 Toolkit::FocusManager::FocusChangedSignalV2& FocusManager::FocusChangedSignal()
875 {
876   return mFocusChangedSignalV2;
877 }
878
879 Toolkit::FocusManager::FocusOvershotSignalV2& FocusManager::FocusOvershotSignal()
880 {
881   return mFocusOvershotSignalV2;
882 }
883
884 Toolkit::FocusManager::FocusedActorActivatedSignalV2& FocusManager::FocusedActorActivatedSignal()
885 {
886   return mFocusedActorActivatedSignalV2;
887 }
888
889 bool FocusManager::DoConnectSignal( BaseObject* object, ConnectionTrackerInterface* tracker, const std::string& signalName, FunctorDelegate* functor )
890 {
891   Dali::BaseHandle handle( object );
892
893   bool connected( true );
894   FocusManager* manager = dynamic_cast<FocusManager*>(object);
895
896   if( Dali::Toolkit::FocusManager::SIGNAL_FOCUS_CHANGED == signalName )
897   {
898     manager->FocusChangedSignal().Connect( tracker, functor );
899   }
900   else if( Dali::Toolkit::FocusManager::SIGNAL_FOCUS_OVERSHOT == signalName )
901   {
902     manager->FocusOvershotSignal().Connect( tracker, functor );
903   }
904   else if( Dali::Toolkit::FocusManager::SIGNAL_FOCUSED_ACTOR_ACTIVATED== signalName )
905   {
906     manager->FocusedActorActivatedSignal().Connect( tracker, functor );
907   }
908   else
909   {
910     // signalName does not match any signal
911     connected = false;
912   }
913
914   return connected;
915 }
916
917 } // namespace Internal
918
919 } // namespace Toolkit
920
921 } // namespace Dali