From e58f2a253b343c07e6199a7736541569f05ca12b Mon Sep 17 00:00:00 2001 From: Seoyeon2Kim <34738918+Seoyeon2Kim@users.noreply.github.com> Date: Wed, 28 May 2025 15:07:30 +0900 Subject: [PATCH] [NUI] Add some accessibility version 2 features for new components (#6907) * [NUI] Add some accessibility features for new components - Introduce essential additions to support accessibility features for OneUI Components. 1) AccessibilityState2 2) AccessibilityRole2 3) AccessibilityIsModal Signed-off-by: Seoyeon Kim * Modify the naming Signed-off-by: Seoyeon Kim * Update the description of `AccessibilityStatesV2.this` Signed-off-by: Seoyeon Kim * Add some test cases Signed-off-by: Seoyeon Kim * Spilt the files according to their own roles - ViewAccessibilityV2.cs / ViewAccessibilityRoleV2.cs / ViewAccessibilityStatesV2.cs Signed-off-by: Seoyeon Kim --------- Signed-off-by: Seoyeon Kim --- .../internal/Interop/Interop.ViewProperty.cs | 6 + .../BaseComponents/ViewAccessibilityRoleV2.cs | 171 ++++++++++++++++++ .../ViewAccessibilityStatesV2.cs | 133 ++++++++++++++ .../BaseComponents/ViewAccessibilityV2.cs | 94 ++++++++++ .../src/public/BaseComponents/ViewEnum.cs | 2 + .../testcase/public/TSView.cs | 58 ++++++ 6 files changed, 464 insertions(+) create mode 100755 src/Tizen.NUI/src/public/BaseComponents/ViewAccessibilityRoleV2.cs create mode 100755 src/Tizen.NUI/src/public/BaseComponents/ViewAccessibilityStatesV2.cs create mode 100755 src/Tizen.NUI/src/public/BaseComponents/ViewAccessibilityV2.cs diff --git a/src/Tizen.NUI/src/internal/Interop/Interop.ViewProperty.cs b/src/Tizen.NUI/src/internal/Interop/Interop.ViewProperty.cs index 9e17e8829..a5c2d0732 100755 --- a/src/Tizen.NUI/src/internal/Interop/Interop.ViewProperty.cs +++ b/src/Tizen.NUI/src/internal/Interop/Interop.ViewProperty.cs @@ -93,6 +93,12 @@ namespace Tizen.NUI [global::System.Runtime.InteropServices.DllImport(NDalicPINVOKE.Lib, EntryPoint = "CSharp_Dali_View_Property_AUTOMATION_ID_get")] public static extern int AutomationIdGet(); + [global::System.Runtime.InteropServices.DllImport(NDalicPINVOKE.Lib, EntryPoint = "CSharp_Dali_View_Property_ACCESSIBILITY_STATES_get")] + public static extern int AccessibilityStateGet(); + + [global::System.Runtime.InteropServices.DllImport(NDalicPINVOKE.Lib, EntryPoint = "CSharp_Dali_View_Property_ACCESSIBILITY_IS_MODAL_get")] + public static extern int AccessibilityIsModalGet(); + [global::System.Runtime.InteropServices.DllImport(NDalicPINVOKE.Lib, EntryPoint = "CSharp_Dali_View_Property_OFFSCREEN_RENDERING_get")] public static extern int OffScreenRenderingGet(); diff --git a/src/Tizen.NUI/src/public/BaseComponents/ViewAccessibilityRoleV2.cs b/src/Tizen.NUI/src/public/BaseComponents/ViewAccessibilityRoleV2.cs new file mode 100755 index 000000000..410f606b2 --- /dev/null +++ b/src/Tizen.NUI/src/public/BaseComponents/ViewAccessibilityRoleV2.cs @@ -0,0 +1,171 @@ +/* + * Copyright(c) 2025 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +using System; +using System.ComponentModel; +using Tizen.NUI; + +namespace Tizen.NUI.BaseComponents +{ + /// + /// Specifies the role of an accessible object. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public enum AccessibilityRoleV2 + { + /// + /// A slider + /// + [EditorBrowsable(EditorBrowsableState.Never)] + Adjustable = 200, + /// + /// An alert + /// + [EditorBrowsable(EditorBrowsableState.Never)] + Alert, + /// + /// A button + /// + [EditorBrowsable(EditorBrowsableState.Never)] + Button, + /// + /// A check box + /// + [EditorBrowsable(EditorBrowsableState.Never)] + CheckBox, + /// + /// A combo box + /// + [EditorBrowsable(EditorBrowsableState.Never)] + ComboBox, + /// + /// A container + /// + [EditorBrowsable(EditorBrowsableState.Never)] + Container, + /// + /// A dialog + /// + [EditorBrowsable(EditorBrowsableState.Never)] + Dialog, + /// + /// An entry + /// + [EditorBrowsable(EditorBrowsableState.Never)] + Entry, + /// + /// A header + /// + [EditorBrowsable(EditorBrowsableState.Never)] + Header, + /// + /// An Image + /// + [EditorBrowsable(EditorBrowsableState.Never)] + Image, + /// + /// A link + /// + [EditorBrowsable(EditorBrowsableState.Never)] + Link, + /// + /// A list + /// + [EditorBrowsable(EditorBrowsableState.Never)] + List, + /// + /// An item of the list + /// + [EditorBrowsable(EditorBrowsableState.Never)] + ListItem, + /// + /// A menu + /// + [EditorBrowsable(EditorBrowsableState.Never)] + Menu, + /// + /// A menu bar + /// + [EditorBrowsable(EditorBrowsableState.Never)] + MenuBar, + /// + /// An item of the menu + /// + [EditorBrowsable(EditorBrowsableState.Never)] + MenuItem, + /// + /// None + /// + [EditorBrowsable(EditorBrowsableState.Never)] + None, + /// + /// A password text + /// + [EditorBrowsable(EditorBrowsableState.Never)] + PasswordText, + /// + /// A popup menu + /// + [EditorBrowsable(EditorBrowsableState.Never)] + PopupMenu, + /// + /// A progress bar + /// + [EditorBrowsable(EditorBrowsableState.Never)] + ProgressBar, + /// + /// A radio button + /// + [EditorBrowsable(EditorBrowsableState.Never)] + RadioButton, + /// + /// A scroll bar + /// + [EditorBrowsable(EditorBrowsableState.Never)] + ScrollBar, + /// + /// A spin button + /// + [EditorBrowsable(EditorBrowsableState.Never)] + SpinButton, + /// + /// A tab + /// + [EditorBrowsable(EditorBrowsableState.Never)] + Tab, + /// + /// A tab list + /// + [EditorBrowsable(EditorBrowsableState.Never)] + TabList, + /// + /// A text + /// + [EditorBrowsable(EditorBrowsableState.Never)] + Text, + /// + /// A toggle button + /// + [EditorBrowsable(EditorBrowsableState.Never)] + ToggleButton, + /// + /// a tool bar + /// + [EditorBrowsable(EditorBrowsableState.Never)] + Toolbar, + } +} diff --git a/src/Tizen.NUI/src/public/BaseComponents/ViewAccessibilityStatesV2.cs b/src/Tizen.NUI/src/public/BaseComponents/ViewAccessibilityStatesV2.cs new file mode 100755 index 000000000..caed57a32 --- /dev/null +++ b/src/Tizen.NUI/src/public/BaseComponents/ViewAccessibilityStatesV2.cs @@ -0,0 +1,133 @@ +/* + * Copyright(c) 2025 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +using System; +using System.ComponentModel; +using Tizen.NUI; + +namespace Tizen.NUI.BaseComponents +{ + /// + /// AccessibilityStateV2 is an enumeration that represents the states of the view to send to accessibility service. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public enum AccessibilityStateV2 + { + /// + /// Indicates whether the view is enabled or not. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + Enabled = 0, + /// + /// Indicates whether a selectable element is currently selected or not. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + Selected, + /// + /// Indicates the state of a checkable element. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + Checked, + /// + /// Indicates whether an element is currently busy or not. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + Busy, + /// + /// Indicates whether an expandable element is currently expanded or collapsed. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + Expanded + } + + /// + /// The AccessibilityStatesV2 structure represents a set of states of the view to communicate to accessibility service. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public struct AccessibilityStatesV2 + { + const uint c_on = 1; + private uint _bitMask; + + /// + /// Gets or sets the value of the specified accessibility state flag using bitmask operations. + /// + /// The enum value representing the accessibility state to check or modify. + /// + /// true if the specified state flag is set in the bitmask; otherwise, false. + /// + /// + /// This indexer uses bitwise operations to efficiently store and retrieve multiple boolean state flags + /// in a single integer field (_bitMask). Each state corresponds to a specific bit position determined + /// by its enum value. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public bool this[AccessibilityStateV2 state] + { + get + { + return Convert.ToBoolean(_bitMask & (c_on << (int)state)); + } + set + { + if (value) + { + _bitMask |= (c_on << (int)state); + } + else + { + _bitMask &= ~(c_on << (int)state); + } + } + } + + AccessibilityStatesV2(int states) + { + _bitMask = (uint)states; + } + + /// + /// Converts an enumeration value to an integer. + /// + /// The value to convert. + /// The integer representation of the specified value. + /// + /// This explicit operator retrieves the internal bitmask value of the enumeration, + /// which represents the combined state flags in a single integer. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public static explicit operator int(AccessibilityStatesV2 state) + { + return (int)state._bitMask; + } + + /// + /// Converts an integer to an enumeration value. + /// + /// The integer value to convert. + /// A new instance of initialized with the specified integer value. + /// + /// This explicit operator creates a new object using the provided integer value, + /// which is interpreted as a bitmask representing multiple state flags. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public static explicit operator AccessibilityStatesV2(int states) + { + return new AccessibilityStatesV2(states); + } + } +} diff --git a/src/Tizen.NUI/src/public/BaseComponents/ViewAccessibilityV2.cs b/src/Tizen.NUI/src/public/BaseComponents/ViewAccessibilityV2.cs new file mode 100755 index 000000000..08232750d --- /dev/null +++ b/src/Tizen.NUI/src/public/BaseComponents/ViewAccessibilityV2.cs @@ -0,0 +1,94 @@ +/* + * Copyright(c) 2025 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +using System; +using System.ComponentModel; +using Tizen.NUI; + +namespace Tizen.NUI.BaseComponents +{ + /// + /// View is the base class for all views. + /// + /// 3 + public partial class View + { + /////////////////////////////////////////////////////////////////// + // ************ Accessibility Methods for Version 2 ************ // + /////////////////////////////////////////////////////////////////// + + /// + /// Gets the AccessibilityStatesV2 property of the view. + /// + /// The states of the view + [EditorBrowsable(EditorBrowsableState.Never)] + public AccessibilityStatesV2 GetAccessibilityStatesV2() + { + return (AccessibilityStatesV2)Object.InternalGetPropertyInt(SwigCPtr, Property.AccessibilityState); + } + + /// + /// Sets the AccessibilityStatesV2 property of the view. + /// + /// The states value to set. + [EditorBrowsable(EditorBrowsableState.Never)] + public void SetAccessibilityStatesV2(AccessibilityStatesV2 states) + { + Object.InternalSetPropertyInt(SwigCPtr, Property.AccessibilityState, (int)states); + } + + /// + /// Gets the accessibility role of the view. + /// + /// The role of the view + [EditorBrowsable(EditorBrowsableState.Never)] + public AccessibilityRoleV2 GetAccessibilityRoleV2() + { + return (AccessibilityRoleV2)Object.InternalGetPropertyInt(SwigCPtr, Property.AccessibilityRole); + } + + /// + /// Sets the accessibiltiy role of the view. + /// + /// The role value to set. + [EditorBrowsable(EditorBrowsableState.Never)] + public void SetAccessibilityRoleV2(AccessibilityRoleV2 role) + { + Object.InternalSetPropertyInt(SwigCPtr, Property.AccessibilityRole, (int)role); + } + + /// + /// Controls whether the view is modal or not. + /// + /// + /// False by default. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public bool AccessibilityIsModal + { + get + { + return Object.InternalGetPropertyBool(SwigCPtr, Property.AccessibilityIsModal); + } + set + { + Object.InternalSetPropertyBool(SwigCPtr, Property.AccessibilityIsModal, value); + } + } + + } +} diff --git a/src/Tizen.NUI/src/public/BaseComponents/ViewEnum.cs b/src/Tizen.NUI/src/public/BaseComponents/ViewEnum.cs index f6cdeeb82..73a0b1a7d 100755 --- a/src/Tizen.NUI/src/public/BaseComponents/ViewEnum.cs +++ b/src/Tizen.NUI/src/public/BaseComponents/ViewEnum.cs @@ -289,6 +289,8 @@ namespace Tizen.NUI.BaseComponents internal static readonly int DispatchKeyEvents = Interop.ViewProperty.DispatchKeyEventsGet(); internal static readonly int AccessibilityHidden = Interop.ViewProperty.AccessibilityHiddenGet(); internal static readonly int AutomationId = Interop.ViewProperty.AutomationIdGet(); + internal static readonly int AccessibilityState = Interop.ViewProperty.AccessibilityStateGet(); + internal static readonly int AccessibilityIsModal = Interop.ViewProperty.AccessibilityIsModalGet(); internal static readonly int UpdateAreaHint = Interop.ActorProperty.UpdateAreaHintGet(); internal static readonly int DispatchTouchMotion = Interop.ActorProperty.DispatchTouchMotionGet(); internal static readonly int DispatchHoverMotion = Interop.ActorProperty.DispatchHoverMotionGet(); diff --git a/test/Tizen.NUI.Devel.Tests.Ubuntu/Tizen.NUI.Devel.Tests/testcase/public/TSView.cs b/test/Tizen.NUI.Devel.Tests.Ubuntu/Tizen.NUI.Devel.Tests/testcase/public/TSView.cs index 3a2ecb63d..f6c9de53b 100644 --- a/test/Tizen.NUI.Devel.Tests.Ubuntu/Tizen.NUI.Devel.Tests/testcase/public/TSView.cs +++ b/test/Tizen.NUI.Devel.Tests.Ubuntu/Tizen.NUI.Devel.Tests/testcase/public/TSView.cs @@ -226,5 +226,63 @@ namespace Tizen.NUI.Devel.Tests testView.Dispose(); } + + [Test] + [Category("P1")] + [Description("Verify SetAccessibilityStatesV2 and GetAccessibilityStatesV2 functionality")] + [Property("SPEC", "Tizen.NUI.BaseComponents.View.GetAccessibilityStatesV2 M")] + [Property("SPEC_URL", "-")] + [Property("CRITERIA", "MR")] + [Property("AUTHOR", "seoyeon2.kim@samsung.com")] + public void AccessibilityStatesV2_SetAndGet_ReturnsCorrectState() + { + /* TEST CODE */ + var testView = new View(); + var expectedStates = new AccessibilityStatesV2(); + expectedStates[AccessibilityStateV2.Enabled] = true; + testView.SetAccessibilityStatesV2(expectedStates); + + var actualStates = testView.GetAccessibilityStatesV2(); + Assert.AreEqual(true, actualStates[AccessibilityStateV2.Enabled], "View AccessibilityStateV2.Enabled should be true."); + + testView.Dispose(); + } + + [Test] + [Category("P1")] + [Description("Verify SetAccessibilityRoleV2 and GetAccessibilityRoleV2 functionality")] + [Property("SPEC", "Tizen.NUI.BaseComponents.View.GetAccessibilityRoleV2 M")] + [Property("SPEC_URL", "-")] + [Property("CRITERIA", "MR")] + [Property("AUTHOR", "seoyeon2.kim@samsung.com")] + public void AccessibilityRoleV2_SetAndGet_ReturnsCorrectRole() + { + /* TEST CODE */ + var testView = new View(); + testView.SetAccessibilityRoleV2(AccessibilityRoleV2.Button); + + var actualRole = testView.GetAccessibilityRoleV2(); + Assert.AreEqual(AccessibilityRoleV2.Button, actualRole, "actualRole should be AccessibilityRoleV2.Button."); + + testView.Dispose(); + } + + [Test] + [Category("P1")] + [Description("Get value test for View.AccessibilityIsModal")] + [Property("SPEC", "Tizen.NUI.BaseComponents.View.AccessibilityIsModal")] + [Property("SPEC_URL", "-")] + [Property("CRITERIA", "PRW")] + [Property("AUTHOR", "seoyeon2.kim@samsung.com")] + public void AccessibilityIsModal_GET_SET_VALUE() + { + /* TEST CODE */ + View testView = new View(); + + testView.AccessibilityIsModal = true; + Assert.AreEqual(true, testView.AccessibilityIsModal, "Should get equal bool value what we set before"); + + testView.Dispose(); + } } } -- 2.34.1