[Tizen] [AT-SPI] Guarantee UnregisterDefaultLabel()
[platform/core/uifw/dali-csharp-binder.git] / dali-csharp-binder / src / nui-view-accessible.cpp
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 // CLASS HEADER
19 #include "nui-view-accessible.h"
20
21 // EXTERNAL INCLUDES
22 #include <dali/integration-api/debug.h>
23
24 // INTERNAL INCLUDES
25 #include "control-devel-wrap.h"
26
27 using namespace Dali;
28 using namespace Dali::Toolkit;
29
30 using Interface     = Accessibility::AtspiInterface;
31 using IntPairType   = NUIViewAccessible::IntPairType;
32 using IntVectorType = NUIViewAccessible::IntVectorType;
33
34 namespace
35 {
36 void GetAttributesCallback(const char* key, const char* value, Accessibility::Attributes* attributes)
37 {
38   attributes->insert_or_assign(key, value);
39 }
40
41 void GetSelectedRowsColumnsCallback(int index, IntVectorType* vector)
42 {
43   vector->push_back(index);
44 }
45
46 using GetAttributesCallbackType          = decltype(&GetAttributesCallback);
47 using GetSelectedRowsColumnsCallbackType = decltype(&GetSelectedRowsColumnsCallback);
48
49 } // unnamed namespace
50
51 // Keep this structure layout binary compatible with the respective C# structure!
52 struct NUIViewAccessible::AccessibilityDelegate
53 {
54   AccessibilityDelegate() = delete;
55
56   // clang-format off
57   char*                 (*getName)                 (RefObject*);                   //  1
58   char*                 (*getDescription)          (RefObject*);                   //  2
59   bool                  (*doAction)                (RefObject*, const char*);      //  3
60   std::uint64_t         (*calculateStates)         (RefObject*, std::uint64_t);    //  4
61   int                   (*getActionCount)          (RefObject*);                   //  5
62   char*                 (*getActionName)           (RefObject*, int);              //  6
63   std::uint32_t         (*getInterfaces)           (RefObject*);                   //  7
64   double                (*getMinimum)              (RefObject*);                   //  8
65   double                (*getCurrent)              (RefObject*);                   //  9
66   double                (*getMaximum)              (RefObject*);                   // 10
67   bool                  (*setCurrent)              (RefObject*, double);           // 11
68   double                (*getMinimumIncrement)     (RefObject*);                   // 12
69   bool                  (*isScrollable)            (RefObject*);                   // 13
70   char*                 (*getText)                 (RefObject*, int, int);         // 14
71   int                   (*getCharacterCount)       (RefObject*);                   // 15
72   int                   (*getCursorOffset)         (RefObject*);                   // 16
73   bool                  (*setCursorOffset)         (RefObject*, int);              // 17
74   Accessibility::Range* (*getTextAtOffset)         (RefObject*, int, int);         // 18
75   Accessibility::Range* (*getRangeOfSelection)     (RefObject*, int);              // 19
76   bool                  (*removeSelection)         (RefObject*, int);              // 20
77   bool                  (*setRangeOfSelection)     (RefObject*, int, int, int);    // 21
78   bool                  (*copyText)                (RefObject*, int, int);         // 22
79   bool                  (*cutText)                 (RefObject*, int, int);         // 23
80   bool                  (*insertText)              (RefObject*, int, const char*); // 24
81   bool                  (*setTextContents)         (RefObject*, const char*);      // 25
82   bool                  (*deleteText)              (RefObject*, int, int);         // 26
83   bool                  (*scrollToChild)           (RefObject*, Actor*);           // 27
84   int                   (*getSelectedChildrenCount)(RefObject*);                   // 28
85   Actor*                (*getSelectedChild)        (RefObject*, int);              // 29
86   bool                  (*selectChild)             (RefObject*, int);              // 30
87   bool                  (*deselectSelectedChild)   (RefObject*, int);              // 31
88   bool                  (*isChildSelected)         (RefObject*, int);              // 32
89   bool                  (*selectAll)               (RefObject*);                   // 33
90   bool                  (*clearSelection)          (RefObject*);                   // 34
91   bool                  (*deselectChild)           (RefObject*, int);              // 35
92   Rect<int>*            (*getRangeExtents)         (RefObject*, int, int, int);    // 36
93   void                  (*getAttributes)           (RefObject*, GetAttributesCallbackType, Accessibility::Attributes*); // 37
94   char*                 (*getValueText)            (RefObject*);                   // 38
95   int                   (*getRowCount)             (RefObject*);                   // 39
96   int                   (*getColumnCount)          (RefObject*);                   // 40
97   int                   (*getSelectedRowCount)     (RefObject*);                   // 41
98   int                   (*getSelectedColumnCount)  (RefObject*);                   // 42
99   Actor*                (*getCaption)              (RefObject*);                   // 43
100   Actor*                (*getSummary)              (RefObject*);                   // 44
101   Actor*                (*getCell)                 (RefObject*, int, int);         // 45
102   std::uint64_t         (*getChildIndex)           (RefObject*, int, int);         // 46
103   IntPairType*          (*getPositionByChildIndex) (RefObject*, std::uint64_t);    // 47
104   char*                 (*getRowDescription)       (RefObject*, int);              // 48
105   char*                 (*getColumnDescription)    (RefObject*, int);              // 49
106   Actor*                (*getRowHeader)            (RefObject*, int);              // 50
107   Actor*                (*getColumnHeader)         (RefObject*, int);              // 51
108   void                  (*getSelectedRows)         (RefObject*, GetSelectedRowsColumnsCallbackType, IntVectorType*); // 52
109   void                  (*getSelectedColumns)      (RefObject*, GetSelectedRowsColumnsCallbackType, IntVectorType*); // 53
110   bool                  (*isRowSelected)           (RefObject*, int);              // 54
111   bool                  (*isColumnSelected)        (RefObject*, int);              // 55
112   bool                  (*isCellSelected)          (RefObject*, int, int);         // 56
113   bool                  (*addRowSelection)         (RefObject*, int);              // 57
114   bool                  (*addColumnSelection)      (RefObject*, int);              // 58
115   bool                  (*removeRowSelection)      (RefObject*, int);              // 59
116   bool                  (*removeColumnSelection)   (RefObject*, int);              // 60
117   Actor*                (*getTable)                (RefObject*);                   // 61
118   IntPairType*          (*getCellPosition)         (RefObject*);                   // 62
119   int                   (*getCellRowSpan)          (RefObject*);                   // 63
120   int                   (*getCellColumnSpan)       (RefObject*);                   // 64
121   // clang-format on
122 };
123
124 NUIViewAccessible::NUIViewAccessible(Actor actor)
125 : ControlAccessible(actor)
126 {
127   DALI_ASSERT_DEBUG(mTable);
128 }
129
130 void NUIViewAccessible::SetAccessibilityDelegate(const AccessibilityDelegate* accessibilityDelegate)
131 {
132   if(mTable)
133   {
134     DALI_LOG_ERROR("Overwriting global AccessibilityDelegate");
135   }
136
137   mTable = accessibilityDelegate;
138 }
139
140 void NUIViewAccessible::Detach()
141 {
142   mIsDetached = true;
143 }
144
145 std::string NUIViewAccessible::StealString(char* str)
146 {
147   std::string ret{};
148
149   if(str)
150   {
151     ret = {str};
152     free(str);
153   }
154
155   return ret;
156 }
157
158 template<typename T>
159 T NUIViewAccessible::StealObject(T* obj)
160 {
161   T ret{};
162
163   if(obj)
164   {
165     ret = std::move(*obj);
166     delete obj;
167   }
168
169   return ret;
170 }
171
172 template<Interface I, typename R, typename... Args>
173 R NUIViewAccessible::CallMethod(R (*method)(RefObject*, Args...), Args... args) const
174 {
175   if(mIsDetached)
176   {
177     DALI_LOG_ERROR("Method called on detached NUIViewAccessible[%p]", static_cast<const void*>(this));
178
179     if constexpr(std::is_same_v<R, void>)
180       return;
181     else
182       return R{};
183   }
184
185   DALI_ASSERT_DEBUG(method);
186   DALI_ASSERT_ALWAYS(GetInterfaces()[I]);
187
188   return method(Self().GetObjectPtr(), args...);
189 }
190
191 //
192 // Standard interfaces (Accessible, Action, Component)
193 //
194
195 std::string NUIViewAccessible::GetNameRaw() const
196 {
197   char* name = CallMethod<Interface::ACCESSIBLE>(mTable->getName);
198
199   return StealString(name);
200 }
201
202 std::string NUIViewAccessible::GetDescriptionRaw() const
203 {
204   char* description = CallMethod<Interface::ACCESSIBLE>(mTable->getDescription);
205
206   return StealString(description);
207 }
208
209 bool NUIViewAccessible::GrabHighlight()
210 {
211   bool ret = ControlAccessible::GrabHighlight();
212
213   if(ret)
214   {
215     // Note: Currently (2021-03-26), size negotiation between the default highlight frame
216     // and NUI Components is known to be broken (and possibly in other cases, too). Please
217     // remove this for GrabHighlight() when it is fixed.
218     auto size = Self().GetProperty<Vector2>(Actor::Property::SIZE);
219     mCurrentHighlightActor.GetHandle().SetProperty(Actor::Property::SIZE, size);
220   }
221
222   return ret;
223 }
224
225 std::string NUIViewAccessible::GetActionName(std::size_t index) const
226 {
227   char* name = CallMethod<Interface::ACTION>(mTable->getActionName, static_cast<int>(index));
228
229   return StealString(name);
230 }
231
232 std::size_t NUIViewAccessible::GetActionCount() const
233 {
234   int count = CallMethod<Interface::ACTION>(mTable->getActionCount);
235
236   return static_cast<std::size_t>(count);
237 }
238
239 bool NUIViewAccessible::DoAction(std::size_t index)
240 {
241   return DoAction(GetActionName(index));
242 }
243
244 bool NUIViewAccessible::DoAction(const std::string& name)
245 {
246   return CallMethod<Interface::ACTION>(mTable->doAction, name.c_str());
247 }
248
249 Accessibility::States NUIViewAccessible::CalculateStates()
250 {
251   std::uint64_t states = ControlAccessible::CalculateStates().GetRawData64();
252
253   states = CallMethod<Interface::ACCESSIBLE>(mTable->calculateStates, states);
254
255   return Accessibility::States{states};
256 }
257
258 Accessibility::Attributes NUIViewAccessible::GetAttributes() const
259 {
260   auto attributes = ControlAccessible::GetAttributes();
261
262   CallMethod<Interface::ACCESSIBLE>(mTable->getAttributes, &GetAttributesCallback, &attributes);
263
264   return attributes;
265 }
266
267 Property::Index NUIViewAccessible::GetNamePropertyIndex()
268 {
269   return Property::INVALID_INDEX;
270 }
271
272 Property::Index NUIViewAccessible::GetDescriptionPropertyIndex()
273 {
274   return Property::INVALID_INDEX;
275 }
276
277 bool NUIViewAccessible::IsScrollable() const
278 {
279   return CallMethod<Interface::COMPONENT>(mTable->isScrollable);
280 }
281
282 bool NUIViewAccessible::ScrollToChild(Actor child)
283 {
284   return CallMethod<Interface::ACCESSIBLE>(mTable->scrollToChild, new Actor(child));
285 }
286
287 Accessibility::AtspiInterfaces NUIViewAccessible::DoGetInterfaces() const
288 {
289   using Interfaces = Accessibility::AtspiInterfaces;
290
291   Interfaces baseInterfaces;
292   Interfaces extraInterfaces;
293
294   // These are always implemented
295   baseInterfaces[Interface::ACCESSIBLE] = true;
296   baseInterfaces[Interface::ACTION]     = true;
297   baseInterfaces[Interface::COLLECTION] = true;
298   baseInterfaces[Interface::COMPONENT]  = true;
299
300   // We cannot use CallMethod() here as that would cause recursion.
301   // Note that the result will be cached and subsequent calls to GetInterfaces()
302   // will not involve calling this virtual method or jumping into C# code.
303   extraInterfaces = Interfaces{mTable->getInterfaces(Self().GetObjectPtr())};
304
305   return baseInterfaces | extraInterfaces;
306 }
307
308 //
309 // Value interface
310 //
311
312 double NUIViewAccessible::GetMinimum() const
313 {
314   return CallMethod<Interface::VALUE>(mTable->getMinimum);
315 }
316
317 double NUIViewAccessible::GetCurrent() const
318 {
319   return CallMethod<Interface::VALUE>(mTable->getCurrent);
320 }
321
322 std::string NUIViewAccessible::GetValueText() const
323 {
324   char *text = CallMethod<Interface::VALUE>(mTable->getValueText);
325
326   return StealString(text);
327 }
328
329 double NUIViewAccessible::GetMaximum() const
330 {
331   return CallMethod<Interface::VALUE>(mTable->getMaximum);
332 }
333
334 bool NUIViewAccessible::SetCurrent(double value)
335 {
336   return CallMethod<Interface::VALUE>(mTable->setCurrent, value);
337 }
338
339 double NUIViewAccessible::GetMinimumIncrement() const
340 {
341   return CallMethod<Interface::VALUE>(mTable->getMinimumIncrement);
342 }
343
344 //
345 // Text interface
346 //
347
348 std::string NUIViewAccessible::GetText(std::size_t startOffset, std::size_t endOffset) const
349 {
350   char* text = CallMethod<Interface::TEXT>(mTable->getText, static_cast<int>(startOffset), static_cast<int>(endOffset));
351
352   return StealString(text);
353 }
354
355 std::size_t NUIViewAccessible::GetCharacterCount() const
356 {
357   int count = CallMethod<Interface::TEXT>(mTable->getCharacterCount);
358
359   return static_cast<std::size_t>(count);
360 }
361
362 std::size_t NUIViewAccessible::GetCursorOffset() const
363 {
364   int offset = CallMethod<Interface::TEXT>(mTable->getCursorOffset);
365
366   return static_cast<std::size_t>(offset);
367 }
368
369 bool NUIViewAccessible::SetCursorOffset(std::size_t offset)
370 {
371   return CallMethod<Interface::TEXT>(mTable->setCursorOffset, static_cast<int>(offset));
372 }
373
374 Accessibility::Range NUIViewAccessible::GetTextAtOffset(std::size_t offset, Accessibility::TextBoundary boundary) const
375 {
376   Accessibility::Range* range = CallMethod<Interface::TEXT>(mTable->getTextAtOffset, static_cast<int>(offset), static_cast<int>(boundary));
377
378   return StealObject(range);
379 }
380
381 Accessibility::Range NUIViewAccessible::GetRangeOfSelection(std::size_t selectionIndex) const
382 {
383   Accessibility::Range* range = CallMethod<Interface::TEXT>(mTable->getRangeOfSelection, static_cast<int>(selectionIndex));
384
385   return StealObject(range);
386 }
387
388 bool NUIViewAccessible::RemoveSelection(std::size_t selectionIndex)
389 {
390   return CallMethod<Interface::TEXT>(mTable->removeSelection, static_cast<int>(selectionIndex));
391 }
392
393 bool NUIViewAccessible::SetRangeOfSelection(std::size_t selectionIndex, std::size_t startOffset, std::size_t endOffset)
394 {
395   return CallMethod<Interface::TEXT>(mTable->setRangeOfSelection, static_cast<int>(selectionIndex), static_cast<int>(startOffset), static_cast<int>(endOffset));
396 }
397
398 Rect<> NUIViewAccessible::GetRangeExtents(std::size_t startOffset, std::size_t endOffset, Accessibility::CoordinateType type)
399 {
400   auto      rectPtr = CallMethod<Interface::TEXT>(mTable->getRangeExtents, static_cast<int>(startOffset), static_cast<int>(endOffset), static_cast<int>(type));
401   Rect<int> rect    = StealObject(rectPtr);
402
403   return {(float)rect.x, (float)rect.y, (float)rect.width, (float)rect.height};
404 }
405
406 //
407 // EditableText interface
408 //
409
410 bool NUIViewAccessible::CopyText(std::size_t startPosition, std::size_t endPosition)
411 {
412   return CallMethod<Interface::EDITABLE_TEXT>(mTable->copyText, static_cast<int>(startPosition), static_cast<int>(endPosition));
413 }
414
415 bool NUIViewAccessible::CutText(std::size_t startPosition, std::size_t endPosition)
416 {
417   return CallMethod<Interface::EDITABLE_TEXT>(mTable->cutText, static_cast<int>(startPosition), static_cast<int>(endPosition));
418 }
419
420 bool NUIViewAccessible::InsertText(std::size_t startPosition, std::string text)
421 {
422   return CallMethod<Interface::EDITABLE_TEXT>(mTable->insertText, static_cast<int>(startPosition), text.c_str());
423 }
424
425 bool NUIViewAccessible::SetTextContents(std::string newContents)
426 {
427   return CallMethod<Interface::EDITABLE_TEXT>(mTable->setTextContents, newContents.c_str());
428 }
429
430 bool NUIViewAccessible::DeleteText(std::size_t startPosition, std::size_t endPosition)
431 {
432   return CallMethod<Interface::EDITABLE_TEXT>(mTable->deleteText, static_cast<int>(startPosition), static_cast<int>(endPosition));
433 }
434
435 //
436 // Selection interface
437 //
438
439 int NUIViewAccessible::GetSelectedChildrenCount() const
440 {
441   return CallMethod<Interface::SELECTION>(mTable->getSelectedChildrenCount);
442 }
443
444 Accessibility::Accessible* NUIViewAccessible::GetSelectedChild(int selectedChildIndex)
445 {
446   Actor* actor = CallMethod<Interface::SELECTION>(mTable->getSelectedChild, selectedChildIndex);
447
448   return actor ? Accessibility::Accessible::Get(*actor) : nullptr;
449 }
450
451 bool NUIViewAccessible::SelectChild(int childIndex)
452 {
453   return CallMethod<Interface::SELECTION>(mTable->selectChild, childIndex);
454 }
455
456 bool NUIViewAccessible::DeselectSelectedChild(int selectedChildIndex)
457 {
458   return CallMethod<Interface::SELECTION>(mTable->deselectSelectedChild, selectedChildIndex);
459 }
460
461 bool NUIViewAccessible::IsChildSelected(int childIndex) const
462 {
463   return CallMethod<Interface::SELECTION>(mTable->isChildSelected, childIndex);
464 }
465
466 bool NUIViewAccessible::SelectAll()
467 {
468   return CallMethod<Interface::SELECTION>(mTable->selectAll);
469 }
470
471 bool NUIViewAccessible::ClearSelection()
472 {
473   return CallMethod<Interface::SELECTION>(mTable->clearSelection);
474 }
475
476 bool NUIViewAccessible::DeselectChild(int childIndex)
477 {
478   return CallMethod<Interface::SELECTION>(mTable->deselectChild, childIndex);
479 }
480
481 //
482 // Table interface
483 //
484
485 int NUIViewAccessible::GetRowCount() const
486 {
487   return CallMethod<Interface::TABLE>(mTable->getRowCount);
488 }
489
490 int NUIViewAccessible::GetColumnCount() const
491 {
492   return CallMethod<Interface::TABLE>(mTable->getColumnCount);
493 }
494
495 int NUIViewAccessible::GetSelectedRowCount() const
496 {
497   return CallMethod<Interface::TABLE>(mTable->getSelectedRowCount);
498 }
499
500 int NUIViewAccessible::GetSelectedColumnCount() const
501 {
502   return CallMethod<Interface::TABLE>(mTable->getSelectedColumnCount);
503 }
504
505 Accessibility::Accessible* NUIViewAccessible::GetCaption() const
506 {
507   Actor* caption = CallMethod<Interface::TABLE>(mTable->getCaption);
508
509   return caption ? Accessibility::Accessible::Get(*caption) : nullptr;
510 }
511
512 Accessibility::Accessible* NUIViewAccessible::GetSummary() const
513 {
514   Actor* summary = CallMethod<Interface::TABLE>(mTable->getSummary);
515
516   return summary ? Accessibility::Accessible::Get(*summary) : nullptr;
517 }
518
519 Accessibility::TableCell* NUIViewAccessible::GetCell(int row, int column) const
520 {
521   Actor* cell = CallMethod<Interface::TABLE>(mTable->getCell, row, column);
522
523   return cell ? Accessibility::TableCell::DownCast(Accessibility::Accessible::Get(*cell)) : nullptr;
524 }
525
526 std::size_t NUIViewAccessible::GetChildIndex(int row, int column) const
527 {
528   std::uint64_t index = CallMethod<Interface::TABLE>(mTable->getChildIndex, row, column);
529
530   return static_cast<std::size_t>(index);
531 }
532
533 IntPairType NUIViewAccessible::GetPositionByChildIndex(std::size_t childIndex) const
534 {
535   IntPairType* position = CallMethod<Interface::TABLE>(mTable->getPositionByChildIndex, static_cast<std::uint64_t>(childIndex));
536
537   return StealObject(position);
538 }
539
540 int NUIViewAccessible::GetRowByChildIndex(std::size_t childIndex) const
541 {
542   return GetPositionByChildIndex(childIndex).first;
543 }
544
545 int NUIViewAccessible::GetColumnByChildIndex(std::size_t childIndex) const
546 {
547   return GetPositionByChildIndex(childIndex).second;
548 }
549
550 std::string NUIViewAccessible::GetRowDescription(int row) const
551 {
552   char* description = CallMethod<Interface::TABLE>(mTable->getRowDescription, row);
553
554   return StealString(description);
555 }
556
557 std::string NUIViewAccessible::GetColumnDescription(int column) const
558 {
559   char* description = CallMethod<Interface::TABLE>(mTable->getColumnDescription, column);
560
561   return StealString(description);
562 }
563
564 int NUIViewAccessible::GetRowSpan(int row, int column) const
565 {
566   Accessibility::TableCell* cell = GetCell(row, column);
567
568   return cell ? cell->GetCellRowSpan() : -1;
569 }
570
571 int NUIViewAccessible::GetColumnSpan(int row, int column) const
572 {
573   Accessibility::TableCell* cell = GetCell(row, column);
574
575   return cell ? cell->GetCellColumnSpan() : -1;
576 }
577
578 Accessibility::Accessible* NUIViewAccessible::GetRowHeader(int row) const
579 {
580   Actor* header = CallMethod<Interface::TABLE>(mTable->getRowHeader, row);
581
582   return header ? Accessibility::Accessible::Get(*header) : nullptr;
583 }
584
585 Accessibility::Accessible* NUIViewAccessible::GetColumnHeader(int column) const
586 {
587   Actor* header = CallMethod<Interface::TABLE>(mTable->getColumnHeader, column);
588
589   return header ? Accessibility::Accessible::Get(*header) : nullptr;
590 }
591
592 IntVectorType NUIViewAccessible::GetSelectedRows() const
593 {
594   IntVectorType result;
595
596   CallMethod<Interface::TABLE>(mTable->getSelectedRows, &GetSelectedRowsColumnsCallback, &result);
597
598   return result;
599 }
600
601 IntVectorType NUIViewAccessible::GetSelectedColumns() const
602 {
603   IntVectorType result;
604
605   CallMethod<Interface::TABLE>(mTable->getSelectedColumns, &GetSelectedRowsColumnsCallback, &result);
606
607   return result;
608 }
609
610 bool NUIViewAccessible::IsRowSelected(int row) const
611 {
612   return CallMethod<Interface::TABLE>(mTable->isRowSelected, row);
613 }
614
615 bool NUIViewAccessible::IsColumnSelected(int column) const
616 {
617   return CallMethod<Interface::TABLE>(mTable->isColumnSelected, column);
618 }
619
620 bool NUIViewAccessible::IsCellSelected(int row, int column) const
621 {
622   return CallMethod<Interface::TABLE>(mTable->isCellSelected, row, column);
623 }
624
625 bool NUIViewAccessible::AddRowSelection(int row)
626 {
627   return CallMethod<Interface::TABLE>(mTable->addRowSelection, row);
628 }
629
630 bool NUIViewAccessible::AddColumnSelection(int column)
631 {
632   return CallMethod<Interface::TABLE>(mTable->addColumnSelection, column);
633 }
634
635 bool NUIViewAccessible::RemoveRowSelection(int row)
636 {
637   return CallMethod<Interface::TABLE>(mTable->removeRowSelection, row);
638 }
639
640 bool NUIViewAccessible::RemoveColumnSelection(int column)
641 {
642   return CallMethod<Interface::TABLE>(mTable->removeColumnSelection, column);
643 }
644
645 Accessibility::Table::RowColumnSpanType NUIViewAccessible::GetRowColumnSpan(std::size_t childIndex) const
646 {
647   Accessibility::Table::RowColumnSpanType span{.success = false};
648
649   std::tie(span.row, span.column) = GetPositionByChildIndex(childIndex);
650   Accessibility::TableCell* cell  = GetCell(span.row, span.column);
651   if (!cell)
652   {
653     return span;
654   }
655
656   span.success    = true;
657   span.isSelected = IsCellSelected(span.row, span.column);
658   span.rowSpan    = cell->GetCellRowSpan();
659   span.columnSpan = cell->GetCellColumnSpan();
660
661   return span;
662 }
663
664 //
665 // TableCell interface
666 //
667
668 Accessibility::Table* NUIViewAccessible::GetTable() const
669 {
670   Actor* table = CallMethod<Interface::TABLE_CELL>(mTable->getTable);
671
672   return table ? Accessibility::Table::DownCast(Accessibility::Accessible::Get(*table)) : nullptr;
673 }
674
675 IntPairType NUIViewAccessible::GetCellPosition() const
676 {
677   IntPairType* position = CallMethod<Interface::TABLE_CELL>(mTable->getCellPosition);
678
679   return StealObject(position);
680 }
681
682 int NUIViewAccessible::GetCellRowSpan() const
683 {
684   return CallMethod<Interface::TABLE_CELL>(mTable->getCellRowSpan);
685 }
686
687 int NUIViewAccessible::GetCellColumnSpan() const
688 {
689   return CallMethod<Interface::TABLE_CELL>(mTable->getCellColumnSpan);
690 }
691
692 Accessibility::TableCell::RowColumnSpanType NUIViewAccessible::GetCellRowColumnSpan() const
693 {
694   Accessibility::TableCell::RowColumnSpanType span{};
695
696   std::tie(span.row, span.column) = GetCellPosition();
697   span.rowSpan                    = GetCellRowSpan();
698   span.columnSpan                 = GetCellColumnSpan();
699
700   return span;
701 }
702
703 #ifdef __cplusplus
704 extern "C" {
705 #endif
706
707 SWIGEXPORT char* SWIGSTDCALL CSharp_Dali_Accessibility_DuplicateString(const char* arg)
708 {
709   return strdup(arg);
710 }
711
712 SWIGEXPORT IntPairType* SWIGSTDCALL CSharp_Dali_Accessibility_MakeIntPair(int first, int second)
713 {
714   return new IntPairType(first, second);
715 }
716
717 SWIGEXPORT void SWIGSTDCALL CSharp_Dali_Accessibility_SetAccessibilityDelegate(const void* arg1_accessibilityDelegate, uint32_t arg2_accessibilityDelegateSize)
718 {
719   GUARD_ON_NULL_RET(arg1_accessibilityDelegate);
720
721   const auto* accessibilityDelegate     = static_cast<const NUIViewAccessible::AccessibilityDelegate*>(arg1_accessibilityDelegate);
722   auto        accessibilityDelegateSize = static_cast<std::size_t>(arg2_accessibilityDelegateSize);
723
724   try_catch(([&]() {
725     if(accessibilityDelegateSize != sizeof(*accessibilityDelegate))
726     {
727       DALI_LOG_ERROR("SetAccessibilityDelegate error: Marshal.SizeOf<AccessibilityDelegate>()[%zu] != sizeof(AccessibilityDelegate)[%zu]\n", accessibilityDelegateSize, sizeof(*accessibilityDelegate));
728       throw std::runtime_error("SetAccessibilityDelegate error: Marshal.SizeOf<AccessibilityDelegate>() != sizeof(AccessibilityDelegate)");
729     }
730
731     NUIViewAccessible::SetAccessibilityDelegate(accessibilityDelegate);
732     Accessibility::Bridge::GetCurrentBridge()->SetToolkitName("nui(dali)");
733   }));
734 }
735
736 SWIGEXPORT void SWIGSTDCALL CSharp_Dali_Accessibility_DetachAccessibleObject(Dali::BaseHandle* arg1_control)
737 {
738   GUARD_ON_NULL_RET(arg1_control);
739
740   try_catch(([&]() {
741     Dali::Toolkit::Control control = Dali::Toolkit::Control::DownCast(*arg1_control);
742     if(DALI_LIKELY(control))
743     {
744       // Call detach only if accessible was created before.
745       if(DevelControl::IsAccessibleCreated(control))
746       {
747         auto* actorAccessible = Dali::Accessibility::Accessible::Get(control);
748         auto* viewAccessible  = dynamic_cast<NUIViewAccessible*>(actorAccessible);
749
750         if(viewAccessible)
751         {
752           viewAccessible->Detach();
753
754           // In case someone forgot View.UnregisterDefaultLabel() before View.Dispose()...
755           Dali::Accessibility::Bridge::GetCurrentBridge()->UnregisterDefaultLabel(viewAccessible);
756         }
757       }
758
759       // Make that we will not create new NUIViewAccessible anymore.
760       DevelControl::EnableCreateAccessible(control, false);
761     }
762   }));
763 }
764
765 #ifdef __cplusplus
766 } // extern "C"
767 #endif