[NUI][AT-SPI] Add IAtspiValue.AccessibilityGetValueText()
authorArtur Świgoń <a.swigon@samsung.com>
Thu, 13 Apr 2023 08:45:11 +0000 (10:45 +0200)
committerdongsug-song <35130733+dongsug-song@users.noreply.github.com>
Mon, 17 Apr 2023 12:42:36 +0000 (21:42 +0900)
This API allows the application to provide the Screen Reader with a formatted
string value rather than the default, floating-point one. This in turn, allows
to customize in detail how e.g. slider values are read.

src/Tizen.NUI.Components/Controls/Pagination.cs
src/Tizen.NUI.Components/Controls/Progress.cs
src/Tizen.NUI.Components/Controls/Slider.cs
src/Tizen.NUI/src/internal/Interop/Interop.ControlDevel.cs
src/Tizen.NUI/src/public/Accessibility/IAtspiValue.cs
src/Tizen.NUI/src/public/BaseComponents/ViewAccessibility.cs
src/Tizen.NUI/src/public/BaseComponents/ViewAccessibilityEvent.cs
src/Tizen.NUI/src/public/BaseComponents/ViewAccessibilityWrappers.cs

index 569dc15..992f527 100755 (executable)
@@ -471,6 +471,15 @@ namespace Tizen.NUI.Components
         }
 
         /// <summary>
+        /// Formatted current value.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        string IAtspiValue.AccessibilityGetValueText()
+        {
+            return $"{SelectedIndex}";
+        }
+
+        /// <summary>
         /// Maximum value.
         /// </summary>
         [EditorBrowsable(EditorBrowsableState.Never)]
index 07561fa..70e88e0 100755 (executable)
@@ -545,6 +545,15 @@ namespace Tizen.NUI.Components
             }
         }
 
+        /// <summary>
+        /// Formatted current value.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        string IAtspiValue.AccessibilityGetValueText()
+        {
+            return (this as IAtspiValue).AccessibilityGetCurrent().ToString();
+        }
+
         [EditorBrowsable(EditorBrowsableState.Never)]
         bool IAtspiValue.AccessibilitySetCurrent(double value)
         {
index cfc3b51..5b21df4 100755 (executable)
@@ -1609,6 +1609,15 @@ namespace Tizen.NUI.Components
         }
 
         /// <summary>
+        /// Formatted current value.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        string IAtspiValue.AccessibilityGetValueText()
+        {
+            return $"{CurrentValue}";
+        }
+
+        /// <summary>
         /// Gets maximum value for Accessibility.
         /// </summary>
         [EditorBrowsable(EditorBrowsableState.Never)]
index 8aadebe..3ed46a0 100755 (executable)
@@ -383,6 +383,11 @@ namespace Tizen.NUI
                 public delegate void AccessibilityGetAttributes(IntPtr self, AccessibilityGetAttributesCallback callback, IntPtr userData);
                 [EditorBrowsable(EditorBrowsableState.Never)]
                 public AccessibilityGetAttributes GetAttributes; // 37
+
+                [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+                public delegate IntPtr AccessibilityGetValueText(IntPtr self);
+                [EditorBrowsable(EditorBrowsableState.Never)]
+                public AccessibilityGetValueText GetValueText; // 38
             }
 
             [DllImport(NDalicPINVOKE.Lib, EntryPoint = "CSharp_Dali_Accessibility_DuplicateString")]
index 338889f..a6fecb7 100644 (file)
@@ -26,9 +26,32 @@ namespace Tizen.NUI.Accessibility
         [EditorBrowsable(EditorBrowsableState.Never)]
         double AccessibilityGetMinimum();
 
+        /// <summary>
+        /// Gets the current numeric value.
+        /// </summary>
+        /// <remarks>
+        /// The application may set the "value_format" attribute to one of the
+        /// following values in order to customize what is read by the Screen Reader:
+        /// 1. "percent" (the default) - AccessibilityGetCurrent() normalized as
+        ///    a percentage of the range [AccessibilityGetMinimum(), AccessibilityGetMaximum()],
+        /// 2. "number" - AccessibilityGetCurrent() verbatim,
+        /// 3. "text" - AccessibilityGetValueText() is used instead of AccessibilityGetCurrent()
+        /// </remarks>
         [EditorBrowsable(EditorBrowsableState.Never)]
         double AccessibilityGetCurrent();
 
+        /// <summary>
+        /// Gets the formatted current value.
+        /// </summary>
+        /// <remarks>
+        /// This does not have to be AccessibilityGetCurrent() formatted in any
+        /// particular way, i.e. it may be an arbitrary string, e.g. "small font size"
+        /// for the numeric value 10.0. The return value of this method is only
+        /// used if the "value_format" attribute is "text".
+        /// </remarks>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        string AccessibilityGetValueText();
+
         [EditorBrowsable(EditorBrowsableState.Never)]
         double AccessibilityGetMaximum();
 
index dbc41bd..efae6ea 100755 (executable)
@@ -59,7 +59,7 @@ namespace Tizen.NUI.BaseComponents
         /// Dictionary of accessibility attributes (key-value pairs of strings).
         /// </summary>
         [EditorBrowsable(EditorBrowsableState.Never)]
-        protected Dictionary<string, string> AccessibilityAttributes { get; } = new Dictionary<string, string>();
+        public Dictionary<string, string> AccessibilityAttributes { get; } = new Dictionary<string, string>();
 
         ///////////////////////////////////////////////////////////////////
         // ************************** Highlight ************************ //
index 89ca54e..2727ef4 100755 (executable)
@@ -420,6 +420,18 @@ namespace Tizen.NUI.BaseComponents
             return ret;
         }
 
+        // AccessibilityValueTextRequested
+
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public class AccessibilityValueTextRequestedEventArgs : EventArgs
+        {
+            [EditorBrowsable(EditorBrowsableState.Never)]
+            public string Text { get; set; }
+        }
+
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public event EventHandler<AccessibilityValueTextRequestedEventArgs> AccessibilityValueTextRequested;
+
         ///////////////////////////////////////////////////////////////////
         // **************** AccessibilityActivatedSignal **************** //
         ///////////////////////////////////////////////////////////////////
index 07bc576..5874cd1 100644 (file)
@@ -400,6 +400,7 @@ namespace Tizen.NUI.BaseComponents
             ad.GetMaximum          = AccessibilityGetMaximumWrapper;
             ad.GetMinimum          = AccessibilityGetMinimumWrapper;
             ad.GetMinimumIncrement = AccessibilityGetMinimumIncrementWrapper;
+            ad.GetValueText        = AccessibilityGetValueTextWrapper;
             ad.SetCurrent          = AccessibilitySetCurrentWrapper;
         }
 
@@ -423,6 +424,33 @@ namespace Tizen.NUI.BaseComponents
             return GetInterfaceFromRefObject<IAtspiValue>(self).AccessibilityGetMinimumIncrement();
         }
 
+        private static IntPtr AccessibilityGetValueTextWrapper(IntPtr self)
+        {
+            var view = GetViewFromRefObject(self);
+            var value = GetInterfaceFromRefObject<IAtspiValue>(self);
+            string text;
+
+            // Mimic the behaviour of the pairs AccessibilityNameRequested & AccessibilityGetName(),
+            // and AccessibilityDescriptionRequested & AccessibilityGetDescription(),
+            // i.e. a higher-priority Accessibility[…]Requested event for application developers,
+            // and a lower-priority AccessibilityGet[…]() virtual method for component developers.
+            // The difference is that event-or-virtual-method dispatching is done in C++ for
+            // Name and Description, and here in this wrapper method for ValueText (because there
+            // is no signal for ValueText in DALi.)
+            if (view.AccessibilityValueTextRequested?.GetInvocationList().Length > 0)
+            {
+                var args = new AccessibilityValueTextRequestedEventArgs();
+                view.AccessibilityValueTextRequested.Invoke(view, args);
+                text = args.Text;
+            }
+            else
+            {
+                text = value.AccessibilityGetValueText();
+            }
+
+            return DuplicateString(text);
+        }
+
         private static bool AccessibilitySetCurrentWrapper(IntPtr self, double value)
         {
             return GetInterfaceFromRefObject<IAtspiValue>(self).AccessibilitySetCurrent(value);