[NUI] Fix text padding issue
[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.Collections.Generic;
20 using System.Runtime.InteropServices;
21 using Tizen.NUI.Accessibility;
22
23 namespace Tizen.NUI.BaseComponents
24 {
25     public partial class View
26     {
27         private static AccessibilityStates AccessibilityInitialStates = new AccessibilityStates();
28
29         private static void RegisterAccessibilityDelegate()
30         {
31             InitializeAccessibilityDelegateAccessibleInterface();
32             InitializeAccessibilityDelegateActionInterface();
33             InitializeAccessibilityDelegateComponentInterface();
34             InitializeAccessibilityDelegateEditableTextInterface();
35             InitializeAccessibilityDelegateSelectionInterface();
36             InitializeAccessibilityDelegateTableInterface();
37             InitializeAccessibilityDelegateTableCellInterface();
38             InitializeAccessibilityDelegateTextInterface();
39             InitializeAccessibilityDelegateValueInterface();
40             InitializeAccessibilityDelegateTizenExtensions();
41
42             var ad   = Interop.ControlDevel.AccessibilityDelegate.Instance;
43             var size = Marshal.SizeOf<Interop.ControlDevel.AccessibilityDelegate>();
44             var ptr  = Marshal.AllocHGlobal(size);
45
46             Marshal.StructureToPtr(ad, ptr, false);
47             Interop.ControlDevel.DaliAccessibilitySetAccessibilityDelegate(ptr, Convert.ToUInt32(size));
48         }
49
50         private static View GetViewFromRefObject(IntPtr refObjectPtr)
51         {
52             View view = Registry.GetManagedBaseHandleFromRefObject(refObjectPtr) as View;
53
54             if (view is null)
55             {
56                 throw new ArgumentException($"RefObject 0x{refObjectPtr:x} is not a View", nameof(refObjectPtr));
57             }
58
59             return view;
60         }
61
62         private static T GetInterfaceFromRefObject<T>(IntPtr refObjectPtr)
63         {
64             var view = GetViewFromRefObject(refObjectPtr);
65
66             // NUIViewAccessible::CallMethod<T> checks whether a given interface is implemented
67             // before jumping to managed code, so this condition should always be true.
68             if (view is T atspiInterface)
69             {
70                 return atspiInterface;
71             }
72
73             throw new ArgumentException($"RefObject 0x{refObjectPtr:x} is not a {typeof(T).FullName}", nameof(refObjectPtr));
74         }
75
76         private static IntPtr DuplicateString(string value)
77         {
78             return Interop.ControlDevel.DaliAccessibilityDuplicateString(value ?? "");
79         }
80
81         private static IntPtr DuplicateAccessibilityRange(AccessibilityRange range)
82         {
83             return Interop.ControlDevel.DaliAccessibilityNewRange(range.StartOffset, range.EndOffset, range.Content);
84         }
85
86         private static IntPtr DuplicateAccessibilityRectangle(Rectangle rect)
87         {
88             return Interop.Rectangle.NewRectangle(rect.X, rect.Y, rect.Width, rect.Height);
89         }
90
91         private static IntPtr DuplicateIntPair(Tuple<int, int> pair)
92         {
93             return Interop.ControlDevel.DaliAccessibilityMakeIntPair(pair.Item1, pair.Item2);
94         }
95
96         //
97         // Accessible interface
98         //
99
100         private static void InitializeAccessibilityDelegateAccessibleInterface()
101         {
102             var ad = Interop.ControlDevel.AccessibilityDelegate.Instance;
103
104             ad.CalculateStates = AccessibilityCalculateStatesWrapper;
105             ad.GetAttributes   = AccessibilityGetAttributes; // Not a wrapper, entirely private implementation
106             ad.GetDescription  = AccessibilityGetDescriptionWrapper;
107             ad.GetInterfaces   = AccessibilityGetInterfaces; // Not a wrapper, entirely private implementation
108             ad.GetName         = AccessibilityGetNameWrapper;
109         }
110
111         private static ulong AccessibilityCalculateStatesWrapper(IntPtr self, ulong initialStates)
112         {
113             View view = GetViewFromRefObject(self);
114
115             ulong bitMask = 0UL;
116
117             lock (AccessibilityInitialStates)
118             {
119                 AccessibilityInitialStates.BitMask = initialStates;
120                 bitMask = view.AccessibilityCalculateStates().BitMask;
121                 AccessibilityInitialStates.BitMask = 0UL;
122             }
123
124             return bitMask;
125         }
126
127         private static void AccessibilityGetAttributes(IntPtr self, Interop.ControlDevel.AccessibilityDelegate.AccessibilityGetAttributesCallback callback, IntPtr userData)
128         {
129             var view = GetViewFromRefObject(self);
130             var attributes = view.AccessibilityAttributes;
131             var classKey = "class";
132
133             if (!attributes.ContainsKey(classKey))
134             {
135                 attributes[classKey] = view.GetType().Name;
136             }
137
138             foreach (var attribute in attributes)
139             {
140                 callback(attribute.Key, attribute.Value, userData);
141             }
142
143             foreach (var attribute in view.AccessibilityDynamicAttributes)
144             {
145                 callback(attribute.Key, attribute.Value.Invoke(), userData);
146             }
147         }
148
149         private static IntPtr AccessibilityGetDescriptionWrapper(IntPtr self)
150         {
151             string description = GetViewFromRefObject(self).AccessibilityGetDescription();
152
153             return DuplicateString(description);
154         }
155
156         private static uint AccessibilityGetInterfaces(IntPtr self)
157         {
158             View view = GetViewFromRefObject(self);
159             uint flags = 0U;
160
161             if (view is IAtspiEditableText)
162             {
163                 flags |= (1U << (int)AccessibilityInterface.EditableText);
164             }
165
166             if (view is IAtspiSelection)
167             {
168                 flags |= (1U << (int)AccessibilityInterface.Selection);
169             }
170
171             if (view is IAtspiTable)
172             {
173                 flags |= (1U << (int)AccessibilityInterface.Table);
174             }
175
176             if (view is IAtspiTableCell)
177             {
178                 flags |= (1U << (int)AccessibilityInterface.TableCell);
179             }
180
181             if (view is IAtspiText)
182             {
183                 flags |= (1U << (int)AccessibilityInterface.Text);
184             }
185
186             if (view is IAtspiValue)
187             {
188                 flags |= (1U << (int)AccessibilityInterface.Value);
189             }
190
191             return flags;
192         }
193
194         private static IntPtr AccessibilityGetNameWrapper(IntPtr self)
195         {
196             string name = GetViewFromRefObject(self).AccessibilityGetName();
197
198             return DuplicateString(name);
199         }
200
201         //
202         // Action interface
203         //
204
205         private static void InitializeAccessibilityDelegateActionInterface()
206         {
207             var ad = Interop.ControlDevel.AccessibilityDelegate.Instance;
208
209             ad.DoAction       = AccessibilityDoActionWrapper;
210             ad.GetActionCount = AccessibilityGetActionCountWrapper;
211             ad.GetActionName  = AccessibilityGetActionNameWrapper;
212         }
213
214         private static bool AccessibilityDoActionWrapper(IntPtr self, IntPtr name)
215         {
216             return GetViewFromRefObject(self).AccessibilityDoAction(Marshal.PtrToStringAnsi(name));
217         }
218
219         private static int AccessibilityGetActionCountWrapper(IntPtr self)
220         {
221             return GetViewFromRefObject(self).AccessibilityGetActionCount();
222         }
223
224         private static IntPtr AccessibilityGetActionNameWrapper(IntPtr self, int index)
225         {
226             string name = GetViewFromRefObject(self).AccessibilityGetActionName(index);
227
228             return DuplicateString(name);
229         }
230
231         //
232         // Component interface
233         //
234
235         private static void InitializeAccessibilityDelegateComponentInterface()
236         {
237             var ad = Interop.ControlDevel.AccessibilityDelegate.Instance;
238
239             ad.IsScrollable = AccessibilityIsScrollableWrapper;
240         }
241
242         private static bool AccessibilityIsScrollableWrapper(IntPtr self)
243         {
244             return GetViewFromRefObject(self).AccessibilityIsScrollable();
245         }
246
247         //
248         // EditableText interface
249         //
250
251         private static void InitializeAccessibilityDelegateEditableTextInterface()
252         {
253             var ad = Interop.ControlDevel.AccessibilityDelegate.Instance;
254
255             ad.CopyText        = AccessibilityCopyTextWrapper;
256             ad.CutText         = AccessibilityCutTextWrapper;
257             ad.DeleteText      = AccessibilityDeleteTextWrapper;
258             ad.InsertText      = AccessibilityInsertTextWrapper;
259             ad.SetTextContents = AccessibilitySetTextContentsWrapper;
260         }
261
262         private static bool AccessibilityCopyTextWrapper(IntPtr self, int startPosition, int endPosition)
263         {
264             return GetInterfaceFromRefObject<IAtspiEditableText>(self).AccessibilityCopyText(startPosition, endPosition);
265         }
266
267         private static bool AccessibilityCutTextWrapper(IntPtr self, int startPosition, int endPosition)
268         {
269             return GetInterfaceFromRefObject<IAtspiEditableText>(self).AccessibilityCutText(startPosition, endPosition);
270         }
271
272         private static bool AccessibilityDeleteTextWrapper(IntPtr self, int startPosition, int endPosition)
273         {
274             return GetInterfaceFromRefObject<IAtspiEditableText>(self).AccessibilityDeleteText(startPosition, endPosition);
275         }
276
277         private static bool AccessibilityInsertTextWrapper(IntPtr self, int startPosition, IntPtr text)
278         {
279             return GetInterfaceFromRefObject<IAtspiEditableText>(self).AccessibilityInsertText(startPosition, Marshal.PtrToStringAnsi(text));
280         }
281
282         private static bool AccessibilitySetTextContentsWrapper(IntPtr self, IntPtr newContents)
283         {
284             return GetInterfaceFromRefObject<IAtspiEditableText>(self).AccessibilitySetTextContents(Marshal.PtrToStringAnsi(newContents));
285         }
286
287         //
288         // Selection interface
289         //
290
291         private static void InitializeAccessibilityDelegateSelectionInterface()
292         {
293             var ad = Interop.ControlDevel.AccessibilityDelegate.Instance;
294
295             ad.ClearSelection           = AccessibilityClearSelectionWrapper;
296             ad.DeselectChild            = AccessibilityDeselectChildWrapper;
297             ad.DeselectSelectedChild    = AccessibilityDeselectSelectedChildWrapper;
298             ad.GetSelectedChild         = AccessibilityGetSelectedChildWrapper;
299             ad.GetSelectedChildrenCount = AccessibilityGetSelectedChildrenCountWrapper;
300             ad.IsChildSelected          = AccessibilityIsChildSelectedWrapper;
301             ad.SelectAll                = AccessibilitySelectAllWrapper;
302             ad.SelectChild              = AccessibilitySelectChildWrapper;
303         }
304
305         private static bool AccessibilityClearSelectionWrapper(IntPtr self)
306         {
307             return GetInterfaceFromRefObject<IAtspiSelection>(self).AccessibilityClearSelection();
308         }
309
310         private static bool AccessibilityDeselectChildWrapper(IntPtr self, int childIndex)
311         {
312             return GetInterfaceFromRefObject<IAtspiSelection>(self).AccessibilityDeselectChild(childIndex);
313         }
314
315         private static bool AccessibilityDeselectSelectedChildWrapper(IntPtr self, int selectedChildIndex)
316         {
317             return GetInterfaceFromRefObject<IAtspiSelection>(self).AccessibilityDeselectSelectedChild(selectedChildIndex);
318         }
319
320         private static IntPtr AccessibilityGetSelectedChildWrapper(IntPtr self, int selectedChildIndex)
321         {
322             View child = GetInterfaceFromRefObject<IAtspiSelection>(self).AccessibilityGetSelectedChild(selectedChildIndex);
323
324             return View.getCPtr(child).Handle;
325         }
326
327         private static int AccessibilityGetSelectedChildrenCountWrapper(IntPtr self)
328         {
329             return GetInterfaceFromRefObject<IAtspiSelection>(self).AccessibilityGetSelectedChildrenCount();
330         }
331
332         private static bool AccessibilityIsChildSelectedWrapper(IntPtr self, int childIndex)
333         {
334             return GetInterfaceFromRefObject<IAtspiSelection>(self).AccessibilityIsChildSelected(childIndex);
335         }
336
337         private static bool AccessibilitySelectAllWrapper(IntPtr self)
338         {
339             return GetInterfaceFromRefObject<IAtspiSelection>(self).AccessibilitySelectAll();
340         }
341
342         private static bool AccessibilitySelectChildWrapper(IntPtr self, int childIndex)
343         {
344             return GetInterfaceFromRefObject<IAtspiSelection>(self).AccessibilitySelectChild(childIndex);
345         }
346
347         //
348         // Table interface
349         //
350
351         private static void InitializeAccessibilityDelegateTableInterface()
352         {
353             var ad = Interop.ControlDevel.AccessibilityDelegate.Instance;
354
355             ad.AddColumnSelection      = AccessibilityAddColumnSelectionWrapper;
356             ad.AddRowSelection         = AccessibilityAddRowSelectionWrapper;
357             ad.GetCaption              = AccessibilityGetCaptionWrapper;
358             ad.GetCell                 = AccessibilityGetCellWrapper;
359             ad.GetChildIndex           = AccessibilityGetChildIndexWrapper;
360             ad.GetColumnCount          = AccessibilityGetColumnCountWrapper;
361             ad.GetColumnDescription    = AccessibilityGetColumnDescriptionWrapper;
362             ad.GetColumnHeader         = AccessibilityGetColumnHeaderWrapper;
363             ad.GetPositionByChildIndex = AccessibilityGetPositionByChildIndexWrapper;
364             ad.GetRowCount             = AccessibilityGetRowCountWrapper;
365             ad.GetRowDescription       = AccessibilityGetRowDescriptionWrapper;
366             ad.GetRowHeader            = AccessibilityGetRowHeaderWrapper;
367             ad.GetSelectedColumnCount  = AccessibilityGetSelectedColumnCountWrapper;
368             ad.GetSelectedColumns      = AccessibilityGetSelectedColumnsWrapper;
369             ad.GetSelectedRowCount     = AccessibilityGetSelectedRowCountWrapper;
370             ad.GetSelectedRows         = AccessibilityGetSelectedRowsWrapper;
371             ad.GetSummary              = AccessibilityGetSummaryWrapper;
372             ad.IsCellSelected          = AccessibilityIsCellSelectedWrapper;
373             ad.IsColumnSelected        = AccessibilityIsColumnSelectedWrapper;
374             ad.IsRowSelected           = AccessibilityIsRowSelectedWrapper;
375             ad.RemoveColumnSelection   = AccessibilityRemoveColumnSelectionWrapper;
376             ad.RemoveRowSelection      = AccessibilityRemoveRowSelectionWrapper;
377         }
378
379         private static bool AccessibilityAddColumnSelectionWrapper(IntPtr self, int column)
380         {
381             return GetInterfaceFromRefObject<IAtspiTable>(self).AccessibilityAddColumnSelection(column);
382         }
383
384         private static bool AccessibilityAddRowSelectionWrapper(IntPtr self, int row)
385         {
386             return GetInterfaceFromRefObject<IAtspiTable>(self).AccessibilityAddRowSelection(row);
387         }
388
389         private static IntPtr AccessibilityGetCaptionWrapper(IntPtr self)
390         {
391             View caption = GetInterfaceFromRefObject<IAtspiTable>(self).AccessibilityGetCaption();
392
393             return View.getCPtr(caption).Handle;
394         }
395
396         private static IntPtr AccessibilityGetCellWrapper(IntPtr self, int row, int column)
397         {
398             IAtspiTableCell cell = GetInterfaceFromRefObject<IAtspiTable>(self).AccessibilityGetCell(row, column);
399
400             if (cell is View view)
401             {
402                 return View.getCPtr(view).Handle;
403             }
404
405             NUILog.Error("Cannot get Actor handle from IAtspiTableCell");
406
407             return IntPtr.Zero;
408         }
409
410         private static ulong AccessibilityGetChildIndexWrapper(IntPtr self, int row, int column)
411         {
412             return (ulong)GetInterfaceFromRefObject<IAtspiTable>(self).AccessibilityGetChildIndex(row, column);
413         }
414
415         private static int AccessibilityGetColumnCountWrapper(IntPtr self)
416         {
417             return GetInterfaceFromRefObject<IAtspiTable>(self).AccessibilityGetColumnCount();
418         }
419
420         private static IntPtr AccessibilityGetColumnDescriptionWrapper(IntPtr self, int column)
421         {
422             string description = GetInterfaceFromRefObject<IAtspiTable>(self).AccessibilityGetColumnDescription(column);
423
424             return DuplicateString(description);
425         }
426
427         private static IntPtr AccessibilityGetColumnHeaderWrapper(IntPtr self, int column)
428         {
429             View header = GetInterfaceFromRefObject<IAtspiTable>(self).AccessibilityGetColumnHeader(column);
430
431             return View.getCPtr(header).Handle;
432         }
433
434         private static IntPtr AccessibilityGetPositionByChildIndexWrapper(IntPtr self, ulong childIndex)
435         {
436             Tuple<int, int> position = GetInterfaceFromRefObject<IAtspiTable>(self).AccessibilityGetPositionByChildIndex((int)childIndex);
437
438             return DuplicateIntPair(position);
439         }
440
441         private static int AccessibilityGetRowCountWrapper(IntPtr self)
442         {
443             return GetInterfaceFromRefObject<IAtspiTable>(self).AccessibilityGetRowCount();
444         }
445
446         private static IntPtr AccessibilityGetRowDescriptionWrapper(IntPtr self, int row)
447         {
448             string description = GetInterfaceFromRefObject<IAtspiTable>(self).AccessibilityGetRowDescription(row);
449
450             return DuplicateString(description);
451         }
452
453         private static IntPtr AccessibilityGetRowHeaderWrapper(IntPtr self, int row)
454         {
455             View header = GetInterfaceFromRefObject<IAtspiTable>(self).AccessibilityGetRowHeader(row);
456
457             return View.getCPtr(header).Handle;
458         }
459
460         private static int AccessibilityGetSelectedColumnCountWrapper(IntPtr self)
461         {
462             return GetInterfaceFromRefObject<IAtspiTable>(self).AccessibilityGetSelectedColumnCount();
463         }
464
465         private static void AccessibilityGetSelectedColumnsWrapper(IntPtr self, Interop.ControlDevel.AccessibilityDelegate.AccessibilityGetSelectedRowsColumnsCallback callback, IntPtr userData)
466         {
467             IEnumerable<int> columns = GetInterfaceFromRefObject<IAtspiTable>(self).AccessibilityGetSelectedColumns();
468
469             foreach (int column in columns)
470             {
471                 callback(column, userData);
472             }
473         }
474
475         private static int AccessibilityGetSelectedRowCountWrapper(IntPtr self)
476         {
477             return GetInterfaceFromRefObject<IAtspiTable>(self).AccessibilityGetSelectedRowCount();
478         }
479
480         private static void AccessibilityGetSelectedRowsWrapper(IntPtr self, Interop.ControlDevel.AccessibilityDelegate.AccessibilityGetSelectedRowsColumnsCallback callback, IntPtr userData)
481         {
482             IEnumerable<int> rows = GetInterfaceFromRefObject<IAtspiTable>(self).AccessibilityGetSelectedRows();
483
484             foreach (int row in rows)
485             {
486                 callback(row, userData);
487             }
488         }
489
490         private static IntPtr AccessibilityGetSummaryWrapper(IntPtr self)
491         {
492             View summary = GetInterfaceFromRefObject<IAtspiTable>(self).AccessibilityGetSummary();
493
494             return View.getCPtr(summary).Handle;
495         }
496
497         private static bool AccessibilityIsCellSelectedWrapper(IntPtr self, int row, int column)
498         {
499             return GetInterfaceFromRefObject<IAtspiTable>(self).AccessibilityIsCellSelected(row, column);
500         }
501
502         private static bool AccessibilityIsColumnSelectedWrapper(IntPtr self, int column)
503         {
504             return GetInterfaceFromRefObject<IAtspiTable>(self).AccessibilityIsColumnSelected(column);
505         }
506
507         private static bool AccessibilityIsRowSelectedWrapper(IntPtr self, int row)
508         {
509             return GetInterfaceFromRefObject<IAtspiTable>(self).AccessibilityIsRowSelected(row);
510         }
511
512         private static bool AccessibilityRemoveColumnSelectionWrapper(IntPtr self, int column)
513         {
514             return GetInterfaceFromRefObject<IAtspiTable>(self).AccessibilityRemoveColumnSelection(column);
515         }
516
517         private static bool AccessibilityRemoveRowSelectionWrapper(IntPtr self, int row)
518         {
519             return GetInterfaceFromRefObject<IAtspiTable>(self).AccessibilityRemoveRowSelection(row);
520         }
521
522         //
523         // TableCell interface
524         //
525
526         private static void InitializeAccessibilityDelegateTableCellInterface()
527         {
528             var ad = Interop.ControlDevel.AccessibilityDelegate.Instance;
529
530             ad.GetCellColumnSpan = AccessibilityGetCellColumnSpanWrapper;
531             ad.GetCellPosition   = AccessibilityGetCellPositionWrapper;
532             ad.GetCellRowSpan    = AccessibilityGetCellRowSpanWrapper;
533             ad.GetTable          = AccessibilityGetTableWrapper;
534         }
535
536         private static int AccessibilityGetCellColumnSpanWrapper(IntPtr self)
537         {
538             return GetInterfaceFromRefObject<IAtspiTableCell>(self).AccessibilityGetCellColumnSpan();
539         }
540
541         private static IntPtr AccessibilityGetCellPositionWrapper(IntPtr self)
542         {
543             Tuple<int, int> position = GetInterfaceFromRefObject<IAtspiTableCell>(self).AccessibilityGetCellPosition();
544
545             return DuplicateIntPair(position);
546         }
547
548         private static int AccessibilityGetCellRowSpanWrapper(IntPtr self)
549         {
550             return GetInterfaceFromRefObject<IAtspiTableCell>(self).AccessibilityGetCellRowSpan();
551         }
552
553         private static IntPtr AccessibilityGetTableWrapper(IntPtr self)
554         {
555             IAtspiTable table = GetInterfaceFromRefObject<IAtspiTableCell>(self).AccessibilityGetTable();
556
557             if (table is View view)
558             {
559                 return View.getCPtr(view).Handle;
560             }
561
562             NUILog.Error("Cannot get Actor handle from IAtspiTable");
563
564             return IntPtr.Zero;
565         }
566
567         //
568         // Text interface
569         //
570
571         private static void InitializeAccessibilityDelegateTextInterface()
572         {
573             var ad = Interop.ControlDevel.AccessibilityDelegate.Instance;
574
575             ad.GetCharacterCount = AccessibilityGetCharacterCountWrapper;
576             ad.GetCursorOffset   = AccessibilityGetCursorOffsetWrapper;
577             ad.GetRangeExtents   = AccessibilityGetRangeExtentsWrapper;
578             ad.GetSelection      = AccessibilityGetSelectionWrapper;
579             ad.GetText           = AccessibilityGetTextWrapper;
580             ad.GetTextAtOffset   = AccessibilityGetTextAtOffsetWrapper;
581             ad.RemoveSelection   = AccessibilityRemoveSelectionWrapper;
582             ad.SetCursorOffset   = AccessibilitySetCursorOffsetWrapper;
583             ad.SetSelection      = AccessibilitySetSelectionWrapper;
584         }
585
586         private static int AccessibilityGetCharacterCountWrapper(IntPtr self)
587         {
588             return GetInterfaceFromRefObject<IAtspiText>(self).AccessibilityGetCharacterCount();
589         }
590
591         private static int AccessibilityGetCursorOffsetWrapper(IntPtr self)
592         {
593             return GetInterfaceFromRefObject<IAtspiText>(self).AccessibilityGetCursorOffset();
594         }
595
596         private static IntPtr AccessibilityGetRangeExtentsWrapper(IntPtr self, int startOffset, int endOffset, int coordType)
597         {
598             using Rectangle rect = GetInterfaceFromRefObject<IAtspiText>(self).AccessibilityGetRangeExtents(startOffset, endOffset, (AccessibilityCoordinateType)coordType);
599
600             return DuplicateAccessibilityRectangle(rect);
601         }
602
603         private static IntPtr AccessibilityGetSelectionWrapper(IntPtr self, int selectionNumber)
604         {
605             AccessibilityRange range = GetInterfaceFromRefObject<IAtspiText>(self).AccessibilityGetSelection(selectionNumber);
606
607             return DuplicateAccessibilityRange(range);
608         }
609
610         private static IntPtr AccessibilityGetTextWrapper(IntPtr self, int startOffset, int endOffset)
611         {
612             string text = GetInterfaceFromRefObject<IAtspiText>(self).AccessibilityGetText(startOffset, endOffset);
613
614             return DuplicateString(text);
615         }
616
617         private static IntPtr AccessibilityGetTextAtOffsetWrapper(IntPtr self, int offset, int boundary)
618         {
619             AccessibilityRange range = GetInterfaceFromRefObject<IAtspiText>(self).AccessibilityGetTextAtOffset(offset, (AccessibilityTextBoundary)boundary);
620
621             return DuplicateAccessibilityRange(range);
622         }
623
624         private static bool AccessibilityRemoveSelectionWrapper(IntPtr self, int selectionNumber)
625         {
626             return GetInterfaceFromRefObject<IAtspiText>(self).AccessibilityRemoveSelection(selectionNumber);
627         }
628
629         private static bool AccessibilitySetCursorOffsetWrapper(IntPtr self, int offset)
630         {
631             return GetInterfaceFromRefObject<IAtspiText>(self).AccessibilitySetCursorOffset(offset);
632         }
633
634         private static bool AccessibilitySetSelectionWrapper(IntPtr self, int selectionNumber, int startOffset, int endOffset)
635         {
636             return GetInterfaceFromRefObject<IAtspiText>(self).AccessibilitySetSelection(selectionNumber, startOffset, endOffset);
637         }
638
639         //
640         // Value interface
641         //
642
643         private static void InitializeAccessibilityDelegateValueInterface()
644         {
645             var ad = Interop.ControlDevel.AccessibilityDelegate.Instance;
646
647             ad.GetCurrent          = AccessibilityGetCurrentWrapper;
648             ad.GetMaximum          = AccessibilityGetMaximumWrapper;
649             ad.GetMinimum          = AccessibilityGetMinimumWrapper;
650             ad.GetMinimumIncrement = AccessibilityGetMinimumIncrementWrapper;
651             ad.GetValueText        = AccessibilityGetValueTextWrapper;
652             ad.SetCurrent          = AccessibilitySetCurrentWrapper;
653         }
654
655         private static double AccessibilityGetCurrentWrapper(IntPtr self)
656         {
657             return GetInterfaceFromRefObject<IAtspiValue>(self).AccessibilityGetCurrent();
658         }
659
660         private static double AccessibilityGetMaximumWrapper(IntPtr self)
661         {
662             return GetInterfaceFromRefObject<IAtspiValue>(self).AccessibilityGetMaximum();
663         }
664
665         private static double AccessibilityGetMinimumWrapper(IntPtr self)
666         {
667             return GetInterfaceFromRefObject<IAtspiValue>(self).AccessibilityGetMinimum();
668         }
669
670         private static double AccessibilityGetMinimumIncrementWrapper(IntPtr self)
671         {
672             return GetInterfaceFromRefObject<IAtspiValue>(self).AccessibilityGetMinimumIncrement();
673         }
674
675         private static IntPtr AccessibilityGetValueTextWrapper(IntPtr self)
676         {
677             var view = GetViewFromRefObject(self);
678             var value = GetInterfaceFromRefObject<IAtspiValue>(self);
679             string text;
680
681             // Mimic the behaviour of the pairs AccessibilityNameRequested & AccessibilityGetName(),
682             // and AccessibilityDescriptionRequested & AccessibilityGetDescription(),
683             // i.e. a higher-priority Accessibility[…]Requested event for application developers,
684             // and a lower-priority AccessibilityGet[…]() virtual method for component developers.
685             // The difference is that event-or-virtual-method dispatching is done in C++ for
686             // Name and Description, and here in this wrapper method for ValueText (because there
687             // is no signal for ValueText in DALi.)
688             if (view.AccessibilityValueTextRequested?.GetInvocationList().Length > 0)
689             {
690                 var args = new AccessibilityValueTextRequestedEventArgs();
691                 view.AccessibilityValueTextRequested.Invoke(view, args);
692                 text = args.Text;
693             }
694             else
695             {
696                 text = value.AccessibilityGetValueText();
697             }
698
699             return DuplicateString(text);
700         }
701
702         private static bool AccessibilitySetCurrentWrapper(IntPtr self, double value)
703         {
704             return GetInterfaceFromRefObject<IAtspiValue>(self).AccessibilitySetCurrent(value);
705         }
706
707         //
708         // Tizen extensions
709         //
710
711         private static void InitializeAccessibilityDelegateTizenExtensions()
712         {
713             var ad = Interop.ControlDevel.AccessibilityDelegate.Instance;
714
715             ad.ScrollToChild            = AccessibilityScrollToChildWrapper;
716         }
717
718         private static bool AccessibilityScrollToChildWrapper(IntPtr self, IntPtr child)
719         {
720             View view = GetViewFromRefObject(self);
721
722             return view.AccessibilityScrollToChild(view.GetInstanceSafely<View>(child));
723         }
724     }
725 }