[NUI] Implement missing properties for LottieAnimationView.
[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, Convert.ToUInt32(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.GetAttributes   = AccessibilityGetAttributes; // Not a wrapper, entirely private implementation
91             ad.GetDescription  = AccessibilityGetDescriptionWrapper;
92             ad.GetInterfaces   = AccessibilityGetInterfaces; // Not a wrapper, entirely private implementation
93             ad.GetName         = AccessibilityGetNameWrapper;
94         }
95
96         private static ulong AccessibilityCalculateStatesWrapper(IntPtr self, ulong initialStates)
97         {
98             View view = GetViewFromRefObject(self);
99             if (view == null)
100                 return 0UL;
101
102             ulong bitMask = 0UL;
103
104             lock (AccessibilityInitialStates)
105             {
106                 AccessibilityInitialStates.BitMask = initialStates;
107                 bitMask = view.AccessibilityCalculateStates().BitMask;
108                 AccessibilityInitialStates.BitMask = 0UL;
109             }
110
111             return bitMask;
112         }
113
114         private static void AccessibilityGetAttributes(IntPtr self, Interop.ControlDevel.AccessibilityDelegate.AccessibilityGetAttributesCallback callback, IntPtr userData)
115         {
116             var view = GetViewFromRefObject(self);
117             var attributes = view.AccessibilityAttributes;
118             var classKey = "class";
119
120             if (!attributes.ContainsKey(classKey))
121             {
122                 attributes[classKey] = view.GetType().Name;
123             }
124
125             foreach (var attribute in attributes)
126             {
127                 callback(attribute.Key, attribute.Value, userData);
128             }
129         }
130
131         private static IntPtr AccessibilityGetDescriptionWrapper(IntPtr self)
132         {
133             string description = GetViewFromRefObject(self).AccessibilityGetDescription();
134
135             return DuplicateString(description);
136         }
137
138         private static uint AccessibilityGetInterfaces(IntPtr self)
139         {
140             View view = GetViewFromRefObject(self);
141             uint flags = 0U;
142
143             if (view is IAtspiEditableText)
144             {
145                 flags |= (1U << (int)AccessibilityInterface.EditableText);
146             }
147
148             if (view is IAtspiSelection)
149             {
150                 flags |= (1U << (int)AccessibilityInterface.Selection);
151             }
152
153             if (view is IAtspiText)
154             {
155                 flags |= (1U << (int)AccessibilityInterface.Text);
156             }
157
158             if (view is IAtspiValue)
159             {
160                 flags |= (1U << (int)AccessibilityInterface.Value);
161             }
162
163             return flags;
164         }
165
166         private static IntPtr AccessibilityGetNameWrapper(IntPtr self)
167         {
168             string name = GetViewFromRefObject(self).AccessibilityGetName();
169
170             return DuplicateString(name);
171         }
172
173         //
174         // Action interface
175         //
176
177         private static void InitializeAccessibilityDelegateActionInterface()
178         {
179             var ad = Interop.ControlDevel.AccessibilityDelegate.Instance;
180
181             ad.DoAction       = AccessibilityDoActionWrapper;
182             ad.GetActionCount = AccessibilityGetActionCountWrapper;
183             ad.GetActionName  = AccessibilityGetActionNameWrapper;
184         }
185
186         private static bool AccessibilityDoActionWrapper(IntPtr self, IntPtr name)
187         {
188             return GetViewFromRefObject(self).AccessibilityDoAction(Marshal.PtrToStringAnsi(name));
189         }
190
191         private static int AccessibilityGetActionCountWrapper(IntPtr self)
192         {
193             return GetViewFromRefObject(self).AccessibilityGetActionCount();
194         }
195
196         private static IntPtr AccessibilityGetActionNameWrapper(IntPtr self, int index)
197         {
198             string name = GetViewFromRefObject(self).AccessibilityGetActionName(index);
199
200             return DuplicateString(name);
201         }
202
203         //
204         // Component interface
205         //
206
207         private static void InitializeAccessibilityDelegateComponentInterface()
208         {
209             var ad = Interop.ControlDevel.AccessibilityDelegate.Instance;
210
211             ad.IsScrollable = AccessibilityIsScrollableWrapper;
212         }
213
214         private static bool AccessibilityIsScrollableWrapper(IntPtr self)
215         {
216             return GetViewFromRefObject(self).AccessibilityIsScrollable();
217         }
218
219         //
220         // EditableText interface
221         //
222
223         private static void InitializeAccessibilityDelegateEditableTextInterface()
224         {
225             var ad = Interop.ControlDevel.AccessibilityDelegate.Instance;
226
227             ad.CopyText        = AccessibilityCopyTextWrapper;
228             ad.CutText         = AccessibilityCutTextWrapper;
229             ad.DeleteText      = AccessibilityDeleteTextWrapper;
230             ad.InsertText      = AccessibilityInsertTextWrapper;
231             ad.SetTextContents = AccessibilitySetTextContentsWrapper;
232         }
233
234         private static bool AccessibilityCopyTextWrapper(IntPtr self, int startPosition, int endPosition)
235         {
236             return GetInterfaceFromRefObject<IAtspiEditableText>(self).AccessibilityCopyText(startPosition, endPosition);
237         }
238
239         private static bool AccessibilityCutTextWrapper(IntPtr self, int startPosition, int endPosition)
240         {
241             return GetInterfaceFromRefObject<IAtspiEditableText>(self).AccessibilityCutText(startPosition, endPosition);
242         }
243
244         private static bool AccessibilityDeleteTextWrapper(IntPtr self, int startPosition, int endPosition)
245         {
246             return GetInterfaceFromRefObject<IAtspiEditableText>(self).AccessibilityDeleteText(startPosition, endPosition);
247         }
248
249         private static bool AccessibilityInsertTextWrapper(IntPtr self, int startPosition, IntPtr text)
250         {
251             return GetInterfaceFromRefObject<IAtspiEditableText>(self).AccessibilityInsertText(startPosition, Marshal.PtrToStringAnsi(text));
252         }
253
254         private static bool AccessibilitySetTextContentsWrapper(IntPtr self, IntPtr newContents)
255         {
256             return GetInterfaceFromRefObject<IAtspiEditableText>(self).AccessibilitySetTextContents(Marshal.PtrToStringAnsi(newContents));
257         }
258
259         //
260         // Selection interface
261         //
262
263         private static void InitializeAccessibilityDelegateSelectionInterface()
264         {
265             var ad = Interop.ControlDevel.AccessibilityDelegate.Instance;
266
267             ad.ClearSelection           = AccessibilityClearSelectionWrapper;
268             ad.DeselectChild            = AccessibilityDeselectChildWrapper;
269             ad.DeselectSelectedChild    = AccessibilityDeselectSelectedChildWrapper;
270             ad.GetSelectedChild         = AccessibilityGetSelectedChildWrapper;
271             ad.GetSelectedChildrenCount = AccessibilityGetSelectedChildrenCountWrapper;
272             ad.IsChildSelected          = AccessibilityIsChildSelectedWrapper;
273             ad.SelectAll                = AccessibilitySelectAllWrapper;
274             ad.SelectChild              = AccessibilitySelectChildWrapper;
275         }
276
277         private static bool AccessibilityClearSelectionWrapper(IntPtr self)
278         {
279             return GetInterfaceFromRefObject<IAtspiSelection>(self).AccessibilityClearSelection();
280         }
281
282         private static bool AccessibilityDeselectChildWrapper(IntPtr self, int childIndex)
283         {
284             return GetInterfaceFromRefObject<IAtspiSelection>(self).AccessibilityDeselectChild(childIndex);
285         }
286
287         private static bool AccessibilityDeselectSelectedChildWrapper(IntPtr self, int selectedChildIndex)
288         {
289             return GetInterfaceFromRefObject<IAtspiSelection>(self).AccessibilityDeselectSelectedChild(selectedChildIndex);
290         }
291
292         private static IntPtr AccessibilityGetSelectedChildWrapper(IntPtr self, int selectedChildIndex)
293         {
294             View child = GetInterfaceFromRefObject<IAtspiSelection>(self).AccessibilityGetSelectedChild(selectedChildIndex);
295
296             return View.getCPtr(child).Handle;
297         }
298
299         private static int AccessibilityGetSelectedChildrenCountWrapper(IntPtr self)
300         {
301             return GetInterfaceFromRefObject<IAtspiSelection>(self).AccessibilityGetSelectedChildrenCount();
302         }
303
304         private static bool AccessibilityIsChildSelectedWrapper(IntPtr self, int childIndex)
305         {
306             return GetInterfaceFromRefObject<IAtspiSelection>(self).AccessibilityIsChildSelected(childIndex);
307         }
308
309         private static bool AccessibilitySelectAllWrapper(IntPtr self)
310         {
311             return GetInterfaceFromRefObject<IAtspiSelection>(self).AccessibilitySelectAll();
312         }
313
314         private static bool AccessibilitySelectChildWrapper(IntPtr self, int childIndex)
315         {
316             return GetInterfaceFromRefObject<IAtspiSelection>(self).AccessibilitySelectChild(childIndex);
317         }
318
319         //
320         // Text interface
321         //
322
323         private static void InitializeAccessibilityDelegateTextInterface()
324         {
325             var ad = Interop.ControlDevel.AccessibilityDelegate.Instance;
326
327             ad.GetCharacterCount = AccessibilityGetCharacterCountWrapper;
328             ad.GetCursorOffset   = AccessibilityGetCursorOffsetWrapper;
329             ad.GetRangeExtents   = AccessibilityGetRangeExtentsWrapper;
330             ad.GetSelection      = AccessibilityGetSelectionWrapper;
331             ad.GetText           = AccessibilityGetTextWrapper;
332             ad.GetTextAtOffset   = AccessibilityGetTextAtOffsetWrapper;
333             ad.RemoveSelection   = AccessibilityRemoveSelectionWrapper;
334             ad.SetCursorOffset   = AccessibilitySetCursorOffsetWrapper;
335             ad.SetSelection      = AccessibilitySetSelectionWrapper;
336         }
337
338         private static int AccessibilityGetCharacterCountWrapper(IntPtr self)
339         {
340             return GetInterfaceFromRefObject<IAtspiText>(self).AccessibilityGetCharacterCount();
341         }
342
343         private static int AccessibilityGetCursorOffsetWrapper(IntPtr self)
344         {
345             return GetInterfaceFromRefObject<IAtspiText>(self).AccessibilityGetCursorOffset();
346         }
347
348         private static IntPtr AccessibilityGetRangeExtentsWrapper(IntPtr self, int startOffset, int endOffset, int coordType)
349         {
350             using Rectangle rect = GetInterfaceFromRefObject<IAtspiText>(self).AccessibilityGetRangeExtents(startOffset, endOffset, (AccessibilityCoordinateType)coordType);
351
352             return DuplicateAccessibilityRectangle(rect);
353         }
354
355         private static IntPtr AccessibilityGetSelectionWrapper(IntPtr self, int selectionNumber)
356         {
357             AccessibilityRange range = GetInterfaceFromRefObject<IAtspiText>(self).AccessibilityGetSelection(selectionNumber);
358
359             return DuplicateAccessibilityRange(range);
360         }
361
362         private static IntPtr AccessibilityGetTextWrapper(IntPtr self, int startOffset, int endOffset)
363         {
364             string text = GetInterfaceFromRefObject<IAtspiText>(self).AccessibilityGetText(startOffset, endOffset);
365
366             return DuplicateString(text);
367         }
368
369         private static IntPtr AccessibilityGetTextAtOffsetWrapper(IntPtr self, int offset, int boundary)
370         {
371             AccessibilityRange range = GetInterfaceFromRefObject<IAtspiText>(self).AccessibilityGetTextAtOffset(offset, (AccessibilityTextBoundary)boundary);
372
373             return DuplicateAccessibilityRange(range);
374         }
375
376         private static bool AccessibilityRemoveSelectionWrapper(IntPtr self, int selectionNumber)
377         {
378             return GetInterfaceFromRefObject<IAtspiText>(self).AccessibilityRemoveSelection(selectionNumber);
379         }
380
381         private static bool AccessibilitySetCursorOffsetWrapper(IntPtr self, int offset)
382         {
383             return GetInterfaceFromRefObject<IAtspiText>(self).AccessibilitySetCursorOffset(offset);
384         }
385
386         private static bool AccessibilitySetSelectionWrapper(IntPtr self, int selectionNumber, int startOffset, int endOffset)
387         {
388             return GetInterfaceFromRefObject<IAtspiText>(self).AccessibilitySetSelection(selectionNumber, startOffset, endOffset);
389         }
390
391         //
392         // Value interface
393         //
394
395         private static void InitializeAccessibilityDelegateValueInterface()
396         {
397             var ad = Interop.ControlDevel.AccessibilityDelegate.Instance;
398
399             ad.GetCurrent          = AccessibilityGetCurrentWrapper;
400             ad.GetMaximum          = AccessibilityGetMaximumWrapper;
401             ad.GetMinimum          = AccessibilityGetMinimumWrapper;
402             ad.GetMinimumIncrement = AccessibilityGetMinimumIncrementWrapper;
403             ad.SetCurrent          = AccessibilitySetCurrentWrapper;
404         }
405
406         private static double AccessibilityGetCurrentWrapper(IntPtr self)
407         {
408             return GetInterfaceFromRefObject<IAtspiValue>(self).AccessibilityGetCurrent();
409         }
410
411         private static double AccessibilityGetMaximumWrapper(IntPtr self)
412         {
413             return GetInterfaceFromRefObject<IAtspiValue>(self).AccessibilityGetMaximum();
414         }
415
416         private static double AccessibilityGetMinimumWrapper(IntPtr self)
417         {
418             return GetInterfaceFromRefObject<IAtspiValue>(self).AccessibilityGetMinimum();
419         }
420
421         private static double AccessibilityGetMinimumIncrementWrapper(IntPtr self)
422         {
423             return GetInterfaceFromRefObject<IAtspiValue>(self).AccessibilityGetMinimumIncrement();
424         }
425
426         private static bool AccessibilitySetCurrentWrapper(IntPtr self, double value)
427         {
428             return GetInterfaceFromRefObject<IAtspiValue>(self).AccessibilitySetCurrent(value);
429         }
430
431         //
432         // Tizen extensions
433         //
434
435         private static void InitializeAccessibilityDelegateTizenExtensions()
436         {
437             var ad = Interop.ControlDevel.AccessibilityDelegate.Instance;
438
439             ad.ScrollToChild            = AccessibilityScrollToChildWrapper;
440         }
441
442         private static bool AccessibilityScrollToChildWrapper(IntPtr self, IntPtr child)
443         {
444             View view = GetViewFromRefObject(self);
445
446             return view.AccessibilityScrollToChild(view.GetInstanceSafely<View>(child));
447         }
448     }
449 }