Improve how AttributedStrings are presented in the widget inspector (#92450)
This commit is contained in:
parent
bd935e5d4f
commit
23f7985e50
@ -2839,14 +2839,23 @@ class DiagnosticsProperty<T> extends DiagnosticsNode {
|
||||
}
|
||||
}
|
||||
|
||||
/// If the [value] of the property equals [defaultValue] the priority [level]
|
||||
/// of the property is downgraded to [DiagnosticLevel.fine] as the property
|
||||
/// value is uninteresting.
|
||||
/// The default value of this property, when it has not been set to a specific
|
||||
/// value.
|
||||
///
|
||||
/// For most [DiagnosticsProperty] classes, if the [value] of the property
|
||||
/// equals [defaultValue], then the priority [level] of the property is
|
||||
/// downgraded to [DiagnosticLevel.fine] on the basis that the property value
|
||||
/// is uninteresting. This is implemented by [isInteresting].
|
||||
///
|
||||
/// The [defaultValue] is [kNoDefaultValue] by default. Otherwise it must be of
|
||||
/// type `T?`.
|
||||
final Object? defaultValue;
|
||||
|
||||
/// Whether to consider the property's value interesting. When a property is
|
||||
/// uninteresting, its [level] is downgraded to [DiagnosticLevel.fine]
|
||||
/// regardless of the value provided as the constructor's `level` argument.
|
||||
bool get isInteresting => defaultValue == kNoDefaultValue || value != defaultValue;
|
||||
|
||||
final DiagnosticLevel _defaultLevel;
|
||||
|
||||
/// Priority level of the diagnostic used to control which diagnostics should
|
||||
@ -2870,8 +2879,7 @@ class DiagnosticsProperty<T> extends DiagnosticsNode {
|
||||
if (value == null && missingIfNull)
|
||||
return DiagnosticLevel.warning;
|
||||
|
||||
// Use a low level when the value matches the default value.
|
||||
if (defaultValue != kNoDefaultValue && value == defaultValue)
|
||||
if (!isInteresting)
|
||||
return DiagnosticLevel.fine;
|
||||
|
||||
return _defaultLevel;
|
||||
@ -3549,7 +3557,9 @@ class DiagnosticsBlock extends DiagnosticsNode {
|
||||
|
||||
@override
|
||||
final DiagnosticLevel level;
|
||||
|
||||
final String? _description;
|
||||
|
||||
@override
|
||||
final Object? value;
|
||||
|
||||
|
@ -255,6 +255,57 @@ class AttributedString {
|
||||
}
|
||||
}
|
||||
|
||||
/// A [DiagnosticsProperty] for [AttributedString]s, which shows a string
|
||||
/// when there are no attributes, and more details otherwise.
|
||||
class AttributedStringProperty extends DiagnosticsProperty<AttributedString> {
|
||||
/// Create a diagnostics property for an [AttributedString] object.
|
||||
///
|
||||
/// Such properties are used with [SemanticsData] objects.
|
||||
AttributedStringProperty(
|
||||
String name,
|
||||
AttributedString? value, {
|
||||
bool showName = true,
|
||||
this.showWhenEmpty = false,
|
||||
Object? defaultValue = kNoDefaultValue,
|
||||
DiagnosticLevel level = DiagnosticLevel.info,
|
||||
String? description,
|
||||
}) : assert(showName != null),
|
||||
assert(level != null),
|
||||
super(
|
||||
name,
|
||||
value,
|
||||
showName: showName,
|
||||
defaultValue: defaultValue,
|
||||
level: level,
|
||||
description: description,
|
||||
);
|
||||
|
||||
/// Whether to show the property when the [value] is an [AttributedString]
|
||||
/// whose [AttributedString.string] is the empty string.
|
||||
///
|
||||
/// This overrides [defaultValue].
|
||||
final bool showWhenEmpty;
|
||||
|
||||
@override
|
||||
bool get isInteresting => super.isInteresting && (showWhenEmpty || (value != null && value!.string.isNotEmpty));
|
||||
|
||||
@override
|
||||
String valueToString({TextTreeConfiguration? parentConfiguration}) {
|
||||
if (value == null)
|
||||
return 'null';
|
||||
String text = value!.string;
|
||||
if (parentConfiguration != null &&
|
||||
!parentConfiguration.lineBreakProperties) {
|
||||
// This follows a similar pattern to StringProperty.
|
||||
text = text.replaceAll('\n', r'\n');
|
||||
}
|
||||
if (value!.attributes.isEmpty) {
|
||||
return '"$text"';
|
||||
}
|
||||
return '"$text" ${value!.attributes}'; // the attributes will be in square brackets since they're a list
|
||||
}
|
||||
}
|
||||
|
||||
/// Summary information about a [SemanticsNode] object.
|
||||
///
|
||||
/// A semantics node might [SemanticsNode.mergeAllDescendantsIntoThisNode],
|
||||
@ -303,9 +354,9 @@ class SemanticsData with Diagnosticable {
|
||||
assert(attributedHint != null),
|
||||
assert(attributedLabel.string == '' || textDirection != null, 'A SemanticsData object with label "${attributedLabel.string}" had a null textDirection.'),
|
||||
assert(attributedValue.string == '' || textDirection != null, 'A SemanticsData object with value "${attributedValue.string}" had a null textDirection.'),
|
||||
assert(attributedHint.string == '' || textDirection != null, 'A SemanticsData object with hint "${attributedHint.string}" had a null textDirection.'),
|
||||
assert(attributedDecreasedValue.string == '' || textDirection != null, 'A SemanticsData object with decreasedValue "${attributedDecreasedValue.string}" had a null textDirection.'),
|
||||
assert(attributedIncreasedValue.string == '' || textDirection != null, 'A SemanticsData object with increasedValue "${attributedIncreasedValue.string}" had a null textDirection.'),
|
||||
assert(attributedHint.string == '' || textDirection != null, 'A SemanticsData object with hint "${attributedHint.string}" had a null textDirection.'),
|
||||
assert(rect != null);
|
||||
|
||||
/// A bit field of [SemanticsFlag]s that apply to this node.
|
||||
@ -317,62 +368,82 @@ class SemanticsData with Diagnosticable {
|
||||
/// A textual description for the current label of the node.
|
||||
///
|
||||
/// The reading direction is given by [textDirection].
|
||||
///
|
||||
/// This exposes the raw text of the [attributedLabel].
|
||||
String get label => attributedLabel.string;
|
||||
|
||||
/// A textual description for the current label of the node in
|
||||
/// [AttributedString] format.
|
||||
///
|
||||
/// The reading direction is given by [textDirection].
|
||||
///
|
||||
/// See also [label], which exposes just the raw text.
|
||||
final AttributedString attributedLabel;
|
||||
|
||||
/// A textual description for the current value of the node.
|
||||
///
|
||||
/// The reading direction is given by [textDirection].
|
||||
///
|
||||
/// This exposes the raw text of the [attributedValue].
|
||||
String get value => attributedValue.string;
|
||||
|
||||
/// A textual description for the current value of the node in
|
||||
/// [AttributedString] format.
|
||||
///
|
||||
/// The reading direction is given by [textDirection].
|
||||
///
|
||||
/// See also [value], which exposes just the raw text.
|
||||
final AttributedString attributedValue;
|
||||
|
||||
/// The value that [value] will become after performing a
|
||||
/// [SemanticsAction.increase] action.
|
||||
///
|
||||
/// The reading direction is given by [textDirection].
|
||||
///
|
||||
/// This exposes the raw text of the [attributedIncreasedValue].
|
||||
String get increasedValue => attributedIncreasedValue.string;
|
||||
|
||||
/// The value that [value] will become after performing a
|
||||
/// [SemanticsAction.increase] action in [AttributedString] format.
|
||||
///
|
||||
/// The reading direction is given by [textDirection].
|
||||
///
|
||||
/// See also [increasedValue], which exposes just the raw text.
|
||||
final AttributedString attributedIncreasedValue;
|
||||
|
||||
/// The value that [value] will become after performing a
|
||||
/// [SemanticsAction.decrease] action.
|
||||
///
|
||||
/// The reading direction is given by [textDirection].
|
||||
///
|
||||
/// This exposes the raw text of the [attributedDecreasedValue].
|
||||
String get decreasedValue => attributedDecreasedValue.string;
|
||||
|
||||
/// The value that [value] will become after performing a
|
||||
/// [SemanticsAction.decrease] action in [AttributedString] format.
|
||||
///
|
||||
/// The reading direction is given by [textDirection].
|
||||
///
|
||||
/// See also [decreasedValue], which exposes just the raw text.
|
||||
final AttributedString attributedDecreasedValue;
|
||||
|
||||
/// A brief description of the result of performing an action on this node.
|
||||
///
|
||||
/// The reading direction is given by [textDirection].
|
||||
///
|
||||
/// This exposes the raw text of the [attributedHint].
|
||||
String get hint => attributedHint.string;
|
||||
|
||||
/// A brief description of the result of performing an action on this node
|
||||
/// in [AttributedString] format.
|
||||
///
|
||||
/// The reading direction is given by [textDirection].
|
||||
///
|
||||
/// See also [hint], which exposes just the raw text.
|
||||
final AttributedString attributedHint;
|
||||
|
||||
/// The reading direction for the text in [label], [value], [hint],
|
||||
/// [increasedValue], and [decreasedValue].
|
||||
/// The reading direction for the text in [label], [value],
|
||||
/// [increasedValue], [decreasedValue], and [hint].
|
||||
final TextDirection? textDirection;
|
||||
|
||||
/// The currently selected text (or the position of the cursor) within [value]
|
||||
@ -524,11 +595,11 @@ class SemanticsData with Diagnosticable {
|
||||
describeEnum(flag),
|
||||
];
|
||||
properties.add(IterableProperty<String>('flags', flagSummary, ifEmpty: null));
|
||||
properties.add(StringProperty('label', attributedLabel.attributes.isEmpty ? label : attributedLabel.toString(), defaultValue: ''));
|
||||
properties.add(StringProperty('value', attributedValue.attributes.isEmpty? value :attributedValue.toString(), defaultValue: ''));
|
||||
properties.add(StringProperty('increasedValue', attributedIncreasedValue.attributes.isEmpty? increasedValue :attributedIncreasedValue.toString(), defaultValue: ''));
|
||||
properties.add(StringProperty('decreasedValue', attributedDecreasedValue.attributes.isEmpty? decreasedValue :attributedDecreasedValue.toString(), defaultValue: ''));
|
||||
properties.add(StringProperty('hint', attributedHint.attributes.isEmpty? hint :attributedHint.toString(), defaultValue: ''));
|
||||
properties.add(AttributedStringProperty('label', attributedLabel));
|
||||
properties.add(AttributedStringProperty('value', attributedValue));
|
||||
properties.add(AttributedStringProperty('increasedValue', attributedIncreasedValue));
|
||||
properties.add(AttributedStringProperty('decreasedValue', attributedDecreasedValue));
|
||||
properties.add(AttributedStringProperty('hint', attributedHint));
|
||||
properties.add(EnumProperty<TextDirection>('textDirection', textDirection, defaultValue: null));
|
||||
if (textSelection?.isValid == true)
|
||||
properties.add(MessageProperty('textSelection', '[${textSelection!.start}, ${textSelection!.end}]'));
|
||||
@ -977,10 +1048,10 @@ class SemanticsProperties extends DiagnosticableTree {
|
||||
///
|
||||
/// * [SemanticsConfiguration.label] for a description of how this is exposed
|
||||
/// in TalkBack and VoiceOver.
|
||||
/// * [attributedLabel] for a [AttributedString] version of this property.
|
||||
/// * [attributedLabel] for an [AttributedString] version of this property.
|
||||
final String? label;
|
||||
|
||||
/// Provides a [AttributedString] version of textual description of the widget.
|
||||
/// Provides an [AttributedString] version of textual description of the widget.
|
||||
///
|
||||
/// If a [attributedLabel] is provided, there must either by an ambient
|
||||
/// [Directionality] or an explicit [textDirection] should be provided.
|
||||
@ -1007,10 +1078,10 @@ class SemanticsProperties extends DiagnosticableTree {
|
||||
///
|
||||
/// * [SemanticsConfiguration.value] for a description of how this is exposed
|
||||
/// in TalkBack and VoiceOver.
|
||||
/// * [attributedLabel] for a [AttributedString] version of this property.
|
||||
/// * [attributedLabel] for an [AttributedString] version of this property.
|
||||
final String? value;
|
||||
|
||||
/// Provides a [AttributedString] version of textual description of the value
|
||||
/// Provides an [AttributedString] version of textual description of the value
|
||||
/// of the widget.
|
||||
///
|
||||
/// If a [attributedValue] is provided, there must either by an ambient
|
||||
@ -1040,7 +1111,7 @@ class SemanticsProperties extends DiagnosticableTree {
|
||||
///
|
||||
/// * [SemanticsConfiguration.increasedValue] for a description of how this
|
||||
/// is exposed in TalkBack and VoiceOver.
|
||||
/// * [attributedIncreasedValue] for a [AttributedString] version of this
|
||||
/// * [attributedIncreasedValue] for an [AttributedString] version of this
|
||||
/// property.
|
||||
final String? increasedValue;
|
||||
|
||||
@ -1075,7 +1146,7 @@ class SemanticsProperties extends DiagnosticableTree {
|
||||
///
|
||||
/// * [SemanticsConfiguration.decreasedValue] for a description of how this
|
||||
/// is exposed in TalkBack and VoiceOver.
|
||||
/// * [attributedDecreasedValue] for a [AttributedString] version of this
|
||||
/// * [attributedDecreasedValue] for an [AttributedString] version of this
|
||||
/// property.
|
||||
final String? decreasedValue;
|
||||
|
||||
@ -1109,10 +1180,10 @@ class SemanticsProperties extends DiagnosticableTree {
|
||||
///
|
||||
/// * [SemanticsConfiguration.hint] for a description of how this is exposed
|
||||
/// in TalkBack and VoiceOver.
|
||||
/// * [attributedHint] for a [AttributedString] version of this property.
|
||||
/// * [attributedHint] for an [AttributedString] version of this property.
|
||||
final String? hint;
|
||||
|
||||
/// Provides a [AttributedString] version of brief textual description of the
|
||||
/// Provides an [AttributedString] version of brief textual description of the
|
||||
/// result of an action performed on the widget.
|
||||
///
|
||||
/// If a [attributedHint] is provided, there must either by an ambient
|
||||
@ -1138,8 +1209,8 @@ class SemanticsProperties extends DiagnosticableTree {
|
||||
/// On iOS, these are always ignored and the default [hint] is used instead.
|
||||
final SemanticsHintOverrides? hintOverrides;
|
||||
|
||||
/// The reading direction of the [label], [value], [hint], [increasedValue],
|
||||
/// and [decreasedValue].
|
||||
/// The reading direction of the [label], [value], [increasedValue],
|
||||
/// [decreasedValue], and [hint].
|
||||
///
|
||||
/// Defaults to the ambient [Directionality].
|
||||
final TextDirection? textDirection;
|
||||
@ -1409,15 +1480,19 @@ class SemanticsProperties extends DiagnosticableTree {
|
||||
super.debugFillProperties(properties);
|
||||
properties.add(DiagnosticsProperty<bool>('checked', checked, defaultValue: null));
|
||||
properties.add(DiagnosticsProperty<bool>('selected', selected, defaultValue: null));
|
||||
properties.add(StringProperty('label', label, defaultValue: ''));
|
||||
properties.add(StringProperty('attributedLabel', attributedLabel.toString(), defaultValue: ''));
|
||||
properties.add(StringProperty('value', value));
|
||||
properties.add(StringProperty('attributedValue', attributedValue.toString(), defaultValue: ''));
|
||||
properties.add(StringProperty('hint', hint));
|
||||
properties.add(StringProperty('attributedHint', attributedHint.toString(), defaultValue: ''));
|
||||
properties.add(StringProperty('label', label, defaultValue: null));
|
||||
properties.add(AttributedStringProperty('attributedLabel', attributedLabel, defaultValue: null));
|
||||
properties.add(StringProperty('value', value, defaultValue: null));
|
||||
properties.add(AttributedStringProperty('attributedValue', attributedValue, defaultValue: null));
|
||||
properties.add(StringProperty('increasedValue', value, defaultValue: null));
|
||||
properties.add(AttributedStringProperty('attributedIncreasedValue', attributedIncreasedValue, defaultValue: null));
|
||||
properties.add(StringProperty('decreasedValue', value, defaultValue: null));
|
||||
properties.add(AttributedStringProperty('attributedDecreasedValue', attributedDecreasedValue, defaultValue: null));
|
||||
properties.add(StringProperty('hint', hint, defaultValue: null));
|
||||
properties.add(AttributedStringProperty('attributedHint', attributedHint, defaultValue: null));
|
||||
properties.add(EnumProperty<TextDirection>('textDirection', textDirection, defaultValue: null));
|
||||
properties.add(DiagnosticsProperty<SemanticsSortKey>('sortKey', sortKey, defaultValue: null));
|
||||
properties.add(DiagnosticsProperty<SemanticsHintOverrides>('hintOverrides', hintOverrides));
|
||||
properties.add(DiagnosticsProperty<SemanticsHintOverrides>('hintOverrides', hintOverrides, defaultValue: null));
|
||||
}
|
||||
|
||||
@override
|
||||
@ -1837,26 +1912,26 @@ class SemanticsNode extends AbstractNode with DiagnosticableTreeMixin {
|
||||
}
|
||||
|
||||
bool _isDifferentFromCurrentSemanticAnnotation(SemanticsConfiguration config) {
|
||||
return _attributedLabel != config.attributedLabel ||
|
||||
_attributedHint != config.attributedHint ||
|
||||
_elevation != config.elevation ||
|
||||
_thickness != config.thickness ||
|
||||
_attributedValue != config.attributedValue ||
|
||||
_attributedIncreasedValue != config.attributedIncreasedValue ||
|
||||
_attributedDecreasedValue != config.attributedDecreasedValue ||
|
||||
_flags != config._flags ||
|
||||
_textDirection != config.textDirection ||
|
||||
_sortKey != config._sortKey ||
|
||||
_textSelection != config._textSelection ||
|
||||
_scrollPosition != config._scrollPosition ||
|
||||
_scrollExtentMax != config._scrollExtentMax ||
|
||||
_scrollExtentMin != config._scrollExtentMin ||
|
||||
_actionsAsBits != config._actionsAsBits ||
|
||||
indexInParent != config.indexInParent ||
|
||||
platformViewId != config.platformViewId ||
|
||||
_maxValueLength != config._maxValueLength ||
|
||||
_currentValueLength != config._currentValueLength ||
|
||||
_mergeAllDescendantsIntoThisNode != config.isMergingSemanticsOfDescendants;
|
||||
return _attributedLabel != config.attributedLabel
|
||||
|| _attributedHint != config.attributedHint
|
||||
|| _elevation != config.elevation
|
||||
|| _thickness != config.thickness
|
||||
|| _attributedValue != config.attributedValue
|
||||
|| _attributedIncreasedValue != config.attributedIncreasedValue
|
||||
|| _attributedDecreasedValue != config.attributedDecreasedValue
|
||||
|| _flags != config._flags
|
||||
|| _textDirection != config.textDirection
|
||||
|| _sortKey != config._sortKey
|
||||
|| _textSelection != config._textSelection
|
||||
|| _scrollPosition != config._scrollPosition
|
||||
|| _scrollExtentMax != config._scrollExtentMax
|
||||
|| _scrollExtentMin != config._scrollExtentMin
|
||||
|| _actionsAsBits != config._actionsAsBits
|
||||
|| indexInParent != config.indexInParent
|
||||
|| platformViewId != config.platformViewId
|
||||
|| _maxValueLength != config._maxValueLength
|
||||
|| _currentValueLength != config._currentValueLength
|
||||
|| _mergeAllDescendantsIntoThisNode != config.isMergingSemanticsOfDescendants;
|
||||
}
|
||||
|
||||
// TAGS, LABELS, ACTIONS
|
||||
@ -1883,45 +1958,34 @@ class SemanticsNode extends AbstractNode with DiagnosticableTreeMixin {
|
||||
/// A textual description of this node.
|
||||
///
|
||||
/// The reading direction is given by [textDirection].
|
||||
///
|
||||
/// This exposes the raw text of the [attributedLabel].
|
||||
String get label => _attributedLabel.string;
|
||||
|
||||
/// A textual description of this node in [AttributedString] format.
|
||||
///
|
||||
/// The reading direction is given by [textDirection].
|
||||
///
|
||||
/// See also [label], which exposes just the raw text.
|
||||
AttributedString get attributedLabel => _attributedLabel;
|
||||
AttributedString _attributedLabel = _kEmptyConfig.attributedLabel;
|
||||
|
||||
/// A textual description for the current value of the node.
|
||||
///
|
||||
/// The reading direction is given by [textDirection].
|
||||
///
|
||||
/// This exposes the raw text of the [attributedValue].
|
||||
String get value => _attributedValue.string;
|
||||
|
||||
/// A textual description for the current value of the node in
|
||||
/// [AttributedString] format.
|
||||
///
|
||||
/// The reading direction is given by [textDirection].
|
||||
///
|
||||
/// See also [value], which exposes just the raw text.
|
||||
AttributedString get attributedValue => _attributedValue;
|
||||
AttributedString _attributedValue = _kEmptyConfig.attributedValue;
|
||||
|
||||
/// 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 => _attributedDecreasedValue.string;
|
||||
|
||||
/// The value in [AttributedString] format that [value] or [attributedValue]
|
||||
/// 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].
|
||||
AttributedString get attributedDecreasedValue => _attributedDecreasedValue;
|
||||
AttributedString _attributedDecreasedValue = _kEmptyConfig.attributedDecreasedValue;
|
||||
|
||||
/// The value that [value] will have after a [SemanticsAction.increase] action
|
||||
/// has been performed.
|
||||
///
|
||||
@ -1929,6 +1993,8 @@ class SemanticsNode extends AbstractNode with DiagnosticableTreeMixin {
|
||||
/// available on this node.
|
||||
///
|
||||
/// The reading direction is given by [textDirection].
|
||||
///
|
||||
/// This exposes the raw text of the [attributedIncreasedValue].
|
||||
String get increasedValue => _attributedIncreasedValue.string;
|
||||
|
||||
/// The value in [AttributedString] format that [value] or [attributedValue]
|
||||
@ -1938,19 +2004,47 @@ class SemanticsNode extends AbstractNode with DiagnosticableTreeMixin {
|
||||
/// available on this node.
|
||||
///
|
||||
/// The reading direction is given by [textDirection].
|
||||
///
|
||||
/// See also [increasedValue], which exposes just the raw text.
|
||||
AttributedString get attributedIncreasedValue => _attributedIncreasedValue;
|
||||
AttributedString _attributedIncreasedValue = _kEmptyConfig.attributedIncreasedValue;
|
||||
|
||||
/// 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].
|
||||
///
|
||||
/// This exposes the raw text of the [attributedDecreasedValue].
|
||||
String get decreasedValue => _attributedDecreasedValue.string;
|
||||
|
||||
/// The value in [AttributedString] format that [value] or [attributedValue]
|
||||
/// 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].
|
||||
///
|
||||
/// See also [decreasedValue], which exposes just the raw text.
|
||||
AttributedString get attributedDecreasedValue => _attributedDecreasedValue;
|
||||
AttributedString _attributedDecreasedValue = _kEmptyConfig.attributedDecreasedValue;
|
||||
|
||||
/// A brief description of the result of performing an action on this node.
|
||||
///
|
||||
/// The reading direction is given by [textDirection].
|
||||
///
|
||||
/// This exposes the raw text of the [attributedHint].
|
||||
String get hint => _attributedHint.string;
|
||||
|
||||
/// A brief description of the result of performing an action on this node
|
||||
/// in [AttributedString] format.
|
||||
///
|
||||
/// The reading direction is given by [textDirection].
|
||||
///
|
||||
/// See also [hint], which exposes just the raw text.
|
||||
AttributedString get attributedHint => _attributedHint;
|
||||
AttributedString _attributedHint = _kEmptyConfig.attributedHint;
|
||||
|
||||
@ -2517,11 +2611,11 @@ class SemanticsNode extends AbstractNode with DiagnosticableTreeMixin {
|
||||
properties.add(IterableProperty<String>('flags', flags, ifEmpty: null));
|
||||
properties.add(FlagProperty('isInvisible', value: isInvisible, ifTrue: 'invisible'));
|
||||
properties.add(FlagProperty('isHidden', value: hasFlag(SemanticsFlag.isHidden), ifTrue: 'HIDDEN'));
|
||||
properties.add(StringProperty('label', _attributedLabel.attributes.isEmpty ? _attributedLabel.string : _attributedLabel.toString(), defaultValue: ''));
|
||||
properties.add(StringProperty('value', _attributedValue.attributes.isEmpty ? _attributedValue.string : _attributedValue.toString(), defaultValue: ''));
|
||||
properties.add(StringProperty('increasedValue', _attributedIncreasedValue.attributes.isEmpty ? _attributedIncreasedValue.string : _attributedIncreasedValue.toString(), defaultValue: ''));
|
||||
properties.add(StringProperty('decreasedValue', _attributedDecreasedValue.attributes.isEmpty ? _attributedDecreasedValue.string : _attributedDecreasedValue.toString(), defaultValue: ''));
|
||||
properties.add(StringProperty('hint', _attributedHint.attributes.isEmpty ? _attributedHint.string : _attributedHint.toString(), defaultValue: ''));
|
||||
properties.add(AttributedStringProperty('label', _attributedLabel));
|
||||
properties.add(AttributedStringProperty('value', _attributedValue));
|
||||
properties.add(AttributedStringProperty('increasedValue', _attributedIncreasedValue));
|
||||
properties.add(AttributedStringProperty('decreasedValue', _attributedDecreasedValue));
|
||||
properties.add(AttributedStringProperty('hint', _attributedHint));
|
||||
properties.add(EnumProperty<TextDirection>('textDirection', _textDirection, defaultValue: null));
|
||||
properties.add(DiagnosticsProperty<SemanticsSortKey>('sortKey', sortKey, defaultValue: null));
|
||||
if (_textSelection?.isValid == true)
|
||||
@ -3692,7 +3786,8 @@ class SemanticsConfiguration {
|
||||
/// The reading direction is given by [textDirection].
|
||||
///
|
||||
/// See also:
|
||||
/// * [attributedLabel]: which is the [AttributedString] of this property.
|
||||
///
|
||||
/// * [attributedLabel], which is the [AttributedString] of this property.
|
||||
String get label => _attributedLabel.string;
|
||||
set label(String label) {
|
||||
assert(label != null);
|
||||
@ -3710,6 +3805,10 @@ class SemanticsConfiguration {
|
||||
/// concatenated value is then used as the `Text` description.
|
||||
///
|
||||
/// The reading direction is given by [textDirection].
|
||||
///
|
||||
/// See also:
|
||||
///
|
||||
/// * [label], which is the raw text of this property.
|
||||
AttributedString get attributedLabel => _attributedLabel;
|
||||
AttributedString _attributedLabel = AttributedString('');
|
||||
set attributedLabel(AttributedString attributedLabel) {
|
||||
@ -3726,10 +3825,10 @@ class SemanticsConfiguration {
|
||||
/// See also:
|
||||
///
|
||||
/// * [attributedValue], which is the [AttributedString] of this property.
|
||||
/// * [decreasedValue] and [attributedDecreasedValue], describes what
|
||||
/// [value] will be after performing [SemanticsAction.decrease].
|
||||
/// * [increasedValue] and [attributedIncreasedValue], describes what
|
||||
/// * [increasedValue] and [attributedIncreasedValue], which describe what
|
||||
/// [value] will be after performing [SemanticsAction.increase].
|
||||
/// * [decreasedValue] and [attributedDecreasedValue], which describe what
|
||||
/// [value] will be after performing [SemanticsAction.decrease].
|
||||
String get value => _attributedValue.string;
|
||||
set value(String value) {
|
||||
assert(value != null);
|
||||
@ -3750,10 +3849,11 @@ class SemanticsConfiguration {
|
||||
///
|
||||
/// See also:
|
||||
///
|
||||
/// * [attributedDecreasedValue], describes what [value] will be after
|
||||
/// performing [SemanticsAction.decrease].
|
||||
/// * [attributedIncreasedValue], describes what [value] will be after
|
||||
/// * [value], which is the raw text of this property.
|
||||
/// * [attributedIncreasedValue], which describes what [value] will be after
|
||||
/// performing [SemanticsAction.increase].
|
||||
/// * [attributedDecreasedValue], which describes what [value] will be after
|
||||
/// performing [SemanticsAction.decrease].
|
||||
AttributedString get attributedValue => _attributedValue;
|
||||
AttributedString _attributedValue = AttributedString('');
|
||||
set attributedValue(AttributedString attributedValue) {
|
||||
@ -3761,38 +3861,6 @@ class SemanticsConfiguration {
|
||||
_hasBeenAnnotated = true;
|
||||
}
|
||||
|
||||
/// The value that [value] will have after performing a
|
||||
/// [SemanticsAction.decrease] action.
|
||||
///
|
||||
/// Setting this attribute will override the [attributedDecreasedValue].
|
||||
///
|
||||
/// One of the [attributedDecreasedValue] or [decreasedValue] must be set if
|
||||
/// a handler for [SemanticsAction.decrease] is provided and one of the
|
||||
/// [value] or [attributedValue] is set.
|
||||
///
|
||||
/// The reading direction is given by [textDirection].
|
||||
String get decreasedValue => _attributedDecreasedValue.string;
|
||||
set decreasedValue(String decreasedValue) {
|
||||
assert(decreasedValue != null);
|
||||
_attributedDecreasedValue = AttributedString(decreasedValue);
|
||||
_hasBeenAnnotated = true;
|
||||
}
|
||||
|
||||
/// The value that [value] will have after performing a
|
||||
/// [SemanticsAction.decrease] action in [AttributedString] format.
|
||||
///
|
||||
/// One of the [attributedDecreasedValue] or [decreasedValue] must be set if
|
||||
/// a handler for [SemanticsAction.decrease] is provided and one of the
|
||||
/// [value] or [attributedValue] is set.
|
||||
///
|
||||
/// The reading direction is given by [textDirection].
|
||||
AttributedString get attributedDecreasedValue => _attributedDecreasedValue;
|
||||
AttributedString _attributedDecreasedValue = AttributedString('');
|
||||
set attributedDecreasedValue(AttributedString attributedDecreasedValue) {
|
||||
_attributedDecreasedValue = attributedDecreasedValue;
|
||||
_hasBeenAnnotated = true;
|
||||
}
|
||||
|
||||
/// The value that [value] will have after performing a
|
||||
/// [SemanticsAction.increase] action.
|
||||
///
|
||||
@ -3803,6 +3871,10 @@ class SemanticsConfiguration {
|
||||
/// [value] or [attributedValue] is set.
|
||||
///
|
||||
/// The reading direction is given by [textDirection].
|
||||
///
|
||||
/// See also:
|
||||
///
|
||||
/// * [attributedIncreasedValue], which is the [AttributedString] of this property.
|
||||
String get increasedValue => _attributedIncreasedValue.string;
|
||||
set increasedValue(String increasedValue) {
|
||||
assert(increasedValue != null);
|
||||
@ -3818,6 +3890,10 @@ class SemanticsConfiguration {
|
||||
/// [value] or [attributedValue] is set.
|
||||
///
|
||||
/// The reading direction is given by [textDirection].
|
||||
///
|
||||
/// See also:
|
||||
///
|
||||
/// * [increasedValue], which is the raw text of this property.
|
||||
AttributedString get attributedIncreasedValue => _attributedIncreasedValue;
|
||||
AttributedString _attributedIncreasedValue = AttributedString('');
|
||||
set attributedIncreasedValue(AttributedString attributedIncreasedValue) {
|
||||
@ -3825,6 +3901,43 @@ class SemanticsConfiguration {
|
||||
_hasBeenAnnotated = true;
|
||||
}
|
||||
|
||||
/// The value that [value] will have after performing a
|
||||
/// [SemanticsAction.decrease] action.
|
||||
///
|
||||
/// Setting this attribute will override the [attributedDecreasedValue].
|
||||
///
|
||||
/// One of the [attributedDecreasedValue] or [decreasedValue] must be set if
|
||||
/// a handler for [SemanticsAction.decrease] is provided and one of the
|
||||
/// [value] or [attributedValue] is set.
|
||||
///
|
||||
/// The reading direction is given by [textDirection].
|
||||
///
|
||||
/// * [attributedDecreasedValue], which is the [AttributedString] of this property.
|
||||
String get decreasedValue => _attributedDecreasedValue.string;
|
||||
set decreasedValue(String decreasedValue) {
|
||||
assert(decreasedValue != null);
|
||||
_attributedDecreasedValue = AttributedString(decreasedValue);
|
||||
_hasBeenAnnotated = true;
|
||||
}
|
||||
|
||||
/// The value that [value] will have after performing a
|
||||
/// [SemanticsAction.decrease] action in [AttributedString] format.
|
||||
///
|
||||
/// One of the [attributedDecreasedValue] or [decreasedValue] must be set if
|
||||
/// a handler for [SemanticsAction.decrease] is provided and one of the
|
||||
/// [value] or [attributedValue] is set.
|
||||
///
|
||||
/// The reading direction is given by [textDirection].
|
||||
///
|
||||
/// See also:
|
||||
///
|
||||
/// * [decreasedValue], which is the raw text of this property.
|
||||
AttributedString get attributedDecreasedValue => _attributedDecreasedValue;
|
||||
AttributedString _attributedDecreasedValue = AttributedString('');
|
||||
set attributedDecreasedValue(AttributedString attributedDecreasedValue) {
|
||||
_attributedDecreasedValue = attributedDecreasedValue;
|
||||
_hasBeenAnnotated = true;
|
||||
}
|
||||
|
||||
/// A brief description of the result of performing an action on this node.
|
||||
///
|
||||
@ -3833,7 +3946,8 @@ class SemanticsConfiguration {
|
||||
/// The reading direction is given by [textDirection].
|
||||
///
|
||||
/// See also:
|
||||
/// * [attributedHint]: which is the [AttributedString] of this property.
|
||||
///
|
||||
/// * [attributedHint], which is the [AttributedString] of this property.
|
||||
String get hint => _attributedHint.string;
|
||||
set hint(String hint) {
|
||||
assert(hint != null);
|
||||
@ -3851,6 +3965,10 @@ class SemanticsConfiguration {
|
||||
/// concatenated value is then used as the `Text` description.
|
||||
///
|
||||
/// The reading direction is given by [textDirection].
|
||||
///
|
||||
/// See also:
|
||||
///
|
||||
/// * [hint], which is the raw text of this property.
|
||||
AttributedString get attributedHint => _attributedHint;
|
||||
AttributedString _attributedHint = AttributedString('');
|
||||
set attributedHint(AttributedString attributedHint) {
|
||||
|
@ -69,6 +69,10 @@ void main() {
|
||||
expect(config.label, 'label1');
|
||||
expect(config.attributedLabel.string, 'label1');
|
||||
expect(config.attributedLabel.attributes.isEmpty, isTrue);
|
||||
expect(
|
||||
(SemanticsNode()..updateWith(config: config)).toString(),
|
||||
'SemanticsNode#1(STALE, owner: null, Rect.fromLTRB(0.0, 0.0, 0.0, 0.0), invisible, label: "label1")',
|
||||
);
|
||||
|
||||
config.attributedLabel = AttributedString(
|
||||
'label2',
|
||||
@ -81,16 +85,28 @@ void main() {
|
||||
expect(config.attributedLabel.attributes.length, 1);
|
||||
expect(config.attributedLabel.attributes[0] is SpellOutStringAttribute, isTrue);
|
||||
expect(config.attributedLabel.attributes[0].range, const TextRange(start: 0, end: 1));
|
||||
expect(
|
||||
(SemanticsNode()..updateWith(config: config)).toString(),
|
||||
'SemanticsNode#2(STALE, owner: null, Rect.fromLTRB(0.0, 0.0, 0.0, 0.0), invisible, label: "label2" [SpellOutStringAttribute(TextRange(start: 0, end: 1))])',
|
||||
);
|
||||
|
||||
config.label = 'label3';
|
||||
expect(config.label, 'label3');
|
||||
expect(config.attributedLabel.string, 'label3');
|
||||
expect(config.attributedLabel.attributes.isEmpty, isTrue);
|
||||
expect(
|
||||
(SemanticsNode()..updateWith(config: config)).toString(),
|
||||
'SemanticsNode#3(STALE, owner: null, Rect.fromLTRB(0.0, 0.0, 0.0, 0.0), invisible, label: "label3")',
|
||||
);
|
||||
|
||||
config.value = 'value1';
|
||||
expect(config.value, 'value1');
|
||||
expect(config.attributedValue.string, 'value1');
|
||||
expect(config.attributedValue.attributes.isEmpty, isTrue);
|
||||
expect(
|
||||
(SemanticsNode()..updateWith(config: config)).toString(),
|
||||
'SemanticsNode#4(STALE, owner: null, Rect.fromLTRB(0.0, 0.0, 0.0, 0.0), invisible, label: "label3", value: "value1")',
|
||||
);
|
||||
|
||||
config.attributedValue = AttributedString(
|
||||
'value2',
|
||||
@ -103,16 +119,28 @@ void main() {
|
||||
expect(config.attributedValue.attributes.length, 1);
|
||||
expect(config.attributedValue.attributes[0] is SpellOutStringAttribute, isTrue);
|
||||
expect(config.attributedValue.attributes[0].range, const TextRange(start: 0, end: 1));
|
||||
expect(
|
||||
(SemanticsNode()..updateWith(config: config)).toString(),
|
||||
'SemanticsNode#5(STALE, owner: null, Rect.fromLTRB(0.0, 0.0, 0.0, 0.0), invisible, label: "label3", value: "value2" [SpellOutStringAttribute(TextRange(start: 0, end: 1))])',
|
||||
);
|
||||
|
||||
config.value = 'value3';
|
||||
expect(config.value, 'value3');
|
||||
expect(config.attributedValue.string, 'value3');
|
||||
expect(config.attributedValue.attributes.isEmpty, isTrue);
|
||||
expect(
|
||||
(SemanticsNode()..updateWith(config: config)).toString(),
|
||||
'SemanticsNode#6(STALE, owner: null, Rect.fromLTRB(0.0, 0.0, 0.0, 0.0), invisible, label: "label3", value: "value3")',
|
||||
);
|
||||
|
||||
config.hint = 'hint1';
|
||||
expect(config.hint, 'hint1');
|
||||
expect(config.attributedHint.string, 'hint1');
|
||||
expect(config.attributedHint.attributes.isEmpty, isTrue);
|
||||
expect(
|
||||
(SemanticsNode()..updateWith(config: config)).toString(),
|
||||
'SemanticsNode#7(STALE, owner: null, Rect.fromLTRB(0.0, 0.0, 0.0, 0.0), invisible, label: "label3", value: "value3", hint: "hint1")',
|
||||
);
|
||||
|
||||
config.attributedHint = AttributedString(
|
||||
'hint2',
|
||||
@ -125,11 +153,19 @@ void main() {
|
||||
expect(config.attributedHint.attributes.length, 1);
|
||||
expect(config.attributedHint.attributes[0] is SpellOutStringAttribute, isTrue);
|
||||
expect(config.attributedHint.attributes[0].range, const TextRange(start: 0, end: 1));
|
||||
expect(
|
||||
(SemanticsNode()..updateWith(config: config)).toString(),
|
||||
'SemanticsNode#8(STALE, owner: null, Rect.fromLTRB(0.0, 0.0, 0.0, 0.0), invisible, label: "label3", value: "value3", hint: "hint2" [SpellOutStringAttribute(TextRange(start: 0, end: 1))])',
|
||||
);
|
||||
|
||||
config.hint = 'hint3';
|
||||
expect(config.hint, 'hint3');
|
||||
expect(config.attributedHint.string, 'hint3');
|
||||
expect(config.attributedHint.attributes.isEmpty, isTrue);
|
||||
expect(
|
||||
(SemanticsNode()..updateWith(config: config)).toString(),
|
||||
'SemanticsNode#9(STALE, owner: null, Rect.fromLTRB(0.0, 0.0, 0.0, 0.0), invisible, label: "label3", value: "value3", hint: "hint3")',
|
||||
);
|
||||
});
|
||||
|
||||
test('mutate existing semantic node list errors', () {
|
||||
@ -654,6 +690,7 @@ void main() {
|
||||
expect(result.attributes.length, 2);
|
||||
expect(result.attributes[0].range, const TextRange(start:0, end:4));
|
||||
expect(result.attributes[0] is SpellOutStringAttribute, isTrue);
|
||||
expect(result.toString(), "AttributedString('string1string2', attributes: [SpellOutStringAttribute(TextRange(start: 0, end: 4)), LocaleStringAttribute(TextRange(start: 7, end: 11), es-MX)])");
|
||||
});
|
||||
|
||||
test('Semantics id does not repeat', () {
|
||||
|
@ -151,6 +151,17 @@ void main() {
|
||||
expect(SemanticsUpdateBuilderSpy.observations[1]!.hintAttributes![0] is SpellOutStringAttribute, isTrue);
|
||||
expect(SemanticsUpdateBuilderSpy.observations[1]!.hintAttributes![0].range, const TextRange(start: 1, end: 2));
|
||||
|
||||
expect(
|
||||
tester.widget(find.byType(Semantics)).toString(),
|
||||
'Semantics('
|
||||
'container: false, '
|
||||
'properties: SemanticsProperties, '
|
||||
'attributedLabel: "label" [SpellOutStringAttribute(TextRange(start: 0, end: 5))], '
|
||||
'attributedValue: "value" [LocaleStringAttribute(TextRange(start: 0, end: 5), en-MX)], '
|
||||
'attributedHint: "hint" [SpellOutStringAttribute(TextRange(start: 1, end: 2))]' // ignore: missing_whitespace_between_adjacent_strings
|
||||
')',
|
||||
);
|
||||
|
||||
SemanticsUpdateBuilderSpy.observations.clear();
|
||||
handle.dispose();
|
||||
});
|
||||
|
Loading…
x
Reference in New Issue
Block a user