2 * Copyright 2020 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/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>
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>
33 using namespace Dali::Accessibility;
36 const std::string& Dali::Accessibility::Address::GetBus() const
38 return mBus.empty() && Bridge::GetCurrentBridge() ? Bridge::GetCurrentBridge()->GetBusName() : mBus;
41 std::string EmptyAccessibleWithAddress::GetRoleName()
46 std::string Accessible::GetLocalizedRoleName()
51 std::string Accessible::GetRoleName()
59 case Role::ACCELERATOR_LABEL:
61 return "accelerator label";
87 case Role::CHECK_MENU_ITEM:
89 return "check menu item";
91 case Role::COLOR_CHOOSER:
93 return "color chooser";
95 case Role::COLUMN_HEADER:
97 return "column header";
103 case Role::DATE_EDITOR:
105 return "date editor";
107 case Role::DESKTOP_ICON:
109 return "desktop icon";
111 case Role::DESKTOP_FRAME:
113 return "desktop frame";
123 case Role::DIRECTORY_PANE:
125 return "directory pane";
127 case Role::DRAWING_AREA:
129 return "drawing area";
131 case Role::FILE_CHOOSER:
133 return "file chooser";
139 case Role::FOCUS_TRAVERSABLE:
141 return "focus traversable";
143 case Role::FONT_CHOOSER:
145 return "font chooser";
151 case Role::GLASS_PANE:
155 case Role::HTML_CONTAINER:
157 return "html container";
167 case Role::INTERNAL_FRAME:
169 return "internal frame";
175 case Role::LAYERED_PANE:
177 return "layered pane";
183 case Role::LIST_ITEM:
195 case Role::MENU_ITEM:
199 case Role::OPTION_PANE:
201 return "option pane";
207 case Role::PAGE_TAB_LIST:
209 return "page tab list";
215 case Role::PASSWORD_TEXT:
217 return "password text";
219 case Role::POPUP_MENU:
223 case Role::PROGRESS_BAR:
225 return "progress bar";
227 case Role::PUSH_BUTTON:
229 return "push button";
231 case Role::RADIO_BUTTON:
233 return "radio button";
235 case Role::RADIO_MENU_ITEM:
237 return "radio menu item";
239 case Role::ROOT_PANE:
243 case Role::ROW_HEADER:
247 case Role::SCROLL_BAR:
251 case Role::SCROLL_PANE:
253 return "scroll pane";
255 case Role::SEPARATOR:
263 case Role::SPIN_BUTTON:
265 return "spin button";
267 case Role::SPLIT_PANE:
271 case Role::STATUS_BAR:
279 case Role::TABLE_CELL:
283 case Role::TABLE_COLUMN_HEADER:
285 return "table column header";
287 case Role::TABLE_ROW_HEADER:
289 return "table row header";
291 case Role::TEAROFF_MENU_ITEM:
293 return "tearoff menu item";
303 case Role::TOGGLE_BUTTON:
305 return "toggle button";
319 case Role::TREE_TABLE:
347 case Role::PARAGRAPH:
355 case Role::APPLICATION:
357 return "application";
359 case Role::AUTOCOMPLETE:
361 return "autocomplete";
383 case Role::DOCUMENT_FRAME:
385 return "document frame";
399 case Role::REDUNDANT_OBJECT:
401 return "redundant object";
411 case Role::INPUT_METHOD_WINDOW:
413 return "input method window";
415 case Role::TABLE_ROW:
419 case Role::TREE_ITEM:
423 case Role::DOCUMENT_SPREADSHEET:
425 return "document spreadsheet";
427 case Role::DOCUMENT_PRESENTATION:
429 return "document presentation";
431 case Role::DOCUMENT_TEXT:
433 return "document text";
435 case Role::DOCUMENT_WEB:
437 return "document web";
439 case Role::DOCUMENT_EMAIL:
441 return "document email";
455 case Role::IMAGE_MAP:
459 case Role::NOTIFICATION:
461 return "notification";
467 case Role::LEVEL_BAR:
471 case Role::TITLE_BAR:
475 case Role::BLOCK_QUOTE:
477 return "block quote";
487 case Role::DEFINITION:
523 case Role::MATH_FRACTION:
525 return "math fraction";
527 case Role::MATH_ROOT:
531 case Role::SUBSCRIPT:
535 case Role::SUPERSCRIPT:
537 return "superscript";
539 case Role::MAX_COUNT:
547 Dali::Actor Accessible::GetCurrentlyHighlightedActor()
549 return IsUp() ? Bridge::GetCurrentBridge()->data->currentlyHighlightedActor : Dali::Actor{};
552 void Accessible::SetCurrentlyHighlightedActor(Dali::Actor actor)
556 Bridge::GetCurrentBridge()->data->currentlyHighlightedActor = actor;
560 Dali::Actor Accessible::GetHighlightActor()
562 return IsUp() ? Bridge::GetCurrentBridge()->data->highlightActor : Dali::Actor{};
565 void Accessible::SetHighlightActor(Dali::Actor actor)
569 Bridge::GetCurrentBridge()->data->highlightActor = actor;
573 void Bridge::ForceDown()
575 auto highlighted = Accessible::GetCurrentlyHighlightedActor();
578 auto p = dynamic_cast< Component* >( Accessible::Get( highlighted ) );
587 void Bridge::SetIsOnRootLevel( Accessible* o )
589 o->isOnRootLevel = true;
594 class NonControlAccessible : public virtual Accessible, public virtual Collection, public virtual Component
600 NonControlAccessible( Dali::Actor actor, bool root ) : actor( actor ), root( root )
604 Dali::Rect<> GetExtents( Dali::Accessibility::CoordType ctype ) override
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 );
612 return { position.x, position.y, size.x, size.y };
614 Dali::Accessibility::ComponentLayer GetLayer() override
616 return Dali::Accessibility::ComponentLayer::WINDOW;
618 int16_t GetMdiZOrder()
626 bool GrabFocus() override
630 bool GrabHighlight() override
634 bool ClearHighlight() override
638 bool IsScrollable() override
642 std::string GetName() override
644 return actor.GetProperty< std::string >( Dali::Actor::Property::NAME );
646 std::string GetDescription() override
650 Accessible* GetParent() override
652 if( GetIsOnRootLevel() )
654 auto b = GetBridgeData();
655 return b->bridge->GetApplication();
657 return Get( actor.GetParent() );
659 size_t GetChildCount() override
661 return static_cast< size_t >( actor.GetChildCount() );
663 Accessible* GetChildAtIndex( size_t index ) override
665 auto s = static_cast< size_t >( actor.GetChildCount() );
668 throw std::domain_error{"invalid index " + std::to_string( index ) + " for object with " + std::to_string( s ) + " children"};
670 return Get( actor.GetChildAt( static_cast< unsigned int >( index ) ) );
672 size_t GetIndexInParent() override
674 auto parent = actor.GetParent();
679 auto size = static_cast< size_t >( parent.GetChildCount() );
680 for( auto i = 0u; i < size; ++i )
682 if( parent.GetChildAt( i ) == actor )
687 throw std::domain_error{"actor is not a child of it's parent"};
689 Role GetRole() override
691 return root ? Role::WINDOW : Role::REDUNDANT_OBJECT;
693 States GetStates() override
698 s[State::ENABLED] = true;
699 s[State::SENSITIVE] = true;
700 s[State::SHOWING] = true;
701 s[State::VISIBLE] = true;
702 s[State::ACTIVE] = true;
706 auto t = GetParent()->GetStates();
707 s[State::SHOWING] = t[State::SHOWING];
708 s[State::VISIBLE] = t[State::VISIBLE];
712 Attributes GetAttributes() override
715 actor.GetTypeInfo( type );
716 return { {"t", type.GetName()}, };
719 bool DoGesture(const GestureInfo &gestureInfo) override
724 std::vector<Relation> GetRelationSet() override
730 using NonControlAccessiblesType = std::unordered_map< const Dali::RefObject*, std::unique_ptr< NonControlAccessible > >;
732 NonControlAccessiblesType nonControlAccessibles;
734 std::function< Accessible*( Dali::Actor ) > convertingFunctor = []( Dali::Actor ) -> Accessible*
739 ObjectRegistry objectRegistry;
742 void Accessible::SetObjectRegistry(ObjectRegistry registry)
744 objectRegistry = registry;
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() && objectRegistry )
763 objectRegistry.ObjectDestroyedSignal().Connect( []( const Dali::RefObject* obj )
765 nonControlAccessibles.erase( obj );
769 auto it = nonControlAccessibles.emplace( &actor.GetBaseObject(), nullptr );
772 it.first->second.reset( new NonControlAccessible( actor, root ) );
774 accessible = it.first->second.get();