| // Copyright 2014 The Flutter Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| |
| import 'package:flutter/foundation.dart'; |
| import 'package:flutter/painting.dart'; |
| |
| export 'dart:ui' show TextDirection; |
| |
| /// Determines the assertiveness level of the accessibility announcement. |
| /// |
| /// It is used by [AnnounceSemanticsEvent] to determine the priority with which |
| /// assistive technology should treat announcements. |
| enum Assertiveness { |
| /// The assistive technology will speak changes whenever the user is idle. |
| polite, |
| |
| /// The assistive technology will interrupt any announcement that it is |
| /// currently making to notify the user about the change. |
| /// |
| /// It should only be used for time-sensitive/critical notifications. |
| assertive, |
| } |
| |
| /// An event sent by the application to notify interested listeners that |
| /// something happened to the user interface (e.g. a view scrolled). |
| /// |
| /// These events are usually interpreted by assistive technologies to give the |
| /// user additional clues about the current state of the UI. |
| abstract class SemanticsEvent { |
| /// Initializes internal fields. |
| /// |
| /// [type] is a string that identifies this class of [SemanticsEvent]s. |
| const SemanticsEvent(this.type); |
| |
| /// The type of this event. |
| /// |
| /// The type is used by the engine to translate this event into the |
| /// appropriate native event (`UIAccessibility*Notification` on iOS and |
| /// `AccessibilityEvent` on Android). |
| final String type; |
| |
| /// Converts this event to a Map that can be encoded with |
| /// [StandardMessageCodec]. |
| /// |
| /// [nodeId] is the unique identifier of the semantics node associated with |
| /// the event, or null if the event is not associated with a semantics node. |
| Map<String, dynamic> toMap({ int? nodeId }) { |
| final Map<String, dynamic> event = <String, dynamic>{ |
| 'type': type, |
| 'data': getDataMap(), |
| }; |
| if (nodeId != null) { |
| event['nodeId'] = nodeId; |
| } |
| |
| return event; |
| } |
| |
| /// Returns the event's data object. |
| Map<String, dynamic> getDataMap(); |
| |
| @override |
| String toString() { |
| final List<String> pairs = <String>[]; |
| final Map<String, dynamic> dataMap = getDataMap(); |
| final List<String> sortedKeys = dataMap.keys.toList()..sort(); |
| for (final String key in sortedKeys) { |
| pairs.add('$key: ${dataMap[key]}'); |
| } |
| return '${objectRuntimeType(this, 'SemanticsEvent')}(${pairs.join(', ')})'; |
| } |
| } |
| |
| /// An event for a semantic announcement. |
| /// |
| /// This should be used for announcement that are not seamlessly announced by |
| /// the system as a result of a UI state change. |
| /// |
| /// For example a camera application can use this method to make accessibility |
| /// announcements regarding objects in the viewfinder. |
| /// |
| /// When possible, prefer using mechanisms like [Semantics] to implicitly |
| /// trigger announcements over using this event. |
| class AnnounceSemanticsEvent extends SemanticsEvent { |
| |
| /// Constructs an event that triggers an announcement by the platform. |
| const AnnounceSemanticsEvent(this.message, this.textDirection, {this.assertiveness = Assertiveness.polite}) |
| : assert(message != null), |
| assert(textDirection != null), |
| super('announce'); |
| |
| /// The message to announce. |
| /// |
| /// This property must not be null. |
| final String message; |
| |
| /// Text direction for [message]. |
| /// |
| /// This property must not be null. |
| final TextDirection textDirection; |
| |
| /// Determines whether the announcement should interrupt any existing announcement, |
| /// or queue after it. |
| /// |
| /// On the web this option uses the aria-live level to set the assertiveness |
| /// of the announcement. On iOS, Android, Windows, Linux, macOS, and Fuchsia |
| /// this option currently has no effect. |
| final Assertiveness assertiveness; |
| |
| @override |
| Map<String, dynamic> getDataMap() { |
| return <String, dynamic> { |
| 'message': message, |
| 'textDirection': textDirection.index, |
| if (assertiveness != Assertiveness.polite) |
| 'assertiveness': assertiveness.index, |
| }; |
| } |
| } |
| |
| /// An event for a semantic announcement of a tooltip. |
| /// |
| /// This is only used by Android to announce tooltip values. |
| class TooltipSemanticsEvent extends SemanticsEvent { |
| /// Constructs an event that triggers a tooltip announcement by the platform. |
| const TooltipSemanticsEvent(this.message) : super('tooltip'); |
| |
| /// The text content of the tooltip. |
| final String message; |
| |
| @override |
| Map<String, dynamic> getDataMap() { |
| return <String, dynamic>{ |
| 'message': message, |
| }; |
| } |
| } |
| |
| /// An event which triggers long press semantic feedback. |
| /// |
| /// Currently only honored on Android. Triggers a long-press specific sound |
| /// when TalkBack is enabled. |
| class LongPressSemanticsEvent extends SemanticsEvent { |
| /// Constructs an event that triggers a long-press semantic feedback by the platform. |
| const LongPressSemanticsEvent() : super('longPress'); |
| |
| @override |
| Map<String, dynamic> getDataMap() => const <String, dynamic>{}; |
| } |
| |
| /// An event which triggers tap semantic feedback. |
| /// |
| /// Currently only honored on Android. Triggers a tap specific sound when |
| /// TalkBack is enabled. |
| class TapSemanticEvent extends SemanticsEvent { |
| /// Constructs an event that triggers a long-press semantic feedback by the platform. |
| const TapSemanticEvent() : super('tap'); |
| |
| @override |
| Map<String, dynamic> getDataMap() => const <String, dynamic>{}; |
| } |