2 * Copyright(c) 2022 Samsung Electronics Co., Ltd.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
19 using System.Runtime.InteropServices;
21 namespace Tizen.NUI.BaseComponents
23 public partial class View
25 private static AccessibilityStates AccessibilityInitialStates = new AccessibilityStates();
27 // To be removed when native C# AT-SPI interfaces are implemented.
28 private uint? AtspiInterfaceFlags = null;
30 private static void RegisterAccessibilityDelegate()
32 InitializeAccessibilityDelegateAccessibleInterface();
33 InitializeAccessibilityDelegateActionInterface();
34 InitializeAccessibilityDelegateComponentInterface();
35 InitializeAccessibilityDelegateEditableTextInterface();
36 InitializeAccessibilityDelegateSelectionInterface();
37 InitializeAccessibilityDelegateTextInterface();
38 InitializeAccessibilityDelegateValueInterface();
39 InitializeAccessibilityDelegateTizenExtensions();
41 var ad = Interop.ControlDevel.AccessibilityDelegate.Instance;
42 var size = Marshal.SizeOf<Interop.ControlDevel.AccessibilityDelegate>();
43 var ptr = Marshal.AllocHGlobal(size);
45 Marshal.StructureToPtr(ad, ptr, false);
46 Interop.ControlDevel.DaliAccessibilitySetAccessibilityDelegate(ptr, size);
49 private static View GetViewFromRefObject(IntPtr refObjectPtr)
51 return Registry.GetManagedBaseHandleFromRefObject(refObjectPtr) as View;
54 private static IntPtr DuplicateString(string value)
56 return Interop.ControlDevel.DaliAccessibilityDuplicateString(value ?? "");
59 private static IntPtr DuplicateAccessibilityRange(AccessibilityRange range)
61 return Interop.ControlDevel.DaliAccessibilityNewRange(range.StartOffset, range.EndOffset, range.Content);
65 // Accessible interface
68 private static void InitializeAccessibilityDelegateAccessibleInterface()
70 var ad = Interop.ControlDevel.AccessibilityDelegate.Instance;
72 ad.CalculateStates = AccessibilityCalculateStatesWrapper;
73 ad.GetDescription = AccessibilityGetDescriptionWrapper;
74 ad.GetInterfaces = AccessibilityGetInterfaces; // Not a wrapper, entirely private implementation
75 ad.GetName = AccessibilityGetNameWrapper;
78 private static ulong AccessibilityCalculateStatesWrapper(IntPtr self, ulong initialStates)
80 View view = GetViewFromRefObject(self);
83 lock (AccessibilityInitialStates)
85 AccessibilityInitialStates.BitMask = initialStates;
86 bitMask = view.AccessibilityCalculateStates().BitMask;
87 AccessibilityInitialStates.BitMask = 0UL;
93 private static IntPtr AccessibilityGetDescriptionWrapper(IntPtr self)
95 string description = GetViewFromRefObject(self).AccessibilityGetDescription();
97 return DuplicateString(description);
100 private static uint AccessibilityGetInterfaces(IntPtr self)
102 // Currently a maximum of one AccessibilityInterface per View is supported.
103 // This will change when we implement AT-SPI interfaces as native C# interfaces.
104 // Then, this method will look like:
107 // if (view is IAtspiSelection) flags |= (1U << (int)AccessibilityInterface.Selection)
108 // if (view is IAtspiValue) flags |= (1U << (int)AccessibilityInterface.Value)
112 View view = GetViewFromRefObject(self);
114 if (!view.AtspiInterfaceFlags.HasValue)
116 NUILog.Error("AtspiInterfaceFlags are not set!");
120 return view.AtspiInterfaceFlags.Value;
123 private static IntPtr AccessibilityGetNameWrapper(IntPtr self)
125 string name = GetViewFromRefObject(self).AccessibilityGetName();
127 return DuplicateString(name);
134 private static void InitializeAccessibilityDelegateActionInterface()
136 var ad = Interop.ControlDevel.AccessibilityDelegate.Instance;
138 ad.DoAction = AccessibilityDoActionWrapper;
139 ad.GetActionCount = AccessibilityGetActionCountWrapper;
140 ad.GetActionName = AccessibilityGetActionNameWrapper;
143 private static bool AccessibilityDoActionWrapper(IntPtr self, IntPtr name)
145 return GetViewFromRefObject(self).AccessibilityDoAction(Marshal.PtrToStringAnsi(name));
148 private static int AccessibilityGetActionCountWrapper(IntPtr self)
150 return GetViewFromRefObject(self).AccessibilityGetActionCount();
153 private static IntPtr AccessibilityGetActionNameWrapper(IntPtr self, int index)
155 string name = GetViewFromRefObject(self).AccessibilityGetActionName(index);
157 return DuplicateString(name);
161 // Component interface
164 private static void InitializeAccessibilityDelegateComponentInterface()
166 var ad = Interop.ControlDevel.AccessibilityDelegate.Instance;
168 ad.IsScrollable = AccessibilityIsScrollableWrapper;
171 private static bool AccessibilityIsScrollableWrapper(IntPtr self)
173 return GetViewFromRefObject(self).AccessibilityIsScrollable();
177 // EditableText interface
180 private static void InitializeAccessibilityDelegateEditableTextInterface()
182 var ad = Interop.ControlDevel.AccessibilityDelegate.Instance;
184 ad.CopyText = AccessibilityCopyTextWrapper;
185 ad.CutText = AccessibilityCutTextWrapper;
186 ad.DeleteText = AccessibilityDeleteTextWrapper;
187 ad.InsertText = AccessibilityInsertTextWrapper;
188 ad.SetTextContents = AccessibilitySetTextContentsWrapper;
191 private static bool AccessibilityCopyTextWrapper(IntPtr self, int startPosition, int endPosition)
193 return GetViewFromRefObject(self).AccessibilityCopyText(startPosition, endPosition);
196 private static bool AccessibilityCutTextWrapper(IntPtr self, int startPosition, int endPosition)
198 return GetViewFromRefObject(self).AccessibilityCutText(startPosition, endPosition);
201 private static bool AccessibilityDeleteTextWrapper(IntPtr self, int startPosition, int endPosition)
203 return GetViewFromRefObject(self).AccessibilityDeleteText(startPosition, endPosition);
206 private static bool AccessibilityInsertTextWrapper(IntPtr self, int startPosition, IntPtr text)
208 return GetViewFromRefObject(self).AccessibilityInsertText(startPosition, Marshal.PtrToStringAnsi(text));
211 private static bool AccessibilitySetTextContentsWrapper(IntPtr self, IntPtr newContents)
213 return GetViewFromRefObject(self).AccessibilitySetTextContents(Marshal.PtrToStringAnsi(newContents));
217 // Selection interface
220 private static void InitializeAccessibilityDelegateSelectionInterface()
222 var ad = Interop.ControlDevel.AccessibilityDelegate.Instance;
224 ad.ClearSelection = AccessibilityClearSelectionWrapper;
225 ad.DeselectChild = AccessibilityDeselectChildWrapper;
226 ad.DeselectSelectedChild = AccessibilityDeselectSelectedChildWrapper;
227 ad.GetSelectedChild = AccessibilityGetSelectedChildWrapper;
228 ad.GetSelectedChildrenCount = AccessibilityGetSelectedChildrenCountWrapper;
229 ad.IsChildSelected = AccessibilityIsChildSelectedWrapper;
230 ad.SelectAll = AccessibilitySelectAllWrapper;
231 ad.SelectChild = AccessibilitySelectChildWrapper;
234 private static bool AccessibilityClearSelectionWrapper(IntPtr self)
236 return GetViewFromRefObject(self).AccessibilityClearSelection();
239 private static bool AccessibilityDeselectChildWrapper(IntPtr self, int childIndex)
241 return GetViewFromRefObject(self).AccessibilityDeselectChild(childIndex);
244 private static bool AccessibilityDeselectSelectedChildWrapper(IntPtr self, int selectedChildIndex)
246 return GetViewFromRefObject(self).AccessibilityDeselectSelectedChild(selectedChildIndex);
249 private static IntPtr AccessibilityGetSelectedChildWrapper(IntPtr self, int selectedChildIndex)
251 View child = GetViewFromRefObject(self).AccessibilityGetSelectedChild(selectedChildIndex);
253 return View.getCPtr(child).Handle;
256 private static int AccessibilityGetSelectedChildrenCountWrapper(IntPtr self)
258 return GetViewFromRefObject(self).AccessibilityGetSelectedChildrenCount();
261 private static bool AccessibilityIsChildSelectedWrapper(IntPtr self, int childIndex)
263 return GetViewFromRefObject(self).AccessibilityIsChildSelected(childIndex);
266 private static bool AccessibilitySelectAllWrapper(IntPtr self)
268 return GetViewFromRefObject(self).AccessibilitySelectAll();
271 private static bool AccessibilitySelectChildWrapper(IntPtr self, int childIndex)
273 return GetViewFromRefObject(self).AccessibilitySelectChild(childIndex);
280 private static void InitializeAccessibilityDelegateTextInterface()
282 var ad = Interop.ControlDevel.AccessibilityDelegate.Instance;
284 ad.GetCharacterCount = AccessibilityGetCharacterCountWrapper;
285 ad.GetCursorOffset = AccessibilityGetCursorOffsetWrapper;
286 ad.GetSelection = AccessibilityGetSelectionWrapper;
287 ad.GetText = AccessibilityGetTextWrapper;
288 ad.GetTextAtOffset = AccessibilityGetTextAtOffsetWrapper;
289 ad.RemoveSelection = AccessibilityRemoveSelectionWrapper;
290 ad.SetCursorOffset = AccessibilitySetCursorOffsetWrapper;
291 ad.SetSelection = AccessibilitySetSelectionWrapper;
294 private static int AccessibilityGetCharacterCountWrapper(IntPtr self)
296 return GetViewFromRefObject(self).AccessibilityGetCharacterCount();
299 private static int AccessibilityGetCursorOffsetWrapper(IntPtr self)
301 return GetViewFromRefObject(self).AccessibilityGetCursorOffset();
304 private static IntPtr AccessibilityGetSelectionWrapper(IntPtr self, int selectionNumber)
306 AccessibilityRange range = GetViewFromRefObject(self).AccessibilityGetSelection(selectionNumber);
308 return DuplicateAccessibilityRange(range);
311 private static IntPtr AccessibilityGetTextWrapper(IntPtr self, int startOffset, int endOffset)
313 string text = GetViewFromRefObject(self).AccessibilityGetText(startOffset, endOffset);
315 return DuplicateString(text);
318 private static IntPtr AccessibilityGetTextAtOffsetWrapper(IntPtr self, int offset, int boundary)
320 AccessibilityRange range = GetViewFromRefObject(self).AccessibilityGetTextAtOffset(offset, (AccessibilityTextBoundary)boundary);
322 return DuplicateAccessibilityRange(range);
325 private static bool AccessibilityRemoveSelectionWrapper(IntPtr self, int selectionNumber)
327 return GetViewFromRefObject(self).AccessibilityRemoveSelection(selectionNumber);
330 private static bool AccessibilitySetCursorOffsetWrapper(IntPtr self, int offset)
332 return GetViewFromRefObject(self).AccessibilitySetCursorOffset(offset);
335 private static bool AccessibilitySetSelectionWrapper(IntPtr self, int selectionNumber, int startOffset, int endOffset)
337 return GetViewFromRefObject(self).AccessibilitySetSelection(selectionNumber, startOffset, endOffset);
344 private static void InitializeAccessibilityDelegateValueInterface()
346 var ad = Interop.ControlDevel.AccessibilityDelegate.Instance;
348 ad.GetCurrent = AccessibilityGetCurrentWrapper;
349 ad.GetMaximum = AccessibilityGetMaximumWrapper;
350 ad.GetMinimum = AccessibilityGetMinimumWrapper;
351 ad.GetMinimumIncrement = AccessibilityGetMinimumIncrementWrapper;
352 ad.SetCurrent = AccessibilitySetCurrentWrapper;
355 private static double AccessibilityGetCurrentWrapper(IntPtr self)
357 return GetViewFromRefObject(self).AccessibilityGetCurrent();
360 private static double AccessibilityGetMaximumWrapper(IntPtr self)
362 return GetViewFromRefObject(self).AccessibilityGetMaximum();
365 private static double AccessibilityGetMinimumWrapper(IntPtr self)
367 return GetViewFromRefObject(self).AccessibilityGetMinimum();
370 private static double AccessibilityGetMinimumIncrementWrapper(IntPtr self)
372 return GetViewFromRefObject(self).AccessibilityGetMinimumIncrement();
375 private static bool AccessibilitySetCurrentWrapper(IntPtr self, double value)
377 return GetViewFromRefObject(self).AccessibilitySetCurrent(value);
384 private static void InitializeAccessibilityDelegateTizenExtensions()
386 var ad = Interop.ControlDevel.AccessibilityDelegate.Instance;
388 ad.ScrollToChild = AccessibilityScrollToChildWrapper;
389 ad.ShouldReportZeroChildren = AccessibilityShouldReportZeroChildrenWrapper;
392 private static bool AccessibilityScrollToChildWrapper(IntPtr self, IntPtr child)
394 View view = GetViewFromRefObject(self);
396 return view.AccessibilityScrollToChild(view.GetInstanceSafely<View>(child));
399 private static bool AccessibilityShouldReportZeroChildrenWrapper(IntPtr self)
401 return GetViewFromRefObject(self).AccessibilityShouldReportZeroChildren();