X-Git-Url: http://review.tizen.org/git/?p=platform%2Fcore%2Fuifw%2Fdali-toolkit.git;a=blobdiff_plain;f=dali-toolkit%2Finternal%2Faccessibility-manager%2Faccessibility-manager-impl.cpp;h=80a6865099bb42597dd35fd95c4cb758a532f39b;hp=e336eeeabf00beb49043c8495a8a6d50c000f37d;hb=8a647e87a01c5c78451653c1264a9eea81ac9b20;hpb=04807c7be2d762bb23e3865fd2642ace1b3f1855;ds=sidebyside diff --git a/dali-toolkit/internal/accessibility-manager/accessibility-manager-impl.cpp b/dali-toolkit/internal/accessibility-manager/accessibility-manager-impl.cpp index e336eee..80a6865 100644 --- a/dali-toolkit/internal/accessibility-manager/accessibility-manager-impl.cpp +++ b/dali-toolkit/internal/accessibility-manager/accessibility-manager-impl.cpp @@ -19,20 +19,13 @@ #include "accessibility-manager-impl.h" // EXTERNAL INCLUDES -#include // for strcmp -#include -#include -#include -#include -#include -#include -#include +#include +#include // INTERNAL INCLUDES -#include #include #include -#include +#include namespace Dali { @@ -43,365 +36,113 @@ namespace Toolkit namespace Internal { -namespace // unnamed namespace -{ - -// Signals - -const char* const SIGNAL_FOCUS_CHANGED = "focusChanged"; -const char* const SIGNAL_FOCUS_OVERSHOT = "focusOvershot"; -const char* const SIGNAL_FOCUSED_ACTOR_ACTIVATED = "focusedActorActivated"; - -#if defined(DEBUG_ENABLED) -Debug::Filter* gLogFilter = Debug::Filter::New(Debug::NoLogging, false, "LOG_FOCUS_MANAGER"); -#endif - -const char* const ACTOR_FOCUSABLE("focusable"); -const char* const IS_FOCUS_GROUP("isFocusGroup"); - -const char* FOCUS_BORDER_IMAGE_FILE_NAME = "B16-8_TTS_focus.9.png"; - -const char* FOCUS_SOUND_FILE_NAME = "Focus.ogg"; -const char* FOCUS_CHAIN_END_SOUND_FILE_NAME = "End_of_List.ogg"; - -/** - * The function to be used in the hit-test algorithm to check whether the actor is hittable. - */ -bool IsActorFocusableFunction(Actor actor, Dali::HitTestAlgorithm::TraverseType type) -{ - bool hittable = false; - - switch (type) - { - case Dali::HitTestAlgorithm::CHECK_ACTOR: - { - // Check whether the actor is visible and not fully transparent. - if( actor.GetCurrentProperty< bool >( Actor::Property::VISIBLE ) - && actor.GetCurrentProperty< Vector4 >( Actor::Property::WORLD_COLOR ).a > 0.01f) // not FULLY_TRANSPARENT - { - // Check whether the actor is focusable - Property::Index propertyActorFocusable = actor.GetPropertyIndex(ACTOR_FOCUSABLE); - if(propertyActorFocusable != Property::INVALID_INDEX) - { - hittable = actor.GetProperty(propertyActorFocusable); - } - } - break; - } - case Dali::HitTestAlgorithm::DESCEND_ACTOR_TREE: - { - if( actor.GetCurrentProperty< bool >( Actor::Property::VISIBLE ) ) // Actor is visible, if not visible then none of its children are visible. - { - hittable = true; - } - break; - } - default: - { - break; - } - } - - return hittable; -}; - -} - AccessibilityManager::AccessibilityManager() -: mCurrentFocusActor(FocusIDPair(0, 0)), - mCurrentGesturedActor(), - mFocusIndicatorActor(), - mPreviousPosition( 0.0f, 0.0f ), - mRecursiveFocusMoveCounter(0), - mFocusSoundFilePath(), - mFocusChainEndSoundFilePath(), - mIsWrapped(false), - mIsFocusWithinGroup(false), - mIsEndcapFeedbackEnabled(false), - mIsEndcapFeedbackPlayed(false), - mIsAccessibilityTtsEnabled(false), - mTtsCreated(false), - mIsFocusIndicatorEnabled(false), - mContinuousPlayMode(false), - mIsFocusSoundFilePathSet(false), - mIsFocusChainEndSoundFilePathSet(false) { + mFocusOrder.push_back( {} ); // zero has a special meaning } AccessibilityManager::~AccessibilityManager() { } -void AccessibilityManager::Initialise() -{ - AccessibilityAdaptor adaptor = AccessibilityAdaptor::Get(); - adaptor.SetActionHandler(*this); - adaptor.SetGestureHandler(*this); - - ChangeAccessibilityStatus(); -} - -AccessibilityManager::ActorAdditionalInfo AccessibilityManager::GetActorAdditionalInfo(const unsigned int actorID) const -{ - ActorAdditionalInfo data; - IDAdditionalInfoConstIter iter = mIDAdditionalInfoContainer.find(actorID); - if(iter != mIDAdditionalInfoContainer.end()) - { - data = (*iter).second; - } - - return data; -} - -void AccessibilityManager::SynchronizeActorAdditionalInfo(const unsigned int actorID, const unsigned int order) -{ - ActorAdditionalInfo actorInfo = GetActorAdditionalInfo(actorID); - actorInfo.mFocusOrder = order; - mIDAdditionalInfoContainer.erase(actorID); - mIDAdditionalInfoContainer.insert(IDAdditionalInfoPair(actorID, actorInfo)); -} - void AccessibilityManager::SetAccessibilityAttribute(Actor actor, Toolkit::AccessibilityManager::AccessibilityAttribute type, const std::string& text) { - if(actor) + switch ( type ) { - unsigned int actorID = actor.GetProperty< int >( Actor::Property::ID ); + case Toolkit::AccessibilityManager::ACCESSIBILITY_LABEL: + actor.SetProperty( Toolkit::DevelControl::Property::ACCESSIBILITY_NAME, text ); + break; - ActorAdditionalInfo info = GetActorAdditionalInfo(actorID); - info.mAccessibilityAttributes[type] = text; + case Toolkit::AccessibilityManager::ACCESSIBILITY_HINT: + actor.SetProperty( Toolkit::DevelControl::Property::ACCESSIBILITY_DESCRIPTION, text ); + break; - mIDAdditionalInfoContainer.erase(actorID); - mIDAdditionalInfoContainer.insert(IDAdditionalInfoPair(actorID, info)); + case Toolkit::AccessibilityManager::ACCESSIBILITY_TRAIT: + case Toolkit::AccessibilityManager::ACCESSIBILITY_VALUE: + default: + break; } } std::string AccessibilityManager::GetAccessibilityAttribute(Actor actor, Toolkit::AccessibilityManager::AccessibilityAttribute type) const { - std::string text; - - if(actor) + switch ( type ) { - ActorAdditionalInfo data = GetActorAdditionalInfo(actor.GetProperty< int >( Actor::Property::ID )); - text = data.mAccessibilityAttributes[type]; - } + case Toolkit::AccessibilityManager::ACCESSIBILITY_LABEL: + return actor.GetProperty< std::string >( Toolkit::DevelControl::Property::ACCESSIBILITY_NAME ); + + case Toolkit::AccessibilityManager::ACCESSIBILITY_HINT: + return actor.GetProperty< std::string >( Toolkit::DevelControl::Property::ACCESSIBILITY_DESCRIPTION ); - return text; + case Toolkit::AccessibilityManager::ACCESSIBILITY_TRAIT: + case Toolkit::AccessibilityManager::ACCESSIBILITY_VALUE: + default: + return ""; + } } void AccessibilityManager::SetFocusOrder(Actor actor, const unsigned int order) { - // Do nothing if the focus order of the actor is not changed. - if(actor && GetFocusOrder(actor) != order) - { - // Firstly delete the actor from the focus chain if it's already there with a different focus order. - mFocusIDContainer.erase(GetFocusOrder(actor)); - - // Create/retrieve actor focusable property - Property::Index propertyActorFocusable = actor.RegisterProperty( ACTOR_FOCUSABLE, true, Property::READ_WRITE ); - - if(order == 0) - { - // The actor is not focusable without a defined focus order. - actor.SetProperty(propertyActorFocusable, false); - - // If the actor is currently being focused, it should clear the focus - if(actor == GetCurrentFocusActor()) - { - ClearFocus(); - } - } - else // Insert the actor to the focus chain - { - // Check whether there is another actor in the focus chain with the same focus order already. - FocusIDIter focusIDIter = mFocusIDContainer.find(order); - if(focusIDIter != mFocusIDContainer.end()) - { - // We need to increase the focus order of that actor and all the actors followed it - // in the focus chain. - FocusIDIter lastIter = mFocusIDContainer.end(); - --lastIter;//We want forward iterator to the last element here - mFocusIDContainer.insert(FocusIDPair((*lastIter).first + 1, (*lastIter).second)); - - // Update the actor's focus order in its additional data - SynchronizeActorAdditionalInfo((*lastIter).second, (*lastIter).first + 1); - - for(FocusIDIter iter = lastIter; iter != focusIDIter; iter--) - { - FocusIDIter previousIter = iter; - --previousIter;//We want forward iterator to the previous element here - unsigned int actorID = (*previousIter).second; - (*iter).second = actorID; + if (order == 0) + return; - // Update the actor's focus order in its additional data - SynchronizeActorAdditionalInfo(actorID, (*iter).first); - } + if (order >= mFocusOrder.size()) + mFocusOrder.resize(order + 1); - mFocusIDContainer.erase(order); - } + auto it = mFocusOrder.begin() + order; + mFocusOrder.insert(it, actor); - // The actor is focusable - actor.SetProperty(propertyActorFocusable, true); - - // Now we insert the actor into the focus chain with the specified focus order - mFocusIDContainer.insert(FocusIDPair(order, actor.GetProperty< int >( Actor::Property::ID ))); - } + if (order > 0) + { + Actor prev = mFocusOrder[order - 1]; + DevelControl::AppendAccessibilityRelation( prev, actor, Accessibility::RelationType::FLOWS_TO ); + DevelControl::AppendAccessibilityRelation( actor, prev, Accessibility::RelationType::FLOWS_FROM ); + } - // Update the actor's focus order in its additional data - SynchronizeActorAdditionalInfo(actor.GetProperty< int >( Actor::Property::ID ), order); + if (order + 1 < mFocusOrder.size()) + { + Actor next = mFocusOrder[order + 1]; + DevelControl::AppendAccessibilityRelation( actor, next, Accessibility::RelationType::FLOWS_TO ); + DevelControl::AppendAccessibilityRelation( next, actor, Accessibility::RelationType::FLOWS_FROM ); } } unsigned int AccessibilityManager::GetFocusOrder(Actor actor) const { - unsigned int focusOrder = 0; - - if(actor) + for (auto it = mFocusOrder.begin(); it != mFocusOrder.end(); ++it) { - ActorAdditionalInfo data = GetActorAdditionalInfo(actor.GetProperty< int >( Actor::Property::ID )); - focusOrder = data.mFocusOrder; + if (actor == *it) + return it - mFocusOrder.begin(); } - return focusOrder; + return 0; } unsigned int AccessibilityManager::GenerateNewFocusOrder() const { - unsigned int order = 1; - FocusIDContainer::const_reverse_iterator iter = mFocusIDContainer.rbegin(); - - if(iter != mFocusIDContainer.rend()) - { - order = (*iter).first + 1; - } - - return order; + return static_cast(mFocusOrder.size()); } Actor AccessibilityManager::GetActorByFocusOrder(const unsigned int order) { - Actor actor = Actor(); + Actor actor; - FocusIDIter focusIDIter = mFocusIDContainer.find(order); - if(focusIDIter != mFocusIDContainer.end()) - { - Actor rootActor = Stage::GetCurrent().GetRootLayer(); - actor = rootActor.FindChildById(mFocusIDContainer[order]); - } + if (order > 0 && order < mFocusOrder.size()) + actor = mFocusOrder[order]; return actor; } bool AccessibilityManager::SetCurrentFocusActor(Actor actor) { - if(actor) - { - return DoSetCurrentFocusActor(actor.GetProperty< int >( Actor::Property::ID )); - } - - return false; -} - -bool AccessibilityManager::DoSetCurrentFocusActor(const unsigned int actorID) -{ - Actor rootActor = Stage::GetCurrent().GetRootLayer(); - - // If the group mode is enabled, check which focus group the current focused actor belongs to - Actor focusGroup; - if(mIsFocusWithinGroup) - { - focusGroup = GetFocusGroup(GetCurrentFocusActor()); - } + Dali::Accessibility::Accessible::SetCurrentlyHighlightedActor(actor); - if(!focusGroup) - { - focusGroup = rootActor; - } - - Actor actor = focusGroup.FindChildById(actorID); - - // Check whether the actor is in the stage - if(actor) - { - // Check whether the actor is focusable - bool actorFocusable = false; - Property::Index propertyActorFocusable = actor.GetPropertyIndex(ACTOR_FOCUSABLE); - if(propertyActorFocusable != Property::INVALID_INDEX) - { - actorFocusable = actor.GetProperty(propertyActorFocusable); - } - - // Go through the actor's hierarchy to check whether the actor is visible - bool actorVisible = actor.GetCurrentProperty< bool >( Actor::Property::VISIBLE ); - Actor parent = actor.GetParent(); - while (actorVisible && parent && parent != rootActor) - { - actorVisible = parent.GetCurrentProperty< bool >( Actor::Property::VISIBLE ); - parent = parent.GetParent(); - } - - // Check whether the actor is fully transparent - bool actorOpaque = actor.GetCurrentProperty< Vector4 >( Actor::Property::WORLD_COLOR ).a > 0.01f; - - // Set the focus only when the actor is focusable and visible and not fully transparent - if(actorVisible && actorFocusable && actorOpaque) - { - // Draw the focus indicator upon the focused actor - if( mIsFocusIndicatorEnabled ) - { - actor.Add( GetFocusIndicatorActor() ); - } - - // Send notification for the change of focus actor - mFocusChangedSignal.Emit( GetCurrentFocusActor(), actor ); - - // Save the current focused actor - mCurrentFocusActor = FocusIDPair(GetFocusOrder(actor), actorID); - - if(mIsAccessibilityTtsEnabled) - { - Dali::SoundPlayer soundPlayer = Dali::SoundPlayer::Get(); - if(soundPlayer) - { - if (!mIsFocusSoundFilePathSet) - { - const std::string soundDirPath = AssetManager::GetDaliSoundPath(); - mFocusSoundFilePath = soundDirPath + FOCUS_SOUND_FILE_NAME; - mIsFocusSoundFilePathSet = true; - } - soundPlayer.PlaySound(mFocusSoundFilePath); - } - - // Play the accessibility attributes with the TTS player. - Dali::TtsPlayer player = Dali::TtsPlayer::Get(Dali::TtsPlayer::SCREEN_READER); - - // Combine attribute texts to one text - std::string informationText; - for(int i = 0; i < Toolkit::AccessibilityManager::ACCESSIBILITY_ATTRIBUTE_NUM; i++) - { - if(!GetActorAdditionalInfo(actorID).mAccessibilityAttributes[i].empty()) - { - if( i > 0 ) - { - informationText += ", "; // for space time between each information - } - informationText += GetActorAdditionalInfo(actorID).mAccessibilityAttributes[i]; - } - } - player.Play(informationText); - } - - return true; - } - } - - DALI_LOG_WARNING("[%s:%d] FAILED\n", __FUNCTION__, __LINE__); - return false; + return true; } Actor AccessibilityManager::GetCurrentFocusActor() { - Actor rootActor = Stage::GetCurrent().GetRootLayer(); - return rootActor.FindChildById(mCurrentFocusActor.second); + return Dali::Accessibility::Accessible::GetCurrentlyHighlightedActor(); } Actor AccessibilityManager::GetCurrentFocusGroup() @@ -411,971 +152,103 @@ Actor AccessibilityManager::GetCurrentFocusGroup() unsigned int AccessibilityManager::GetCurrentFocusOrder() { - return mCurrentFocusActor.first; + auto actor = GetCurrentFocusActor(); + unsigned order = 0; + + if (actor) + order = GetFocusOrder( actor ); + + return order; } bool AccessibilityManager::MoveFocusForward() { - bool ret = false; - mRecursiveFocusMoveCounter = 0; + unsigned current = GetCurrentFocusOrder(); - FocusIDIter focusIDIter = mFocusIDContainer.find(mCurrentFocusActor.first); - if(focusIDIter != mFocusIDContainer.end()) - { - DALI_LOG_INFO( gLogFilter, Debug::General, "[%s:%d] focus order : %d\n", __FUNCTION__, __LINE__, (*focusIDIter).first); - ret = DoMoveFocus(focusIDIter, true, mIsWrapped); - } - else - { - // TODO: if there is not focused actor, move first actor - if(!mFocusIDContainer.empty()) - { - //if there is not focused actor, move 1st actor - focusIDIter = mFocusIDContainer.begin(); // TODO: I'm not sure it was sorted. - DALI_LOG_INFO( gLogFilter, Debug::General, "[%s:%d] focus order : %d\n", __FUNCTION__, __LINE__, (*focusIDIter).first); - ret = DoSetCurrentFocusActor((*focusIDIter).second); - } - } + if (current + 1 < mFocusOrder.size()) + return SetCurrentFocusActor(mFocusOrder[current + 1]); - DALI_LOG_INFO( gLogFilter, Debug::General, "[%s] %s\n", __FUNCTION__, ret?"SUCCEED!!!":"FAILED!!!"); - - return ret; + return false; } bool AccessibilityManager::MoveFocusBackward() { - bool ret = false; - mRecursiveFocusMoveCounter = 0; - - FocusIDIter focusIDIter = mFocusIDContainer.find(mCurrentFocusActor.first); - if(focusIDIter != mFocusIDContainer.end()) - { - DALI_LOG_INFO( gLogFilter, Debug::General, "[%s:%d] focus order : %d\n", __FUNCTION__, __LINE__, (*focusIDIter).first); - ret = DoMoveFocus(focusIDIter, false, mIsWrapped); - } - else - { - // TODO: if there is not focused actor, move last actor - if(!mFocusIDContainer.empty()) - { - //if there is not focused actor, move last actor - focusIDIter = mFocusIDContainer.end(); - --focusIDIter;//We want forward iterator to the last element here - DALI_LOG_INFO( gLogFilter, Debug::General, "[%s:%d] focus order : %d\n", __FUNCTION__, __LINE__, (*focusIDIter).first); - ret = DoSetCurrentFocusActor((*focusIDIter).second); - } - } + unsigned current = GetCurrentFocusOrder(); - DALI_LOG_INFO( gLogFilter, Debug::General, "[%s] %s\n", __FUNCTION__, ret?"SUCCEED!!!":"FAILED!!!"); + if (current > 1) // zero has a special meaning + return SetCurrentFocusActor(mFocusOrder[current - 1]); - return ret; + return false; } -void AccessibilityManager::DoActivate(Actor actor) +void AccessibilityManager::ClearFocus() { - if(actor) - { - Dali::Toolkit::Control control = Dali::Toolkit::Control::DownCast(actor); - if(control) - { - // Notify the control that it is activated - GetImplementation( control ).AccessibilityActivate(); - } - - // Send notification for the activation of focused actor - mFocusedActorActivatedSignal.Emit(actor); - } + auto actor = GetCurrentFocusActor(); + Toolkit::DevelControl::ClearAccessibilityHighlight( actor ); } -void AccessibilityManager::ClearFocus() +void AccessibilityManager::Reset() { - Actor actor = GetCurrentFocusActor(); - if( actor && mFocusIndicatorActor ) - { - actor.Remove( mFocusIndicatorActor ); - } - - mCurrentFocusActor = FocusIDPair(0, 0); - - // Send notification for the change of focus actor - mFocusChangedSignal.Emit(actor, Actor()); + ClearFocus(); - if(mIsAccessibilityTtsEnabled) + for (std::size_t i = 2; i < mFocusOrder.size(); ++i) { - // Stop the TTS playing if any - Dali::TtsPlayer player = Dali::TtsPlayer::Get(Dali::TtsPlayer::SCREEN_READER); - player.Stop(); + Actor prev = mFocusOrder[i - 1]; + Actor next = mFocusOrder[i]; + + DevelControl::RemoveAccessibilityRelation( prev, next, Accessibility::RelationType::FLOWS_TO ); + DevelControl::RemoveAccessibilityRelation( next, prev, Accessibility::RelationType::FLOWS_FROM ); } -} -void AccessibilityManager::Reset() -{ - ClearFocus(); - mFocusIDContainer.clear(); - mIDAdditionalInfoContainer.clear(); + mFocusOrder.clear(); + mFocusOrder.push_back( {} ); } void AccessibilityManager::SetFocusGroup(Actor actor, bool isFocusGroup) { - if(actor) - { - // Create/Set focus group property. - actor.RegisterProperty( IS_FOCUS_GROUP, isFocusGroup, Property::READ_WRITE ); - } } bool AccessibilityManager::IsFocusGroup(Actor actor) const { - // Check whether the actor is a focus group - bool isFocusGroup = false; - - if(actor) - { - Property::Index propertyIsFocusGroup = actor.GetPropertyIndex(IS_FOCUS_GROUP); - if(propertyIsFocusGroup != Property::INVALID_INDEX) - { - isFocusGroup = actor.GetProperty(propertyIsFocusGroup); - } - } - - return isFocusGroup; + return false; } Actor AccessibilityManager::GetFocusGroup(Actor actor) { - // Go through the actor's hierarchy to check which focus group the actor belongs to - while (actor && !IsFocusGroup(actor)) - { - actor = actor.GetParent(); - } - - return actor; + return {}; } Vector2 AccessibilityManager::GetReadPosition() const { - AccessibilityAdaptor adaptor = AccessibilityAdaptor::Get(); - return adaptor.GetReadPosition(); + return {}; } void AccessibilityManager::SetGroupMode(bool enabled) { - mIsFocusWithinGroup = enabled; } bool AccessibilityManager::GetGroupMode() const { - return mIsFocusWithinGroup; + return false; } void AccessibilityManager::SetWrapMode(bool wrapped) { - mIsWrapped = wrapped; } bool AccessibilityManager::GetWrapMode() const { - return mIsWrapped; + return true; } void AccessibilityManager::SetFocusIndicatorActor(Actor indicator) { - if( mFocusIndicatorActor != indicator ) - { - Actor currentFocusActor = GetCurrentFocusActor(); - if( currentFocusActor ) - { - // The new focus indicator should be added to the current focused actor immediately - if( mFocusIndicatorActor ) - { - currentFocusActor.Remove( mFocusIndicatorActor ); - } - - if( indicator ) - { - currentFocusActor.Add( indicator ); - } - } - - mFocusIndicatorActor = indicator; - } + Dali::Accessibility::Accessible::SetHighlightActor( indicator ); } Actor AccessibilityManager::GetFocusIndicatorActor() { - if( ! mFocusIndicatorActor ) - { - // Create the default if it hasn't been set and one that's shared by all the keyboard focusable actors - const std::string imageDirPath = AssetManager::GetDaliImagePath(); - const std::string focusBorderImagePath = imageDirPath + FOCUS_BORDER_IMAGE_FILE_NAME; - - mFocusIndicatorActor = Toolkit::ImageView::New(focusBorderImagePath); - mFocusIndicatorActor.SetProperty( Actor::Property::PARENT_ORIGIN, ParentOrigin::CENTER ); - mFocusIndicatorActor.SetProperty( Actor::Property::POSITION_Z, 1.0f ); - - // Apply size constraint to the focus indicator - mFocusIndicatorActor.SetResizePolicy( ResizePolicy::FILL_TO_PARENT, Dimension::ALL_DIMENSIONS ); - } - - return mFocusIndicatorActor; -} - -bool AccessibilityManager::DoMoveFocus(FocusIDIter focusIDIter, bool forward, bool wrapped) -{ - DALI_LOG_INFO( gLogFilter, Debug::General, "[%s:%d] %d focusable actors\n", __FUNCTION__, __LINE__, mFocusIDContainer.size()); - DALI_LOG_INFO( gLogFilter, Debug::General, "[%s:%d] focus order : %d\n", __FUNCTION__, __LINE__, (*focusIDIter).first); - - if( (forward && ++focusIDIter == mFocusIDContainer.end()) - || (!forward && focusIDIter-- == mFocusIDContainer.begin()) ) - { - if(mIsEndcapFeedbackEnabled) - { - if(mIsEndcapFeedbackPlayed == false) - { - // play sound & skip moving once - Dali::SoundPlayer soundPlayer = Dali::SoundPlayer::Get(); - if(soundPlayer) - { - if (!mIsFocusChainEndSoundFilePathSet) - { - const std::string soundDirPath = AssetManager::GetDaliSoundPath(); - mFocusChainEndSoundFilePath = soundDirPath + FOCUS_CHAIN_END_SOUND_FILE_NAME; - mIsFocusChainEndSoundFilePathSet = true; - } - soundPlayer.PlaySound(mFocusChainEndSoundFilePath); - } - - mIsEndcapFeedbackPlayed = true; - return true; - } - mIsEndcapFeedbackPlayed = false; - } - - if(wrapped) - { - if(forward) - { - focusIDIter = mFocusIDContainer.begin(); - } - else - { - focusIDIter = mFocusIDContainer.end(); - --focusIDIter;//We want forward iterator to the last element here - } - } - else - { - DALI_LOG_INFO( gLogFilter, Debug::General, "[%s:%d] Overshot\n", __FUNCTION__, __LINE__); - // Send notification for handling overshooted situation - mFocusOvershotSignal.Emit(GetCurrentFocusActor(), forward ? Toolkit::AccessibilityManager::OVERSHOT_NEXT : Toolkit::AccessibilityManager::OVERSHOT_PREVIOUS); - - return false; // Try to move the focus out of the scope - } - } - - // Invalid focus. - if( focusIDIter == mFocusIDContainer.end() ) - { - return false; - } - - // Note: This function performs the focus change. - if( !DoSetCurrentFocusActor( (*focusIDIter).second ) ) - { - mRecursiveFocusMoveCounter++; - if(mRecursiveFocusMoveCounter > mFocusIDContainer.size()) - { - // We've attempted to focus all the actors in the whole focus chain and no actor - // can be focused successfully. - DALI_LOG_WARNING("[%s] There is no more focusable actor in %d focus chains\n", __FUNCTION__, mRecursiveFocusMoveCounter); - - return false; - } - else - { - return DoMoveFocus(focusIDIter, forward, wrapped); - } - } - - return true; -} - -void AccessibilityManager::SetFocusable(Actor actor, bool focusable) -{ - if(actor) - { - // Create/Set actor focusable property. - actor.RegisterProperty( ACTOR_FOCUSABLE, focusable, Property::READ_WRITE ); - } -} - -bool AccessibilityManager::ChangeAccessibilityStatus() -{ - AccessibilityAdaptor adaptor = AccessibilityAdaptor::Get(); - mIsAccessibilityTtsEnabled = adaptor.IsEnabled(); - Dali::Toolkit::AccessibilityManager handle( this ); - - if(mIsAccessibilityTtsEnabled) - { - // Show indicator when tts turned on if there is focused actor. - Actor actor = GetCurrentFocusActor(); - if(actor) - { - actor.Add( GetFocusIndicatorActor() ); - } - mIsFocusIndicatorEnabled = true; - - // Connect a signal to the TTS player to implement continuous reading mode. - Dali::TtsPlayer player = Dali::TtsPlayer::Get( Dali::TtsPlayer::SCREEN_READER ); - player.StateChangedSignal().Connect( this, &AccessibilityManager::TtsStateChanged ); - mTtsCreated = true; - } - else - { - // Hide indicator when tts turned off - Actor actor = GetCurrentFocusActor(); - if( actor && mFocusIndicatorActor ) - { - actor.Remove( mFocusIndicatorActor ); - } - mIsFocusIndicatorEnabled = false; - - if( mTtsCreated ) - { - // Disconnect the TTS state change signal. - Dali::TtsPlayer player = Dali::TtsPlayer::Get( Dali::TtsPlayer::SCREEN_READER ); - player.StateChangedSignal().Disconnect( this, &AccessibilityManager::TtsStateChanged ); - mTtsCreated = true; - } - } - - mStatusChangedSignal.Emit( handle ); - - return true; -} - -bool AccessibilityManager::AccessibilityActionNext(bool allowEndFeedback) -{ - Dali::Toolkit::AccessibilityManager handle( this ); - if( !mActionNextSignal.Empty() ) - { - mActionNextSignal.Emit( handle ); - } - - if(mIsAccessibilityTtsEnabled) - { - mIsEndcapFeedbackEnabled = allowEndFeedback; - return MoveFocusForward(); - } - else - { - return false; - } -} - -bool AccessibilityManager::AccessibilityActionPrevious(bool allowEndFeedback) -{ - Dali::Toolkit::AccessibilityManager handle( this ); - if( !mActionPreviousSignal.Empty() ) - { - mActionPreviousSignal.Emit( handle ); - } - - if(mIsAccessibilityTtsEnabled) - { - mIsEndcapFeedbackEnabled = allowEndFeedback; - return MoveFocusBackward(); - } - else - { - return false; - } -} - -bool AccessibilityManager::AccessibilityActionActivate() -{ - Dali::Toolkit::AccessibilityManager handle( this ); - if( !mActionActivateSignal.Empty() ) - { - mActionActivateSignal.Emit( handle ); - } - - bool ret = false; - - Actor actor = GetCurrentFocusActor(); - if(actor) - { - DoActivate(actor); - ret = true; - } - - return ret; -} - -bool AccessibilityManager::AccessibilityActionRead(bool allowReadAgain) -{ - Dali::Toolkit::AccessibilityManager handle( this ); - - if( allowReadAgain ) - { - if ( !mActionReadSignal.Empty() ) - { - mActionReadSignal.Emit( handle ); - } - } - else - { - if ( !mActionOverSignal.Empty() ) - { - mActionOverSignal.Emit( handle ); - } - } - - bool ret = false; - - if(mIsAccessibilityTtsEnabled) - { - // Find the focusable actor at the read position - AccessibilityAdaptor adaptor = AccessibilityAdaptor::Get(); - Dali::HitTestAlgorithm::Results results; - Dali::HitTestAlgorithm::HitTest( Stage::GetCurrent(), adaptor.GetReadPosition(), results, IsActorFocusableFunction ); - - FocusIDIter focusIDIter = mFocusIDContainer.find(GetFocusOrder(results.actor)); - if(focusIDIter != mFocusIDContainer.end()) - { - if( allowReadAgain || (results.actor != GetCurrentFocusActor()) ) - { - // Move the focus to the actor - ret = SetCurrentFocusActor(results.actor); - DALI_LOG_INFO( gLogFilter, Debug::General, "[%s:%d] SetCurrentFocusActor returns %s\n", __FUNCTION__, __LINE__, ret?"TRUE":"FALSE"); - } - } - } - - return ret; -} - -bool AccessibilityManager::AccessibilityActionReadNext(bool allowEndFeedback) -{ - Dali::Toolkit::AccessibilityManager handle( this ); - if( !mActionReadNextSignal.Empty() ) - { - mActionReadNextSignal.Emit( handle ); - } - - if(mIsAccessibilityTtsEnabled) - { - return MoveFocusForward(); - } - else - { - return false; - } -} - -bool AccessibilityManager::AccessibilityActionReadPrevious(bool allowEndFeedback) -{ - Dali::Toolkit::AccessibilityManager handle( this ); - if( !mActionReadPreviousSignal.Empty() ) - { - mActionReadPreviousSignal.Emit( handle ); - } - - if(mIsAccessibilityTtsEnabled) - { - return MoveFocusBackward(); - } - else - { - return false; - } -} - -bool AccessibilityManager::AccessibilityActionUp() -{ - Dali::Toolkit::AccessibilityManager handle( this ); - if( !mActionUpSignal.Empty() ) - { - mActionUpSignal.Emit( handle ); - } - - bool ret = false; - - if(mIsAccessibilityTtsEnabled) - { - Actor actor = GetCurrentFocusActor(); - if(actor) - { - Dali::Toolkit::Control control = Dali::Toolkit::Control::DownCast(actor); - if(control) - { - // Notify the control that it is activated - ret = GetImplementation( control ).OnAccessibilityValueChange(true); - } - } - } - - return ret; -} - -bool AccessibilityManager::AccessibilityActionDown() -{ - Dali::Toolkit::AccessibilityManager handle( this ); - if( !mActionDownSignal.Empty() ) - { - mActionDownSignal.Emit( handle ); - } - - bool ret = false; - - if(mIsAccessibilityTtsEnabled) - { - Actor actor = GetCurrentFocusActor(); - if(actor) - { - Dali::Toolkit::Control control = Dali::Toolkit::Control::DownCast(actor); - if(control) - { - // Notify the control that it is activated - ret = GetImplementation( control ).OnAccessibilityValueChange(false); - } - } - } - - return ret; -} - -bool AccessibilityManager::ClearAccessibilityFocus() -{ - Dali::Toolkit::AccessibilityManager handle( this ); - if( !mActionClearFocusSignal.Empty() ) - { - mActionClearFocusSignal.Emit( handle ); - } - - if(mIsAccessibilityTtsEnabled) - { - ClearFocus(); - return true; - } - else - { - return false; - } -} - -bool AccessibilityManager::AccessibilityActionScroll( Dali::TouchEvent& touch ) -{ - Dali::Toolkit::AccessibilityManager handle( this ); - if( !mActionScrollSignal.Empty() ) - { - mActionScrollSignal.Emit( handle, touch ); - } - - return true; -} - -bool AccessibilityManager::AccessibilityActionBack() -{ - Dali::Toolkit::AccessibilityManager handle( this ); - if( !mActionBackSignal.Empty() ) - { - mActionBackSignal.Emit( handle ); - } - - // TODO: Back to previous view - - return mIsAccessibilityTtsEnabled; -} - -bool AccessibilityManager::AccessibilityActionScrollUp() -{ - Dali::Toolkit::AccessibilityManager handle( this ); - if( !mActionScrollUpSignal.Empty() ) - { - mActionScrollUpSignal.Emit( handle ); - } - - bool ret = false; - - if(mIsAccessibilityTtsEnabled) - { - Actor actor = GetCurrentFocusActor(); - if(actor) - { - Dali::Toolkit::Control control = Dali::Toolkit::Control::DownCast(actor); - if(control) - { - // TODO: Notify the control to scroll up. Should control handle this? -// ret = GetImplementation( control ).OnAccessibilityScroll(Direction::UP); - } - } - } - - return ret; -} - -bool AccessibilityManager::AccessibilityActionScrollDown() -{ - Dali::Toolkit::AccessibilityManager handle( this ); - if( !mActionScrollDownSignal.Empty() ) - { - mActionScrollDownSignal.Emit( handle ); - } - - bool ret = false; - - if(mIsAccessibilityTtsEnabled) - { - Actor actor = GetCurrentFocusActor(); - if(actor) - { - Dali::Toolkit::Control control = Dali::Toolkit::Control::DownCast(actor); - if(control) - { - // TODO: Notify the control to scroll down. Should control handle this? -// ret = GetImplementation( control ).OnAccessibilityScrollDown(Direction::DOWN); - } - } - } - - return ret; -} - -bool AccessibilityManager::AccessibilityActionPageLeft() -{ - Dali::Toolkit::AccessibilityManager handle( this ); - if( !mActionPageLeftSignal.Empty() ) - { - mActionPageLeftSignal.Emit( handle ); - } - - bool ret = false; - - if(mIsAccessibilityTtsEnabled) - { - Actor actor = GetCurrentFocusActor(); - if(actor) - { - Dali::Toolkit::Control control = Dali::Toolkit::Control::DownCast(actor); - if(control) - { - // TODO: Notify the control to scroll left to the previous page. Should control handle this? -// ret = GetImplementation( control ).OnAccessibilityScrollToPage(Direction::LEFT); - } - } - } - - return ret; -} - -bool AccessibilityManager::AccessibilityActionPageRight() -{ - Dali::Toolkit::AccessibilityManager handle( this ); - if( !mActionPageRightSignal.Empty() ) - { - mActionPageRightSignal.Emit( handle ); - } - - bool ret = false; - - if(mIsAccessibilityTtsEnabled) - { - Actor actor = GetCurrentFocusActor(); - if(actor) - { - Dali::Toolkit::Control control = Dali::Toolkit::Control::DownCast(actor); - if(control) - { - // TODO: Notify the control to scroll right to the next page. Should control handle this? -// ret = GetImplementation( control ).OnAccessibilityScrollToPage(Direction::RIGHT); - } - } - } - - return ret; -} - -bool AccessibilityManager::AccessibilityActionPageUp() -{ - Dali::Toolkit::AccessibilityManager handle( this ); - if( !mActionPageUpSignal.Empty() ) - { - mActionPageUpSignal.Emit( handle ); - } - - bool ret = false; - - if(mIsAccessibilityTtsEnabled) - { - Actor actor = GetCurrentFocusActor(); - if(actor) - { - Dali::Toolkit::Control control = Dali::Toolkit::Control::DownCast(actor); - if(control) - { - // TODO: Notify the control to scroll up to the previous page. Should control handle this? -// ret = GetImplementation( control ).OnAccessibilityScrollToPage(Direction::UP); - } - } - } - - return ret; -} - -bool AccessibilityManager::AccessibilityActionPageDown() -{ - Dali::Toolkit::AccessibilityManager handle( this ); - if( !mActionPageDownSignal.Empty() ) - { - mActionPageDownSignal.Emit( handle ); - } - - bool ret = false; - - if(mIsAccessibilityTtsEnabled) - { - Actor actor = GetCurrentFocusActor(); - if(actor) - { - Dali::Toolkit::Control control = Dali::Toolkit::Control::DownCast(actor); - if(control) - { - // TODO: Notify the control to scroll down to the next page. Should control handle this? -// ret = GetImplementation( control ).OnAccessibilityScrollToPage(Direction::DOWN); - } - } - } - - return ret; -} - -bool AccessibilityManager::AccessibilityActionMoveToFirst() -{ - Dali::Toolkit::AccessibilityManager handle( this ); - if( !mActionMoveToFirstSignal.Empty() ) - { - mActionMoveToFirstSignal.Emit( handle ); - } - - // TODO: Move to the first item on screen - - return mIsAccessibilityTtsEnabled; -} - -bool AccessibilityManager::AccessibilityActionMoveToLast() -{ - Dali::Toolkit::AccessibilityManager handle( this ); - if( !mActionMoveToLastSignal.Empty() ) - { - mActionMoveToLastSignal.Emit( handle ); - } - - // TODO: Move to the last item on screen - - return mIsAccessibilityTtsEnabled; -} - -bool AccessibilityManager::AccessibilityActionReadFromTop() -{ - Dali::Toolkit::AccessibilityManager handle( this ); - if( !mActionReadFromTopSignal.Empty() ) - { - mActionReadFromTopSignal.Emit( handle ); - } - - // TODO: Move to the top item on screen and read from the item continuously - - return mIsAccessibilityTtsEnabled; -} - -bool AccessibilityManager::AccessibilityActionReadFromNext() -{ - Dali::Toolkit::AccessibilityManager handle( this ); - - if( !mActionReadFromNextSignal.Empty() ) - { - mActionReadFromNextSignal.Emit( handle ); - } - - if( mIsAccessibilityTtsEnabled ) - { - // Mark that we are in continuous play mode, so TTS signals can move focus. - mContinuousPlayMode = true; - - // Attempt to move to the next item and read from the item continuously. - MoveFocusForward(); - } - - return mIsAccessibilityTtsEnabled; -} - -void AccessibilityManager::TtsStateChanged( const Dali::TtsPlayer::State previousState, const Dali::TtsPlayer::State currentState ) -{ - if( mContinuousPlayMode ) - { - // If we were playing and now we have stopped, attempt to play the next item. - if( ( previousState == Dali::TtsPlayer::PLAYING ) && ( currentState == Dali::TtsPlayer::READY ) ) - { - // Attempt to move the focus forward and play. - // If we can't cancel continuous play mode. - if( !MoveFocusForward() ) - { - // We are done, exit continuous play mode. - mContinuousPlayMode = false; - } - } - else - { - // Unexpected play state change, exit continuous play mode. - mContinuousPlayMode = false; - } - } -} - -bool AccessibilityManager::AccessibilityActionZoom() -{ - Dali::Toolkit::AccessibilityManager handle( this ); - if( !mActionZoomSignal.Empty() ) - { - mActionZoomSignal.Emit( handle ); - } - - bool ret = false; - - if(mIsAccessibilityTtsEnabled) - { - Actor actor = GetCurrentFocusActor(); - if(actor) - { - Dali::Toolkit::Control control = Dali::Toolkit::Control::DownCast(actor); - if(control) - { - // Notify the control to zoom - ret = GetImplementation( control ).OnAccessibilityZoom(); - } - } - } - - return ret; -} - -bool AccessibilityManager::AccessibilityActionReadPauseResume() -{ - Dali::Toolkit::AccessibilityManager handle( this ); - if( !mActionReadPauseResumeSignal.Empty() ) - { - mActionReadPauseResumeSignal.Emit( handle ); - } - - bool ret = false; - - if(mIsAccessibilityTtsEnabled) - { - // Pause or resume the TTS player - Dali::TtsPlayer player = Dali::TtsPlayer::Get(Dali::TtsPlayer::SCREEN_READER); - Dali::TtsPlayer::State state = player.GetState(); - if(state == Dali::TtsPlayer::PLAYING) - { - player.Pause(); - ret = true; - } - else if(state == Dali::TtsPlayer::PAUSED) - { - player.Resume(); - ret = true; - } - } - - return ret; -} - -bool AccessibilityManager::AccessibilityActionStartStop() -{ - Dali::Toolkit::AccessibilityManager handle( this ); - if( !mActionStartStopSignal.Empty() ) - { - mActionStartStopSignal.Emit( handle ); - } - - // TODO: Start/stop the current action - - return mIsAccessibilityTtsEnabled; -} - -bool AccessibilityManager::HandlePanGesture(const AccessibilityGestureEvent& panEvent) -{ - bool handled = false; - - if( panEvent.state == AccessibilityGestureEvent::STARTED ) - { - // Find the focusable actor at the event position - Dali::HitTestAlgorithm::Results results; - AccessibilityAdaptor adaptor = AccessibilityAdaptor::Get(); - - Dali::HitTestAlgorithm::HitTest( Stage::GetCurrent(), panEvent.currentPosition, results, IsActorFocusableFunction ); - mCurrentGesturedActor = results.actor; - - if(!mCurrentGesturedActor) - { - DALI_LOG_ERROR("Gesture detected, but no hit actor\n"); - } - } - - // GestureState::FINISHED (Up) events are delivered with previous (Motion) event position - // Use the real previous position; otherwise we may incorrectly get a ZERO velocity - if ( AccessibilityGestureEvent::FINISHED != panEvent.state ) - { - // Store the previous position for next GestureState::FINISHED iteration. - mPreviousPosition = panEvent.previousPosition; - } - - Actor rootActor = Stage::GetCurrent().GetRootLayer(); - - Dali::PanGesture pan = DevelPanGesture::New( static_cast(panEvent.state) ); - DevelPanGesture::SetTime( pan, panEvent.time ); - DevelPanGesture::SetNumberOfTouches( pan, panEvent.numberOfTouches ); - DevelPanGesture::SetScreenPosition( pan, panEvent.currentPosition ); - DevelPanGesture::SetScreenDisplacement( pan, mPreviousPosition - panEvent.currentPosition ); - DevelPanGesture::SetScreenVelocity( pan, Vector2( pan.GetScreenDisplacement().x / panEvent.timeDelta, pan.GetScreenDisplacement().y / panEvent.timeDelta ) ); - - // Only handle the pan gesture when the current focused actor is scrollable or within a scrollable actor - while(mCurrentGesturedActor && mCurrentGesturedActor != rootActor && !handled) - { - Dali::Toolkit::Control control = Dali::Toolkit::Control::DownCast(mCurrentGesturedActor); - if(control) - { - Vector2 localCurrent; - control.ScreenToLocal( localCurrent.x, localCurrent.y, panEvent.currentPosition.x, panEvent.currentPosition.y ); - DevelPanGesture::SetPosition( pan, localCurrent ); - - Vector2 localPrevious; - control.ScreenToLocal( localPrevious.x, localPrevious.y, mPreviousPosition.x, mPreviousPosition.y ); - - DevelPanGesture::SetDisplacement( pan, localCurrent - localPrevious ); - DevelPanGesture::SetVelocity( pan, Vector2( pan.GetDisplacement().x / panEvent.timeDelta, pan.GetDisplacement().y / panEvent.timeDelta )); - - handled = GetImplementation( control ).OnAccessibilityPan(pan); - } - - // If the gesture is not handled by the control, check its parent - if(!handled) - { - mCurrentGesturedActor = mCurrentGesturedActor.GetParent(); - - if(!mCurrentGesturedActor) - { - DALI_LOG_ERROR("no more gestured actor\n"); - } - } - else - { - // If handled, then update the pan gesture properties - PanGestureDetector::SetPanGestureProperties( pan ); - } - } - - return handled; + return Dali::Accessibility::Accessible::GetHighlightActor(); } Toolkit::AccessibilityManager::FocusChangedSignalType& AccessibilityManager::FocusChangedSignal()