1 #ifndef DALI_ACCESSIBILITY_DEVEL_H
2 #define DALI_ACCESSIBILITY_DEVEL_H
5 * Copyright (c) 2019 Samsung Electronics Co., Ltd.
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
11 * http://www.apache.org/licenses/LICENSE-2.0
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
22 #include <dali/public-api/actors/actor.h>
23 #include <dali/public-api/math/rect.h>
30 #include <unordered_map>
31 #include <unordered_set>
36 #include <dali/public-api/adaptor-framework/accessibility.h>
40 namespace Accessibility
50 * @brief Base class for different accessibility bridges
52 * Bridge is resposible for initializing and managing connection on accessibility bus.
53 * Accessibility clients will not get any information about UI without initialized and upraised bridge.
54 * Concrete implementation depends on the accessibility technology available on the platform.
56 * @note This class is singleton.
58 struct DALI_ADAPTOR_API Bridge
60 enum class ForceUpResult
69 virtual ~Bridge() = default;
72 * @brief Get bus name which bridge is initialized on
74 virtual const std::string& GetBusName() const = 0;
77 * @brief Registers top level window
79 * Hierarchy of objects visible for accessibility clients is based on tree-like
80 * structure created from Actors objects. This method allows to connect chosen
81 * object as direct ancestor of application and therefore make it visible for
82 * accessibility clients.
84 virtual void AddTopLevelWindow( Accessible* ) = 0;
87 * @brief Removes top level window
89 * Hierarchy of objects visible for accessibility clients is based on tree-like
90 * structure created from Actors objects. This method removes previously added
91 * window from visible accessibility objects.
93 virtual void RemoveTopLevelWindow( Accessible* ) = 0;
96 * @brief Adds popup window
98 * Hierarchy of objects visible for accessibility clients is based on tree-like
99 * structure created from Actors objects. This method adds new popup to the tree.
101 virtual void AddPopup( Accessible* ) = 0;
104 * @brief Removes popup window
106 * Hierarchy of objects visible for accessibility clients is based on tree-like
107 * structure created from Actors objects. This method removes previously added
110 virtual void RemovePopup( Accessible* ) = 0;
113 * @brief Set name of current application which will be visible on accessibility bus
115 virtual void SetApplicationName( std::string ) = 0;
118 * @brief Get object being root of accessibility tree
120 * @return handler to accessibility object
122 virtual Accessible* GetApplication() const = 0;
125 * @brief Find an object in accessibility tree
127 * @param[in] s path to object
129 * @return handler to accessibility object
131 virtual Accessible* FindByPath( const std::string& s) const = 0;
134 * @brief Show application on accessibility bus
136 virtual void ApplicationShown() = 0;
139 * @brief Hide application on accessibility bus
141 virtual void ApplicationHidden() = 0;
144 * @brief Initialize accessibility bus
146 virtual void Initialize() = 0;
149 * @brief Terminate accessibility bus
151 virtual void Terminate() = 0;
154 * @brief This method is called, when bridge is being activated.
156 virtual ForceUpResult ForceUp()
159 return ForceUpResult::ALREADY_UP;
160 data = std::make_shared< Data >();
162 return ForceUpResult::JUST_STARTED;
164 virtual void ForceDown();
165 bool IsUp() const { return bool(data); }
168 * @brief Emits caret-moved event on at-spi bus.
170 virtual void EmitCaretMoved( Accessible* obj, unsigned int cursorPosition ) = 0;
173 * @brief Emits active-descendant-changed event on at-spi bus.
175 virtual void EmitActiveDescendantChanged( Accessible* obj, Accessible *child ) = 0;
178 * @brief Emits text-changed event on at-spi bus.
180 virtual void EmitTextChanged( Accessible* obj, TextChangedState state, unsigned int position, unsigned int length, const std::string &content ) = 0;
183 * @brief Emits state-changed event on at-spi bus.
185 virtual void EmitStateChanged( Accessible* obj, State state, int val1, int val2 = 0 ) = 0;
188 * @brief Emits window event on at-spi bus.
190 virtual void Emit( Accessible* obj, WindowEvent we, unsigned int detail1 = 0 ) = 0;
193 * @brief Emits property-changed event on at-spi bus.
195 virtual void Emit( Accessible* obj, ObjectPropertyChangeEvent ev ) = 0;
198 * @brief Emits bounds-changed event on at-spi bus.
200 virtual void EmitBoundsChanged( Accessible* obj, Rect<> rect ) = 0;
203 * @brief Emits key event on at-spi bus.
205 * Screen-reader might receive this event and reply, that given keycode is consumed. In that case
206 * further processing of the keycode should be ignored.
208 virtual Consumed Emit( KeyEventType type, unsigned int keyCode, const std::string& keyName, unsigned int timeStamp, bool isText ) = 0;
211 * @brief Force accessibility client to read provided text.
213 * @note Text can be read only if accessibility client uses Text To Speach module
215 * @param[in] text string that should be read
216 * @param[in] discardable flag pointing if text can be discarded by subsequent reading request
217 * @param[in] callback function called every time the status of reading has changed, callback type
218 * specifies one parameter (of type std::string), which can be one of the following signals:
223 virtual void Say( const std::string& text, bool discardable, std::function<void(std::string)> callback ) = 0;
226 * @brief Force accessibility client to pause / resume.
228 * @param[in] pause true if you want to pause, false if you want to resume
230 virtual void PauseResume( bool pause ) = 0;
233 * @brief Returns instance of bridge singleton object.
235 static Bridge* GetCurrentBridge();
240 std::unordered_set< Accessible* > knownObjects;
242 Bridge* bridge = nullptr;
243 Actor highlightActor, currentlyHighlightedActor;
245 std::shared_ptr< Data > data;
246 friend class Accessible;
249 * @brief Registers accessible object to be known in bridge object
251 * Bridge must known about all currently alive accessible objects, as some requst
252 * might come and object will be identified by number id (it's memory address).
253 * To avoid memory corruption number id is checked against set of known objects.
255 void RegisterOnBridge( Accessible* );
258 * @brief Tells bridge, that given object is considered root (doesn't have any parents).
260 * All root objects will have the same parent - application object. Application object
261 * is controlled by bridge and private.
263 void SetIsOnRootLevel( Accessible* );
268 return Bridge::GetCurrentBridge()->IsUp();
272 * @brief Basic interface implemented by all accessibility objects
274 class DALI_IMPORT_API Accessible
279 Accessible( const Accessible& ) = delete;
280 Accessible( Accessible&& ) = delete;
282 Accessible& operator=( const Accessible& ) = delete;
283 Accessible& operator=( Accessible&& ) = delete;
286 virtual ~Accessible();
288 using utf8_t = unsigned char;
291 * @brief Calculaties word boundaries in given utf8 text.
293 * s and length represents source text pointer and it's length respectively. langauge represents
294 * language to use. Word boundaries are returned as non-zero values in table breaks, which
295 * must be of size at least length.
297 void FindWordSeparationsUtf8( const utf8_t *s, size_t length, const char *language, char *breaks );
300 * @brief Calculaties line boundaries in given utf8 text.
302 * s and length represents source text pointer and it's length respectively. langauge represents
303 * language to use. Line boundaries are returned as non-zero values in table breaks, which
304 * must be of size at least length.
306 void FindLineSeparationsUtf8( const utf8_t *s, size_t length, const char *language, char *breaks );
309 * @brief Helper function for emiting active-descendant-changed event
311 void EmitActiveDescendantChanged( Accessible* obj, Accessible *child );
314 * @brief Helper function for emiting state-changed event
316 void EmitStateChanged( State state, int newValue1, int newValue2 = 0 );
319 * @brief Helper function for emiting bounds-changed event
321 void EmitBoundsChanged( Rect<> rect );
324 * @brief Emit "showing" event.
325 * The method inform accessibility clients about "showing" state
327 * @param[in] showing flag pointing if object is showing
329 void EmitShowing( bool showing );
332 * @brief Emit "visible" event.
333 * The method inform accessibility clients about "visible" state
335 * @param[in] visible flag pointing if object is visible
337 void EmitVisible( bool visible );
340 * @brief Emit "highlighted" event.
341 * The method inform accessibility clients about "highlighted" state
343 * @param[in] set flag pointing if object is highlighted
345 void EmitHighlighted( bool set );
348 * @brief Emit "focused" event.
349 * The method inform accessibility clients about "focused" state
351 * @param[in] set flag pointing if object is focused
353 void EmitFocused( bool set );
356 * @brief Emit "text inserted" event
358 * @param[in] position caret position
359 * @param[in] length text length
360 * @param[in] content inserted text
362 void EmitTextInserted( unsigned int position, unsigned int length, const std::string &content );
365 * @brief Emit "text deleted" event
367 * @param[in] position caret position
368 * @param[in] length text length
369 * @param[in] content deleted text
371 void EmitTextDeleted( unsigned int position, unsigned int length, const std::string &content );
374 * @brief Emit "caret moved" event
376 * @param[in] cursorPosition new caret position
378 void EmitTextCaretMoved( unsigned int cursorPosition );
381 * @brief Emit "highlighted" event
383 * @param[in] we enumerated window event
384 * @param[in] detail1 additional parameter which interpretation depends on chosen event
386 void Emit( WindowEvent we, unsigned int detail1 = 0 );
388 void Emit( ObjectPropertyChangeEvent ev );
390 * @brief Get accessibility name
392 * @return string with name
394 virtual std::string GetName() = 0;
397 * @brief Get accessibility description
399 * @return string with description
401 virtual std::string GetDescription() = 0;
406 * @return handler to accessibility object
408 virtual Accessible* GetParent() = 0;
411 * @brief Get count of children
413 * @return unsigned integer value
415 virtual size_t GetChildCount() = 0;
418 * @brief Get collection with all children
420 * @return collection of accessibility objects
422 virtual std::vector< Accessible* > GetChildren();
425 * @brief Get nth child
427 * @return accessibility object
429 virtual Accessible* GetChildAtIndex( size_t index ) = 0;
432 * @brief Get index that current object has in its parent's children collection
434 * @return unsigned integer index
436 virtual size_t GetIndexInParent() = 0;
439 * @brief Get accessibility role
441 * @return Role enumeration
443 * @see Dali::Accessibility::Role
445 virtual Role GetRole() = 0;
448 * @brief Get name of accessibility role
450 * @return string with human readable role converted from enumeration
452 * @see Dali::Accessibility::Role
453 * @see Accessibility::Accessible::GetRole
455 virtual std::string GetRoleName();
458 * @brief Get localized name of accessibility role
460 * @return string with human readable role translated according to current
463 * @see Dali::Accessibility::Role
464 * @see Accessibility::Accessible::GetRole
465 * @see Accessibility::Accessible::GetRoleName
467 * @note translation is not supported in this version
469 virtual std::string GetLocalizedRoleName();
472 * @brief Get accessibility states
474 * @return collection of states
476 * @note States class is instatation of ArrayBitset template class
478 * @see Dali::Accessibility::State
479 * @see Dali::Accessibility::ArrayBitset
481 virtual States GetStates() = 0;
484 * @brief Get accessibility attributes
486 * @return map of attributes and their values
488 virtual Attributes GetAttributes() = 0;
490 //TODO probably shouldn't be public
491 virtual bool IsProxy();
494 * @brief Get unique address on accessibility bus
496 * @return class containing address
498 * @see Dali::Accessibility::Address
500 virtual Address GetAddress();
503 * @brief Get accessibility object, which is "default label" for this object
505 virtual Accessible* GetDefaultLabel();
508 * @brief Depute an object to perform provided gesture
510 * @param[in] gestureInfo structure describing the gesture
512 * @return true on success, false otherwise
514 * @see Dali::Accessibility::GestureInfo
516 virtual bool DoGesture(const GestureInfo &gestureInfo) = 0;
519 * @brief Re-emits selected states of an Accessibility Object
521 * @param[in] states chosen states to re-emit
522 * @param[in] doRecursive if true all children of the Accessibility Object will also re-emit the states
524 void NotifyAccessibilityStateChange( Dali::Accessibility::States states, bool doRecursive );
527 * @brief Get information about current object and all relations that connects
528 * it with other accessibility objects
530 * @return iterable collection of Relation objects
532 * @see Dali::Accessibility::Relation
534 virtual std::vector<Relation> GetRelationSet() = 0;
537 * @brief Get all implemented interfaces
539 * @return collection of strings with implemented interfaces
541 std::vector< std::string > GetInterfaces();
544 * @brief Check if object is on root level
546 bool GetIsOnRootLevel() const { return isOnRootLevel; }
549 * @brief The method registers functor resposible for converting Actor into Accessible
550 * @param functor returning Accessible handle from Actor object
552 static void RegisterControlAccessibilityGetter( std::function< Accessible*( Dali::Actor ) > functor);
555 * @brief Acquire Accessible object from Actor object
557 * @param[in] actor Actor object
558 * @param[in] root true, if it's top level object (window)
560 * @return handle to Accessible object
562 static Accessible* Get( Dali::Actor actor, bool root = false );
565 std::shared_ptr< Bridge::Data > GetBridgeData();
566 static Dali::Actor GetHighlightActor();
567 static void SetHighlightActor(Dali::Actor actor);
568 static Dali::Actor GetCurrentlyHighlightedActor();
569 static void SetCurrentlyHighlightedActor(Dali::Actor);
573 std::weak_ptr< Bridge::Data > bridgeData;
574 bool isOnRootLevel = false;
578 * @brief Interface enabling to perform provided actions
580 class DALI_IMPORT_API Action : public virtual Accessible
584 * @brief Get name of action with given index
586 * @param[in] index index of action
588 * @return string with name of action
590 virtual std::string GetActionName( size_t index ) = 0;
593 * @brief Get translated name of action with given index
595 * @param[in] index index of action
597 * @return string with name of action translated according to current translation domain
599 * @note translation is not supported in this version
601 virtual std::string GetLocalizedActionName( size_t index ) = 0;
604 * @brief Get description of action with given index
606 * @param[in] index index of action
608 * @return string with description of action
610 virtual std::string GetActionDescription( size_t index ) = 0;
613 * @brief Get key code binded to action with given index
615 * @param[in] index index of action
617 * @return string with key name
619 virtual std::string GetActionKeyBinding( size_t index ) = 0;
622 * @brief Get number of provided actions
624 * @return unsigned integer with number of actions
626 virtual size_t GetActionCount() = 0;
629 * @brief Perform an action with given index
631 * @param index index of action
633 * @return true on success, false otherwise
635 virtual bool DoAction( size_t index ) = 0;
638 * @brief Perform an action with given name
640 * @param name name of action
642 * @return true on success, false otherwise
644 virtual bool DoAction( const std::string& name ) = 0;
650 * @brief Interface enabling advanced quering of accessibility objects
652 * @note since all mathods can be implemented inside bridge,
653 * none methods have to be overrided
655 class DALI_IMPORT_API Collection : public virtual Accessible
661 * @brief Interface representing objects having screen coordinates
663 class DALI_IMPORT_API Component : public virtual Accessible
667 * @brief Get rectangle describing size
669 * @param[in] ctype enumeration with type of coordinate systems
671 * @return Rect<> object
675 virtual Rect<> GetExtents( CoordType ctype ) = 0;
678 * @brief Get layer current object is localized on
680 * @return enumeration pointing layer
682 * @see Dali::Accessibility::ComponentLayer
684 virtual ComponentLayer GetLayer() = 0;
687 * @brief Get value of z-order
689 * @return value of z-order
691 virtual int16_t GetMdiZOrder() = 0;
694 * @brief Set current object as "focused"
696 * @return true on success, false otherwise
698 virtual bool GrabFocus() = 0;
701 * @brief Get value of alpha channel
703 * @return alpha channel value in range [0.0, 1.0]
705 virtual double GetAlpha() = 0;
708 * @brief Set current object as "highlighted"
710 * The method assings "highlighted" state, simultaneously removing it
711 * from currently highlighted object.
713 * @return true on success, false otherwise
715 virtual bool GrabHighlight() = 0;
718 * @brief Set current object as "unhighlighted"
720 * The method removes "highlighted" state from object.
722 * @return true on success, false otherwise
724 * @see Dali:Accessibility::State
726 virtual bool ClearHighlight() = 0;
729 virtual int GetHighlightIndex() = 0;
732 * @brief Check whether object can be scrolled
734 * @return true if object is scrollable, false otherwise
736 * @see Dali:Accessibility::State
738 virtual bool IsScrollable();
741 * @brief Get Accessible object containing given point
743 * @param[in] p two-dimensional point
744 * @param[in] ctype enumeration with type of coordinate system
746 * @return handle to last child of current object which contains given point
748 * @see Dali::Accessibility::Point
750 virtual Accessible* GetAccessibleAtPoint( Point p, CoordType ctype );
753 * @brief Check if current object contains given point
755 * @param[in] p two-dimensional point
756 * @param[in] ctype enumeration with type of coordinate system
758 * @return handle to Accessible object
760 * @see Dali::Accessibility::Point
762 virtual bool Contains( Point p, CoordType ctype );
766 * @brief Interface representing objects which can store numeric value
768 class DALI_IMPORT_API Value : public virtual Accessible
772 * @brief Get the lowest possible value
774 * @return double value
776 virtual double GetMinimum() = 0;
779 * @brief Get current value
781 * @return double value
783 virtual double GetCurrent() = 0;
786 * @brief Get the highest possible value
788 * @return double value
790 virtual double GetMaximum() = 0;
795 * @param[in] val double value
797 * @return true if value could have been assigned, false otherwise
799 virtual bool SetCurrent( double val) = 0;
802 * @brief Get the lowest increment that can be distinguished
804 * @return double value
806 virtual double GetMinimumIncrement() = 0;
810 * @brief Interface representing objects which can store immutable texts
812 * @see Dali::Accessibility::EditableText
814 class DALI_IMPORT_API Text : public virtual Accessible
818 * @brief Get stored text in given range
820 * @param[in] startOffset index of first character
821 * @param[in] endOffset index of first character after the last one expected
823 * @return substring of stored text
825 virtual std::string GetText( size_t startOffset, size_t endOffset ) = 0;
828 * @brief Get number of all stored characters
830 * @return number of characters
832 virtual size_t GetCharacterCount() = 0;
834 virtual size_t GetCaretOffset() = 0;
835 virtual bool SetCaretOffset(size_t offset) = 0;
838 * @brief Get substring of stored text truncated in concrete gradation
840 * @param[in] offset position in stored text
841 * @param[in] boundary enumeration describing text gradation
843 * @return Range structure containing acquired text and offsets in original string
845 * @see Dali::Accessibility::Range
847 virtual Range GetTextAtOffset( size_t offset, TextBoundary boundary ) = 0;
850 * @brief Get selected text
852 * @param[in] selectionNum selection index
853 * @note Currently only one selection (i.e. with index = 0) is supported
855 * @return Range structure containing acquired text and offsets in original string
857 * @see Dali::Accessibility::Range
859 virtual Range GetSelection( size_t selectionNum ) = 0;
862 * @brief Remove selection
864 * @param[in] selectionNum selection index
865 * @note Currently only one selection (i.e. with index = 0) is supported
867 * @return bool on success, false otherwise
869 virtual bool RemoveSelection( size_t selectionNum ) = 0;
872 * @brief Get selected text
874 * @param[in] selectionNum selection index
875 * @param[in] startOffset index of first character
876 * @param[in] endOffset index of first character after the last one expected
878 * @note Currently only one selection (i.e. with index = 0) is supported
880 * @return true on success, false otherwise
882 virtual bool SetSelection( size_t selectionNum, size_t startOffset, size_t endOffset ) = 0;
886 * @brief Interface representing objects which can store editable texts
888 * @note Paste method is entirely implemented inside bridge
890 * @see Dali::Accessibility::EditableText
892 class DALI_IMPORT_API EditableText : public virtual Accessible
896 * @brief Copy text in range to system clipboard
898 * @param[in] startPosition index of first character
899 * @param[in] endPosition index of first character after the last one expected
901 * @return true on success, false otherwise
903 virtual bool CopyText( size_t startPosition, size_t endPosition ) = 0;
906 * @brief Cut text in range to system clipboard
908 * @param[in] startPosition index of first character
909 * @param[in] endPosition index of first character after the last one expected
911 * @return true on success, false otherwise
913 virtual bool CutText( size_t startPosition, size_t endPosition ) = 0;
917 * @brief minimalistic, always empty Accessible object with settable address
919 * For those situations, where you want to return address in different bridge
920 * (embedding for example), but the object itself ain't planned to be used otherwise.
921 * This object has null parent, no children, empty name and so on
923 class DALI_IMPORT_API EmptyAccessibleWithAddress : public virtual Accessible
926 EmptyAccessibleWithAddress() = default;
927 EmptyAccessibleWithAddress( Address address ) : address( std::move( address ) ) {}
929 void SetAddress( Address address ) { this->address = std::move( address ); }
931 std::string GetName() override { return ""; }
932 std::string GetDescription() override { return ""; }
933 Accessible* GetParent() override { return nullptr; }
934 size_t GetChildCount() override { return 0; }
935 std::vector< Accessible* > GetChildren() override { return {}; }
936 Accessible* GetChildAtIndex( size_t index ) override
938 throw std::domain_error{"out of bounds index (" + std::to_string( index ) + ") - no children"};
940 size_t GetIndexInParent() override { return static_cast< size_t >( -1 ); }
941 Role GetRole() override { return {}; }
942 std::string GetRoleName() override;
943 States GetStates() override { return {}; }
944 Attributes GetAttributes() override { return {}; }
945 Address GetAddress() override
949 bool DoGesture(const GestureInfo &gestureInfo) override
953 std::vector<Relation> GetRelationSet() override
965 #endif // DALI_ACCESSIBILITY_DEVEL_H