[AT-SPI] Removal of unused code
[platform/core/uifw/dali-adaptor.git] / dali / devel-api / adaptor-framework / accessibility-impl.cpp
1 /*
2  * Copyright 2020  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 // CLASS HEADER
18
19 // EXTERNAL INCLUDES
20 #include <dali/integration-api/debug.h>
21 #include <dali/public-api/actors/actor.h>
22 #include <dali/public-api/actors/layer.h>
23 #include <dali/public-api/object/base-object.h>
24 #include <dali/public-api/object/object-registry.h>
25 #include <dali/public-api/object/type-info.h>
26 #include <dali/public-api/object/type-registry-helper.h>
27
28 // INTERNAL INCLUDES
29 #include <dali/public-api/dali-adaptor-common.h>
30 #include <dali/devel-api/adaptor-framework/accessibility-impl.h>
31 #include <dali/internal/adaptor/common/adaptor-impl.h>
32
33 using namespace Dali::Accessibility;
34 using namespace Dali;
35
36 const std::string& Dali::Accessibility::Address::GetBus() const
37 {
38   return mBus.empty() && Bridge::GetCurrentBridge() ? Bridge::GetCurrentBridge()->GetBusName() : mBus;
39 }
40
41 std::string EmptyAccessibleWithAddress::GetRoleName()
42 {
43   return "";
44 }
45
46 std::string Accessible::GetLocalizedRoleName()
47 {
48   return GetRoleName();
49 }
50
51 std::string Accessible::GetRoleName()
52 {
53   switch( GetRole() )
54   {
55     case Role::INVALID:
56     {
57       return "invalid";
58     }
59     case Role::ACCELERATOR_LABEL:
60     {
61       return "accelerator label";
62     }
63     case Role::ALERT:
64     {
65       return "alert";
66     }
67     case Role::ANIMATION:
68     {
69       return "animation";
70     }
71     case Role::ARROW:
72     {
73       return "arrow";
74     }
75     case Role::CALENDAR:
76     {
77       return "calendar";
78     }
79     case Role::CANVAS:
80     {
81       return "canvas";
82     }
83     case Role::CHECK_BOX:
84     {
85       return "check box";
86     }
87     case Role::CHECK_MENU_ITEM:
88     {
89       return "check menu item";
90     }
91     case Role::COLOR_CHOOSER:
92     {
93       return "color chooser";
94     }
95     case Role::COLUMN_HEADER:
96     {
97       return "column header";
98     }
99     case Role::COMBO_BOX:
100     {
101       return "combo box";
102     }
103     case Role::DATE_EDITOR:
104     {
105       return "date editor";
106     }
107     case Role::DESKTOP_ICON:
108     {
109       return "desktop icon";
110     }
111     case Role::DESKTOP_FRAME:
112     {
113       return "desktop frame";
114     }
115     case Role::DIAL:
116     {
117       return "dial";
118     }
119     case Role::DIALOG:
120     {
121       return "dialog";
122     }
123     case Role::DIRECTORY_PANE:
124     {
125       return "directory pane";
126     }
127     case Role::DRAWING_AREA:
128     {
129       return "drawing area";
130     }
131     case Role::FILE_CHOOSER:
132     {
133       return "file chooser";
134     }
135     case Role::FILLER:
136     {
137       return "filler";
138     }
139     case Role::FOCUS_TRAVERSABLE:
140     {
141       return "focus traversable";
142     }
143     case Role::FONT_CHOOSER:
144     {
145       return "font chooser";
146     }
147     case Role::FRAME:
148     {
149       return "frame";
150     }
151     case Role::GLASS_PANE:
152     {
153       return "glass pane";
154     }
155     case Role::HTML_CONTAINER:
156     {
157       return "html container";
158     }
159     case Role::ICON:
160     {
161       return "icon";
162     }
163     case Role::IMAGE:
164     {
165       return "image";
166     }
167     case Role::INTERNAL_FRAME:
168     {
169       return "internal frame";
170     }
171     case Role::LABEL:
172     {
173       return "label";
174     }
175     case Role::LAYERED_PANE:
176     {
177       return "layered pane";
178     }
179     case Role::LIST:
180     {
181       return "list";
182     }
183     case Role::LIST_ITEM:
184     {
185       return "list item";
186     }
187     case Role::MENU:
188     {
189       return "menu";
190     }
191     case Role::MENU_BAR:
192     {
193       return "menu bar";
194     }
195     case Role::MENU_ITEM:
196     {
197       return "menu item";
198     }
199     case Role::OPTION_PANE:
200     {
201       return "option pane";
202     }
203     case Role::PAGE_TAB:
204     {
205       return "page tab";
206     }
207     case Role::PAGE_TAB_LIST:
208     {
209       return "page tab list";
210     }
211     case Role::PANEL:
212     {
213       return "panel";
214     }
215     case Role::PASSWORD_TEXT:
216     {
217       return "password text";
218     }
219     case Role::POPUP_MENU:
220     {
221       return "popup menu";
222     }
223     case Role::PROGRESS_BAR:
224     {
225       return "progress bar";
226     }
227     case Role::PUSH_BUTTON:
228     {
229       return "push button";
230     }
231     case Role::RADIO_BUTTON:
232     {
233       return "radio button";
234     }
235     case Role::RADIO_MENU_ITEM:
236     {
237       return "radio menu item";
238     }
239     case Role::ROOT_PANE:
240     {
241       return "root pane";
242     }
243     case Role::ROW_HEADER:
244     {
245       return "row header";
246     }
247     case Role::SCROLL_BAR:
248     {
249       return "scroll bar";
250     }
251     case Role::SCROLL_PANE:
252     {
253       return "scroll pane";
254     }
255     case Role::SEPARATOR:
256     {
257       return "separator";
258     }
259     case Role::SLIDER:
260     {
261       return "slider";
262     }
263     case Role::SPIN_BUTTON:
264     {
265       return "spin button";
266     }
267     case Role::SPLIT_PANE:
268     {
269       return "split pane";
270     }
271     case Role::STATUS_BAR:
272     {
273       return "status bar";
274     }
275     case Role::TABLE:
276     {
277       return "table";
278     }
279     case Role::TABLE_CELL:
280     {
281       return "table cell";
282     }
283     case Role::TABLE_COLUMN_HEADER:
284     {
285       return "table column header";
286     }
287     case Role::TABLE_ROW_HEADER:
288     {
289       return "table row header";
290     }
291     case Role::TEAROFF_MENU_ITEM:
292     {
293       return "tearoff menu item";
294     }
295     case Role::TERMINAL:
296     {
297       return "terminal";
298     }
299     case Role::TEXT:
300     {
301       return "text";
302     }
303     case Role::TOGGLE_BUTTON:
304     {
305       return "toggle button";
306     }
307     case Role::TOOL_BAR:
308     {
309       return "tool bar";
310     }
311     case Role::TOOL_TIP:
312     {
313       return "tool tip";
314     }
315     case Role::TREE:
316     {
317       return "tree";
318     }
319     case Role::TREE_TABLE:
320     {
321       return "tree table";
322     }
323     case Role::UNKNOWN:
324     {
325       return "unknown";
326     }
327     case Role::VIEWPORT:
328     {
329       return "viewport";
330     }
331     case Role::WINDOW:
332     {
333       return "window";
334     }
335     case Role::EXTENDED:
336     {
337       return "extended";
338     }
339     case Role::HEADER:
340     {
341       return "header";
342     }
343     case Role::FOOTER:
344     {
345       return "footer";
346     }
347     case Role::PARAGRAPH:
348     {
349       return "paragraph";
350     }
351     case Role::RULER:
352     {
353       return "ruler";
354     }
355     case Role::APPLICATION:
356     {
357       return "application";
358     }
359     case Role::AUTOCOMPLETE:
360     {
361       return "autocomplete";
362     }
363     case Role::EDITBAR:
364     {
365       return "edit bar";
366     }
367     case Role::EMBEDDED:
368     {
369       return "embedded";
370     }
371     case Role::ENTRY:
372     {
373       return "entry";
374     }
375     case Role::CHART:
376     {
377       return "chart";
378     }
379     case Role::CAPTION:
380     {
381       return "caution";
382     }
383     case Role::DOCUMENT_FRAME:
384     {
385       return "document frame";
386     }
387     case Role::HEADING:
388     {
389       return "heading";
390     }
391     case Role::PAGE:
392     {
393       return "page";
394     }
395     case Role::SECTION:
396     {
397       return "section";
398     }
399     case Role::REDUNDANT_OBJECT:
400     {
401       return "redundant object";
402     }
403     case Role::FORM:
404     {
405       return "form";
406     }
407     case Role::LINK:
408     {
409       return "link";
410     }
411     case Role::INPUT_METHOD_WINDOW:
412     {
413       return "input method window";
414     }
415     case Role::TABLE_ROW:
416     {
417       return "table row";
418     }
419     case Role::TREE_ITEM:
420     {
421       return "tree item";
422     }
423     case Role::DOCUMENT_SPREADSHEET:
424     {
425       return "document spreadsheet";
426     }
427     case Role::DOCUMENT_PRESENTATION:
428     {
429       return "document presentation";
430     }
431     case Role::DOCUMENT_TEXT:
432     {
433       return "document text";
434     }
435     case Role::DOCUMENT_WEB:
436     {
437       return "document web";
438     }
439     case Role::DOCUMENT_EMAIL:
440     {
441       return "document email";
442     }
443     case Role::COMMENT:
444     {
445       return "comment";
446     }
447     case Role::LIST_BOX:
448     {
449       return "list box";
450     }
451     case Role::GROUPING:
452     {
453       return "grouping";
454     }
455     case Role::IMAGE_MAP:
456     {
457       return "image map";
458     }
459     case Role::NOTIFICATION:
460     {
461       return "notification";
462     }
463     case Role::INFO_BAR:
464     {
465       return "info bar";
466     }
467     case Role::LEVEL_BAR:
468     {
469       return "level bar";
470     }
471     case Role::TITLE_BAR:
472     {
473       return "title bar";
474     }
475     case Role::BLOCK_QUOTE:
476     {
477       return "block quote";
478     }
479     case Role::AUDIO:
480     {
481       return "audio";
482     }
483     case Role::VIDEO:
484     {
485       return "video";
486     }
487     case Role::DEFINITION:
488     {
489       return "definition";
490     }
491     case Role::ARTICLE:
492     {
493       return "article";
494     }
495     case Role::LANDMARK:
496     {
497       return "landmark";
498     }
499     case Role::LOG:
500     {
501       return "log";
502     }
503     case Role::MARQUEE:
504     {
505       return "marquee";
506     }
507     case Role::MATH:
508     {
509       return "math";
510     }
511     case Role::RATING:
512     {
513       return "rating";
514     }
515     case Role::TIMER:
516     {
517       return "timer";
518     }
519     case Role::STATIC:
520     {
521       return "static";
522     }
523     case Role::MATH_FRACTION:
524     {
525       return "math fraction";
526     }
527     case Role::MATH_ROOT:
528     {
529       return "math root";
530     }
531     case Role::SUBSCRIPT:
532     {
533       return "subscript";
534     }
535     case Role::SUPERSCRIPT:
536     {
537       return "superscript";
538     }
539     case Role::MAX_COUNT:
540     {
541       break;
542     }
543   }
544   return "";
545 }
546
547 Dali::Actor Accessible::GetCurrentlyHighlightedActor()
548 {
549   return IsUp() ? Bridge::GetCurrentBridge()->data->currentlyHighlightedActor : Dali::Actor{};
550 }
551
552 void Accessible::SetCurrentlyHighlightedActor(Dali::Actor actor)
553 {
554   if (IsUp())
555   {
556     Bridge::GetCurrentBridge()->data->currentlyHighlightedActor = actor;
557   }
558 }
559
560 Dali::Actor Accessible::GetHighlightActor()
561 {
562   return IsUp() ? Bridge::GetCurrentBridge()->data->highlightActor : Dali::Actor{};
563 }
564
565 void Accessible::SetHighlightActor(Dali::Actor actor)
566 {
567   if (IsUp())
568   {
569     Bridge::GetCurrentBridge()->data->highlightActor = actor;
570   }
571 }
572
573 void Bridge::ForceDown()
574 {
575   auto highlighted = Accessible::GetCurrentlyHighlightedActor();
576   if( highlighted )
577   {
578     auto p = dynamic_cast< Component* >( Accessible::Get( highlighted ) );
579     if( p )
580     {
581       p->ClearHighlight();
582     }
583   }
584   data = {};
585 }
586
587 void Bridge::SetIsOnRootLevel( Accessible* o )
588 {
589   o->isOnRootLevel = true;
590 }
591
592 namespace
593 {
594 class NonControlAccessible : public virtual Accessible, public virtual Collection, public virtual Component
595 {
596 public:
597   Dali::Actor actor;
598   bool root = false;
599
600   NonControlAccessible( Dali::Actor actor, bool root ) : actor( actor ), root( root )
601   {
602   }
603
604   Dali::Rect<> GetExtents( Dali::Accessibility::CoordType ctype ) override
605   {
606     Vector2 screenPosition = actor.GetProperty( Actor::Property::SCREEN_POSITION ).Get< Vector2 >();
607     Vector3 size = actor.GetCurrentProperty< Vector3 >( Actor::Property::SIZE ) * actor.GetCurrentProperty< Vector3 >( Actor::Property::WORLD_SCALE );
608     bool positionUsesAnchorPoint = actor.GetProperty( Actor::Property::POSITION_USES_ANCHOR_POINT ).Get< bool >();
609     Vector3 anchorPointOffSet = size * ( positionUsesAnchorPoint ? actor.GetCurrentProperty< Vector3 >( Actor::Property::ANCHOR_POINT ) : AnchorPoint::TOP_LEFT );
610     Vector2 position = Vector2( screenPosition.x - anchorPointOffSet.x, screenPosition.y - anchorPointOffSet.y );
611
612     return { position.x, position.y, size.x, size.y };
613   }
614   Dali::Accessibility::ComponentLayer GetLayer() override
615   {
616     return Dali::Accessibility::ComponentLayer::WINDOW;
617   }
618   int16_t GetMdiZOrder()
619   {
620     return 0;
621   }
622   double GetAlpha()
623   {
624     return 0;
625   }
626   bool GrabFocus() override
627   {
628     return false;
629   }
630   bool GrabHighlight() override
631   {
632     return false;
633   }
634   bool ClearHighlight() override
635   {
636     return false;
637   }
638   bool IsScrollable() override
639   {
640     return false;
641   }
642   std::string GetName() override
643   {
644     return actor.GetProperty< std::string >( Dali::Actor::Property::NAME );
645   }
646   std::string GetDescription() override
647   {
648     return "";
649   }
650   Accessible* GetParent() override
651   {
652     if( GetIsOnRootLevel() )
653     {
654       auto b = GetBridgeData();
655       return b->bridge->GetApplication();
656     }
657     return Get( actor.GetParent() );
658   }
659   size_t GetChildCount() override
660   {
661     return static_cast< size_t >( actor.GetChildCount() );
662   }
663   Accessible* GetChildAtIndex( size_t index ) override
664   {
665     auto s = static_cast< size_t >( actor.GetChildCount() );
666     if( index >= s )
667     {
668       throw std::domain_error{"invalid index " + std::to_string( index ) + " for object with " + std::to_string( s ) + " children"};
669     }
670     return Get( actor.GetChildAt( static_cast< unsigned int >( index ) ) );
671   }
672   size_t GetIndexInParent() override
673   {
674     auto parent = actor.GetParent();
675     if( !parent )
676     {
677       return 0;
678     }
679     auto size = static_cast< size_t >( parent.GetChildCount() );
680     for( auto i = 0u; i < size; ++i )
681     {
682       if( parent.GetChildAt( i ) == actor )
683       {
684         return i;
685       }
686     }
687     throw std::domain_error{"actor is not a child of it's parent"};
688   }
689   Role GetRole() override
690   {
691     return root ? Role::WINDOW : Role::REDUNDANT_OBJECT;
692   }
693   States GetStates() override
694   {
695     States s;
696     if( root )
697     {
698       s[State::HIGHLIGHTABLE] = true;
699       s[State::ENABLED] = true;
700       s[State::SENSITIVE] = true;
701       s[State::SHOWING] = true;
702       s[State::VISIBLE] = true;
703       s[State::ACTIVE] = true;
704     }
705     else
706     {
707       auto t = GetParent()->GetStates();
708       s[State::SHOWING] = t[State::SHOWING];
709       s[State::VISIBLE] = t[State::VISIBLE];
710     }
711     return s;
712   }
713   Attributes GetAttributes() override
714   {
715     Dali::TypeInfo type;
716     actor.GetTypeInfo( type );
717     return { {"t", type.GetName()}, };
718   }
719
720   bool DoGesture(const GestureInfo &gestureInfo) override
721   {
722     return false;
723   }
724
725   std::vector<Relation> GetRelationSet() override
726   {
727     return {};
728   }
729 };
730
731 using NonControlAccessiblesType = std::unordered_map< const Dali::RefObject*, std::unique_ptr< NonControlAccessible > >;
732
733 NonControlAccessiblesType nonControlAccessibles;
734
735 std::function< Accessible*( Dali::Actor ) > convertingFunctor = []( Dali::Actor ) -> Accessible*
736 {
737   return nullptr;
738 };
739
740 ObjectRegistry objectRegistry;
741 } // namespace
742
743 void Accessible::SetObjectRegistry(ObjectRegistry registry)
744 {
745   objectRegistry = registry;
746 }
747
748 void Accessible::RegisterControlAccessibilityGetter( std::function< Accessible*( Dali::Actor ) > functor )
749 {
750   convertingFunctor = functor;
751 }
752
753 Accessible* Accessible::Get( Dali::Actor actor, bool root )
754 {
755   if( !actor )
756   {
757     return nullptr;
758   }
759   auto accessible = convertingFunctor( actor );
760   if( !accessible )
761   {
762     if( nonControlAccessibles.empty() && objectRegistry )
763     {
764       objectRegistry.ObjectDestroyedSignal().Connect( []( const Dali::RefObject* obj )
765       {
766         nonControlAccessibles.erase( obj );
767       }
768       );
769     }
770     auto it = nonControlAccessibles.emplace( &actor.GetBaseObject(), nullptr );
771     if( it.second )
772     {
773       it.first->second.reset( new NonControlAccessible( actor, root ) );
774     }
775     accessible = it.first->second.get();
776   }
777   return accessible;
778 }