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;
20 using Tizen.NUI.Accessibility;
22 namespace Tizen.NUI.BaseComponents
24 public partial class View
26 private static AccessibilityStates AccessibilityInitialStates = new AccessibilityStates();
28 private static void RegisterAccessibilityDelegate()
30 InitializeAccessibilityDelegateAccessibleInterface();
31 InitializeAccessibilityDelegateActionInterface();
32 InitializeAccessibilityDelegateComponentInterface();
33 InitializeAccessibilityDelegateEditableTextInterface();
34 InitializeAccessibilityDelegateSelectionInterface();
35 InitializeAccessibilityDelegateTextInterface();
36 InitializeAccessibilityDelegateValueInterface();
37 InitializeAccessibilityDelegateTizenExtensions();
39 var ad = Interop.ControlDevel.AccessibilityDelegate.Instance;
40 var size = Marshal.SizeOf<Interop.ControlDevel.AccessibilityDelegate>();
41 var ptr = Marshal.AllocHGlobal(size);
43 Marshal.StructureToPtr(ad, ptr, false);
44 Interop.ControlDevel.DaliAccessibilitySetAccessibilityDelegate(ptr, size);
47 private static View GetViewFromRefObject(IntPtr refObjectPtr)
49 return Registry.GetManagedBaseHandleFromRefObject(refObjectPtr) as View;
52 private static T GetInterfaceFromRefObject<T>(IntPtr refObjectPtr)
54 var view = GetViewFromRefObject(refObjectPtr);
56 // NUIViewAccessible::CallMethod<T> checks whether a given interface is implemented
57 // before jumping to managed code, so this condition should always be true.
58 if (view is T atspiInterface)
60 return atspiInterface;
66 private static IntPtr DuplicateString(string value)
68 return Interop.ControlDevel.DaliAccessibilityDuplicateString(value ?? "");
71 private static IntPtr DuplicateAccessibilityRange(AccessibilityRange range)
73 return Interop.ControlDevel.DaliAccessibilityNewRange(range.StartOffset, range.EndOffset, range.Content);
76 private static IntPtr DuplicateAccessibilityRectangle(Rectangle rect)
78 return Interop.Rectangle.NewRectangle(rect.X, rect.Y, rect.Width, rect.Height);
82 // Accessible interface
85 private static void InitializeAccessibilityDelegateAccessibleInterface()
87 var ad = Interop.ControlDevel.AccessibilityDelegate.Instance;
89 ad.CalculateStates = AccessibilityCalculateStatesWrapper;
90 ad.GetDescription = AccessibilityGetDescriptionWrapper;
91 ad.GetInterfaces = AccessibilityGetInterfaces; // Not a wrapper, entirely private implementation
92 ad.GetName = AccessibilityGetNameWrapper;
95 private static ulong AccessibilityCalculateStatesWrapper(IntPtr self, ulong initialStates)
97 View view = GetViewFromRefObject(self);
100 lock (AccessibilityInitialStates)
102 AccessibilityInitialStates.BitMask = initialStates;
103 bitMask = view.AccessibilityCalculateStates().BitMask;
104 AccessibilityInitialStates.BitMask = 0UL;
110 private static IntPtr AccessibilityGetDescriptionWrapper(IntPtr self)
112 string description = GetViewFromRefObject(self).AccessibilityGetDescription();
114 return DuplicateString(description);
117 private static uint AccessibilityGetInterfaces(IntPtr self)
119 View view = GetViewFromRefObject(self);
122 if (view is IAtspiEditableText)
124 flags |= (1U << (int)AccessibilityInterface.EditableText);
127 if (view is IAtspiSelection)
129 flags |= (1U << (int)AccessibilityInterface.Selection);
132 if (view is IAtspiText)
134 flags |= (1U << (int)AccessibilityInterface.Text);
137 if (view is IAtspiValue)
139 flags |= (1U << (int)AccessibilityInterface.Value);
145 private static IntPtr AccessibilityGetNameWrapper(IntPtr self)
147 string name = GetViewFromRefObject(self).AccessibilityGetName();
149 return DuplicateString(name);
156 private static void InitializeAccessibilityDelegateActionInterface()
158 var ad = Interop.ControlDevel.AccessibilityDelegate.Instance;
160 ad.DoAction = AccessibilityDoActionWrapper;
161 ad.GetActionCount = AccessibilityGetActionCountWrapper;
162 ad.GetActionName = AccessibilityGetActionNameWrapper;
165 private static bool AccessibilityDoActionWrapper(IntPtr self, IntPtr name)
167 return GetViewFromRefObject(self).AccessibilityDoAction(Marshal.PtrToStringAnsi(name));
170 private static int AccessibilityGetActionCountWrapper(IntPtr self)
172 return GetViewFromRefObject(self).AccessibilityGetActionCount();
175 private static IntPtr AccessibilityGetActionNameWrapper(IntPtr self, int index)
177 string name = GetViewFromRefObject(self).AccessibilityGetActionName(index);
179 return DuplicateString(name);
183 // Component interface
186 private static void InitializeAccessibilityDelegateComponentInterface()
188 var ad = Interop.ControlDevel.AccessibilityDelegate.Instance;
190 ad.IsScrollable = AccessibilityIsScrollableWrapper;
193 private static bool AccessibilityIsScrollableWrapper(IntPtr self)
195 return GetViewFromRefObject(self).AccessibilityIsScrollable();
199 // EditableText interface
202 private static void InitializeAccessibilityDelegateEditableTextInterface()
204 var ad = Interop.ControlDevel.AccessibilityDelegate.Instance;
206 ad.CopyText = AccessibilityCopyTextWrapper;
207 ad.CutText = AccessibilityCutTextWrapper;
208 ad.DeleteText = AccessibilityDeleteTextWrapper;
209 ad.InsertText = AccessibilityInsertTextWrapper;
210 ad.SetTextContents = AccessibilitySetTextContentsWrapper;
213 private static bool AccessibilityCopyTextWrapper(IntPtr self, int startPosition, int endPosition)
215 return GetInterfaceFromRefObject<IAtspiEditableText>(self).AccessibilityCopyText(startPosition, endPosition);
218 private static bool AccessibilityCutTextWrapper(IntPtr self, int startPosition, int endPosition)
220 return GetInterfaceFromRefObject<IAtspiEditableText>(self).AccessibilityCutText(startPosition, endPosition);
223 private static bool AccessibilityDeleteTextWrapper(IntPtr self, int startPosition, int endPosition)
225 return GetInterfaceFromRefObject<IAtspiEditableText>(self).AccessibilityDeleteText(startPosition, endPosition);
228 private static bool AccessibilityInsertTextWrapper(IntPtr self, int startPosition, IntPtr text)
230 return GetInterfaceFromRefObject<IAtspiEditableText>(self).AccessibilityInsertText(startPosition, Marshal.PtrToStringAnsi(text));
233 private static bool AccessibilitySetTextContentsWrapper(IntPtr self, IntPtr newContents)
235 return GetInterfaceFromRefObject<IAtspiEditableText>(self).AccessibilitySetTextContents(Marshal.PtrToStringAnsi(newContents));
239 // Selection interface
242 private static void InitializeAccessibilityDelegateSelectionInterface()
244 var ad = Interop.ControlDevel.AccessibilityDelegate.Instance;
246 ad.ClearSelection = AccessibilityClearSelectionWrapper;
247 ad.DeselectChild = AccessibilityDeselectChildWrapper;
248 ad.DeselectSelectedChild = AccessibilityDeselectSelectedChildWrapper;
249 ad.GetSelectedChild = AccessibilityGetSelectedChildWrapper;
250 ad.GetSelectedChildrenCount = AccessibilityGetSelectedChildrenCountWrapper;
251 ad.IsChildSelected = AccessibilityIsChildSelectedWrapper;
252 ad.SelectAll = AccessibilitySelectAllWrapper;
253 ad.SelectChild = AccessibilitySelectChildWrapper;
256 private static bool AccessibilityClearSelectionWrapper(IntPtr self)
258 return GetInterfaceFromRefObject<IAtspiSelection>(self).AccessibilityClearSelection();
261 private static bool AccessibilityDeselectChildWrapper(IntPtr self, int childIndex)
263 return GetInterfaceFromRefObject<IAtspiSelection>(self).AccessibilityDeselectChild(childIndex);
266 private static bool AccessibilityDeselectSelectedChildWrapper(IntPtr self, int selectedChildIndex)
268 return GetInterfaceFromRefObject<IAtspiSelection>(self).AccessibilityDeselectSelectedChild(selectedChildIndex);
271 private static IntPtr AccessibilityGetSelectedChildWrapper(IntPtr self, int selectedChildIndex)
273 View child = GetInterfaceFromRefObject<IAtspiSelection>(self).AccessibilityGetSelectedChild(selectedChildIndex);
275 return View.getCPtr(child).Handle;
278 private static int AccessibilityGetSelectedChildrenCountWrapper(IntPtr self)
280 return GetInterfaceFromRefObject<IAtspiSelection>(self).AccessibilityGetSelectedChildrenCount();
283 private static bool AccessibilityIsChildSelectedWrapper(IntPtr self, int childIndex)
285 return GetInterfaceFromRefObject<IAtspiSelection>(self).AccessibilityIsChildSelected(childIndex);
288 private static bool AccessibilitySelectAllWrapper(IntPtr self)
290 return GetInterfaceFromRefObject<IAtspiSelection>(self).AccessibilitySelectAll();
293 private static bool AccessibilitySelectChildWrapper(IntPtr self, int childIndex)
295 return GetInterfaceFromRefObject<IAtspiSelection>(self).AccessibilitySelectChild(childIndex);
302 private static void InitializeAccessibilityDelegateTextInterface()
304 var ad = Interop.ControlDevel.AccessibilityDelegate.Instance;
306 ad.GetCharacterCount = AccessibilityGetCharacterCountWrapper;
307 ad.GetCursorOffset = AccessibilityGetCursorOffsetWrapper;
308 ad.GetRangeExtents = AccessibilityGetRangeExtentsWrapper;
309 ad.GetSelection = AccessibilityGetSelectionWrapper;
310 ad.GetText = AccessibilityGetTextWrapper;
311 ad.GetTextAtOffset = AccessibilityGetTextAtOffsetWrapper;
312 ad.RemoveSelection = AccessibilityRemoveSelectionWrapper;
313 ad.SetCursorOffset = AccessibilitySetCursorOffsetWrapper;
314 ad.SetSelection = AccessibilitySetSelectionWrapper;
317 private static int AccessibilityGetCharacterCountWrapper(IntPtr self)
319 return GetInterfaceFromRefObject<IAtspiText>(self).AccessibilityGetCharacterCount();
322 private static int AccessibilityGetCursorOffsetWrapper(IntPtr self)
324 return GetInterfaceFromRefObject<IAtspiText>(self).AccessibilityGetCursorOffset();
327 private static IntPtr AccessibilityGetRangeExtentsWrapper(IntPtr self, int startOffset, int endOffset, int coordType)
329 using Rectangle rect = GetInterfaceFromRefObject<IAtspiText>(self).AccessibilityGetRangeExtents(startOffset, endOffset, (AccessibilityCoordinateType)coordType);
331 return DuplicateAccessibilityRectangle(rect);
334 private static IntPtr AccessibilityGetSelectionWrapper(IntPtr self, int selectionNumber)
336 AccessibilityRange range = GetInterfaceFromRefObject<IAtspiText>(self).AccessibilityGetSelection(selectionNumber);
338 return DuplicateAccessibilityRange(range);
341 private static IntPtr AccessibilityGetTextWrapper(IntPtr self, int startOffset, int endOffset)
343 string text = GetInterfaceFromRefObject<IAtspiText>(self).AccessibilityGetText(startOffset, endOffset);
345 return DuplicateString(text);
348 private static IntPtr AccessibilityGetTextAtOffsetWrapper(IntPtr self, int offset, int boundary)
350 AccessibilityRange range = GetInterfaceFromRefObject<IAtspiText>(self).AccessibilityGetTextAtOffset(offset, (AccessibilityTextBoundary)boundary);
352 return DuplicateAccessibilityRange(range);
355 private static bool AccessibilityRemoveSelectionWrapper(IntPtr self, int selectionNumber)
357 return GetInterfaceFromRefObject<IAtspiText>(self).AccessibilityRemoveSelection(selectionNumber);
360 private static bool AccessibilitySetCursorOffsetWrapper(IntPtr self, int offset)
362 return GetInterfaceFromRefObject<IAtspiText>(self).AccessibilitySetCursorOffset(offset);
365 private static bool AccessibilitySetSelectionWrapper(IntPtr self, int selectionNumber, int startOffset, int endOffset)
367 return GetInterfaceFromRefObject<IAtspiText>(self).AccessibilitySetSelection(selectionNumber, startOffset, endOffset);
374 private static void InitializeAccessibilityDelegateValueInterface()
376 var ad = Interop.ControlDevel.AccessibilityDelegate.Instance;
378 ad.GetCurrent = AccessibilityGetCurrentWrapper;
379 ad.GetMaximum = AccessibilityGetMaximumWrapper;
380 ad.GetMinimum = AccessibilityGetMinimumWrapper;
381 ad.GetMinimumIncrement = AccessibilityGetMinimumIncrementWrapper;
382 ad.SetCurrent = AccessibilitySetCurrentWrapper;
385 private static double AccessibilityGetCurrentWrapper(IntPtr self)
387 return GetInterfaceFromRefObject<IAtspiValue>(self).AccessibilityGetCurrent();
390 private static double AccessibilityGetMaximumWrapper(IntPtr self)
392 return GetInterfaceFromRefObject<IAtspiValue>(self).AccessibilityGetMaximum();
395 private static double AccessibilityGetMinimumWrapper(IntPtr self)
397 return GetInterfaceFromRefObject<IAtspiValue>(self).AccessibilityGetMinimum();
400 private static double AccessibilityGetMinimumIncrementWrapper(IntPtr self)
402 return GetInterfaceFromRefObject<IAtspiValue>(self).AccessibilityGetMinimumIncrement();
405 private static bool AccessibilitySetCurrentWrapper(IntPtr self, double value)
407 return GetInterfaceFromRefObject<IAtspiValue>(self).AccessibilitySetCurrent(value);
414 private static void InitializeAccessibilityDelegateTizenExtensions()
416 var ad = Interop.ControlDevel.AccessibilityDelegate.Instance;
418 ad.ScrollToChild = AccessibilityScrollToChildWrapper;
419 ad.ShouldReportZeroChildren = AccessibilityShouldReportZeroChildrenWrapper;
422 private static bool AccessibilityScrollToChildWrapper(IntPtr self, IntPtr child)
424 View view = GetViewFromRefObject(self);
426 return view.AccessibilityScrollToChild(view.GetInstanceSafely<View>(child));
429 private static bool AccessibilityShouldReportZeroChildrenWrapper(IntPtr self)
431 return GetViewFromRefObject(self).AccessibilityShouldReportZeroChildren();