- if( ! mFocusIndicatorActor )
- {
- // Create the default if it hasn't been set and one that's shared by all the keyboard focusable actors
- mFocusIndicatorActor = Toolkit::ImageView::New( FOCUS_BORDER_IMAGE_PATH );
- mFocusIndicatorActor.SetParentOrigin( ParentOrigin::CENTER );
- mFocusIndicatorActor.SetZ( 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)
- {
- soundPlayer.PlaySound(FOCUS_CHAIN_END_SOUND_FILE);
- }
-
- 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& touchEvent )
-{
- Dali::Toolkit::AccessibilityManager handle( this );
- if( !mActionScrollSignal.Empty() )
- {
- mActionScrollSignal.Emit( handle, touchEvent );
- }
-
- 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::AccessibilityActionTouch(const TouchEvent& touchEvent)
-{
- bool handled = false;
-
- // TODO: Need to convert the touchevent for the focused actor?
-
- Dali::Toolkit::Control control = Dali::Toolkit::Control::DownCast(GetCurrentFocusActor());
- if(control)
- {
- handled = GetImplementation( control ).OnAccessibilityTouch(touchEvent);
- }
-
- return handled;
-}
-
-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");
- }
- }
-
- // Gesture::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 Gesture::Finished iteration.
- mPreviousPosition = panEvent.previousPosition;
- }
-
- Actor rootActor = Stage::GetCurrent().GetRootLayer();
-
- Dali::PanGesture pan( static_cast<Dali::Gesture::State>(panEvent.state) );
-
- pan.time = panEvent.time;
- pan.numberOfTouches = panEvent.numberOfTouches;
- pan.screenPosition = panEvent.currentPosition;
- pan.screenDisplacement = mPreviousPosition - panEvent.currentPosition;
- pan.screenVelocity.x = pan.screenDisplacement.x / panEvent.timeDelta;
- pan.screenVelocity.y = pan.screenDisplacement.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 );
- pan.position = localCurrent;
-
- Vector2 localPrevious;
- control.ScreenToLocal( localPrevious.x, localPrevious.y, mPreviousPosition.x, mPreviousPosition.y );
-
- pan.displacement = localCurrent - localPrevious;
- pan.velocity.x = pan.displacement.x / panEvent.timeDelta;
- pan.velocity.y = pan.displacement.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;