The JUCE cross-platform C++ framework, with DISTRHO/KXStudio specific changes
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

326 lines
13KB

  1. /*
  2. ==============================================================================
  3. This file is part of the JUCE library.
  4. Copyright (c) 2020 - Raw Material Software Limited
  5. JUCE is an open source library subject to commercial or open-source
  6. licensing.
  7. By using JUCE, you agree to the terms of both the JUCE 6 End-User License
  8. Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020).
  9. End User License Agreement: www.juce.com/juce-6-licence
  10. Privacy Policy: www.juce.com/juce-privacy-policy
  11. Or: You may also use this code under the terms of the GPL v3 (see
  12. www.gnu.org/licenses).
  13. JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
  14. EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
  15. DISCLAIMED.
  16. ==============================================================================
  17. */
  18. namespace juce
  19. {
  20. class AccessibilityNativeHandle;
  21. /** Base class for accessible Components.
  22. This class wraps a Component and provides methods that allow an accessibility client,
  23. such as VoiceOver on macOS, or Narrator on Windows, to control it.
  24. It handles hierarchical navigation, properties, state, and various interfaces.
  25. @tags{Accessibility}
  26. */
  27. class JUCE_API AccessibilityHandler
  28. {
  29. public:
  30. /** Utility struct which holds one or more accessibility interfaces.
  31. The main purpose of this class is to provide convenience constructors from each
  32. of the four types of accessibility interface.
  33. */
  34. struct JUCE_API Interfaces
  35. {
  36. Interfaces() = default;
  37. Interfaces (std::unique_ptr<AccessibilityValueInterface> ptr) : value (std::move (ptr)) {}
  38. Interfaces (std::unique_ptr<AccessibilityTextInterface> ptr) : text (std::move (ptr)) {}
  39. Interfaces (std::unique_ptr<AccessibilityTableInterface> ptr) : table (std::move (ptr)) {}
  40. Interfaces (std::unique_ptr<AccessibilityCellInterface> ptr) : cell (std::move (ptr)) {}
  41. Interfaces (std::unique_ptr<AccessibilityValueInterface> valueIn,
  42. std::unique_ptr<AccessibilityTextInterface> textIn,
  43. std::unique_ptr<AccessibilityTableInterface> tableIn,
  44. std::unique_ptr<AccessibilityCellInterface> cellIn)
  45. : value (std::move (valueIn)),
  46. text (std::move (textIn)),
  47. table (std::move (tableIn)),
  48. cell (std::move (cellIn))
  49. {
  50. }
  51. std::unique_ptr<AccessibilityValueInterface> value;
  52. std::unique_ptr<AccessibilityTextInterface> text;
  53. std::unique_ptr<AccessibilityTableInterface> table;
  54. std::unique_ptr<AccessibilityCellInterface> cell;
  55. };
  56. /** Constructor.
  57. This will create a AccessibilityHandler which wraps the provided Component and makes
  58. it visible to accessibility clients. You must also specify a role for the UI element
  59. from the `AccessibilityRole` list which best describes it.
  60. To enable users to interact with the UI element you should provide the set of supported
  61. actions and their associated callbacks via the `accessibilityActions` parameter.
  62. For UI elements that support more complex interaction the value, text, table, and cell
  63. interfaces should be implemented as required and passed as the final argument of this
  64. constructor. See the documentation of these classes for more information about the
  65. types of control they represent and which methods need to be implemented.
  66. */
  67. AccessibilityHandler (Component& componentToWrap,
  68. AccessibilityRole accessibilityRole,
  69. AccessibilityActions actions = {},
  70. Interfaces interfaces = {});
  71. /** Destructor. */
  72. virtual ~AccessibilityHandler();
  73. //==============================================================================
  74. /** Returns the Component that this handler represents. */
  75. const Component& getComponent() const noexcept { return component; }
  76. /** Returns the Component that this handler represents. */
  77. Component& getComponent() noexcept { return component; }
  78. //==============================================================================
  79. /** The type of UI element that this accessibility handler represents.
  80. @see AccessibilityRole
  81. */
  82. AccessibilityRole getRole() const noexcept { return role; }
  83. /** The title of the UI element.
  84. This will be read out by the system and should be concise, preferably matching
  85. the visible title of the UI element (if any). For example, this might be the
  86. text of a button or a simple label.
  87. The default implementation will call `Component::getTitle()`, but you can override
  88. this to return a different string if required.
  89. If neither a name nor a description is provided then the UI element may be
  90. ignored by accessibility clients.
  91. This must be a localised string.
  92. */
  93. virtual String getTitle() const { return component.getTitle(); }
  94. /** A short description of the UI element.
  95. This may be read out by the system. It should not include the type of the UI
  96. element and should ideally be a single word, for example "Open" for a button
  97. that opens a window.
  98. The default implementation will call `Component::getDescription()`, but you
  99. can override this to return a different string if required.
  100. If neither a name nor a description is provided then the UI element may be
  101. ignored by accessibility clients.
  102. This must be a localised string.
  103. */
  104. virtual String getDescription() const { return component.getDescription(); }
  105. /** Some help text for the UI element (if required).
  106. This may be read out by the system. This string functions in a similar way to
  107. a tooltip, for example "Click to open window." for a button which opens a window.
  108. The default implementation will call `Component::getHelpText()`, but you can
  109. override this to return a different string if required.
  110. This must be a localised string.
  111. */
  112. virtual String getHelp() const { return component.getHelpText(); }
  113. /** Returns the current state of the UI element.
  114. The default implementation of this method will set the focusable flag and, if
  115. this UI element is currently focused, will also set the focused flag.
  116. */
  117. virtual AccessibleState getCurrentState() const;
  118. /** Returns true if this UI element should be ignored by accessibility clients. */
  119. bool isIgnored() const;
  120. //==============================================================================
  121. /** Returns the set of actions that the UI element supports and the associated
  122. callbacks.
  123. */
  124. const AccessibilityActions& getActions() const noexcept;
  125. /** Returns the value interface for this UI element, or nullptr if it is not supported.
  126. @see AccessibilityValueInterface
  127. */
  128. AccessibilityValueInterface* getValueInterface() const;
  129. /** Returns the table interface for this UI element, or nullptr if it is not supported.
  130. @see AccessibilityTableInterface
  131. */
  132. AccessibilityTableInterface* getTableInterface() const;
  133. /** Returns the cell interface for this UI element, or nullptr if it is not supported.
  134. @see AccessibilityCellInterface
  135. */
  136. AccessibilityCellInterface* getCellInterface() const;
  137. /** Returns the text interface for this UI element, or nullptr if it is not supported.
  138. @see AccessibilityTextInterface
  139. */
  140. AccessibilityTextInterface* getTextInterface() const;
  141. //==============================================================================
  142. /** Returns the first unignored parent of this UI element in the accessibility hierarchy,
  143. or nullptr if this is a root element without a parent.
  144. */
  145. AccessibilityHandler* getParent() const;
  146. /** Returns the unignored children of this UI element in the accessibility hierarchy. */
  147. std::vector<AccessibilityHandler*> getChildren() const;
  148. /** Checks whether a given UI element is a child of this one in the accessibility
  149. hierarchy.
  150. */
  151. bool isParentOf (const AccessibilityHandler* possibleChild) const noexcept;
  152. /** Returns the deepest child of this UI element in the accessibility hierarchy that
  153. contains the given screen point, or nullptr if there is no child at this point.
  154. */
  155. AccessibilityHandler* getChildAt (Point<int> screenPoint);
  156. /** Returns the deepest UI element which currently has focus.
  157. This can be a child of this UI element or, if no child is focused,
  158. this element itself.
  159. Note that this can be different to the value of the Component with keyboard
  160. focus returned by Component::getCurrentlyFocusedComponent().
  161. @see hasFocus
  162. */
  163. AccessibilityHandler* getChildFocus();
  164. /** Returns true if this UI element has the focus.
  165. @param trueIfChildFocused if this is true, this method will also return true
  166. if any child of this UI element in the accessibility
  167. hierarchy has focus
  168. */
  169. bool hasFocus (bool trueIfChildFocused) const;
  170. /** Tries to give focus to this UI element.
  171. If the UI element is focusable, as indicated by AccessibleState::isFocusable(),
  172. this will perform its AccessibilityActionType::focus action, try to give keyboard
  173. focus to the Component it represents, and notify any listening accessibility
  174. clients that the current focus has changed.
  175. @see hasFocus, giveAwayFocus
  176. */
  177. void grabFocus();
  178. /** If this UI element or any of its children in the accessibility hierarchy currently
  179. have focus, this will defocus it.
  180. This will also give away the keyboard focus from the Component it represents, and
  181. notify any listening accessibility clients that the current focus has changed.
  182. @see hasFocus, grabFocus
  183. */
  184. void giveAwayFocus() const;
  185. //==============================================================================
  186. /** Used to send a notification to any observing accessibility clients that something
  187. has changed in the UI element.
  188. @see AccessibilityEvent
  189. */
  190. void notifyAccessibilityEvent (AccessibilityEvent event) const;
  191. /** A priority level that can help an accessibility client determine how to handle
  192. an announcement request.
  193. Exactly what this controls is platform-specific, but generally a low priority
  194. announcement will be read when the screen reader is free, whereas a high priority
  195. announcement will interrupt the current speech.
  196. */
  197. enum class AnnouncementPriority
  198. {
  199. low,
  200. medium,
  201. high
  202. };
  203. /** Posts an announcement to be made to the user.
  204. @param announcementString a localised string containing the announcement to be read out
  205. @param priority the appropriate priority level for the announcement
  206. */
  207. static void postAnnouncement (const String& announcementString, AnnouncementPriority priority);
  208. //==============================================================================
  209. /** @internal */
  210. AccessibilityNativeHandle* getNativeImplementation() const;
  211. /** @internal */
  212. std::type_index getTypeIndex() const { return typeIndex; }
  213. private:
  214. //==============================================================================
  215. friend class AccessibilityNativeHandle;
  216. //==============================================================================
  217. void grabFocusInternal (bool);
  218. void giveAwayFocusInternal() const;
  219. void takeFocus();
  220. static AccessibilityHandler* currentlyFocusedHandler;
  221. //==============================================================================
  222. Component& component;
  223. std::type_index typeIndex;
  224. const AccessibilityRole role;
  225. AccessibilityActions actions;
  226. Interfaces interfaces;
  227. //==============================================================================
  228. class AccessibilityNativeImpl;
  229. struct DestroyNativeImpl
  230. {
  231. void operator() (AccessibilityNativeImpl*) const noexcept;
  232. };
  233. static AccessibilityNativeImpl* createNativeImpl (AccessibilityHandler&);
  234. std::unique_ptr<AccessibilityNativeImpl, DestroyNativeImpl> nativeImpl;
  235. //==============================================================================
  236. JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (AccessibilityHandler)
  237. };
  238. } // namespace juce