-
Notifications
You must be signed in to change notification settings - Fork 29.7k
Theme.of provides all TextStyle properties #12552
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's too bad there's no way to force this test to be updated if any properties are added to TextStyle...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There is one way. Have a class in this file that "implements" TextStyle. The analyzer will flag this file whenever we add a member.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Wow, this trick is so devious that I implemented it.
|
LGTM, but I'd wait for @Hixie to confirm that this is the right way to go before merging. |
|
I would prefer the output of Theme.of to be a ThemeData whose text styles are all inherit:false. That way, if we add anything else to TextStyle, we don't have to keep updating ThemeData. |
Done (see 6885e8a). I wonder, however, if people would want to get Test case: var original = Theme.of(context);
return new Theme(
// This will fail during localization.
theme: original.copyWith(
accentTextTheme: someOtherTextTheme,
),
child: someWidget,
);One way to solve this is to not localize text styles that are inherit:false. Then in the example above we will localize |
|
Discussion:
|
6885e8a to
dd85edf
Compare
|
PTAL |
| accentTextTheme ??= accentIsDark ? typography.white : typography.black; | ||
| textTheme ??= (isDark ? typography.white : typography.black).apply(decoration: TextDecoration.none); | ||
| primaryTextTheme ??= (primaryIsDark ? typography.white : typography.black).apply(decoration: TextDecoration.none); | ||
| accentTextTheme ??= (accentIsDark ? typography.white : typography.black).apply(decoration: TextDecoration.none); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
how would you feel about either removing these additions (relying on the way we inherit from a base that doesn't have an underline) or hard-coding them into the constants? It seems weird to have these done in the middle-ground manner.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, now that the result of Theme.of no longer inherits from text styles, this property is not strictly necessary. However, I added the value to the Typography constants to be explicit that by default we do not have decorations rather than not having them as a side-effect of never setting them.
| String package, | ||
| }) : fontFamily = package == null ? fontFamily : 'packages/$package/$fontFamily', | ||
| assert(inherit != null); | ||
| debugLabel = debugLabel == null ? _kDefaultDebugLabel : debugLabel, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
debugLabel = debugLabel ?? _kDefaultDebugLabel
Or, if it doesn't interfere with other logic, just make it a default and assert non-null.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Alternatively, default to null, which will be more efficient in release builds and in comparisons against the default value, and only bringing _kDefaultDebugLabel when you need to merge strings (using debugLabel ?? _kDefaultDebugLabel)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Went with the last option: default to null, only bring in the default label when merging strings.
| assert(inherit != null); | ||
| debugLabel = debugLabel == null ? _kDefaultDebugLabel : debugLabel, | ||
| assert(inherit != null), | ||
| assert(debugLabel == null || debugLabel.length <= 100); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd avoid the maximum length. It's likely that we'll accidentally exceed it at some point when creating a lerp of a lerp of a lerp or some crazy thing.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
(...but need to see the whole length because it's meaningful in some way to what we're debugging, or something)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I guess maybe you added this because in regular operation we generate 1000-long messages? I defer to your judgement on this. If we do generate ridiculous chains in normal operation, let me know, though. That seems surprising.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Removed the cap. I was just paranoid. Easy to add later if we find a legitimate use-case for infinite chains of styles.
| /// A human-readable description of this text style. | ||
| /// | ||
| /// This property is not considered when comparing text styles using `==` or | ||
| /// [compareTo], and it does not affect [hashCode]. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
say something about it only being managed in debug builds.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
| /// Creates a copy of this text style but with the numeric fields multiplied | ||
| /// by the given factors and then incremented by the given deltas. | ||
| static String _capDebugLabelLength(String label) { | ||
| const int maxLabelLength = 100; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
i'd probably remove this entire function but if you do keep it:
- use the same constant everywhere (here and in the assert above)
- remove excessive braces
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done. Removed.
| /// replaced by the non-null parameters of the given text style. If the given | ||
| /// text style is null, simply returns this text style. | ||
| /// Returns a new text style that is a combination of this style and the given | ||
| /// [other] style, following the following rules. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
remove "following the following rules" because the first sentence needs to be able to stand alone.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
| /// | ||
| /// If the given [other] text style has its [TextStyle.inherit] set to true, | ||
| /// its null properties are replaced with the non-null properties of this text | ||
| /// style. It is said that the [other] style inherits properties of this |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd probably strike "It is said that", it's one of those phrases that when you really get down to it doesn't add anything meaningful to the docs (like my personal nemesis, "Note that...").
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done, but the sentence still doesn't quite sound right. Here I am trying introduce our nouns and verbs around the "inherit" flag and "merge" method. When you "a.merge(b)" you can say "b inherits properties of a".
| /// simply returns the given [other] style unchanged. It is said that the | ||
| /// [other] style does not inherit properties of this style. | ||
| /// | ||
| /// If the given text style is null, simply returns this text style. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
similarly with "simply". It just leads to people muttering "doesn't seem so simple to me" to themselves.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
not that i ever mutter to myself when reading documentation. no sir.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done. This was there already. I just reformatted the sentence.
| void debugFillProperties(DiagnosticPropertiesBuilder properties, { String prefix: '' }) { | ||
| super.debugFillProperties(properties); | ||
| if (debugLabel != _kDefaultDebugLabel) | ||
| properties.add(new StringProperty('${prefix}debugLabel', debugLabel, defaultValue: null)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
probably showName: false? Or maybe this is a MessageProperty? Check to see what @jacob314 did with the other debugLabels.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
showName: false sounds reasonable. I don't see any other debugLabel properties added as diagnosticProperty. Generally, if you thing debugLabel does conceptually represent a property name, StringProperty is what you want. If debugLabel is just a debugging message you want to show than MessageProperty is what you want.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks! Switched to MessageProperty.
| TextStyle cappedCopy = foo; | ||
| TextStyle cappedApply = foo; | ||
| TextStyle cappedLerp = foo; | ||
| for (int i = 0; i < 50; i++) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
i += 1 (my preference) or ++i
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is gone now.
| expect(TextStyle.lerp(foo, bar, 0.5).debugLabel, 'lerp(foo, bar)'); | ||
| expect(TextStyle.lerp(foo.merge(bar), baz, 0.5).copyWith().debugLabel, 'copy of lerp(bar < foo, baz)'); | ||
|
|
||
| expect(() => new TextStyle(debugLabel: 'a' * 300), throwsA(const isInstanceOf<AssertionError>())); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
you can import flutter_test and use throwsAssertionError
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is gone now.
Fixes #12548
Fixes #12550
See also #12537
This adds
decorationproperty toTextStyles vended byTheme.of.