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