2 * Copyright (c) 2014 Samsung Electronics Co., Ltd.
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
19 #include "focus-manager-impl.h"
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>
35 namespace // unnamed namespace
38 #if defined(DEBUG_ENABLED)
39 Debug::Filter* gLogFilter = Debug::Filter::New(Debug::NoLogging, false, "LOG_FOCUS_MANAGER");
42 const char * const ACTOR_FOCUSABLE("focusable");
43 const char * const IS_FOCUS_GROUP("is-focus-group");
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);
49 * The function to be used in the hit-test algorithm to check whether the actor is hittable.
51 bool IsActorFocusableFunction(Actor actor, Dali::HitTestAlgorithm::TraverseType type)
53 bool hittable = false;
57 case Dali::HitTestAlgorithm::CHECK_ACTOR:
59 // Check whether the actor is visible and not fully transparent.
61 && actor.GetCurrentWorldColor().a > 0.01f) // not FULLY_TRANSPARENT
63 // Check whether the actor is focusable
64 Property::Index propertyActorFocusable = actor.GetPropertyIndex(ACTOR_FOCUSABLE);
65 if(propertyActorFocusable != Property::INVALID_INDEX)
67 hittable = actor.GetProperty<bool>(propertyActorFocusable);
72 case Dali::HitTestAlgorithm::DESCEND_ACTOR_TREE:
74 if( actor.IsVisible() ) // Actor is visible, if not visible then none of its children are visible.
91 FocusManager::FocusManager()
93 mIsFocusWithinGroup(false),
94 mCurrentFocusActor(FocusIDPair(0, 0)),
95 mFocusIndicatorActor(Actor()),
96 mRecursiveFocusMoveCounter(0),
97 mIsAccessibilityTtsEnabled(false),
98 mIsFocusIndicatorEnabled(false)
100 CreateDefaultFocusIndicatorActor();
102 AccessibilityManager manager = AccessibilityManager::Get();
103 manager.SetActionHandler(*this);
104 manager.SetGestureHandler(*this);
106 ChangeAccessibilityStatus();
109 FocusManager::~FocusManager()
113 FocusManager::ActorAdditionalInfo FocusManager::GetActorAdditionalInfo(const unsigned int actorID) const
115 ActorAdditionalInfo data;
116 IDAdditionalInfoConstIter iter = mIDAdditionalInfoContainer.find(actorID);
117 if(iter != mIDAdditionalInfoContainer.end())
119 data = (*iter).second;
125 void FocusManager::SynchronizeActorAdditionalInfo(const unsigned int actorID, const unsigned int order)
127 ActorAdditionalInfo actorInfo = GetActorAdditionalInfo(actorID);
128 actorInfo.mFocusOrder = order;
129 mIDAdditionalInfoContainer.erase(actorID);
130 mIDAdditionalInfoContainer.insert(IDAdditionalInfoPair(actorID, actorInfo));
133 void FocusManager::SetAccessibilityAttribute(Actor actor, Toolkit::FocusManager::AccessibilityAttribute type, const std::string& text)
137 unsigned int actorID = actor.GetId();
139 ActorAdditionalInfo info = GetActorAdditionalInfo(actorID);
140 info.mAccessibilityAttributes[type] = text;
142 mIDAdditionalInfoContainer.erase(actorID);
143 mIDAdditionalInfoContainer.insert(IDAdditionalInfoPair(actorID, info));
147 std::string FocusManager::GetAccessibilityAttribute(Actor actor, Toolkit::FocusManager::AccessibilityAttribute type) const
153 ActorAdditionalInfo data = GetActorAdditionalInfo(actor.GetId());
154 text = data.mAccessibilityAttributes[type];
160 void FocusManager::SetFocusOrder(Actor actor, const unsigned int order)
162 // Do nothing if the focus order of the actor is not changed.
163 if(actor && GetFocusOrder(actor) != order)
165 // Firstly delete the actor from the focus chain if it's already there with a different focus order.
166 mFocusIDContainer.erase(GetFocusOrder(actor));
168 // Create actor focusable property if not already created.
169 Property::Index propertyActorFocusable = actor.GetPropertyIndex(ACTOR_FOCUSABLE);
170 if(propertyActorFocusable == Property::INVALID_INDEX)
172 propertyActorFocusable = actor.RegisterProperty(ACTOR_FOCUSABLE, true);
177 // The actor is not focusable without a defined focus order.
178 actor.SetProperty(propertyActorFocusable, false);
180 // If the actor is currently being focused, it should clear the focus
181 if(actor == GetCurrentFocusActor())
186 else // Insert the actor to the focus chain
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())
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));
198 // Update the actor's focus order in its additional data
199 SynchronizeActorAdditionalInfo((*lastIter).second, (*lastIter).first + 1);
201 for(FocusIDIter iter = lastIter; iter != focusIDIter; iter--)
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;
208 // Update the actor's focus order in its additional data
209 SynchronizeActorAdditionalInfo(actorID, (*iter).first);
212 mFocusIDContainer.erase(order);
215 // The actor is focusable
216 actor.SetProperty(propertyActorFocusable, true);
218 // Now we insert the actor into the focus chain with the specified focus order
219 mFocusIDContainer.insert(FocusIDPair(order, actor.GetId()));
222 // Update the actor's focus order in its additional data
223 SynchronizeActorAdditionalInfo(actor.GetId(), order);
227 unsigned int FocusManager::GetFocusOrder(Actor actor) const
229 unsigned int focusOrder = 0;
233 ActorAdditionalInfo data = GetActorAdditionalInfo(actor.GetId());
234 focusOrder = data.mFocusOrder;
240 unsigned int FocusManager::GenerateNewFocusOrder() const
242 unsigned int order = 1;
243 FocusIDContainer::const_reverse_iterator iter = mFocusIDContainer.rbegin();
245 if(iter != mFocusIDContainer.rend())
247 order = (*iter).first + 1;
253 Actor FocusManager::GetActorByFocusOrder(const unsigned int order)
255 Actor actor = Actor();
257 FocusIDIter focusIDIter = mFocusIDContainer.find(order);
258 if(focusIDIter != mFocusIDContainer.end())
260 Actor rootActor = Stage::GetCurrent().GetRootLayer();
261 actor = rootActor.FindChildById(mFocusIDContainer[order]);
267 bool FocusManager::SetCurrentFocusActor(Actor actor)
271 return DoSetCurrentFocusActor(actor.GetId());
277 bool FocusManager::DoSetCurrentFocusActor(const unsigned int actorID)
279 Actor rootActor = Stage::GetCurrent().GetRootLayer();
281 // If the group mode is enabled, check which focus group the current focused actor belongs to
283 if(mIsFocusWithinGroup)
285 focusGroup = GetFocusGroup(GetCurrentFocusActor());
290 focusGroup = rootActor;
293 Actor actor = focusGroup.FindChildById(actorID);
295 // Check whether the actor is in the stage
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)
303 actorFocusable = actor.GetProperty<bool>(propertyActorFocusable);
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)
311 actorVisible = parent.IsVisible();
312 parent = parent.GetParent();
315 // Check whether the actor is fully transparent
316 bool actorOpaque = actor.GetCurrentWorldColor().a > 0.01f;
318 // Set the focus only when the actor is focusable and visible and not fully transparent
319 if(actorVisible && actorFocusable && actorOpaque)
321 // Draw the focus indicator upon the focused actor
322 if(mIsFocusIndicatorEnabled && mFocusIndicatorActor)
324 actor.Add(mFocusIndicatorActor);
327 // Send notification for the change of focus actor
328 mFocusChangedSignalV2.Emit( GetCurrentFocusActor(), actor );
330 // Save the current focused actor
331 mCurrentFocusActor = FocusIDPair(GetFocusOrder(actor), actorID);
333 if(mIsAccessibilityTtsEnabled)
335 // Play the accessibility attributes with the TTS player.
336 Dali::TtsPlayer player = Dali::TtsPlayer::Get(Dali::TtsPlayer::SCREEN_READER);
338 // Combine attribute texts to one text
339 std::string informationText;
340 for(int i = 0; i < Toolkit::FocusManager::ACCESSIBILITY_ATTRIBUTE_NUM; i++)
342 if(!GetActorAdditionalInfo(actorID).mAccessibilityAttributes[i].empty())
346 informationText += ", "; // for space time between each information
348 informationText += GetActorAdditionalInfo(actorID).mAccessibilityAttributes[i];
351 player.Play(informationText);
358 DALI_LOG_WARNING("[%s:%d] FAILED\n", __FUNCTION__, __LINE__);
362 Actor FocusManager::GetCurrentFocusActor()
364 Actor rootActor = Stage::GetCurrent().GetRootLayer();
365 return rootActor.FindChildById(mCurrentFocusActor.second);
368 Actor FocusManager::GetCurrentFocusGroup()
370 return GetFocusGroup(GetCurrentFocusActor());
373 unsigned int FocusManager::GetCurrentFocusOrder()
375 return mCurrentFocusActor.first;
378 bool FocusManager::MoveFocusForward()
381 mRecursiveFocusMoveCounter = 0;
383 FocusIDIter focusIDIter = mFocusIDContainer.find(mCurrentFocusActor.first);
384 if(focusIDIter != mFocusIDContainer.end())
386 DALI_LOG_INFO( gLogFilter, Debug::General, "[%s:%d] focus order : %d\n", __FUNCTION__, __LINE__, (*focusIDIter).first);
387 ret = DoMoveFocus(focusIDIter, true, mIsWrapped);
391 // TODO: if there is not focused actor, move first actor
392 if(!mFocusIDContainer.empty())
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);
401 DALI_LOG_INFO( gLogFilter, Debug::General, "[%s] %s\n", __FUNCTION__, ret?"SUCCEED!!!":"FAILED!!!");
406 bool FocusManager::MoveFocusBackward()
409 mRecursiveFocusMoveCounter = 0;
411 FocusIDIter focusIDIter = mFocusIDContainer.find(mCurrentFocusActor.first);
412 if(focusIDIter != mFocusIDContainer.end())
414 DALI_LOG_INFO( gLogFilter, Debug::General, "[%s:%d] focus order : %d\n", __FUNCTION__, __LINE__, (*focusIDIter).first);
415 ret = DoMoveFocus(focusIDIter, false, mIsWrapped);
419 // TODO: if there is not focused actor, move last actor
420 if(!mFocusIDContainer.empty())
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);
430 DALI_LOG_INFO( gLogFilter, Debug::General, "[%s] %s\n", __FUNCTION__, ret?"SUCCEED!!!":"FAILED!!!");
435 void FocusManager::DoActivate(Actor actor)
439 Dali::Toolkit::Control control = Dali::Toolkit::Control::DownCast(actor);
442 // Notify the control that it is activated
443 control.GetImplementation().OnActivated();
446 // Send notification for the activation of focused actor
447 mFocusedActorActivatedSignalV2.Emit(actor);
451 void FocusManager::ClearFocus()
453 Actor actor = GetCurrentFocusActor();
456 actor.Remove(mFocusIndicatorActor);
459 mCurrentFocusActor = FocusIDPair(0, 0);
461 // Send notification for the change of focus actor
462 mFocusChangedSignalV2.Emit(actor, Actor());
464 if(mIsAccessibilityTtsEnabled)
466 // Stop the TTS playing if any
467 Dali::TtsPlayer player = Dali::TtsPlayer::Get(Dali::TtsPlayer::SCREEN_READER);
472 void FocusManager::Reset()
475 mFocusIDContainer.clear();
476 mIDAdditionalInfoContainer.clear();
479 void FocusManager::SetFocusGroup(Actor actor, bool isFocusGroup)
483 // Create focus group property if not already created.
484 Property::Index propertyIsFocusGroup = actor.GetPropertyIndex(IS_FOCUS_GROUP);
485 if(propertyIsFocusGroup == Property::INVALID_INDEX)
487 propertyIsFocusGroup = actor.RegisterProperty(IS_FOCUS_GROUP, isFocusGroup);
491 actor.SetProperty(propertyIsFocusGroup, isFocusGroup);
496 bool FocusManager::IsFocusGroup(Actor actor) const
498 // Check whether the actor is a focus group
499 bool isFocusGroup = false;
503 Property::Index propertyIsFocusGroup = actor.GetPropertyIndex(IS_FOCUS_GROUP);
504 if(propertyIsFocusGroup != Property::INVALID_INDEX)
506 isFocusGroup = actor.GetProperty<bool>(propertyIsFocusGroup);
513 Actor FocusManager::GetFocusGroup(Actor actor)
515 // Go through the actor's hierarchy to check which focus group the actor belongs to
516 while (actor && !IsFocusGroup(actor))
518 actor = actor.GetParent();
524 void FocusManager::SetGroupMode(bool enabled)
526 mIsFocusWithinGroup = enabled;
529 bool FocusManager::GetGroupMode() const
531 return mIsFocusWithinGroup;
534 void FocusManager::SetWrapMode(bool wrapped)
536 mIsWrapped = wrapped;
539 bool FocusManager::GetWrapMode() const
544 void FocusManager::SetFocusIndicatorActor(Actor indicator)
546 mFocusIndicatorActor = indicator;
549 Actor FocusManager::GetFocusIndicatorActor()
551 return mFocusIndicatorActor;
554 bool FocusManager::DoMoveFocus(FocusIDIter focusIDIter, bool forward, bool wrapped)
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);
559 if( (forward && ++focusIDIter == mFocusIDContainer.end())
560 || (!forward && focusIDIter-- == mFocusIDContainer.begin()) )
566 focusIDIter = mFocusIDContainer.begin();
570 focusIDIter = mFocusIDContainer.end();
571 --focusIDIter;//We want forward iterator to the last element here
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);
580 return false; // Try to move the focus out of the scope
584 if((focusIDIter != mFocusIDContainer.end()) && !DoSetCurrentFocusActor((*focusIDIter).second))
586 mRecursiveFocusMoveCounter++;
587 if(mRecursiveFocusMoveCounter > mFocusIDContainer.size())
589 // We've attempted to focus all the actors in the whole focus chain and no actor
590 // can be focused successfully.
592 DALI_LOG_WARNING("[%s] There is no more focusable actor in %d focus chains\n", __FUNCTION__, mRecursiveFocusMoveCounter);
598 return DoMoveFocus(focusIDIter, forward, wrapped);
605 void FocusManager::SetFocusable(Actor actor, bool focusable)
609 // Create actor focusable property if not already created.
610 Property::Index propertyActorFocusable = actor.GetPropertyIndex(ACTOR_FOCUSABLE);
611 if(propertyActorFocusable == Property::INVALID_INDEX)
613 propertyActorFocusable = actor.RegisterProperty(ACTOR_FOCUSABLE, focusable);
617 actor.SetProperty(propertyActorFocusable, focusable);
622 void FocusManager::CreateDefaultFocusIndicatorActor()
624 // Create a focus indicator actor shared by all the focusable actors
625 Image borderImage = Image::New(FOCUS_BORDER_IMAGE_PATH);
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));
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);
639 SetFocusIndicatorActor(focusIndicator);
642 bool FocusManager::ChangeAccessibilityStatus()
644 AccessibilityManager manager = AccessibilityManager::Get();
645 mIsAccessibilityTtsEnabled = manager.IsEnabled();
647 if(mIsAccessibilityTtsEnabled)
649 // Show indicator when tts turned on if there is focused actor.
650 Actor actor = GetCurrentFocusActor();
653 if(mFocusIndicatorActor)
655 actor.Add(mFocusIndicatorActor);
658 mIsFocusIndicatorEnabled = true;
662 // Hide indicator when tts turned off
663 Actor actor = GetCurrentFocusActor();
666 actor.Remove(mFocusIndicatorActor);
668 mIsFocusIndicatorEnabled = false;
674 bool FocusManager::AccessibilityActionNext()
676 if(mIsAccessibilityTtsEnabled)
678 return MoveFocusForward();
686 bool FocusManager::AccessibilityActionPrevious()
688 if(mIsAccessibilityTtsEnabled)
690 return MoveFocusBackward();
698 bool FocusManager::AccessibilityActionActivate()
702 Actor actor = GetCurrentFocusActor();
712 bool FocusManager::AccessibilityActionRead(bool allowReadAgain)
716 if(mIsAccessibilityTtsEnabled)
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 );
723 FocusIDIter focusIDIter = mFocusIDContainer.find(GetFocusOrder(results.actor));
724 if(focusIDIter != mFocusIDContainer.end())
726 if( allowReadAgain || (results.actor != GetCurrentFocusActor()) )
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");
738 bool FocusManager::AccessibilityActionReadNext()
740 if(mIsAccessibilityTtsEnabled)
742 return MoveFocusForward();
750 bool FocusManager::AccessibilityActionReadPrevious()
752 if(mIsAccessibilityTtsEnabled)
754 return MoveFocusBackward();
762 bool FocusManager::AccessibilityActionUp()
766 if(mIsAccessibilityTtsEnabled)
768 Actor actor = GetCurrentFocusActor();
771 Dali::Toolkit::Control control = Dali::Toolkit::Control::DownCast(actor);
774 // Notify the control that it is activated
775 ret = control.GetImplementation().OnAccessibilityValueChange(true);
783 bool FocusManager::AccessibilityActionDown()
787 if(mIsAccessibilityTtsEnabled)
789 Actor actor = GetCurrentFocusActor();
792 Dali::Toolkit::Control control = Dali::Toolkit::Control::DownCast(actor);
795 // Notify the control that it is activated
796 ret = control.GetImplementation().OnAccessibilityValueChange(false);
804 bool FocusManager::ClearAccessibilityFocus()
806 if(mIsAccessibilityTtsEnabled)
817 bool FocusManager::AccessibilityActionBack()
819 // TODO: Back to previous view
821 return mIsAccessibilityTtsEnabled;
824 bool FocusManager::HandlePanGesture(const Integration::PanGestureEvent& panEvent)
826 bool handled = false;
828 Actor currentGesturedActor = GetCurrentFocusActor();
829 Actor rootActor = Stage::GetCurrent().GetRootLayer();
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;
839 // Only handle the pan gesture when the current focused actor is scrollable or within a scrollable actor
840 while(currentGesturedActor && currentGesturedActor != rootActor && !handled)
842 Dali::Toolkit::Control control = Dali::Toolkit::Control::DownCast(currentGesturedActor);
845 Vector2 localCurrent;
846 control.ScreenToLocal( localCurrent.x, localCurrent.y, panEvent.currentPosition.x, panEvent.currentPosition.y );
847 pan.position = localCurrent;
849 Vector2 localPrevious;
850 control.ScreenToLocal( localPrevious.x, localPrevious.y, panEvent.previousPosition.x, panEvent.previousPosition.y );
852 pan.displacement = localCurrent - localPrevious;
853 pan.velocity.x = pan.displacement.x / panEvent.timeDelta;
854 pan.velocity.y = pan.displacement.y / panEvent.timeDelta;
856 handled = control.GetImplementation().OnAccessibilityPan(pan);
859 // If the gesture is not handled by the control, check its parent
862 currentGesturedActor = currentGesturedActor.GetParent();
866 // If handled, then update the pan gesture properties
867 PanGestureDetector::SetPanGestureProperties( pan );
874 Toolkit::FocusManager::FocusChangedSignalV2& FocusManager::FocusChangedSignal()
876 return mFocusChangedSignalV2;
879 Toolkit::FocusManager::FocusOvershotSignalV2& FocusManager::FocusOvershotSignal()
881 return mFocusOvershotSignalV2;
884 Toolkit::FocusManager::FocusedActorActivatedSignalV2& FocusManager::FocusedActorActivatedSignal()
886 return mFocusedActorActivatedSignalV2;
889 bool FocusManager::DoConnectSignal( BaseObject* object, ConnectionTrackerInterface* tracker, const std::string& signalName, FunctorDelegate* functor )
891 Dali::BaseHandle handle( object );
893 bool connected( true );
894 FocusManager* manager = dynamic_cast<FocusManager*>(object);
896 if( Dali::Toolkit::FocusManager::SIGNAL_FOCUS_CHANGED == signalName )
898 manager->FocusChangedSignal().Connect( tracker, functor );
900 else if( Dali::Toolkit::FocusManager::SIGNAL_FOCUS_OVERSHOT == signalName )
902 manager->FocusOvershotSignal().Connect( tracker, functor );
904 else if( Dali::Toolkit::FocusManager::SIGNAL_FOCUSED_ACTOR_ACTIVATED== signalName )
906 manager->FocusedActorActivatedSignal().Connect( tracker, functor );
910 // signalName does not match any signal
917 } // namespace Internal
919 } // namespace Toolkit