2 * Copyright 2019 Samsung Electronics Co., Ltd
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
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/common/stage.h>
24 #include <dali/public-api/object/base-object.h>
25 #include <dali/public-api/object/object-registry.h>
26 #include <dali/public-api/object/type-info.h>
27 #include <dali/public-api/object/type-registry-helper.h>
28 #include <dali/devel-api/actors/actor-devel.h>
31 #include <dali/public-api/dali-adaptor-common.h>
32 #include <dali/internal/accessibility/tizen-wayland/atspi/accessibility-impl.h>
34 using namespace Dali::Accessibility;
37 const std::string& Dali::Accessibility::Address::GetBus() const
39 return mBus.empty() && Bridge::GetCurrentBridge() ? Bridge::GetCurrentBridge()->GetBusName() : mBus;
42 std::string EmptyAccessibleWithAddress::GetRoleName()
47 std::string Accessible::GetLocalizedRoleName()
52 std::string Accessible::GetRoleName()
60 case Role::ACCELERATOR_LABEL:
62 return "accelerator label";
88 case Role::CHECK_MENU_ITEM:
90 return "check menu item";
92 case Role::COLOR_CHOOSER:
94 return "color chooser";
96 case Role::COLUMN_HEADER:
98 return "column header";
100 case Role::COMBO_BOX:
104 case Role::DATE_EDITOR:
106 return "date editor";
108 case Role::DESKTOP_ICON:
110 return "desktop icon";
112 case Role::DESKTOP_FRAME:
114 return "desktop frame";
124 case Role::DIRECTORY_PANE:
126 return "directory pane";
128 case Role::DRAWING_AREA:
130 return "drawing area";
132 case Role::FILE_CHOOSER:
134 return "file chooser";
140 case Role::FOCUS_TRAVERSABLE:
142 return "focus traversable";
144 case Role::FONT_CHOOSER:
146 return "font chooser";
152 case Role::GLASS_PANE:
156 case Role::HTML_CONTAINER:
158 return "html container";
168 case Role::INTERNAL_FRAME:
170 return "internal frame";
176 case Role::LAYERED_PANE:
178 return "layered pane";
184 case Role::LIST_ITEM:
196 case Role::MENU_ITEM:
200 case Role::OPTION_PANE:
202 return "option pane";
208 case Role::PAGE_TAB_LIST:
210 return "page tab list";
216 case Role::PASSWORD_TEXT:
218 return "password text";
220 case Role::POPUP_MENU:
224 case Role::PROGRESS_BAR:
226 return "progress bar";
228 case Role::PUSH_BUTTON:
230 return "push button";
232 case Role::RADIO_BUTTON:
234 return "radio button";
236 case Role::RADIO_MENU_ITEM:
238 return "radio menu item";
240 case Role::ROOT_PANE:
244 case Role::ROW_HEADER:
248 case Role::SCROLL_BAR:
252 case Role::SCROLL_PANE:
254 return "scroll pane";
256 case Role::SEPARATOR:
264 case Role::SPIN_BUTTON:
266 return "spin button";
268 case Role::SPLIT_PANE:
272 case Role::STATUS_BAR:
280 case Role::TABLE_CELL:
284 case Role::TABLE_COLUMN_HEADER:
286 return "table column header";
288 case Role::TABLE_ROW_HEADER:
290 return "table row header";
292 case Role::TEAROFF_MENU_ITEM:
294 return "tearoff menu item";
304 case Role::TOGGLE_BUTTON:
306 return "toggle button";
320 case Role::TREE_TABLE:
348 case Role::PARAGRAPH:
356 case Role::APPLICATION:
358 return "application";
360 case Role::AUTOCOMPLETE:
362 return "autocomplete";
384 case Role::DOCUMENT_FRAME:
386 return "document frame";
400 case Role::REDUNDANT_OBJECT:
402 return "redundant object";
412 case Role::INPUT_METHOD_WINDOW:
414 return "input method window";
416 case Role::TABLE_ROW:
420 case Role::TREE_ITEM:
424 case Role::DOCUMENT_SPREADSHEET:
426 return "document spreadsheet";
428 case Role::DOCUMENT_PRESENTATION:
430 return "document presentation";
432 case Role::DOCUMENT_TEXT:
434 return "document text";
436 case Role::DOCUMENT_WEB:
438 return "document web";
440 case Role::DOCUMENT_EMAIL:
442 return "document email";
456 case Role::IMAGE_MAP:
460 case Role::NOTIFICATION:
462 return "notification";
468 case Role::LEVEL_BAR:
472 case Role::TITLE_BAR:
476 case Role::BLOCK_QUOTE:
478 return "block quote";
488 case Role::DEFINITION:
524 case Role::MATH_FRACTION:
526 return "math fraction";
528 case Role::MATH_ROOT:
532 case Role::SUBSCRIPT:
536 case Role::SUPERSCRIPT:
538 return "superscript";
540 case Role::MAX_COUNT:
548 Dali::Actor Accessible::GetCurrentlyHighlightedActor()
550 return IsUp() ? Bridge::GetCurrentBridge()->data->currentlyHighlightedActor : Dali::Actor{};
553 void Accessible::SetCurrentlyHighlightedActor(Dali::Actor actor)
557 Bridge::GetCurrentBridge()->data->currentlyHighlightedActor = actor;
561 Dali::Actor Accessible::GetHighlightActor()
563 return IsUp() ? Bridge::GetCurrentBridge()->data->highlightActor : Dali::Actor{};
566 void Accessible::SetHighlightActor(Dali::Actor actor)
570 Bridge::GetCurrentBridge()->data->highlightActor = actor;
574 void Bridge::ForceDown()
576 auto highlighted = Accessible::GetCurrentlyHighlightedActor();
579 auto p = dynamic_cast< Component* >( Accessible::Get( highlighted ) );
588 void Bridge::SetIsOnRootLevel( Accessible* o )
590 o->isOnRootLevel = true;
595 class NonControlAccessible : public virtual Accessible, public virtual Collection, public virtual Component
601 NonControlAccessible( Dali::Actor actor, bool root ) : actor( actor ), root( root )
605 Dali::Rect<> GetExtents( Dali::Accessibility::CoordType ctype ) override
607 Vector2 screenPosition = actor.GetProperty( Dali::DevelActor::Property::SCREEN_POSITION ).Get< Vector2 >();
608 Vector3 size = actor.GetCurrentSize() * actor.GetCurrentWorldScale();
609 bool positionUsesAnchorPoint = actor.GetProperty( Dali::DevelActor::Property::POSITION_USES_ANCHOR_POINT ).Get< bool >();
610 Vector3 anchorPointOffSet = size * ( positionUsesAnchorPoint ? actor.GetCurrentAnchorPoint() : AnchorPoint::TOP_LEFT );
611 Vector2 position = Vector2( screenPosition.x - anchorPointOffSet.x, screenPosition.y - anchorPointOffSet.y );
613 return { position.x, position.y, size.x, size.y };
615 Dali::Accessibility::ComponentLayer GetLayer() override
617 return Dali::Accessibility::ComponentLayer::WINDOW;
619 int16_t GetMdiZOrder()
627 bool GrabFocus() override
631 bool GrabHighlight() override
635 bool ClearHighlight() override
639 int GetHighlightIndex() override
643 bool IsScrollable() override
647 std::string GetName() override
649 return actor.GetName();
651 std::string GetDescription() override
655 Accessible* GetParent() override
657 if( GetIsOnRootLevel() )
659 auto b = GetBridgeData();
660 return b->bridge->GetApplication();
662 return Get( actor.GetParent() );
664 size_t GetChildCount() override
666 return static_cast< size_t >( actor.GetChildCount() );
668 Accessible* GetChildAtIndex( size_t index ) override
670 auto s = static_cast< size_t >( actor.GetChildCount() );
673 throw std::domain_error{"invalid index " + std::to_string( index ) + " for object with " + std::to_string( s ) + " children"};
675 return Get( actor.GetChildAt( static_cast< unsigned int >( index ) ) );
677 size_t GetIndexInParent() override
679 auto parent = actor.GetParent();
684 auto size = static_cast< size_t >( parent.GetChildCount() );
685 for( auto i = 0u; i < size; ++i )
687 if( parent.GetChildAt( i ) == actor )
692 throw std::domain_error{"actor is not a child of it's parent"};
694 Role GetRole() override
696 return root ? Role::WINDOW : Role::REDUNDANT_OBJECT;
698 States GetStates() override
703 s[State::HIGHLIGHTABLE] = true;
704 s[State::ENABLED] = true;
705 s[State::SENSITIVE] = true;
706 s[State::SHOWING] = true;
707 s[State::VISIBLE] = true;
708 s[State::ACTIVE] = true;
712 auto t = GetParent()->GetStates();
713 s[State::SHOWING] = t[State::SHOWING];
714 s[State::VISIBLE] = t[State::VISIBLE];
718 Attributes GetAttributes() override
721 actor.GetTypeInfo( type );
722 return { {"t", type.GetName()}, };
725 bool DoGesture(const GestureInfo &gestureInfo) override
730 std::vector<Relation> GetRelationSet() override
736 using NonControlAccessiblesType = std::unordered_map< const Dali::RefObject*, std::unique_ptr< NonControlAccessible > >;
738 NonControlAccessiblesType nonControlAccessibles;
740 std::function< Accessible*( Dali::Actor ) > convertingFunctor = []( Dali::Actor ) -> Accessible*
747 void Accessible::RegisterControlAccessibilityGetter( std::function< Accessible*( Dali::Actor ) > functor )
749 convertingFunctor = functor;
752 Accessible* Accessible::Get( Dali::Actor actor, bool root )
758 auto accessible = convertingFunctor( actor );
761 if( nonControlAccessibles.empty() )
763 auto registry = Dali::Stage::GetCurrent().GetObjectRegistry();
764 registry.ObjectDestroyedSignal().Connect( []( const Dali::RefObject* obj )
766 nonControlAccessibles.erase( obj );
770 auto it = nonControlAccessibles.emplace( &actor.GetBaseObject(), nullptr );
773 it.first->second.reset( new NonControlAccessible( actor, root ) );
775 accessible = it.first->second.get();