[NUI][AT-SPI] Remove SetAccessibilityConstructor()
[platform/core/csapi/tizenfx.git] / src / Tizen.NUI / src / public / BaseComponents / ViewAccessibilityWrappers.cs
1 /*
2  * Copyright(c) 2022 Samsung Electronics Co., Ltd.
3  *
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
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
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.
15  *
16  */
17
18 using System;
19 using System.Runtime.InteropServices;
20 using Tizen.NUI.Accessibility;
21
22 namespace Tizen.NUI.BaseComponents
23 {
24     public partial class View
25     {
26         private static AccessibilityStates AccessibilityInitialStates = new AccessibilityStates();
27
28         private static void RegisterAccessibilityDelegate()
29         {
30             InitializeAccessibilityDelegateAccessibleInterface();
31             InitializeAccessibilityDelegateActionInterface();
32             InitializeAccessibilityDelegateComponentInterface();
33             InitializeAccessibilityDelegateEditableTextInterface();
34             InitializeAccessibilityDelegateSelectionInterface();
35             InitializeAccessibilityDelegateTextInterface();
36             InitializeAccessibilityDelegateValueInterface();
37             InitializeAccessibilityDelegateTizenExtensions();
38
39             var ad   = Interop.ControlDevel.AccessibilityDelegate.Instance;
40             var size = Marshal.SizeOf<Interop.ControlDevel.AccessibilityDelegate>();
41             var ptr  = Marshal.AllocHGlobal(size);
42
43             Marshal.StructureToPtr(ad, ptr, false);
44             Interop.ControlDevel.DaliAccessibilitySetAccessibilityDelegate(ptr, size);
45         }
46
47         private static View GetViewFromRefObject(IntPtr refObjectPtr)
48         {
49             return Registry.GetManagedBaseHandleFromRefObject(refObjectPtr) as View;
50         }
51
52         private static T GetInterfaceFromRefObject<T>(IntPtr refObjectPtr)
53         {
54             var view = GetViewFromRefObject(refObjectPtr);
55
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)
59             {
60                 return atspiInterface;
61             }
62
63             return default(T);
64         }
65
66         private static IntPtr DuplicateString(string value)
67         {
68             return Interop.ControlDevel.DaliAccessibilityDuplicateString(value ?? "");
69         }
70
71         private static IntPtr DuplicateAccessibilityRange(AccessibilityRange range)
72         {
73             return Interop.ControlDevel.DaliAccessibilityNewRange(range.StartOffset, range.EndOffset, range.Content);
74         }
75
76         private static IntPtr DuplicateAccessibilityRectangle(Rectangle rect)
77         {
78             return Interop.Rectangle.NewRectangle(rect.X, rect.Y, rect.Width, rect.Height);
79         }
80
81         //
82         // Accessible interface
83         //
84
85         private static void InitializeAccessibilityDelegateAccessibleInterface()
86         {
87             var ad = Interop.ControlDevel.AccessibilityDelegate.Instance;
88
89             ad.CalculateStates = AccessibilityCalculateStatesWrapper;
90             ad.GetDescription  = AccessibilityGetDescriptionWrapper;
91             ad.GetInterfaces   = AccessibilityGetInterfaces; // Not a wrapper, entirely private implementation
92             ad.GetName         = AccessibilityGetNameWrapper;
93         }
94
95         private static ulong AccessibilityCalculateStatesWrapper(IntPtr self, ulong initialStates)
96         {
97             View view = GetViewFromRefObject(self);
98             ulong bitMask = 0UL;
99
100             lock (AccessibilityInitialStates)
101             {
102                 AccessibilityInitialStates.BitMask = initialStates;
103                 bitMask = view.AccessibilityCalculateStates().BitMask;
104                 AccessibilityInitialStates.BitMask = 0UL;
105             }
106
107             return bitMask;
108         }
109
110         private static IntPtr AccessibilityGetDescriptionWrapper(IntPtr self)
111         {
112             string description = GetViewFromRefObject(self).AccessibilityGetDescription();
113
114             return DuplicateString(description);
115         }
116
117         private static uint AccessibilityGetInterfaces(IntPtr self)
118         {
119             View view = GetViewFromRefObject(self);
120             uint flags = 0U;
121
122             if (view is IAtspiEditableText)
123             {
124                 flags |= (1U << (int)AccessibilityInterface.EditableText);
125             }
126
127             if (view is IAtspiSelection)
128             {
129                 flags |= (1U << (int)AccessibilityInterface.Selection);
130             }
131
132             if (view is IAtspiText)
133             {
134                 flags |= (1U << (int)AccessibilityInterface.Text);
135             }
136
137             if (view is IAtspiValue)
138             {
139                 flags |= (1U << (int)AccessibilityInterface.Value);
140             }
141
142             return flags;
143         }
144
145         private static IntPtr AccessibilityGetNameWrapper(IntPtr self)
146         {
147             string name = GetViewFromRefObject(self).AccessibilityGetName();
148
149             return DuplicateString(name);
150         }
151
152         //
153         // Action interface
154         //
155
156         private static void InitializeAccessibilityDelegateActionInterface()
157         {
158             var ad = Interop.ControlDevel.AccessibilityDelegate.Instance;
159
160             ad.DoAction       = AccessibilityDoActionWrapper;
161             ad.GetActionCount = AccessibilityGetActionCountWrapper;
162             ad.GetActionName  = AccessibilityGetActionNameWrapper;
163         }
164
165         private static bool AccessibilityDoActionWrapper(IntPtr self, IntPtr name)
166         {
167             return GetViewFromRefObject(self).AccessibilityDoAction(Marshal.PtrToStringAnsi(name));
168         }
169
170         private static int AccessibilityGetActionCountWrapper(IntPtr self)
171         {
172             return GetViewFromRefObject(self).AccessibilityGetActionCount();
173         }
174
175         private static IntPtr AccessibilityGetActionNameWrapper(IntPtr self, int index)
176         {
177             string name = GetViewFromRefObject(self).AccessibilityGetActionName(index);
178
179             return DuplicateString(name);
180         }
181
182         //
183         // Component interface
184         //
185
186         private static void InitializeAccessibilityDelegateComponentInterface()
187         {
188             var ad = Interop.ControlDevel.AccessibilityDelegate.Instance;
189
190             ad.IsScrollable = AccessibilityIsScrollableWrapper;
191         }
192
193         private static bool AccessibilityIsScrollableWrapper(IntPtr self)
194         {
195             return GetViewFromRefObject(self).AccessibilityIsScrollable();
196         }
197
198         //
199         // EditableText interface
200         //
201
202         private static void InitializeAccessibilityDelegateEditableTextInterface()
203         {
204             var ad = Interop.ControlDevel.AccessibilityDelegate.Instance;
205
206             ad.CopyText        = AccessibilityCopyTextWrapper;
207             ad.CutText         = AccessibilityCutTextWrapper;
208             ad.DeleteText      = AccessibilityDeleteTextWrapper;
209             ad.InsertText      = AccessibilityInsertTextWrapper;
210             ad.SetTextContents = AccessibilitySetTextContentsWrapper;
211         }
212
213         private static bool AccessibilityCopyTextWrapper(IntPtr self, int startPosition, int endPosition)
214         {
215             return GetInterfaceFromRefObject<IAtspiEditableText>(self).AccessibilityCopyText(startPosition, endPosition);
216         }
217
218         private static bool AccessibilityCutTextWrapper(IntPtr self, int startPosition, int endPosition)
219         {
220             return GetInterfaceFromRefObject<IAtspiEditableText>(self).AccessibilityCutText(startPosition, endPosition);
221         }
222
223         private static bool AccessibilityDeleteTextWrapper(IntPtr self, int startPosition, int endPosition)
224         {
225             return GetInterfaceFromRefObject<IAtspiEditableText>(self).AccessibilityDeleteText(startPosition, endPosition);
226         }
227
228         private static bool AccessibilityInsertTextWrapper(IntPtr self, int startPosition, IntPtr text)
229         {
230             return GetInterfaceFromRefObject<IAtspiEditableText>(self).AccessibilityInsertText(startPosition, Marshal.PtrToStringAnsi(text));
231         }
232
233         private static bool AccessibilitySetTextContentsWrapper(IntPtr self, IntPtr newContents)
234         {
235             return GetInterfaceFromRefObject<IAtspiEditableText>(self).AccessibilitySetTextContents(Marshal.PtrToStringAnsi(newContents));
236         }
237
238         //
239         // Selection interface
240         //
241
242         private static void InitializeAccessibilityDelegateSelectionInterface()
243         {
244             var ad = Interop.ControlDevel.AccessibilityDelegate.Instance;
245
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;
254         }
255
256         private static bool AccessibilityClearSelectionWrapper(IntPtr self)
257         {
258             return GetInterfaceFromRefObject<IAtspiSelection>(self).AccessibilityClearSelection();
259         }
260
261         private static bool AccessibilityDeselectChildWrapper(IntPtr self, int childIndex)
262         {
263             return GetInterfaceFromRefObject<IAtspiSelection>(self).AccessibilityDeselectChild(childIndex);
264         }
265
266         private static bool AccessibilityDeselectSelectedChildWrapper(IntPtr self, int selectedChildIndex)
267         {
268             return GetInterfaceFromRefObject<IAtspiSelection>(self).AccessibilityDeselectSelectedChild(selectedChildIndex);
269         }
270
271         private static IntPtr AccessibilityGetSelectedChildWrapper(IntPtr self, int selectedChildIndex)
272         {
273             View child = GetInterfaceFromRefObject<IAtspiSelection>(self).AccessibilityGetSelectedChild(selectedChildIndex);
274
275             return View.getCPtr(child).Handle;
276         }
277
278         private static int AccessibilityGetSelectedChildrenCountWrapper(IntPtr self)
279         {
280             return GetInterfaceFromRefObject<IAtspiSelection>(self).AccessibilityGetSelectedChildrenCount();
281         }
282
283         private static bool AccessibilityIsChildSelectedWrapper(IntPtr self, int childIndex)
284         {
285             return GetInterfaceFromRefObject<IAtspiSelection>(self).AccessibilityIsChildSelected(childIndex);
286         }
287
288         private static bool AccessibilitySelectAllWrapper(IntPtr self)
289         {
290             return GetInterfaceFromRefObject<IAtspiSelection>(self).AccessibilitySelectAll();
291         }
292
293         private static bool AccessibilitySelectChildWrapper(IntPtr self, int childIndex)
294         {
295             return GetInterfaceFromRefObject<IAtspiSelection>(self).AccessibilitySelectChild(childIndex);
296         }
297
298         //
299         // Text interface
300         //
301
302         private static void InitializeAccessibilityDelegateTextInterface()
303         {
304             var ad = Interop.ControlDevel.AccessibilityDelegate.Instance;
305
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;
315         }
316
317         private static int AccessibilityGetCharacterCountWrapper(IntPtr self)
318         {
319             return GetInterfaceFromRefObject<IAtspiText>(self).AccessibilityGetCharacterCount();
320         }
321
322         private static int AccessibilityGetCursorOffsetWrapper(IntPtr self)
323         {
324             return GetInterfaceFromRefObject<IAtspiText>(self).AccessibilityGetCursorOffset();
325         }
326
327         private static IntPtr AccessibilityGetRangeExtentsWrapper(IntPtr self, int startOffset, int endOffset, int coordType)
328         {
329             using Rectangle rect = GetInterfaceFromRefObject<IAtspiText>(self).AccessibilityGetRangeExtents(startOffset, endOffset, (AccessibilityCoordinateType)coordType);
330
331             return DuplicateAccessibilityRectangle(rect);
332         }
333
334         private static IntPtr AccessibilityGetSelectionWrapper(IntPtr self, int selectionNumber)
335         {
336             AccessibilityRange range = GetInterfaceFromRefObject<IAtspiText>(self).AccessibilityGetSelection(selectionNumber);
337
338             return DuplicateAccessibilityRange(range);
339         }
340
341         private static IntPtr AccessibilityGetTextWrapper(IntPtr self, int startOffset, int endOffset)
342         {
343             string text = GetInterfaceFromRefObject<IAtspiText>(self).AccessibilityGetText(startOffset, endOffset);
344
345             return DuplicateString(text);
346         }
347
348         private static IntPtr AccessibilityGetTextAtOffsetWrapper(IntPtr self, int offset, int boundary)
349         {
350             AccessibilityRange range = GetInterfaceFromRefObject<IAtspiText>(self).AccessibilityGetTextAtOffset(offset, (AccessibilityTextBoundary)boundary);
351
352             return DuplicateAccessibilityRange(range);
353         }
354
355         private static bool AccessibilityRemoveSelectionWrapper(IntPtr self, int selectionNumber)
356         {
357             return GetInterfaceFromRefObject<IAtspiText>(self).AccessibilityRemoveSelection(selectionNumber);
358         }
359
360         private static bool AccessibilitySetCursorOffsetWrapper(IntPtr self, int offset)
361         {
362             return GetInterfaceFromRefObject<IAtspiText>(self).AccessibilitySetCursorOffset(offset);
363         }
364
365         private static bool AccessibilitySetSelectionWrapper(IntPtr self, int selectionNumber, int startOffset, int endOffset)
366         {
367             return GetInterfaceFromRefObject<IAtspiText>(self).AccessibilitySetSelection(selectionNumber, startOffset, endOffset);
368         }
369
370         //
371         // Value interface
372         //
373
374         private static void InitializeAccessibilityDelegateValueInterface()
375         {
376             var ad = Interop.ControlDevel.AccessibilityDelegate.Instance;
377
378             ad.GetCurrent          = AccessibilityGetCurrentWrapper;
379             ad.GetMaximum          = AccessibilityGetMaximumWrapper;
380             ad.GetMinimum          = AccessibilityGetMinimumWrapper;
381             ad.GetMinimumIncrement = AccessibilityGetMinimumIncrementWrapper;
382             ad.SetCurrent          = AccessibilitySetCurrentWrapper;
383         }
384
385         private static double AccessibilityGetCurrentWrapper(IntPtr self)
386         {
387             return GetInterfaceFromRefObject<IAtspiValue>(self).AccessibilityGetCurrent();
388         }
389
390         private static double AccessibilityGetMaximumWrapper(IntPtr self)
391         {
392             return GetInterfaceFromRefObject<IAtspiValue>(self).AccessibilityGetMaximum();
393         }
394
395         private static double AccessibilityGetMinimumWrapper(IntPtr self)
396         {
397             return GetInterfaceFromRefObject<IAtspiValue>(self).AccessibilityGetMinimum();
398         }
399
400         private static double AccessibilityGetMinimumIncrementWrapper(IntPtr self)
401         {
402             return GetInterfaceFromRefObject<IAtspiValue>(self).AccessibilityGetMinimumIncrement();
403         }
404
405         private static bool AccessibilitySetCurrentWrapper(IntPtr self, double value)
406         {
407             return GetInterfaceFromRefObject<IAtspiValue>(self).AccessibilitySetCurrent(value);
408         }
409
410         //
411         // Tizen extensions
412         //
413
414         private static void InitializeAccessibilityDelegateTizenExtensions()
415         {
416             var ad = Interop.ControlDevel.AccessibilityDelegate.Instance;
417
418             ad.ScrollToChild            = AccessibilityScrollToChildWrapper;
419             ad.ShouldReportZeroChildren = AccessibilityShouldReportZeroChildrenWrapper;
420         }
421
422         private static bool AccessibilityScrollToChildWrapper(IntPtr self, IntPtr child)
423         {
424             View view = GetViewFromRefObject(self);
425
426             return view.AccessibilityScrollToChild(view.GetInstanceSafely<View>(child));
427         }
428
429         private static bool AccessibilityShouldReportZeroChildrenWrapper(IntPtr self)
430         {
431             return GetViewFromRefObject(self).AccessibilityShouldReportZeroChildren();
432         }
433     }
434 }