(FocusManager) Updated accessibility features
authorSinjae Lee <sinjae4b.lee@samsung.com>
Fri, 16 May 2014 06:02:32 +0000 (15:02 +0900)
committerAdeel Kazmi <adeel.kazmi@samsung.com>
Tue, 27 May 2014 14:38:44 +0000 (15:38 +0100)
1. Shoot accessibility pan to hit-actor instead of currently focused actor (done)
2. Added sound resources (done)
   Play sound for focus, end of focus list
3. Added Get/SetEndcapFeedbackEnabled api to handle the feedback
   In case of evas-plugin usage, need to disable endcap feedback since EFL will do.
4. TODO: support tap & hold event on focused actor (NEXT PATCH)

base/dali-toolkit/internal/focus-manager/focus-manager-impl.cpp
base/dali-toolkit/internal/focus-manager/focus-manager-impl.h
base/dali-toolkit/public-api/focus-manager/focus-manager.cpp
base/dali-toolkit/sounds/End_of_List.ogg [new file with mode: 0644]
base/dali-toolkit/sounds/Focus.ogg [new file with mode: 0644]
base/dali-toolkit/sounds/List_scroll.ogg [new file with mode: 0644]
base/dali-toolkit/sounds/file.list [new file with mode: 0644]
build/slp/dali-toolkit-base/Makefile.am
build/slp/dali-toolkit/Makefile.am
capi/dali-toolkit/public-api/focus-manager/focus-manager.h
packaging/dali-toolkit.spec

index 80e5c2d..a52d480 100644 (file)
@@ -44,6 +44,9 @@ const char * const IS_FOCUS_GROUP("is-focus-group");
 const char* FOCUS_BORDER_IMAGE_PATH = DALI_IMAGE_DIR "B16-8_TTS_focus.png";
 const Vector4 FOCUS_BORDER_IMAGE_BORDER = Vector4(7.0f, 7.0f, 7.0f, 7.0f);
 
 const char* FOCUS_BORDER_IMAGE_PATH = DALI_IMAGE_DIR "B16-8_TTS_focus.png";
 const Vector4 FOCUS_BORDER_IMAGE_BORDER = Vector4(7.0f, 7.0f, 7.0f, 7.0f);
 
+const char* FOCUS_SOUND_FILE = DALI_SOUND_DIR "Focus.ogg";
+const char* FOCUS_CHAIN_END_SOUND_FILE = DALI_SOUND_DIR "End_of_List.ogg";
+
 /**
  * The function to be used in the hit-test algorithm to check whether the actor is hittable.
  */
 /**
  * The function to be used in the hit-test algorithm to check whether the actor is hittable.
  */
@@ -90,6 +93,8 @@ bool IsActorFocusableFunction(Actor actor, Dali::HitTestAlgorithm::TraverseType
 FocusManager::FocusManager()
 : mIsWrapped(false),
   mIsFocusWithinGroup(false),
 FocusManager::FocusManager()
 : mIsWrapped(false),
   mIsFocusWithinGroup(false),
+  mIsEndcapFeedbackEnabled(true),
+  mIsEndcapFeedbackPlayed(false),
   mCurrentFocusActor(FocusIDPair(0, 0)),
   mFocusIndicatorActor(Actor()),
   mRecursiveFocusMoveCounter(0),
   mCurrentFocusActor(FocusIDPair(0, 0)),
   mFocusIndicatorActor(Actor()),
   mRecursiveFocusMoveCounter(0),
@@ -331,6 +336,9 @@ bool FocusManager::DoSetCurrentFocusActor(const unsigned int actorID)
 
       if(mIsAccessibilityTtsEnabled)
       {
 
       if(mIsAccessibilityTtsEnabled)
       {
+        Dali::SoundPlayer soundPlayer = Dali::SoundPlayer::Get();
+        soundPlayer.PlaySound(FOCUS_SOUND_FILE);
+
         // Play the accessibility attributes with the TTS player.
         Dali::TtsPlayer player = Dali::TtsPlayer::Get(Dali::TtsPlayer::SCREEN_READER);
 
         // Play the accessibility attributes with the TTS player.
         Dali::TtsPlayer player = Dali::TtsPlayer::Get(Dali::TtsPlayer::SCREEN_READER);
 
@@ -540,6 +548,16 @@ bool FocusManager::GetWrapMode() const
   return mIsWrapped;
 }
 
   return mIsWrapped;
 }
 
+void FocusManager::SetEndCapFeedbackEnabled(bool enabled)
+{
+  mIsEndcapFeedbackEnabled = enabled;
+}
+
+bool FocusManager::GetEndCapFeedbackEnabled() const
+{
+  return mIsEndcapFeedbackEnabled;
+}
+
 void FocusManager::SetFocusIndicatorActor(Actor indicator)
 {
   mFocusIndicatorActor = indicator;
 void FocusManager::SetFocusIndicatorActor(Actor indicator)
 {
   mFocusIndicatorActor = indicator;
@@ -560,6 +578,20 @@ bool FocusManager::DoMoveFocus(FocusIDIter focusIDIter, bool forward, bool wrapp
   {
     if(wrapped)
     {
   {
     if(wrapped)
     {
+      if(mIsEndcapFeedbackEnabled)
+      {
+        if(mIsEndcapFeedbackPlayed == false)
+        {
+          // play sound & skip to move once
+          Dali::SoundPlayer soundPlayer = Dali::SoundPlayer::Get();
+          soundPlayer.PlaySound(FOCUS_CHAIN_END_SOUND_FILE);
+
+          mIsEndcapFeedbackPlayed = true;
+          return true;
+        }
+        mIsEndcapFeedbackPlayed = false;
+      }
+
       if(forward)
       {
         focusIDIter = mFocusIDContainer.begin();
       if(forward)
       {
         focusIDIter = mFocusIDContainer.begin();
@@ -572,6 +604,12 @@ bool FocusManager::DoMoveFocus(FocusIDIter focusIDIter, bool forward, bool wrapp
     }
     else
     {
     }
     else
     {
+      if(mIsEndcapFeedbackEnabled)
+      {
+        Dali::SoundPlayer soundPlayer = Dali::SoundPlayer::Get();
+        soundPlayer.PlaySound(FOCUS_CHAIN_END_SOUND_FILE);
+      }
+
       DALI_LOG_INFO( gLogFilter, Debug::General, "[%s:%d] Overshot\n", __FUNCTION__, __LINE__);
       // Send notification for handling overshooted situation
       mFocusOvershotSignalV2.Emit(GetCurrentFocusActor(), forward ? Toolkit::FocusManager::OVERSHOT_NEXT : Toolkit::FocusManager::OVERSHOT_PREVIOUS);
       DALI_LOG_INFO( gLogFilter, Debug::General, "[%s:%d] Overshot\n", __FUNCTION__, __LINE__);
       // Send notification for handling overshooted situation
       mFocusOvershotSignalV2.Emit(GetCurrentFocusActor(), forward ? Toolkit::FocusManager::OVERSHOT_NEXT : Toolkit::FocusManager::OVERSHOT_PREVIOUS);
@@ -824,7 +862,21 @@ bool FocusManager::HandlePanGesture(const Integration::PanGestureEvent& panEvent
 {
   bool handled = false;
 
 {
   bool handled = false;
 
-  Actor currentGesturedActor = GetCurrentFocusActor();
+  if( panEvent.state == Gesture::Started )
+  {
+    // Find the focusable actor at the event position
+    Dali::HitTestAlgorithm::Results results;
+    AccessibilityManager manager = AccessibilityManager::Get();
+
+    Dali::HitTestAlgorithm::HitTest( Stage::GetCurrent(), panEvent.currentPosition, results, IsActorFocusableFunction );
+    mCurrentGesturedActor = results.actor;
+
+    if(!mCurrentGesturedActor)
+    {
+      DALI_LOG_ERROR("Gesture detected, but no hit actor");
+    }
+  }
+
   Actor rootActor = Stage::GetCurrent().GetRootLayer();
 
   Dali::PanGesture pan(panEvent.state);
   Actor rootActor = Stage::GetCurrent().GetRootLayer();
 
   Dali::PanGesture pan(panEvent.state);
@@ -836,9 +888,9 @@ bool FocusManager::HandlePanGesture(const Integration::PanGestureEvent& panEvent
   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
   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(currentGesturedActor && currentGesturedActor != rootActor && !handled)
+  while(mCurrentGesturedActor && mCurrentGesturedActor != rootActor && !handled)
   {
   {
-    Dali::Toolkit::Control control = Dali::Toolkit::Control::DownCast(currentGesturedActor);
+    Dali::Toolkit::Control control = Dali::Toolkit::Control::DownCast(mCurrentGesturedActor);
     if(control)
     {
       Vector2 localCurrent;
     if(control)
     {
       Vector2 localCurrent;
@@ -858,7 +910,12 @@ bool FocusManager::HandlePanGesture(const Integration::PanGestureEvent& panEvent
     // If the gesture is not handled by the control, check its parent
     if(!handled)
     {
     // If the gesture is not handled by the control, check its parent
     if(!handled)
     {
-      currentGesturedActor = currentGesturedActor.GetParent();
+      mCurrentGesturedActor = mCurrentGesturedActor.GetParent();
+
+      if(!mCurrentGesturedActor)
+      {
+        DALI_LOG_ERROR("no more gestured actor");
+      }
     }
     else
     {
     }
     else
     {
index aefd0f6..de2cd39 100644 (file)
@@ -170,6 +170,16 @@ public:
   bool GetWrapMode() const;
 
   /**
   bool GetWrapMode() const;
 
   /**
+   * @copydoc Toolkit::FocusManager::SetEndCapFeedbackEnabled
+   */
+  void SetEndCapFeedbackEnabled(bool enabled);
+
+  /**
+   * @copydoc Toolkit::FocusManager::GetEndCapFeedbackEnabled
+   */
+  bool GetEndCapFeedbackEnabled() const;
+
+  /**
    * @copydoc Toolkit::FocusManager::SetFocusIndicatorActor
    */
   void SetFocusIndicatorActor(Actor indicator);
    * @copydoc Toolkit::FocusManager::SetFocusIndicatorActor
    */
   void SetFocusIndicatorActor(Actor indicator);
@@ -365,10 +375,14 @@ private:
   bool mIsWrapped; ///< Whether the focus movement is wrapped around or not
   bool mIsFocusWithinGroup; ///< Whether the focus movement is limited to the current focus group or not
 
   bool mIsWrapped; ///< Whether the focus movement is wrapped around or not
   bool mIsFocusWithinGroup; ///< Whether the focus movement is limited to the current focus group or not
 
+  bool mIsEndcapFeedbackEnabled; ///< Whether the endcap feedback need to be played when the focus leaves the end or vice versa
+  bool mIsEndcapFeedbackPlayed; ///< Whether the endcap feedback was played or not
+
   FocusIDContainer mFocusIDContainer; ///< The container to look up actor ID by focus order
   IDAdditionalInfoContainer mIDAdditionalInfoContainer; ///< The container to look up additional information by actor ID
 
   FocusIDPair mCurrentFocusActor; ///< The focus order and actor ID of current focused actor
   FocusIDContainer mFocusIDContainer; ///< The container to look up actor ID by focus order
   IDAdditionalInfoContainer mIDAdditionalInfoContainer; ///< The container to look up additional information by actor ID
 
   FocusIDPair mCurrentFocusActor; ///< The focus order and actor ID of current focused actor
+  Actor mCurrentGesturedActor; ///< The actor that will handle the gesture
 
   Actor mFocusIndicatorActor; ///< The focus indicator actor shared by all the focusable actors for highlight
 
 
   Actor mFocusIndicatorActor; ///< The focus indicator actor shared by all the focusable actors for highlight
 
index d172135..873ec65 100644 (file)
@@ -170,6 +170,16 @@ bool FocusManager::GetWrapMode() const
   return GetImpl(*this).GetWrapMode();
 }
 
   return GetImpl(*this).GetWrapMode();
 }
 
+void FocusManager::SetEndCapFeedbackEnabled(bool enabled)
+{
+  GetImpl(*this).SetEndCapFeedbackEnabled(enabled);
+}
+
+bool FocusManager::GetEndCapFeedbackEnabled() const
+{
+  return GetImpl(*this).GetEndCapFeedbackEnabled();
+}
+
 void FocusManager::SetFocusIndicatorActor(Actor indicator)
 {
   GetImpl(*this).SetFocusIndicatorActor(indicator);
 void FocusManager::SetFocusIndicatorActor(Actor indicator)
 {
   GetImpl(*this).SetFocusIndicatorActor(indicator);
diff --git a/base/dali-toolkit/sounds/End_of_List.ogg b/base/dali-toolkit/sounds/End_of_List.ogg
new file mode 100644 (file)
index 0000000..3777683
Binary files /dev/null and b/base/dali-toolkit/sounds/End_of_List.ogg differ
diff --git a/base/dali-toolkit/sounds/Focus.ogg b/base/dali-toolkit/sounds/Focus.ogg
new file mode 100644 (file)
index 0000000..aec6d44
Binary files /dev/null and b/base/dali-toolkit/sounds/Focus.ogg differ
diff --git a/base/dali-toolkit/sounds/List_scroll.ogg b/base/dali-toolkit/sounds/List_scroll.ogg
new file mode 100644 (file)
index 0000000..c40fd6a
Binary files /dev/null and b/base/dali-toolkit/sounds/List_scroll.ogg differ
diff --git a/base/dali-toolkit/sounds/file.list b/base/dali-toolkit/sounds/file.list
new file mode 100644 (file)
index 0000000..74ee1c1
--- /dev/null
@@ -0,0 +1,4 @@
+# Files to install here
+
+dali_toolkit_base_sound_files =\
+       $(toolkit_base_sounds_dir)/*.ogg
index f644a6e..50eaa34 100644 (file)
 
 # Base files
 toolkit_base_images_dir = ../../../base/dali-toolkit/images
 
 # Base files
 toolkit_base_images_dir = ../../../base/dali-toolkit/images
+toolkit_base_sounds_dir = ../../../base/dali-toolkit/sounds
 toolkit_base_src_dir    = ../../../base/dali-toolkit/internal
 public_api_base_src_dir = ../../../base/dali-toolkit/public-api
 
 include ../../../base/dali-toolkit/images/file.list
 toolkit_base_src_dir    = ../../../base/dali-toolkit/internal
 public_api_base_src_dir = ../../../base/dali-toolkit/public-api
 
 include ../../../base/dali-toolkit/images/file.list
+include ../../../base/dali-toolkit/sounds/file.list
 include ../../../base/dali-toolkit/internal/file.list
 include ../../../base/dali-toolkit/public-api/file.list
 
 #resources_dir = ../../../resources
 #daliimagedir = ${dataReadOnlyDir}/toolkit/images/
 #daliimage_DATA = ${dali_toolkit_base_image_files}
 include ../../../base/dali-toolkit/internal/file.list
 include ../../../base/dali-toolkit/public-api/file.list
 
 #resources_dir = ../../../resources
 #daliimagedir = ${dataReadOnlyDir}/toolkit/images/
 #daliimage_DATA = ${dali_toolkit_base_image_files}
+#dalisounddir = ${dataReadOnlyDir}/toolkit/sounds/
+#dalisound_DATA = ${dali_toolkit_base_sound_files}
 
 # The Base library
 lib_LTLIBRARIES = libdali-toolkit-base.la
 
 # The Base library
 lib_LTLIBRARIES = libdali-toolkit-base.la
@@ -40,6 +44,7 @@ libdali_toolkit_base_la_DEPENDENCIES =
 
 libdali_toolkit_base_la_CXXFLAGS = -DDALI_COMPILATION \
                       -DDALI_IMAGE_DIR="\"${daliimagedir}\"" \
 
 libdali_toolkit_base_la_CXXFLAGS = -DDALI_COMPILATION \
                       -DDALI_IMAGE_DIR="\"${daliimagedir}\"" \
+                      -DDALI_SOUND_DIR="\"${dalisounddir}\"" \
                       -Werror -Wall \
                       -I../../../base \
                       -I../../../capi \
                       -Werror -Wall \
                       -I../../../base \
                       -I../../../capi \
index c460e57..79f3c62 100644 (file)
 
 # Base files
 toolkit_base_images_dir = ../../../base/dali-toolkit/images
 
 # Base files
 toolkit_base_images_dir = ../../../base/dali-toolkit/images
+toolkit_base_sounds_dir = ../../../base/dali-toolkit/sounds
 toolkit_base_src_dir    = ../../../base/dali-toolkit/internal
 public_api_base_src_dir = ../../../base/dali-toolkit/public-api
 
 include ../../../base/dali-toolkit/images/file.list
 toolkit_base_src_dir    = ../../../base/dali-toolkit/internal
 public_api_base_src_dir = ../../../base/dali-toolkit/public-api
 
 include ../../../base/dali-toolkit/images/file.list
+include ../../../base/dali-toolkit/sounds/file.list
 include ../../../base/dali-toolkit/internal/file.list
 include ../../../base/dali-toolkit/public-api/file.list
 
 include ../../../base/dali-toolkit/internal/file.list
 include ../../../base/dali-toolkit/public-api/file.list
 
@@ -44,6 +46,9 @@ daliimagedir = ${dataReadOnlyDir}/toolkit/images/
 daliimage_DATA = ${dali_toolkit_base_image_files} \
                  ${dali_toolkit_optional_image_files}
 
 daliimage_DATA = ${dali_toolkit_base_image_files} \
                  ${dali_toolkit_optional_image_files}
 
+dalisounddir = ${dataReadOnlyDir}/toolkit/sounds/
+dalisound_DATA = ${dali_toolkit_base_sound_files}
+
 # The Combined library
 lib_LTLIBRARIES = libdali-toolkit.la
 
 # The Combined library
 lib_LTLIBRARIES = libdali-toolkit.la
 
@@ -57,6 +62,7 @@ libdali_toolkit_la_DEPENDENCIES =
 
 libdali_toolkit_la_CXXFLAGS = -DDALI_COMPILATION \
                       -DDALI_IMAGE_DIR="\"${daliimagedir}\"" \
 
 libdali_toolkit_la_CXXFLAGS = -DDALI_COMPILATION \
                       -DDALI_IMAGE_DIR="\"${daliimagedir}\"" \
+                      -DDALI_SOUND_DIR="\"${dalisounddir}\"" \
                       -Werror -Wall \
                       -I../../../base \
                       -I../../../optional \
                       -Werror -Wall \
                       -I../../../base \
                       -I../../../optional \
index 7f3b31e..750716f 100644 (file)
@@ -336,6 +336,25 @@ public:
   bool GetWrapMode() const;
 
   /**
   bool GetWrapMode() const;
 
   /**
+   * @brief Set whether focus manager will play a feedback when the focus leaves the end or vice versa.
+   *
+   * If wrap mode is enabled, the feedback will be played once. In next time, focus will move continueously.
+   * Otherwise, feedback will be played with overshot signal
+   *
+   * @pre The FocusManager has been initialized.
+   * @param enabled Whether the endcap feedback is enabled or not
+   */
+  void SetEndCapFeedbackEnabled(bool enabled);
+
+  /**
+   * @brief Get whether the endcap feedback is enabled or not.
+   *
+   * @pre The FocusManager has been initialized.
+   * @return Whether the endcap feedback is enabled or not.
+   */
+  bool GetEndCapFeedbackEnabled() const;
+
+  /**
    * @brief Set the focus indicator actor.
    *
    * This will replace the default focus indicator actor in
    * @brief Set the focus indicator actor.
    *
    * This will replace the default focus indicator actor in
index f16f1ed..ad70a14 100644 (file)
@@ -57,6 +57,7 @@ all the controls provided by the main package.
 %define dali_data_rw_dir            /opt/usr/share/dali/
 %define dali_data_ro_dir            /usr/share/dali/
 %define dali_toolkit_image_files    %{dali_data_ro_dir}/toolkit/images/
 %define dali_data_rw_dir            /opt/usr/share/dali/
 %define dali_data_ro_dir            /usr/share/dali/
 %define dali_toolkit_image_files    %{dali_data_ro_dir}/toolkit/images/
+%define dali_toolkit_sound_files    %{dali_data_ro_dir}/toolkit/sounds/
 %define dev_include_path %{_includedir}
 
 ##############################
 %define dev_include_path %{_includedir}
 
 ##############################
@@ -121,6 +122,7 @@ exit 0
 %defattr(-,root,root,-)
 %{_libdir}/lib%{name}.so*
 %{dali_toolkit_image_files}/*
 %defattr(-,root,root,-)
 %{_libdir}/lib%{name}.so*
 %{dali_toolkit_image_files}/*
+%{dali_toolkit_sound_files}/*
 %{_datadir}/license/%{name}
 
 %files devel
 %{_datadir}/license/%{name}
 
 %files devel