Support value announcement for increase/decrease (#12741)
* Support value announcment for increase/decrease * ++ * review comments about docs
This commit is contained in:
parent
e1174eb0f2
commit
9184dfba14
@ -3177,6 +3177,8 @@ class RenderSemanticsAnnotations extends RenderProxyBox {
|
|||||||
bool button,
|
bool button,
|
||||||
String label,
|
String label,
|
||||||
String value,
|
String value,
|
||||||
|
String increasedValue,
|
||||||
|
String decreasedValue,
|
||||||
String hint,
|
String hint,
|
||||||
TextDirection textDirection,
|
TextDirection textDirection,
|
||||||
VoidCallback onTap,
|
VoidCallback onTap,
|
||||||
@ -3195,6 +3197,8 @@ class RenderSemanticsAnnotations extends RenderProxyBox {
|
|||||||
_button = button,
|
_button = button,
|
||||||
_label = label,
|
_label = label,
|
||||||
_value = value,
|
_value = value,
|
||||||
|
_increasedValue = increasedValue,
|
||||||
|
_decreasedValue = decreasedValue,
|
||||||
_hint = hint,
|
_hint = hint,
|
||||||
_textDirection = textDirection,
|
_textDirection = textDirection,
|
||||||
_onTap = onTap,
|
_onTap = onTap,
|
||||||
@ -3283,7 +3287,7 @@ class RenderSemanticsAnnotations extends RenderProxyBox {
|
|||||||
|
|
||||||
/// If non-null, sets the [SemanticsNode.label] semantic to the given value.
|
/// If non-null, sets the [SemanticsNode.label] semantic to the given value.
|
||||||
///
|
///
|
||||||
/// The text's reading direction is given by [textDirection].
|
/// The reading direction is given by [textDirection].
|
||||||
String get label => _label;
|
String get label => _label;
|
||||||
String _label;
|
String _label;
|
||||||
set label(String value) {
|
set label(String value) {
|
||||||
@ -3296,7 +3300,7 @@ class RenderSemanticsAnnotations extends RenderProxyBox {
|
|||||||
|
|
||||||
/// If non-null, sets the [SemanticsNode.value] semantic to the given value.
|
/// If non-null, sets the [SemanticsNode.value] semantic to the given value.
|
||||||
///
|
///
|
||||||
/// The text's reading direction is given by [textDirection].
|
/// The reading direction is given by [textDirection].
|
||||||
String get value => _value;
|
String get value => _value;
|
||||||
String _value;
|
String _value;
|
||||||
set value(String value) {
|
set value(String value) {
|
||||||
@ -3307,9 +3311,37 @@ class RenderSemanticsAnnotations extends RenderProxyBox {
|
|||||||
markNeedsSemanticsUpdate(onlyLocalUpdates: (value != null) == hadValue);
|
markNeedsSemanticsUpdate(onlyLocalUpdates: (value != null) == hadValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// If non-null, sets the [SemanticsNode.increasedValue] semantic to the given
|
||||||
|
/// value.
|
||||||
|
///
|
||||||
|
/// The reading direction is given by [textDirection].
|
||||||
|
String get increasedValue => _increasedValue;
|
||||||
|
String _increasedValue;
|
||||||
|
set increasedValue(String value) {
|
||||||
|
if (_increasedValue == value)
|
||||||
|
return;
|
||||||
|
final bool hadValue = _increasedValue != null;
|
||||||
|
_increasedValue = value;
|
||||||
|
markNeedsSemanticsUpdate(onlyLocalUpdates: (value != null) == hadValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// If non-null, sets the [SemanticsNode.decreasedValue] semantic to the given
|
||||||
|
/// value.
|
||||||
|
///
|
||||||
|
/// The reading direction is given by [textDirection].
|
||||||
|
String get decreasedValue => _decreasedValue;
|
||||||
|
String _decreasedValue;
|
||||||
|
set decreasedValue(String value) {
|
||||||
|
if (_decreasedValue == value)
|
||||||
|
return;
|
||||||
|
final bool hadValue = _decreasedValue != null;
|
||||||
|
_decreasedValue = value;
|
||||||
|
markNeedsSemanticsUpdate(onlyLocalUpdates: (value != null) == hadValue);
|
||||||
|
}
|
||||||
|
|
||||||
/// If non-null, sets the [SemanticsNode.hint] semantic to the given value.
|
/// If non-null, sets the [SemanticsNode.hint] semantic to the given value.
|
||||||
///
|
///
|
||||||
/// The text's reading direction is given by [textDirection].
|
/// The reading direction is given by [textDirection].
|
||||||
String get hint => _hint;
|
String get hint => _hint;
|
||||||
String _hint;
|
String _hint;
|
||||||
set hint(String value) {
|
set hint(String value) {
|
||||||
@ -3322,7 +3354,8 @@ class RenderSemanticsAnnotations extends RenderProxyBox {
|
|||||||
|
|
||||||
/// If non-null, sets the [SemanticsNode.textDirection] semantic to the given value.
|
/// If non-null, sets the [SemanticsNode.textDirection] semantic to the given value.
|
||||||
///
|
///
|
||||||
/// This must not be null if [label], [hint], or [value] is not null.
|
/// This must not be null if [label], [hint], [value], [increasedValue], or
|
||||||
|
/// [decreasedValue] are not null.
|
||||||
TextDirection get textDirection => _textDirection;
|
TextDirection get textDirection => _textDirection;
|
||||||
TextDirection _textDirection;
|
TextDirection _textDirection;
|
||||||
set textDirection(TextDirection value) {
|
set textDirection(TextDirection value) {
|
||||||
@ -3499,6 +3532,15 @@ class RenderSemanticsAnnotations extends RenderProxyBox {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
void describeSemanticsConfiguration(SemanticsConfiguration config) {
|
void describeSemanticsConfiguration(SemanticsConfiguration config) {
|
||||||
|
assert(
|
||||||
|
onIncrease == null || (value == null) == (increasedValue == null),
|
||||||
|
'If "onIncrease" is set either both "value" and "increasedValue" or neither have to be set.',
|
||||||
|
);
|
||||||
|
assert(
|
||||||
|
onDecrease == null || (value == null) == (decreasedValue == null),
|
||||||
|
'If "onDecrease" is set either both "value" and "decreasedValue" or neither have to be set.',
|
||||||
|
);
|
||||||
|
|
||||||
config.isSemanticBoundary = container;
|
config.isSemanticBoundary = container;
|
||||||
config.explicitChildNodes = explicitChildNodes;
|
config.explicitChildNodes = explicitChildNodes;
|
||||||
|
|
||||||
@ -3512,6 +3554,10 @@ class RenderSemanticsAnnotations extends RenderProxyBox {
|
|||||||
config.label = label;
|
config.label = label;
|
||||||
if (value != null)
|
if (value != null)
|
||||||
config.value = value;
|
config.value = value;
|
||||||
|
if (increasedValue != null)
|
||||||
|
config.increasedValue = increasedValue;
|
||||||
|
if (decreasedValue != null)
|
||||||
|
config.decreasedValue = decreasedValue;
|
||||||
if (hint != null)
|
if (hint != null)
|
||||||
config.hint = hint;
|
config.hint = hint;
|
||||||
if (textDirection != null)
|
if (textDirection != null)
|
||||||
|
@ -76,7 +76,9 @@ class SemanticsData extends Diagnosticable {
|
|||||||
@required this.flags,
|
@required this.flags,
|
||||||
@required this.actions,
|
@required this.actions,
|
||||||
@required this.label,
|
@required this.label,
|
||||||
|
@required this.increasedValue,
|
||||||
@required this.value,
|
@required this.value,
|
||||||
|
@required this.decreasedValue,
|
||||||
@required this.hint,
|
@required this.hint,
|
||||||
@required this.textDirection,
|
@required this.textDirection,
|
||||||
@required this.rect,
|
@required this.rect,
|
||||||
@ -85,7 +87,15 @@ class SemanticsData extends Diagnosticable {
|
|||||||
}) : assert(flags != null),
|
}) : assert(flags != null),
|
||||||
assert(actions != null),
|
assert(actions != null),
|
||||||
assert(label != null),
|
assert(label != null),
|
||||||
|
assert(value != null),
|
||||||
|
assert(decreasedValue != null),
|
||||||
|
assert(increasedValue != null),
|
||||||
|
assert(hint != null),
|
||||||
assert(label == '' || textDirection != null, 'A SemanticsData object with label "$label" had a null textDirection.'),
|
assert(label == '' || textDirection != null, 'A SemanticsData object with label "$label" had a null textDirection.'),
|
||||||
|
assert(value == '' || textDirection != null, 'A SemanticsData object with value "$value" had a null textDirection.'),
|
||||||
|
assert(hint == '' || textDirection != null, 'A SemanticsData object with hint "$hint" had a null textDirection.'),
|
||||||
|
assert(decreasedValue == '' || textDirection != null, 'A SemanticsData object with decreasedValue "$decreasedValue" had a null textDirection.'),
|
||||||
|
assert(increasedValue == '' || textDirection != null, 'A SemanticsData object with increasedValue "$increasedValue" had a null textDirection.'),
|
||||||
assert(rect != null);
|
assert(rect != null);
|
||||||
|
|
||||||
/// A bit field of [SemanticsFlags] that apply to this node.
|
/// A bit field of [SemanticsFlags] that apply to this node.
|
||||||
@ -96,20 +106,33 @@ class SemanticsData extends Diagnosticable {
|
|||||||
|
|
||||||
/// A textual description of this node.
|
/// A textual description of this node.
|
||||||
///
|
///
|
||||||
/// The text's reading direction is given by [textDirection].
|
/// The reading direction is given by [textDirection].
|
||||||
final String label;
|
final String label;
|
||||||
|
|
||||||
/// A textual description for the current value of the node.
|
/// A textual description for the current value of the node.
|
||||||
///
|
///
|
||||||
/// The text's reading direction is given by [textDirection].
|
/// The reading direction is given by [textDirection].
|
||||||
final String value;
|
final String value;
|
||||||
|
|
||||||
|
/// The value that [value] will become after performing a
|
||||||
|
/// [SemanticsAction.increase] action.
|
||||||
|
///
|
||||||
|
/// The reading direction is given by [textDirection].
|
||||||
|
final String increasedValue;
|
||||||
|
|
||||||
|
/// The value that [value] will become after performing a
|
||||||
|
/// [SemanticsAction.decrease] action.
|
||||||
|
///
|
||||||
|
/// The reading direction is given by [textDirection].
|
||||||
|
final String decreasedValue;
|
||||||
|
|
||||||
/// A brief description of the result of performing an action on this node.
|
/// A brief description of the result of performing an action on this node.
|
||||||
///
|
///
|
||||||
/// The text's reading direction is given by [textDirection].
|
/// The reading direction is given by [textDirection].
|
||||||
final String hint;
|
final String hint;
|
||||||
|
|
||||||
/// The reading direction for the text in [label], [value], and [hint].
|
/// The reading direction for the text in [label], [value], [hint],
|
||||||
|
/// [increasedValue], and [decreasedValue].
|
||||||
final TextDirection textDirection;
|
final TextDirection textDirection;
|
||||||
|
|
||||||
/// The bounding box for this node in its coordinate system.
|
/// The bounding box for this node in its coordinate system.
|
||||||
@ -153,6 +176,10 @@ class SemanticsData extends Diagnosticable {
|
|||||||
}
|
}
|
||||||
properties.add(new IterableProperty<String>('flags', flagSummary, ifEmpty: null));
|
properties.add(new IterableProperty<String>('flags', flagSummary, ifEmpty: null));
|
||||||
properties.add(new StringProperty('label', label, defaultValue: ''));
|
properties.add(new StringProperty('label', label, defaultValue: ''));
|
||||||
|
properties.add(new StringProperty('value', value, defaultValue: ''));
|
||||||
|
properties.add(new StringProperty('increasedValue', increasedValue, defaultValue: ''));
|
||||||
|
properties.add(new StringProperty('decreasedValue', decreasedValue, defaultValue: ''));
|
||||||
|
properties.add(new StringProperty('hint', hint, defaultValue: ''));
|
||||||
properties.add(new EnumProperty<TextDirection>('textDirection', textDirection, defaultValue: null));
|
properties.add(new EnumProperty<TextDirection>('textDirection', textDirection, defaultValue: null));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -495,7 +522,9 @@ class SemanticsNode extends AbstractNode with DiagnosticableTreeMixin {
|
|||||||
bool _isDifferentFromCurrentSemanticAnnotation(SemanticsConfiguration config) {
|
bool _isDifferentFromCurrentSemanticAnnotation(SemanticsConfiguration config) {
|
||||||
return _label != config.label ||
|
return _label != config.label ||
|
||||||
_hint != config.hint ||
|
_hint != config.hint ||
|
||||||
|
_decreasedValue != config.decreasedValue ||
|
||||||
_value != config.value ||
|
_value != config.value ||
|
||||||
|
_increasedValue != config.increasedValue ||
|
||||||
_flags != config._flags ||
|
_flags != config._flags ||
|
||||||
_textDirection != config.textDirection ||
|
_textDirection != config.textDirection ||
|
||||||
_actionsAsBits != config._actionsAsBits ||
|
_actionsAsBits != config._actionsAsBits ||
|
||||||
@ -523,23 +552,44 @@ class SemanticsNode extends AbstractNode with DiagnosticableTreeMixin {
|
|||||||
|
|
||||||
/// A textual description of this node.
|
/// A textual description of this node.
|
||||||
///
|
///
|
||||||
/// The text's reading direction is given by [textDirection].
|
/// The reading direction is given by [textDirection].
|
||||||
String get label => _label;
|
String get label => _label;
|
||||||
String _label = _kEmptyConfig.label;
|
String _label = _kEmptyConfig.label;
|
||||||
|
|
||||||
/// A textual description for the current value of the node.
|
/// A textual description for the current value of the node.
|
||||||
///
|
///
|
||||||
/// The text's reading direction is given by [textDirection].
|
/// The reading direction is given by [textDirection].
|
||||||
String get value => _value;
|
String get value => _value;
|
||||||
String _value = _kEmptyConfig.value;
|
String _value = _kEmptyConfig.value;
|
||||||
|
|
||||||
|
/// The value that [value] will have after a [SemanticsAction.decrease] action
|
||||||
|
/// has been performed.
|
||||||
|
///
|
||||||
|
/// This property is only valid if the [SemanticsAction.decrease] action is
|
||||||
|
/// available on this node.
|
||||||
|
///
|
||||||
|
/// The reading direction is given by [textDirection].
|
||||||
|
String get decreasedValue => _decreasedValue;
|
||||||
|
String _decreasedValue = _kEmptyConfig.decreasedValue;
|
||||||
|
|
||||||
|
/// The value that [value] will have after a [SemanticsAction.increase] action
|
||||||
|
/// has been performed.
|
||||||
|
///
|
||||||
|
/// This property is only valid if the [SemanticsAction.increase] action is
|
||||||
|
/// available on this node.
|
||||||
|
///
|
||||||
|
/// The reading direction is given by [textDirection].
|
||||||
|
String get increasedValue => _increasedValue;
|
||||||
|
String _increasedValue = _kEmptyConfig.increasedValue;
|
||||||
|
|
||||||
/// A brief description of the result of performing an action on this node.
|
/// A brief description of the result of performing an action on this node.
|
||||||
///
|
///
|
||||||
/// The text's reading direction is given by [textDirection].
|
/// The reading direction is given by [textDirection].
|
||||||
String get hint => _hint;
|
String get hint => _hint;
|
||||||
String _hint = _kEmptyConfig.hint;
|
String _hint = _kEmptyConfig.hint;
|
||||||
|
|
||||||
/// The reading direction for [label], [value], and [hint].
|
/// The reading direction for [label], [value], [hint], [increasedValue], and
|
||||||
|
/// [decreasedValue].
|
||||||
TextDirection get textDirection => _textDirection;
|
TextDirection get textDirection => _textDirection;
|
||||||
TextDirection _textDirection = _kEmptyConfig.textDirection;
|
TextDirection _textDirection = _kEmptyConfig.textDirection;
|
||||||
|
|
||||||
@ -556,7 +606,9 @@ class SemanticsNode extends AbstractNode with DiagnosticableTreeMixin {
|
|||||||
_markDirty();
|
_markDirty();
|
||||||
|
|
||||||
_label = config.label;
|
_label = config.label;
|
||||||
|
_decreasedValue = config.decreasedValue;
|
||||||
_value = config.value;
|
_value = config.value;
|
||||||
|
_increasedValue = config.increasedValue;
|
||||||
_hint = config.hint;
|
_hint = config.hint;
|
||||||
_flags = config._flags;
|
_flags = config._flags;
|
||||||
_textDirection = config.textDirection;
|
_textDirection = config.textDirection;
|
||||||
@ -564,6 +616,15 @@ class SemanticsNode extends AbstractNode with DiagnosticableTreeMixin {
|
|||||||
_actionsAsBits = config._actionsAsBits;
|
_actionsAsBits = config._actionsAsBits;
|
||||||
_mergeAllDescendantsIntoThisNode = config.isMergingSemanticsOfDescendants;
|
_mergeAllDescendantsIntoThisNode = config.isMergingSemanticsOfDescendants;
|
||||||
_replaceChildren(childrenInInversePaintOrder ?? const <SemanticsNode>[]);
|
_replaceChildren(childrenInInversePaintOrder ?? const <SemanticsNode>[]);
|
||||||
|
|
||||||
|
assert(
|
||||||
|
!_canPerformAction(SemanticsAction.increase) || (_value == '') == (_increasedValue == ''),
|
||||||
|
'A SemanticsNode with action "increase" needs to be annotated with either both "value" and "increasedValue" or neither',
|
||||||
|
);
|
||||||
|
assert(
|
||||||
|
!_canPerformAction(SemanticsAction.decrease) || (_value == '') == (_decreasedValue == ''),
|
||||||
|
'A SemanticsNode with action "increase" needs to be annotated with either both "value" and "decreasedValue" or neither',
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -578,6 +639,8 @@ class SemanticsNode extends AbstractNode with DiagnosticableTreeMixin {
|
|||||||
String label = _label;
|
String label = _label;
|
||||||
String hint = _hint;
|
String hint = _hint;
|
||||||
String value = _value;
|
String value = _value;
|
||||||
|
String increasedValue = _increasedValue;
|
||||||
|
String decreasedValue = _decreasedValue;
|
||||||
TextDirection textDirection = _textDirection;
|
TextDirection textDirection = _textDirection;
|
||||||
Set<SemanticsTag> mergedTags = tags == null ? null : new Set<SemanticsTag>.from(tags);
|
Set<SemanticsTag> mergedTags = tags == null ? null : new Set<SemanticsTag>.from(tags);
|
||||||
|
|
||||||
@ -589,6 +652,10 @@ class SemanticsNode extends AbstractNode with DiagnosticableTreeMixin {
|
|||||||
textDirection ??= node._textDirection;
|
textDirection ??= node._textDirection;
|
||||||
if (value == '' || value == null)
|
if (value == '' || value == null)
|
||||||
value = node._value;
|
value = node._value;
|
||||||
|
if (increasedValue == '' || increasedValue == null)
|
||||||
|
increasedValue = node._increasedValue;
|
||||||
|
if (decreasedValue == '' || decreasedValue == null)
|
||||||
|
decreasedValue = node._decreasedValue;
|
||||||
if (node.tags != null) {
|
if (node.tags != null) {
|
||||||
mergedTags ??= new Set<SemanticsTag>();
|
mergedTags ??= new Set<SemanticsTag>();
|
||||||
mergedTags.addAll(node.tags);
|
mergedTags.addAll(node.tags);
|
||||||
@ -614,6 +681,8 @@ class SemanticsNode extends AbstractNode with DiagnosticableTreeMixin {
|
|||||||
actions: actions,
|
actions: actions,
|
||||||
label: label,
|
label: label,
|
||||||
value: value,
|
value: value,
|
||||||
|
increasedValue: increasedValue,
|
||||||
|
decreasedValue: decreasedValue,
|
||||||
hint: hint,
|
hint: hint,
|
||||||
textDirection: textDirection,
|
textDirection: textDirection,
|
||||||
rect: rect,
|
rect: rect,
|
||||||
@ -648,6 +717,8 @@ class SemanticsNode extends AbstractNode with DiagnosticableTreeMixin {
|
|||||||
rect: data.rect,
|
rect: data.rect,
|
||||||
label: data.label,
|
label: data.label,
|
||||||
value: data.value,
|
value: data.value,
|
||||||
|
decreasedValue: data.decreasedValue,
|
||||||
|
increasedValue: data.increasedValue,
|
||||||
hint: data.hint,
|
hint: data.hint,
|
||||||
textDirection: data.textDirection,
|
textDirection: data.textDirection,
|
||||||
transform: data.transform?.storage ?? _kIdentityTransform,
|
transform: data.transform?.storage ?? _kIdentityTransform,
|
||||||
@ -707,6 +778,8 @@ class SemanticsNode extends AbstractNode with DiagnosticableTreeMixin {
|
|||||||
properties.add(new FlagProperty('isButton', value: _hasFlag(SemanticsFlags.isButton), ifTrue: 'button'));
|
properties.add(new FlagProperty('isButton', value: _hasFlag(SemanticsFlags.isButton), ifTrue: 'button'));
|
||||||
properties.add(new StringProperty('label', _label, defaultValue: ''));
|
properties.add(new StringProperty('label', _label, defaultValue: ''));
|
||||||
properties.add(new StringProperty('value', _value, defaultValue: ''));
|
properties.add(new StringProperty('value', _value, defaultValue: ''));
|
||||||
|
properties.add(new StringProperty('increasedValue', _increasedValue, defaultValue: ''));
|
||||||
|
properties.add(new StringProperty('decreasedValue', _decreasedValue, defaultValue: ''));
|
||||||
properties.add(new StringProperty('hint', _hint, defaultValue: ''));
|
properties.add(new StringProperty('hint', _hint, defaultValue: ''));
|
||||||
properties.add(new EnumProperty<TextDirection>('textDirection', _textDirection, defaultValue: null));
|
properties.add(new EnumProperty<TextDirection>('textDirection', _textDirection, defaultValue: null));
|
||||||
}
|
}
|
||||||
@ -1018,6 +1091,7 @@ class SemanticsConfiguration {
|
|||||||
///
|
///
|
||||||
/// Whenever the user performs `action` the provided `handler` is called.
|
/// Whenever the user performs `action` the provided `handler` is called.
|
||||||
void addAction(SemanticsAction action, VoidCallback handler) {
|
void addAction(SemanticsAction action, VoidCallback handler) {
|
||||||
|
assert(handler != null);
|
||||||
_actions[action] = handler;
|
_actions[action] = handler;
|
||||||
_actionsAsBits |= action.index;
|
_actionsAsBits |= action.index;
|
||||||
_hasBeenAnnotated = true;
|
_hasBeenAnnotated = true;
|
||||||
@ -1050,10 +1124,11 @@ class SemanticsConfiguration {
|
|||||||
/// [value] and [hint] in the following order: [value], [label], [hint].
|
/// [value] and [hint] in the following order: [value], [label], [hint].
|
||||||
/// The concatenated value is then used as the `Text` description.
|
/// The concatenated value is then used as the `Text` description.
|
||||||
///
|
///
|
||||||
/// The text's reading direction is given by [textDirection].
|
/// The reading direction is given by [textDirection].
|
||||||
String get label => _label;
|
String get label => _label;
|
||||||
String _label = '';
|
String _label = '';
|
||||||
set label(String label) {
|
set label(String label) {
|
||||||
|
assert(label != null);
|
||||||
_label = label;
|
_label = label;
|
||||||
_hasBeenAnnotated = true;
|
_hasBeenAnnotated = true;
|
||||||
}
|
}
|
||||||
@ -1065,14 +1140,51 @@ class SemanticsConfiguration {
|
|||||||
/// [label] and [hint] in the following order: [value], [label], [hint].
|
/// [label] and [hint] in the following order: [value], [label], [hint].
|
||||||
/// The concatenated value is then used as the `Text` description.
|
/// The concatenated value is then used as the `Text` description.
|
||||||
///
|
///
|
||||||
/// The text's reading direction is given by [textDirection].
|
/// The reading direction is given by [textDirection].
|
||||||
|
///
|
||||||
|
/// See also:
|
||||||
|
/// * [decreasedValue], describes what [value] will be after performing
|
||||||
|
/// [SemanticsAction.decrease]
|
||||||
|
/// * [increasedValue], describes what [value] will be after performing
|
||||||
|
/// [SemanticsAction.increase]
|
||||||
String get value => _value;
|
String get value => _value;
|
||||||
String _value = '';
|
String _value = '';
|
||||||
set value(String value) {
|
set value(String value) {
|
||||||
|
assert(value != null);
|
||||||
_value = value;
|
_value = value;
|
||||||
_hasBeenAnnotated = true;
|
_hasBeenAnnotated = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// The value that [value] will have after performing a
|
||||||
|
/// [SemanticsAction.decrease] action.
|
||||||
|
///
|
||||||
|
/// This must be set if a handler for [SemanticsAction.decrease] is provided
|
||||||
|
/// and [value] is set.
|
||||||
|
///
|
||||||
|
/// The reading direction is given by [textDirection].
|
||||||
|
String get decreasedValue => _decreasedValue;
|
||||||
|
String _decreasedValue = '';
|
||||||
|
set decreasedValue(String decreasedValue) {
|
||||||
|
assert(decreasedValue != null);
|
||||||
|
_decreasedValue = decreasedValue;
|
||||||
|
_hasBeenAnnotated = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// The value that [value] will have after performing a
|
||||||
|
/// [SemanticsAction.increase] action.
|
||||||
|
///
|
||||||
|
/// This must be set if a handler for [SemanticsAction.increase] is provided
|
||||||
|
/// and [value] is set.
|
||||||
|
///
|
||||||
|
/// The reading direction is given by [textDirection].
|
||||||
|
String get increasedValue => _increasedValue;
|
||||||
|
String _increasedValue = '';
|
||||||
|
set increasedValue(String increasedValue) {
|
||||||
|
assert(increasedValue != null);
|
||||||
|
_increasedValue = increasedValue;
|
||||||
|
_hasBeenAnnotated = true;
|
||||||
|
}
|
||||||
|
|
||||||
/// A brief description of the result of performing an action on this node.
|
/// A brief description of the result of performing an action on this node.
|
||||||
///
|
///
|
||||||
/// On iOS this is used for the `accessibilityHint` property defined in the
|
/// On iOS this is used for the `accessibilityHint` property defined in the
|
||||||
@ -1080,15 +1192,17 @@ class SemanticsConfiguration {
|
|||||||
/// [label] and [value] in the following order: [value], [label], [hint].
|
/// [label] and [value] in the following order: [value], [label], [hint].
|
||||||
/// The concatenated value is then used as the `Text` description.
|
/// The concatenated value is then used as the `Text` description.
|
||||||
///
|
///
|
||||||
/// The text's reading direction is given by [textDirection].
|
/// The reading direction is given by [textDirection].
|
||||||
String get hint => _hint;
|
String get hint => _hint;
|
||||||
String _hint = '';
|
String _hint = '';
|
||||||
set hint(String hint) {
|
set hint(String hint) {
|
||||||
|
assert(hint != null);
|
||||||
_hint = hint;
|
_hint = hint;
|
||||||
_hasBeenAnnotated = true;
|
_hasBeenAnnotated = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The reading direction for the text in [label], [value], and [hint].
|
/// The reading direction for the text in [label], [value], [hint],
|
||||||
|
/// [increasedValue], and [decreasedValue].
|
||||||
TextDirection get textDirection => _textDirection;
|
TextDirection get textDirection => _textDirection;
|
||||||
TextDirection _textDirection;
|
TextDirection _textDirection;
|
||||||
set textDirection(TextDirection textDirection) {
|
set textDirection(TextDirection textDirection) {
|
||||||
@ -1182,8 +1296,12 @@ class SemanticsConfiguration {
|
|||||||
otherString: other._label,
|
otherString: other._label,
|
||||||
otherTextDirection: other.textDirection,
|
otherTextDirection: other.textDirection,
|
||||||
);
|
);
|
||||||
|
if (_decreasedValue == '' || _decreasedValue == null)
|
||||||
|
_decreasedValue = other._decreasedValue;
|
||||||
if (_value == '' || _value == null)
|
if (_value == '' || _value == null)
|
||||||
_value = other._value;
|
_value = other._value;
|
||||||
|
if (_increasedValue == '' || _increasedValue == null)
|
||||||
|
_increasedValue = other._increasedValue;
|
||||||
_hint = _concatStrings(
|
_hint = _concatStrings(
|
||||||
thisString: _hint,
|
thisString: _hint,
|
||||||
thisTextDirection: textDirection,
|
thisTextDirection: textDirection,
|
||||||
@ -1202,7 +1320,9 @@ class SemanticsConfiguration {
|
|||||||
.._hasBeenAnnotated = _hasBeenAnnotated
|
.._hasBeenAnnotated = _hasBeenAnnotated
|
||||||
.._textDirection = _textDirection
|
.._textDirection = _textDirection
|
||||||
.._label = _label
|
.._label = _label
|
||||||
|
.._increasedValue = _increasedValue
|
||||||
.._value = _value
|
.._value = _value
|
||||||
|
.._decreasedValue = _decreasedValue
|
||||||
.._hint = _hint
|
.._hint = _hint
|
||||||
.._flags = _flags
|
.._flags = _flags
|
||||||
.._actionsAsBits = _actionsAsBits
|
.._actionsAsBits = _actionsAsBits
|
||||||
|
@ -4454,6 +4454,8 @@ class Semantics extends SingleChildRenderObjectWidget {
|
|||||||
this.button,
|
this.button,
|
||||||
this.label,
|
this.label,
|
||||||
this.value,
|
this.value,
|
||||||
|
this.increasedValue,
|
||||||
|
this.decreasedValue,
|
||||||
this.hint,
|
this.hint,
|
||||||
this.textDirection,
|
this.textDirection,
|
||||||
this.onTap,
|
this.onTap,
|
||||||
@ -4528,6 +4530,30 @@ class Semantics extends SingleChildRenderObjectWidget {
|
|||||||
/// in TalkBack and VoiceOver.
|
/// in TalkBack and VoiceOver.
|
||||||
final String value;
|
final String value;
|
||||||
|
|
||||||
|
/// The value that [value] will become after a [SemanticsAction.increase]
|
||||||
|
/// action has been performed on this widget.
|
||||||
|
///
|
||||||
|
/// If a value is provided, [onIncrease] must also be set and there must
|
||||||
|
/// either be an ambient [Directionality] or an explicit [textDirection]
|
||||||
|
/// must be provided.
|
||||||
|
///
|
||||||
|
/// See also:
|
||||||
|
/// * [SemanticsConfiguration.increasedValue] for a description of how this
|
||||||
|
/// is exposed in TalkBack and VoiceOver.
|
||||||
|
final String increasedValue;
|
||||||
|
|
||||||
|
/// The value that [value] will become after a [SemanticsAction.decrease]
|
||||||
|
/// action has been performed on this widget.
|
||||||
|
///
|
||||||
|
/// If a value is provided, [onDecrease] must also be set and there must
|
||||||
|
/// either be an ambient [Directionality] or an explicit [textDirection]
|
||||||
|
/// must be provided.
|
||||||
|
///
|
||||||
|
/// See also:
|
||||||
|
/// * [SemanticsConfiguration.decreasedValue] for a description of how this
|
||||||
|
/// is exposed in TalkBack and VoiceOver.
|
||||||
|
final String decreasedValue;
|
||||||
|
|
||||||
/// Provides a brief textual description of the result of an action performed
|
/// Provides a brief textual description of the result of an action performed
|
||||||
/// on the widget.
|
/// on the widget.
|
||||||
///
|
///
|
||||||
@ -4539,7 +4565,8 @@ class Semantics extends SingleChildRenderObjectWidget {
|
|||||||
/// in TalkBack and VoiceOver.
|
/// in TalkBack and VoiceOver.
|
||||||
final String hint;
|
final String hint;
|
||||||
|
|
||||||
/// The reading direction of the [label], [value], and [hint].
|
/// The reading direction of the [label], [value], [hint], [increasedValue],
|
||||||
|
/// and [decreasedValue].
|
||||||
///
|
///
|
||||||
/// Defaults to the ambient [Directionality].
|
/// Defaults to the ambient [Directionality].
|
||||||
final TextDirection textDirection;
|
final TextDirection textDirection;
|
||||||
@ -4625,6 +4652,9 @@ class Semantics extends SingleChildRenderObjectWidget {
|
|||||||
/// This is a request to increase the value represented by the widget. For
|
/// This is a request to increase the value represented by the widget. For
|
||||||
/// example, this action might be recognized by a slider control.
|
/// example, this action might be recognized by a slider control.
|
||||||
///
|
///
|
||||||
|
/// If a [value] is set, [increasedValue] must also be provided and
|
||||||
|
/// [onIncrease] must ensure that [value] will be set to [increasedValue].
|
||||||
|
///
|
||||||
/// VoiceOver users on iOS can trigger this action by swiping up with one
|
/// VoiceOver users on iOS can trigger this action by swiping up with one
|
||||||
/// finger. TalkBack users on Android can trigger this action by pressing the
|
/// finger. TalkBack users on Android can trigger this action by pressing the
|
||||||
/// volume up button.
|
/// volume up button.
|
||||||
@ -4635,6 +4665,9 @@ class Semantics extends SingleChildRenderObjectWidget {
|
|||||||
/// This is a request to decrease the value represented by the widget. For
|
/// This is a request to decrease the value represented by the widget. For
|
||||||
/// example, this action might be recognized by a slider control.
|
/// example, this action might be recognized by a slider control.
|
||||||
///
|
///
|
||||||
|
/// If a [value] is set, [decreasedValue] must also be provided and
|
||||||
|
/// [onDecrease] must ensure that [value] will be set to [decreasedValue].
|
||||||
|
///
|
||||||
/// VoiceOver users on iOS can trigger this action by swiping down with one
|
/// VoiceOver users on iOS can trigger this action by swiping down with one
|
||||||
/// finger. TalkBack users on Android can trigger this action by pressing the
|
/// finger. TalkBack users on Android can trigger this action by pressing the
|
||||||
/// volume down button.
|
/// volume down button.
|
||||||
@ -4650,6 +4683,8 @@ class Semantics extends SingleChildRenderObjectWidget {
|
|||||||
button: button,
|
button: button,
|
||||||
label: label,
|
label: label,
|
||||||
value: value,
|
value: value,
|
||||||
|
increasedValue: increasedValue,
|
||||||
|
decreasedValue: decreasedValue,
|
||||||
hint: hint,
|
hint: hint,
|
||||||
textDirection: _getTextDirection(context),
|
textDirection: _getTextDirection(context),
|
||||||
onTap: onTap,
|
onTap: onTap,
|
||||||
@ -4672,6 +4707,8 @@ class Semantics extends SingleChildRenderObjectWidget {
|
|||||||
..selected = selected
|
..selected = selected
|
||||||
..label = label
|
..label = label
|
||||||
..value = value
|
..value = value
|
||||||
|
..increasedValue = increasedValue
|
||||||
|
..decreasedValue = decreasedValue
|
||||||
..hint = hint
|
..hint = hint
|
||||||
..textDirection = _getTextDirection(context)
|
..textDirection = _getTextDirection(context)
|
||||||
..onTap = onTap
|
..onTap = onTap
|
||||||
|
@ -198,7 +198,7 @@ void main() {
|
|||||||
|
|
||||||
expect(
|
expect(
|
||||||
minimalProperties.toStringDeep(minLevel: DiagnosticLevel.hidden),
|
minimalProperties.toStringDeep(minLevel: DiagnosticLevel.hidden),
|
||||||
'SemanticsNode#16(owner: null, isPartOfNodeMerging: false, Rect.fromLTRB(0.0, 0.0, 0.0, 0.0), actions: [], isSelected: false, isButton: false, label: "", value: "", hint: "", textDirection: null)\n',
|
'SemanticsNode#16(owner: null, isPartOfNodeMerging: false, Rect.fromLTRB(0.0, 0.0, 0.0, 0.0), actions: [], isSelected: false, isButton: false, label: "", value: "", increasedValue: "", decreasedValue: "", hint: "", textDirection: null)\n',
|
||||||
);
|
);
|
||||||
|
|
||||||
final SemanticsConfiguration config = new SemanticsConfiguration()
|
final SemanticsConfiguration config = new SemanticsConfiguration()
|
||||||
|
@ -513,4 +513,36 @@ void main() {
|
|||||||
|
|
||||||
semantics.dispose();
|
semantics.dispose();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
testWidgets('Increased/decreased values are annotated', (WidgetTester tester) async {
|
||||||
|
final SemanticsTester semantics = new SemanticsTester(tester);
|
||||||
|
|
||||||
|
await tester.pumpWidget(
|
||||||
|
new Directionality(
|
||||||
|
textDirection: TextDirection.ltr,
|
||||||
|
child: new Semantics(
|
||||||
|
container: true,
|
||||||
|
value: '10s',
|
||||||
|
increasedValue: '11s',
|
||||||
|
decreasedValue: '9s',
|
||||||
|
onIncrease: () => () {},
|
||||||
|
onDecrease: () => () {},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
expect(semantics, hasSemantics(new TestSemantics.root(
|
||||||
|
children: <TestSemantics>[
|
||||||
|
new TestSemantics.rootChild(
|
||||||
|
actions: SemanticsAction.increase.index | SemanticsAction.decrease.index,
|
||||||
|
textDirection: TextDirection.ltr,
|
||||||
|
value: '10s',
|
||||||
|
increasedValue: '11s',
|
||||||
|
decreasedValue: '9s',
|
||||||
|
),
|
||||||
|
],
|
||||||
|
), ignoreTransform: true, ignoreRect: true, ignoreId: true));
|
||||||
|
|
||||||
|
semantics.dispose();
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
@ -36,6 +36,8 @@ class TestSemantics {
|
|||||||
this.actions: 0,
|
this.actions: 0,
|
||||||
this.label: '',
|
this.label: '',
|
||||||
this.value: '',
|
this.value: '',
|
||||||
|
this.increasedValue: '',
|
||||||
|
this.decreasedValue: '',
|
||||||
this.hint: '',
|
this.hint: '',
|
||||||
this.textDirection,
|
this.textDirection,
|
||||||
this.rect,
|
this.rect,
|
||||||
@ -45,6 +47,8 @@ class TestSemantics {
|
|||||||
}) : assert(flags != null),
|
}) : assert(flags != null),
|
||||||
assert(label != null),
|
assert(label != null),
|
||||||
assert(value != null),
|
assert(value != null),
|
||||||
|
assert(increasedValue != null),
|
||||||
|
assert(decreasedValue != null),
|
||||||
assert(hint != null),
|
assert(hint != null),
|
||||||
assert(children != null),
|
assert(children != null),
|
||||||
tags = tags?.toSet() ?? new Set<SemanticsTag>();
|
tags = tags?.toSet() ?? new Set<SemanticsTag>();
|
||||||
@ -56,6 +60,8 @@ class TestSemantics {
|
|||||||
this.actions: 0,
|
this.actions: 0,
|
||||||
this.label: '',
|
this.label: '',
|
||||||
this.value: '',
|
this.value: '',
|
||||||
|
this.increasedValue: '',
|
||||||
|
this.decreasedValue: '',
|
||||||
this.hint: '',
|
this.hint: '',
|
||||||
this.textDirection,
|
this.textDirection,
|
||||||
this.transform,
|
this.transform,
|
||||||
@ -64,6 +70,8 @@ class TestSemantics {
|
|||||||
}) : id = 0,
|
}) : id = 0,
|
||||||
assert(flags != null),
|
assert(flags != null),
|
||||||
assert(label != null),
|
assert(label != null),
|
||||||
|
assert(increasedValue != null),
|
||||||
|
assert(decreasedValue != null),
|
||||||
assert(value != null),
|
assert(value != null),
|
||||||
assert(hint != null),
|
assert(hint != null),
|
||||||
rect = TestSemantics.rootRect,
|
rect = TestSemantics.rootRect,
|
||||||
@ -86,6 +94,8 @@ class TestSemantics {
|
|||||||
this.label: '',
|
this.label: '',
|
||||||
this.hint: '',
|
this.hint: '',
|
||||||
this.value: '',
|
this.value: '',
|
||||||
|
this.increasedValue: '',
|
||||||
|
this.decreasedValue: '',
|
||||||
this.textDirection,
|
this.textDirection,
|
||||||
this.rect,
|
this.rect,
|
||||||
Matrix4 transform,
|
Matrix4 transform,
|
||||||
@ -94,6 +104,8 @@ class TestSemantics {
|
|||||||
}) : assert(flags != null),
|
}) : assert(flags != null),
|
||||||
assert(label != null),
|
assert(label != null),
|
||||||
assert(value != null),
|
assert(value != null),
|
||||||
|
assert(increasedValue != null),
|
||||||
|
assert(decreasedValue != null),
|
||||||
assert(hint != null),
|
assert(hint != null),
|
||||||
transform = _applyRootChildScale(transform),
|
transform = _applyRootChildScale(transform),
|
||||||
assert(children != null),
|
assert(children != null),
|
||||||
@ -117,6 +129,14 @@ class TestSemantics {
|
|||||||
/// A textual description for the value of this node.
|
/// A textual description for the value of this node.
|
||||||
final String value;
|
final String value;
|
||||||
|
|
||||||
|
/// What [value] will become after [SemanticsAction.increase] has been
|
||||||
|
/// performed.
|
||||||
|
final String increasedValue;
|
||||||
|
|
||||||
|
/// What [value] will become after [SemanticsAction.decrease] has been
|
||||||
|
/// performed.
|
||||||
|
final String decreasedValue;
|
||||||
|
|
||||||
/// A brief textual description of the result of the action that can be
|
/// A brief textual description of the result of the action that can be
|
||||||
/// performed on this node.
|
/// performed on this node.
|
||||||
final String hint;
|
final String hint;
|
||||||
@ -190,11 +210,15 @@ class TestSemantics {
|
|||||||
return fail('expected node id $id to have label "$label" but found label "${nodeData.label}".');
|
return fail('expected node id $id to have label "$label" but found label "${nodeData.label}".');
|
||||||
if (value != nodeData.value)
|
if (value != nodeData.value)
|
||||||
return fail('expected node id $id to have value "$value" but found value "${nodeData.value}".');
|
return fail('expected node id $id to have value "$value" but found value "${nodeData.value}".');
|
||||||
|
if (increasedValue != nodeData.increasedValue)
|
||||||
|
return fail('expected node id $id to have increasedValue "$increasedValue" but found value "${nodeData.increasedValue}".');
|
||||||
|
if (decreasedValue != nodeData.decreasedValue)
|
||||||
|
return fail('expected node id $id to have decreasedValue "$decreasedValue" but found value "${nodeData.decreasedValue}".');
|
||||||
if (hint != nodeData.hint)
|
if (hint != nodeData.hint)
|
||||||
return fail('expected node id $id to have hint "$hint" but found hint "${nodeData.hint}".');
|
return fail('expected node id $id to have hint "$hint" but found hint "${nodeData.hint}".');
|
||||||
if (textDirection != null && textDirection != nodeData.textDirection)
|
if (textDirection != null && textDirection != nodeData.textDirection)
|
||||||
return fail('expected node id $id to have textDirection "$textDirection" but found "${nodeData.textDirection}".');
|
return fail('expected node id $id to have textDirection "$textDirection" but found "${nodeData.textDirection}".');
|
||||||
if ((nodeData.label != '' || nodeData.value != '' || nodeData.hint != '') && nodeData.textDirection == null)
|
if ((nodeData.label != '' || nodeData.value != '' || nodeData.hint != '' || node.increasedValue != '' || node.decreasedValue != '') && nodeData.textDirection == null)
|
||||||
return fail('expected node id $id, which has a label, value, or hint, to have a textDirection, but it did not.');
|
return fail('expected node id $id, which has a label, value, or hint, to have a textDirection, but it did not.');
|
||||||
if (!ignoreRect && rect != nodeData.rect)
|
if (!ignoreRect && rect != nodeData.rect)
|
||||||
return fail('expected node id $id to have rect $rect but found rect ${nodeData.rect}.');
|
return fail('expected node id $id to have rect $rect but found rect ${nodeData.rect}.');
|
||||||
|
Loading…
x
Reference in New Issue
Block a user