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);
103 lock (AccessibilityInitialStates)
105 AccessibilityInitialStates.BitMask = initialStates;
106 bitMask = view.AccessibilityCalculateStates().BitMask;
107 AccessibilityInitialStates.BitMask = 0UL;
113 private static IntPtr AccessibilityGetDescriptionWrapper(IntPtr self)
115 string description = GetViewFromRefObject(self).AccessibilityGetDescription();
117 return DuplicateString(description);
120 private static uint AccessibilityGetInterfaces(IntPtr self)
122 View view = GetViewFromRefObject(self);
125 if (view is IAtspiEditableText)
127 flags |= (1U << (int)AccessibilityInterface.EditableText);
130 if (view is IAtspiSelection)
132 flags |= (1U << (int)AccessibilityInterface.Selection);
135 if (view is IAtspiText)
137 flags |= (1U << (int)AccessibilityInterface.Text);
140 if (view is IAtspiValue)
142 flags |= (1U << (int)AccessibilityInterface.Value);
148 private static IntPtr AccessibilityGetNameWrapper(IntPtr self)
150 string name = GetViewFromRefObject(self).AccessibilityGetName();
152 return DuplicateString(name);
159 private static void InitializeAccessibilityDelegateActionInterface()
161 var ad = Interop.ControlDevel.AccessibilityDelegate.Instance;
163 ad.DoAction = AccessibilityDoActionWrapper;
164 ad.GetActionCount = AccessibilityGetActionCountWrapper;
165 ad.GetActionName = AccessibilityGetActionNameWrapper;
168 private static bool AccessibilityDoActionWrapper(IntPtr self, IntPtr name)
170 return GetViewFromRefObject(self).AccessibilityDoAction(Marshal.PtrToStringAnsi(name));
173 private static int AccessibilityGetActionCountWrapper(IntPtr self)
175 return GetViewFromRefObject(self).AccessibilityGetActionCount();
178 private static IntPtr AccessibilityGetActionNameWrapper(IntPtr self, int index)
180 string name = GetViewFromRefObject(self).AccessibilityGetActionName(index);
182 return DuplicateString(name);
186 // Component interface
189 private static void InitializeAccessibilityDelegateComponentInterface()
191 var ad = Interop.ControlDevel.AccessibilityDelegate.Instance;
193 ad.IsScrollable = AccessibilityIsScrollableWrapper;
196 private static bool AccessibilityIsScrollableWrapper(IntPtr self)
198 return GetViewFromRefObject(self).AccessibilityIsScrollable();
202 // EditableText interface
205 private static void InitializeAccessibilityDelegateEditableTextInterface()
207 var ad = Interop.ControlDevel.AccessibilityDelegate.Instance;
209 ad.CopyText = AccessibilityCopyTextWrapper;
210 ad.CutText = AccessibilityCutTextWrapper;
211 ad.DeleteText = AccessibilityDeleteTextWrapper;
212 ad.InsertText = AccessibilityInsertTextWrapper;
213 ad.SetTextContents = AccessibilitySetTextContentsWrapper;
216 private static bool AccessibilityCopyTextWrapper(IntPtr self, int startPosition, int endPosition)
218 return GetInterfaceFromRefObject<IAtspiEditableText>(self).AccessibilityCopyText(startPosition, endPosition);
221 private static bool AccessibilityCutTextWrapper(IntPtr self, int startPosition, int endPosition)
223 return GetInterfaceFromRefObject<IAtspiEditableText>(self).AccessibilityCutText(startPosition, endPosition);
226 private static bool AccessibilityDeleteTextWrapper(IntPtr self, int startPosition, int endPosition)
228 return GetInterfaceFromRefObject<IAtspiEditableText>(self).AccessibilityDeleteText(startPosition, endPosition);
231 private static bool AccessibilityInsertTextWrapper(IntPtr self, int startPosition, IntPtr text)
233 return GetInterfaceFromRefObject<IAtspiEditableText>(self).AccessibilityInsertText(startPosition, Marshal.PtrToStringAnsi(text));
236 private static bool AccessibilitySetTextContentsWrapper(IntPtr self, IntPtr newContents)
238 return GetInterfaceFromRefObject<IAtspiEditableText>(self).AccessibilitySetTextContents(Marshal.PtrToStringAnsi(newContents));
242 // Selection interface
245 private static void InitializeAccessibilityDelegateSelectionInterface()
247 var ad = Interop.ControlDevel.AccessibilityDelegate.Instance;
249 ad.ClearSelection = AccessibilityClearSelectionWrapper;
250 ad.DeselectChild = AccessibilityDeselectChildWrapper;
251 ad.DeselectSelectedChild = AccessibilityDeselectSelectedChildWrapper;
252 ad.GetSelectedChild = AccessibilityGetSelectedChildWrapper;
253 ad.GetSelectedChildrenCount = AccessibilityGetSelectedChildrenCountWrapper;
254 ad.IsChildSelected = AccessibilityIsChildSelectedWrapper;
255 ad.SelectAll = AccessibilitySelectAllWrapper;
256 ad.SelectChild = AccessibilitySelectChildWrapper;
259 private static bool AccessibilityClearSelectionWrapper(IntPtr self)
261 return GetInterfaceFromRefObject<IAtspiSelection>(self).AccessibilityClearSelection();
264 private static bool AccessibilityDeselectChildWrapper(IntPtr self, int childIndex)
266 return GetInterfaceFromRefObject<IAtspiSelection>(self).AccessibilityDeselectChild(childIndex);
269 private static bool AccessibilityDeselectSelectedChildWrapper(IntPtr self, int selectedChildIndex)
271 return GetInterfaceFromRefObject<IAtspiSelection>(self).AccessibilityDeselectSelectedChild(selectedChildIndex);
274 private static IntPtr AccessibilityGetSelectedChildWrapper(IntPtr self, int selectedChildIndex)
276 View child = GetInterfaceFromRefObject<IAtspiSelection>(self).AccessibilityGetSelectedChild(selectedChildIndex);
278 return View.getCPtr(child).Handle;
281 private static int AccessibilityGetSelectedChildrenCountWrapper(IntPtr self)
283 return GetInterfaceFromRefObject<IAtspiSelection>(self).AccessibilityGetSelectedChildrenCount();
286 private static bool AccessibilityIsChildSelectedWrapper(IntPtr self, int childIndex)
288 return GetInterfaceFromRefObject<IAtspiSelection>(self).AccessibilityIsChildSelected(childIndex);
291 private static bool AccessibilitySelectAllWrapper(IntPtr self)
293 return GetInterfaceFromRefObject<IAtspiSelection>(self).AccessibilitySelectAll();
296 private static bool AccessibilitySelectChildWrapper(IntPtr self, int childIndex)
298 return GetInterfaceFromRefObject<IAtspiSelection>(self).AccessibilitySelectChild(childIndex);
305 private static void InitializeAccessibilityDelegateTextInterface()
307 var ad = Interop.ControlDevel.AccessibilityDelegate.Instance;
309 ad.GetCharacterCount = AccessibilityGetCharacterCountWrapper;
310 ad.GetCursorOffset = AccessibilityGetCursorOffsetWrapper;
311 ad.GetRangeExtents = AccessibilityGetRangeExtentsWrapper;
312 ad.GetSelection = AccessibilityGetSelectionWrapper;
313 ad.GetText = AccessibilityGetTextWrapper;
314 ad.GetTextAtOffset = AccessibilityGetTextAtOffsetWrapper;
315 ad.RemoveSelection = AccessibilityRemoveSelectionWrapper;
316 ad.SetCursorOffset = AccessibilitySetCursorOffsetWrapper;
317 ad.SetSelection = AccessibilitySetSelectionWrapper;
320 private static int AccessibilityGetCharacterCountWrapper(IntPtr self)
322 return GetInterfaceFromRefObject<IAtspiText>(self).AccessibilityGetCharacterCount();
325 private static int AccessibilityGetCursorOffsetWrapper(IntPtr self)
327 return GetInterfaceFromRefObject<IAtspiText>(self).AccessibilityGetCursorOffset();
330 private static IntPtr AccessibilityGetRangeExtentsWrapper(IntPtr self, int startOffset, int endOffset, int coordType)
332 using Rectangle rect = GetInterfaceFromRefObject<IAtspiText>(self).AccessibilityGetRangeExtents(startOffset, endOffset, (AccessibilityCoordinateType)coordType);
334 return DuplicateAccessibilityRectangle(rect);
337 private static IntPtr AccessibilityGetSelectionWrapper(IntPtr self, int selectionNumber)
339 AccessibilityRange range = GetInterfaceFromRefObject<IAtspiText>(self).AccessibilityGetSelection(selectionNumber);
341 return DuplicateAccessibilityRange(range);
344 private static IntPtr AccessibilityGetTextWrapper(IntPtr self, int startOffset, int endOffset)
346 string text = GetInterfaceFromRefObject<IAtspiText>(self).AccessibilityGetText(startOffset, endOffset);
348 return DuplicateString(text);
351 private static IntPtr AccessibilityGetTextAtOffsetWrapper(IntPtr self, int offset, int boundary)
353 AccessibilityRange range = GetInterfaceFromRefObject<IAtspiText>(self).AccessibilityGetTextAtOffset(offset, (AccessibilityTextBoundary)boundary);
355 return DuplicateAccessibilityRange(range);
358 private static bool AccessibilityRemoveSelectionWrapper(IntPtr self, int selectionNumber)
360 return GetInterfaceFromRefObject<IAtspiText>(self).AccessibilityRemoveSelection(selectionNumber);
363 private static bool AccessibilitySetCursorOffsetWrapper(IntPtr self, int offset)
365 return GetInterfaceFromRefObject<IAtspiText>(self).AccessibilitySetCursorOffset(offset);
368 private static bool AccessibilitySetSelectionWrapper(IntPtr self, int selectionNumber, int startOffset, int endOffset)
370 return GetInterfaceFromRefObject<IAtspiText>(self).AccessibilitySetSelection(selectionNumber, startOffset, endOffset);
377 private static void InitializeAccessibilityDelegateValueInterface()
379 var ad = Interop.ControlDevel.AccessibilityDelegate.Instance;
381 ad.GetCurrent = AccessibilityGetCurrentWrapper;
382 ad.GetMaximum = AccessibilityGetMaximumWrapper;
383 ad.GetMinimum = AccessibilityGetMinimumWrapper;
384 ad.GetMinimumIncrement = AccessibilityGetMinimumIncrementWrapper;
385 ad.SetCurrent = AccessibilitySetCurrentWrapper;
388 private static double AccessibilityGetCurrentWrapper(IntPtr self)
390 return GetInterfaceFromRefObject<IAtspiValue>(self).AccessibilityGetCurrent();
393 private static double AccessibilityGetMaximumWrapper(IntPtr self)
395 return GetInterfaceFromRefObject<IAtspiValue>(self).AccessibilityGetMaximum();
398 private static double AccessibilityGetMinimumWrapper(IntPtr self)
400 return GetInterfaceFromRefObject<IAtspiValue>(self).AccessibilityGetMinimum();
403 private static double AccessibilityGetMinimumIncrementWrapper(IntPtr self)
405 return GetInterfaceFromRefObject<IAtspiValue>(self).AccessibilityGetMinimumIncrement();
408 private static bool AccessibilitySetCurrentWrapper(IntPtr self, double value)
410 return GetInterfaceFromRefObject<IAtspiValue>(self).AccessibilitySetCurrent(value);
417 private static void InitializeAccessibilityDelegateTizenExtensions()
419 var ad = Interop.ControlDevel.AccessibilityDelegate.Instance;
421 ad.ScrollToChild = AccessibilityScrollToChildWrapper;
424 private static bool AccessibilityScrollToChildWrapper(IntPtr self, IntPtr child)
426 View view = GetViewFromRefObject(self);
428 return view.AccessibilityScrollToChild(view.GetInstanceSafely<View>(child));