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