2 // Copyright (c) 2014 Samsung Electronics Co., Ltd.
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
8 // http://floralicense.org/license/
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.
18 #include "focus-manager-impl.h"
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>
34 namespace // unnamed namespace
37 #if defined(DEBUG_ENABLED)
38 Debug::Filter* gLogFilter = Debug::Filter::New(Debug::NoLogging, false, "LOG_FOCUS_MANAGER");
41 const char * const ACTOR_FOCUSABLE("focusable");
42 const char * const IS_FOCUS_GROUP("is-focus-group");
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);
48 * The function to be used in the hit-test algorithm to check whether the actor is hittable.
50 bool IsActorFocusableFunction(Actor actor, Dali::HitTestAlgorithm::TraverseType type)
52 bool hittable = false;
56 case Dali::HitTestAlgorithm::CHECK_ACTOR:
58 // Check whether the actor is visible and not fully transparent.
60 && actor.GetCurrentWorldColor().a > 0.01f) // not FULLY_TRANSPARENT
62 // Check whether the actor is focusable
63 Property::Index propertyActorFocusable = actor.GetPropertyIndex(ACTOR_FOCUSABLE);
64 if(propertyActorFocusable != Property::INVALID_INDEX)
66 hittable = actor.GetProperty<bool>(propertyActorFocusable);
71 case Dali::HitTestAlgorithm::DESCEND_ACTOR_TREE:
73 if( actor.IsVisible() ) // Actor is visible, if not visible then none of its children are visible.
90 FocusManager::FocusManager()
92 mIsFocusWithinGroup(false),
93 mCurrentFocusActor(FocusIDPair(0, 0)),
94 mFocusIndicatorActor(Actor()),
95 mRecursiveFocusMoveCounter(0),
96 mIsAccessibilityTtsEnabled(false),
97 mIsFocusIndicatorEnabled(false)
99 CreateDefaultFocusIndicatorActor();
101 AccessibilityManager manager = AccessibilityManager::Get();
102 manager.SetActionHandler(*this);
103 manager.SetGestureHandler(*this);
105 ChangeAccessibilityStatus();
108 FocusManager::~FocusManager()
112 FocusManager::ActorAdditionalInfo FocusManager::GetActorAdditionalInfo(const unsigned int actorID) const
114 ActorAdditionalInfo data;
115 IDAdditionalInfoConstIter iter = mIDAdditionalInfoContainer.find(actorID);
116 if(iter != mIDAdditionalInfoContainer.end())
118 data = (*iter).second;
124 void FocusManager::SynchronizeActorAdditionalInfo(const unsigned int actorID, const unsigned int order)
126 ActorAdditionalInfo actorInfo = GetActorAdditionalInfo(actorID);
127 actorInfo.mFocusOrder = order;
128 mIDAdditionalInfoContainer.erase(actorID);
129 mIDAdditionalInfoContainer.insert(IDAdditionalInfoPair(actorID, actorInfo));
132 void FocusManager::SetAccessibilityAttribute(Actor actor, Toolkit::FocusManager::AccessibilityAttribute type, const std::string& text)
136 unsigned int actorID = actor.GetId();
138 ActorAdditionalInfo info = GetActorAdditionalInfo(actorID);
139 info.mAccessibilityAttributes[type] = text;
141 mIDAdditionalInfoContainer.erase(actorID);
142 mIDAdditionalInfoContainer.insert(IDAdditionalInfoPair(actorID, info));
146 std::string FocusManager::GetAccessibilityAttribute(Actor actor, Toolkit::FocusManager::AccessibilityAttribute type) const
152 ActorAdditionalInfo data = GetActorAdditionalInfo(actor.GetId());
153 text = data.mAccessibilityAttributes[type];
159 void FocusManager::SetFocusOrder(Actor actor, const unsigned int order)
161 // Do nothing if the focus order of the actor is not changed.
162 if(actor && GetFocusOrder(actor) != order)
164 // Firstly delete the actor from the focus chain if it's already there with a different focus order.
165 mFocusIDContainer.erase(GetFocusOrder(actor));
167 // Create actor focusable property if not already created.
168 Property::Index propertyActorFocusable = actor.GetPropertyIndex(ACTOR_FOCUSABLE);
169 if(propertyActorFocusable == Property::INVALID_INDEX)
171 propertyActorFocusable = actor.RegisterProperty(ACTOR_FOCUSABLE, true);
176 // The actor is not focusable without a defined focus order.
177 actor.SetProperty(propertyActorFocusable, false);
179 // If the actor is currently being focused, it should clear the focus
180 if(actor == GetCurrentFocusActor())
185 else // Insert the actor to the focus chain
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())
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));
197 // Update the actor's focus order in its additional data
198 SynchronizeActorAdditionalInfo((*lastIter).second, (*lastIter).first + 1);
200 for(FocusIDIter iter = lastIter; iter != focusIDIter; iter--)
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;
207 // Update the actor's focus order in its additional data
208 SynchronizeActorAdditionalInfo(actorID, (*iter).first);
211 mFocusIDContainer.erase(order);
214 // The actor is focusable
215 actor.SetProperty(propertyActorFocusable, true);
217 // Now we insert the actor into the focus chain with the specified focus order
218 mFocusIDContainer.insert(FocusIDPair(order, actor.GetId()));
221 // Update the actor's focus order in its additional data
222 SynchronizeActorAdditionalInfo(actor.GetId(), order);
226 unsigned int FocusManager::GetFocusOrder(Actor actor) const
228 unsigned int focusOrder = 0;
232 ActorAdditionalInfo data = GetActorAdditionalInfo(actor.GetId());
233 focusOrder = data.mFocusOrder;
239 unsigned int FocusManager::GenerateNewFocusOrder() const
241 unsigned int order = 1;
242 FocusIDContainer::const_reverse_iterator iter = mFocusIDContainer.rbegin();
244 if(iter != mFocusIDContainer.rend())
246 order = (*iter).first + 1;
252 Actor FocusManager::GetActorByFocusOrder(const unsigned int order)
254 Actor actor = Actor();
256 FocusIDIter focusIDIter = mFocusIDContainer.find(order);
257 if(focusIDIter != mFocusIDContainer.end())
259 Actor rootActor = Stage::GetCurrent().GetRootLayer();
260 actor = rootActor.FindChildById(mFocusIDContainer[order]);
266 bool FocusManager::SetCurrentFocusActor(Actor actor)
270 return DoSetCurrentFocusActor(actor.GetId());
276 bool FocusManager::DoSetCurrentFocusActor(const unsigned int actorID)
278 Actor rootActor = Stage::GetCurrent().GetRootLayer();
280 // If the group mode is enabled, check which focus group the current focused actor belongs to
282 if(mIsFocusWithinGroup)
284 focusGroup = GetFocusGroup(GetCurrentFocusActor());
289 focusGroup = rootActor;
292 Actor actor = focusGroup.FindChildById(actorID);
294 // Check whether the actor is in the stage
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)
302 actorFocusable = actor.GetProperty<bool>(propertyActorFocusable);
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)
310 actorVisible = parent.IsVisible();
311 parent = parent.GetParent();
314 // Check whether the actor is fully transparent
315 bool actorOpaque = actor.GetCurrentWorldColor().a > 0.01f;
317 // Set the focus only when the actor is focusable and visible and not fully transparent
318 if(actorVisible && actorFocusable && actorOpaque)
320 // Draw the focus indicator upon the focused actor
321 if(mIsFocusIndicatorEnabled && mFocusIndicatorActor)
323 actor.Add(mFocusIndicatorActor);
326 // Send notification for the change of focus actor
327 mFocusChangedSignalV2.Emit( GetCurrentFocusActor(), actor );
329 // Save the current focused actor
330 mCurrentFocusActor = FocusIDPair(GetFocusOrder(actor), actorID);
332 if(mIsAccessibilityTtsEnabled)
334 // Play the accessibility attributes with the TTS player.
335 Dali::TtsPlayer player = Dali::TtsPlayer::Get(Dali::TtsPlayer::SCREEN_READER);
337 // Combine attribute texts to one text
338 std::string informationText;
339 for(int i = 0; i < Toolkit::FocusManager::ACCESSIBILITY_ATTRIBUTE_NUM; i++)
341 if(!GetActorAdditionalInfo(actorID).mAccessibilityAttributes[i].empty())
345 informationText += ", "; // for space time between each information
347 informationText += GetActorAdditionalInfo(actorID).mAccessibilityAttributes[i];
350 player.Play(informationText);
357 DALI_LOG_WARNING("[%s:%d] FAILED\n", __FUNCTION__, __LINE__);
361 Actor FocusManager::GetCurrentFocusActor()
363 Actor rootActor = Stage::GetCurrent().GetRootLayer();
364 return rootActor.FindChildById(mCurrentFocusActor.second);
367 Actor FocusManager::GetCurrentFocusGroup()
369 return GetFocusGroup(GetCurrentFocusActor());
372 unsigned int FocusManager::GetCurrentFocusOrder()
374 return mCurrentFocusActor.first;
377 bool FocusManager::MoveFocusForward()
380 mRecursiveFocusMoveCounter = 0;
382 FocusIDIter focusIDIter = mFocusIDContainer.find(mCurrentFocusActor.first);
383 if(focusIDIter != mFocusIDContainer.end())
385 DALI_LOG_INFO( gLogFilter, Debug::General, "[%s:%d] focus order : %d\n", __FUNCTION__, __LINE__, (*focusIDIter).first);
386 ret = DoMoveFocus(focusIDIter, true, mIsWrapped);
390 // TODO: if there is not focused actor, move first actor
391 if(!mFocusIDContainer.empty())
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);
400 DALI_LOG_INFO( gLogFilter, Debug::General, "[%s] %s\n", __FUNCTION__, ret?"SUCCEED!!!":"FAILED!!!");
405 bool FocusManager::MoveFocusBackward()
408 mRecursiveFocusMoveCounter = 0;
410 FocusIDIter focusIDIter = mFocusIDContainer.find(mCurrentFocusActor.first);
411 if(focusIDIter != mFocusIDContainer.end())
413 DALI_LOG_INFO( gLogFilter, Debug::General, "[%s:%d] focus order : %d\n", __FUNCTION__, __LINE__, (*focusIDIter).first);
414 ret = DoMoveFocus(focusIDIter, false, mIsWrapped);
418 // TODO: if there is not focused actor, move last actor
419 if(!mFocusIDContainer.empty())
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);
429 DALI_LOG_INFO( gLogFilter, Debug::General, "[%s] %s\n", __FUNCTION__, ret?"SUCCEED!!!":"FAILED!!!");
434 void FocusManager::DoActivate(Actor actor)
438 Dali::Toolkit::Control control = Dali::Toolkit::Control::DownCast(actor);
441 // Notify the control that it is activated
442 control.GetImplementation().OnActivated();
445 // Send notification for the activation of focused actor
446 mFocusedActorActivatedSignalV2.Emit(actor);
450 void FocusManager::ClearFocus()
452 Actor actor = GetCurrentFocusActor();
455 actor.Remove(mFocusIndicatorActor);
458 mCurrentFocusActor = FocusIDPair(0, 0);
460 // Send notification for the change of focus actor
461 mFocusChangedSignalV2.Emit(actor, Actor());
463 if(mIsAccessibilityTtsEnabled)
465 // Stop the TTS playing if any
466 Dali::TtsPlayer player = Dali::TtsPlayer::Get(Dali::TtsPlayer::SCREEN_READER);
471 void FocusManager::Reset()
474 mFocusIDContainer.clear();
475 mIDAdditionalInfoContainer.clear();
478 void FocusManager::SetFocusGroup(Actor actor, bool isFocusGroup)
482 // Create focus group property if not already created.
483 Property::Index propertyIsFocusGroup = actor.GetPropertyIndex(IS_FOCUS_GROUP);
484 if(propertyIsFocusGroup == Property::INVALID_INDEX)
486 propertyIsFocusGroup = actor.RegisterProperty(IS_FOCUS_GROUP, isFocusGroup);
490 actor.SetProperty(propertyIsFocusGroup, isFocusGroup);
495 bool FocusManager::IsFocusGroup(Actor actor) const
497 // Check whether the actor is a focus group
498 bool isFocusGroup = false;
502 Property::Index propertyIsFocusGroup = actor.GetPropertyIndex(IS_FOCUS_GROUP);
503 if(propertyIsFocusGroup != Property::INVALID_INDEX)
505 isFocusGroup = actor.GetProperty<bool>(propertyIsFocusGroup);
512 Actor FocusManager::GetFocusGroup(Actor actor)
514 // Go through the actor's hierarchy to check which focus group the actor belongs to
515 while (actor && !IsFocusGroup(actor))
517 actor = actor.GetParent();
523 void FocusManager::SetGroupMode(bool enabled)
525 mIsFocusWithinGroup = enabled;
528 bool FocusManager::GetGroupMode() const
530 return mIsFocusWithinGroup;
533 void FocusManager::SetWrapMode(bool wrapped)
535 mIsWrapped = wrapped;
538 bool FocusManager::GetWrapMode() const
543 void FocusManager::SetFocusIndicatorActor(Actor indicator)
545 mFocusIndicatorActor = indicator;
548 Actor FocusManager::GetFocusIndicatorActor()
550 return mFocusIndicatorActor;
553 bool FocusManager::DoMoveFocus(FocusIDIter focusIDIter, bool forward, bool wrapped)
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);
558 if( (forward && ++focusIDIter == mFocusIDContainer.end())
559 || (!forward && focusIDIter-- == mFocusIDContainer.begin()) )
565 focusIDIter = mFocusIDContainer.begin();
569 focusIDIter = mFocusIDContainer.end();
570 --focusIDIter;//We want forward iterator to the last element here
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);
579 return false; // Try to move the focus out of the scope
583 if((focusIDIter != mFocusIDContainer.end()) && !DoSetCurrentFocusActor((*focusIDIter).second))
585 mRecursiveFocusMoveCounter++;
586 if(mRecursiveFocusMoveCounter > mFocusIDContainer.size())
588 // We've attempted to focus all the actors in the whole focus chain and no actor
589 // can be focused successfully.
591 DALI_LOG_WARNING("[%s] There is no more focusable actor in %d focus chains\n", __FUNCTION__, mRecursiveFocusMoveCounter);
597 return DoMoveFocus(focusIDIter, forward, wrapped);
604 void FocusManager::SetFocusable(Actor actor, bool focusable)
608 // Create actor focusable property if not already created.
609 Property::Index propertyActorFocusable = actor.GetPropertyIndex(ACTOR_FOCUSABLE);
610 if(propertyActorFocusable == Property::INVALID_INDEX)
612 propertyActorFocusable = actor.RegisterProperty(ACTOR_FOCUSABLE, focusable);
616 actor.SetProperty(propertyActorFocusable, focusable);
621 void FocusManager::CreateDefaultFocusIndicatorActor()
623 // Create a focus indicator actor shared by all the focusable actors
624 Image borderImage = Image::New(FOCUS_BORDER_IMAGE_PATH);
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));
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);
638 SetFocusIndicatorActor(focusIndicator);
641 bool FocusManager::ChangeAccessibilityStatus()
643 AccessibilityManager manager = AccessibilityManager::Get();
644 mIsAccessibilityTtsEnabled = manager.IsEnabled();
646 if(mIsAccessibilityTtsEnabled)
648 // Show indicator when tts turned on if there is focused actor.
649 Actor actor = GetCurrentFocusActor();
652 if(mFocusIndicatorActor)
654 actor.Add(mFocusIndicatorActor);
657 mIsFocusIndicatorEnabled = true;
661 // Hide indicator when tts turned off
662 Actor actor = GetCurrentFocusActor();
665 actor.Remove(mFocusIndicatorActor);
667 mIsFocusIndicatorEnabled = false;
673 bool FocusManager::AccessibilityActionNext()
675 if(mIsAccessibilityTtsEnabled)
677 return MoveFocusForward();
685 bool FocusManager::AccessibilityActionPrevious()
687 if(mIsAccessibilityTtsEnabled)
689 return MoveFocusBackward();
697 bool FocusManager::AccessibilityActionActivate()
701 Actor actor = GetCurrentFocusActor();
711 bool FocusManager::AccessibilityActionRead(bool allowReadAgain)
715 if(mIsAccessibilityTtsEnabled)
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 );
722 FocusIDIter focusIDIter = mFocusIDContainer.find(GetFocusOrder(results.actor));
723 if(focusIDIter != mFocusIDContainer.end())
725 if( allowReadAgain || (results.actor != GetCurrentFocusActor()) )
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");
737 bool FocusManager::AccessibilityActionReadNext()
739 if(mIsAccessibilityTtsEnabled)
741 return MoveFocusForward();
749 bool FocusManager::AccessibilityActionReadPrevious()
751 if(mIsAccessibilityTtsEnabled)
753 return MoveFocusBackward();
761 bool FocusManager::AccessibilityActionUp()
765 if(mIsAccessibilityTtsEnabled)
767 Actor actor = GetCurrentFocusActor();
770 Dali::Toolkit::Control control = Dali::Toolkit::Control::DownCast(actor);
773 // Notify the control that it is activated
774 ret = control.GetImplementation().OnAccessibilityValueChange(true);
782 bool FocusManager::AccessibilityActionDown()
786 if(mIsAccessibilityTtsEnabled)
788 Actor actor = GetCurrentFocusActor();
791 Dali::Toolkit::Control control = Dali::Toolkit::Control::DownCast(actor);
794 // Notify the control that it is activated
795 ret = control.GetImplementation().OnAccessibilityValueChange(false);
803 bool FocusManager::ClearAccessibilityFocus()
805 if(mIsAccessibilityTtsEnabled)
816 bool FocusManager::AccessibilityActionBack()
818 // TODO: Back to previous view
820 return mIsAccessibilityTtsEnabled;
823 bool FocusManager::HandlePanGesture(const Integration::PanGestureEvent& panEvent)
825 bool handled = false;
827 Actor currentGesturedActor = GetCurrentFocusActor();
828 Actor rootActor = Stage::GetCurrent().GetRootLayer();
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;
838 // Only handle the pan gesture when the current focused actor is scrollable or within a scrollable actor
839 while(currentGesturedActor && currentGesturedActor != rootActor && !handled)
841 Dali::Toolkit::Control control = Dali::Toolkit::Control::DownCast(currentGesturedActor);
844 Vector2 localCurrent;
845 control.ScreenToLocal( localCurrent.x, localCurrent.y, panEvent.currentPosition.x, panEvent.currentPosition.y );
846 pan.position = localCurrent;
848 Vector2 localPrevious;
849 control.ScreenToLocal( localPrevious.x, localPrevious.y, panEvent.previousPosition.x, panEvent.previousPosition.y );
851 pan.displacement = localCurrent - localPrevious;
852 pan.velocity.x = pan.displacement.x / panEvent.timeDelta;
853 pan.velocity.y = pan.displacement.y / panEvent.timeDelta;
855 handled = control.GetImplementation().OnAccessibilityPan(pan);
858 // If the gesture is not handled by the control, check its parent
861 currentGesturedActor = currentGesturedActor.GetParent();
865 // If handled, then update the pan gesture properties
866 PanGestureDetector::SetPanGestureProperties( pan );
873 Toolkit::FocusManager::FocusChangedSignalV2& FocusManager::FocusChangedSignal()
875 return mFocusChangedSignalV2;
878 Toolkit::FocusManager::FocusOvershotSignalV2& FocusManager::FocusOvershotSignal()
880 return mFocusOvershotSignalV2;
883 Toolkit::FocusManager::FocusedActorActivatedSignalV2& FocusManager::FocusedActorActivatedSignal()
885 return mFocusedActorActivatedSignalV2;
888 bool FocusManager::DoConnectSignal( BaseObject* object, ConnectionTrackerInterface* tracker, const std::string& signalName, FunctorDelegate* functor )
890 Dali::BaseHandle handle( object );
892 bool connected( true );
893 FocusManager* manager = dynamic_cast<FocusManager*>(object);
895 if( Dali::Toolkit::FocusManager::SIGNAL_FOCUS_CHANGED == signalName )
897 manager->FocusChangedSignal().Connect( tracker, functor );
899 else if( Dali::Toolkit::FocusManager::SIGNAL_FOCUS_OVERSHOT == signalName )
901 manager->FocusOvershotSignal().Connect( tracker, functor );
903 else if( Dali::Toolkit::FocusManager::SIGNAL_FOCUSED_ACTOR_ACTIVATED== signalName )
905 manager->FocusedActorActivatedSignal().Connect( tracker, functor );
909 // signalName does not match any signal
916 } // namespace Internal
918 } // namespace Toolkit