From 8293b4c9d4eae626e5ca3c9ea3968d6bd8d4efa8 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Artur=20=C5=9Awigo=C5=84?= Date: Thu, 13 Apr 2023 10:45:11 +0200 Subject: [PATCH] [NUI][AT-SPI] Add IAtspiValue.AccessibilityGetValueText() 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 | 9 +++++++ src/Tizen.NUI.Components/Controls/Progress.cs | 9 +++++++ src/Tizen.NUI.Components/Controls/Slider.cs | 9 +++++++ .../src/internal/Interop/Interop.ControlDevel.cs | 5 ++++ .../src/public/Accessibility/IAtspiValue.cs | 23 ++++++++++++++++++ .../src/public/BaseComponents/ViewAccessibility.cs | 2 +- .../BaseComponents/ViewAccessibilityEvent.cs | 12 ++++++++++ .../BaseComponents/ViewAccessibilityWrappers.cs | 28 ++++++++++++++++++++++ 8 files changed, 96 insertions(+), 1 deletion(-) diff --git a/src/Tizen.NUI.Components/Controls/Pagination.cs b/src/Tizen.NUI.Components/Controls/Pagination.cs index 569dc15..992f527 100755 --- a/src/Tizen.NUI.Components/Controls/Pagination.cs +++ b/src/Tizen.NUI.Components/Controls/Pagination.cs @@ -471,6 +471,15 @@ namespace Tizen.NUI.Components } /// + /// Formatted current value. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + string IAtspiValue.AccessibilityGetValueText() + { + return $"{SelectedIndex}"; + } + + /// /// Maximum value. /// [EditorBrowsable(EditorBrowsableState.Never)] diff --git a/src/Tizen.NUI.Components/Controls/Progress.cs b/src/Tizen.NUI.Components/Controls/Progress.cs index 07561fa..70e88e0 100755 --- a/src/Tizen.NUI.Components/Controls/Progress.cs +++ b/src/Tizen.NUI.Components/Controls/Progress.cs @@ -545,6 +545,15 @@ namespace Tizen.NUI.Components } } + /// + /// Formatted current value. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + string IAtspiValue.AccessibilityGetValueText() + { + return (this as IAtspiValue).AccessibilityGetCurrent().ToString(); + } + [EditorBrowsable(EditorBrowsableState.Never)] bool IAtspiValue.AccessibilitySetCurrent(double value) { diff --git a/src/Tizen.NUI.Components/Controls/Slider.cs b/src/Tizen.NUI.Components/Controls/Slider.cs index cfc3b51..5b21df4 100755 --- a/src/Tizen.NUI.Components/Controls/Slider.cs +++ b/src/Tizen.NUI.Components/Controls/Slider.cs @@ -1609,6 +1609,15 @@ namespace Tizen.NUI.Components } /// + /// Formatted current value. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + string IAtspiValue.AccessibilityGetValueText() + { + return $"{CurrentValue}"; + } + + /// /// Gets maximum value for Accessibility. /// [EditorBrowsable(EditorBrowsableState.Never)] diff --git a/src/Tizen.NUI/src/internal/Interop/Interop.ControlDevel.cs b/src/Tizen.NUI/src/internal/Interop/Interop.ControlDevel.cs index ae7a04d..93d2d94 100755 --- a/src/Tizen.NUI/src/internal/Interop/Interop.ControlDevel.cs +++ b/src/Tizen.NUI/src/internal/Interop/Interop.ControlDevel.cs @@ -391,6 +391,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")] diff --git a/src/Tizen.NUI/src/public/Accessibility/IAtspiValue.cs b/src/Tizen.NUI/src/public/Accessibility/IAtspiValue.cs index 338889f..a6fecb7 100644 --- a/src/Tizen.NUI/src/public/Accessibility/IAtspiValue.cs +++ b/src/Tizen.NUI/src/public/Accessibility/IAtspiValue.cs @@ -26,9 +26,32 @@ namespace Tizen.NUI.Accessibility [EditorBrowsable(EditorBrowsableState.Never)] double AccessibilityGetMinimum(); + /// + /// Gets the current numeric value. + /// + /// + /// 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() + /// [EditorBrowsable(EditorBrowsableState.Never)] double AccessibilityGetCurrent(); + /// + /// Gets the formatted current value. + /// + /// + /// 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". + /// + [EditorBrowsable(EditorBrowsableState.Never)] + string AccessibilityGetValueText(); + [EditorBrowsable(EditorBrowsableState.Never)] double AccessibilityGetMaximum(); diff --git a/src/Tizen.NUI/src/public/BaseComponents/ViewAccessibility.cs b/src/Tizen.NUI/src/public/BaseComponents/ViewAccessibility.cs index 843c364..e909dc6 100755 --- a/src/Tizen.NUI/src/public/BaseComponents/ViewAccessibility.cs +++ b/src/Tizen.NUI/src/public/BaseComponents/ViewAccessibility.cs @@ -59,7 +59,7 @@ namespace Tizen.NUI.BaseComponents /// Dictionary of accessibility attributes (key-value pairs of strings). /// [EditorBrowsable(EditorBrowsableState.Never)] - protected Dictionary AccessibilityAttributes { get; } = new Dictionary(); + public Dictionary AccessibilityAttributes { get; } = new Dictionary(); /////////////////////////////////////////////////////////////////// // ************************** Highlight ************************ // diff --git a/src/Tizen.NUI/src/public/BaseComponents/ViewAccessibilityEvent.cs b/src/Tizen.NUI/src/public/BaseComponents/ViewAccessibilityEvent.cs index 89ca54e..2727ef4 100755 --- a/src/Tizen.NUI/src/public/BaseComponents/ViewAccessibilityEvent.cs +++ b/src/Tizen.NUI/src/public/BaseComponents/ViewAccessibilityEvent.cs @@ -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 AccessibilityValueTextRequested; + /////////////////////////////////////////////////////////////////// // **************** AccessibilityActivatedSignal **************** // /////////////////////////////////////////////////////////////////// diff --git a/src/Tizen.NUI/src/public/BaseComponents/ViewAccessibilityWrappers.cs b/src/Tizen.NUI/src/public/BaseComponents/ViewAccessibilityWrappers.cs index 07bc576..5874cd1 100644 --- a/src/Tizen.NUI/src/public/BaseComponents/ViewAccessibilityWrappers.cs +++ b/src/Tizen.NUI/src/public/BaseComponents/ViewAccessibilityWrappers.cs @@ -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(self).AccessibilityGetMinimumIncrement(); } + private static IntPtr AccessibilityGetValueTextWrapper(IntPtr self) + { + var view = GetViewFromRefObject(self); + var value = GetInterfaceFromRefObject(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(self).AccessibilitySetCurrent(value); -- 2.7.4