Commit ee903af0 authored by Adam Barth's avatar Adam Barth

Move TextAlign out of TextStyle (#3789)

TextAlign applies to a whole paragraph instead of applying to an individual
text span. This patch moves the property out of TextStyle and into a separate
property on Text and RichText.
parent 8f4a5659
...@@ -32,13 +32,12 @@ class CardCollectionState extends State<CardCollection> { ...@@ -32,13 +32,12 @@ class CardCollectionState extends State<CardCollection> {
static const double kCardMargins = 8.0; static const double kCardMargins = 8.0;
static const double kFixedCardHeight = 100.0; static const double kFixedCardHeight = 100.0;
final TextStyle backgroundTextStyle = final TextStyle backgroundTextStyle = Typography.white.title;
Typography.white.title.copyWith(textAlign: TextAlign.center);
Map<int, Color> _primaryColor = Colors.deepPurple; Map<int, Color> _primaryColor = Colors.deepPurple;
List<CardModel> _cardModels; List<CardModel> _cardModels;
DismissDirection _dismissDirection = DismissDirection.horizontal; DismissDirection _dismissDirection = DismissDirection.horizontal;
TextStyle _textStyle = new TextStyle(textAlign: TextAlign.center); TextAlign _textAlign = TextAlign.center;
bool _editable = false; bool _editable = false;
bool _snapToCenter = false; bool _snapToCenter = false;
bool _fixedSizeCards = false; bool _fixedSizeCards = false;
...@@ -143,9 +142,9 @@ class CardCollectionState extends State<CardCollection> { ...@@ -143,9 +142,9 @@ class CardCollectionState extends State<CardCollection> {
buildDrawerDirectionRadioItem("Dismiss left", DismissDirection.endToStart, _dismissDirection, _changeDismissDirection, icon: Icons.arrow_back), buildDrawerDirectionRadioItem("Dismiss left", DismissDirection.endToStart, _dismissDirection, _changeDismissDirection, icon: Icons.arrow_back),
buildDrawerDirectionRadioItem("Dismiss right", DismissDirection.startToEnd, _dismissDirection, _changeDismissDirection, icon: Icons.arrow_forward), buildDrawerDirectionRadioItem("Dismiss right", DismissDirection.startToEnd, _dismissDirection, _changeDismissDirection, icon: Icons.arrow_forward),
new Divider(), new Divider(),
buildFontRadioItem("Left-align text", new TextStyle(textAlign: TextAlign.left), _textStyle, _changeTextStyle, icon: Icons.format_align_left, enabled: !_editable), buildFontRadioItem("Left-align text", TextAlign.left, _textAlign, _changeTextAlign, icon: Icons.format_align_left, enabled: !_editable),
buildFontRadioItem("Center-align text", new TextStyle(textAlign: TextAlign.center), _textStyle, _changeTextStyle, icon: Icons.format_align_center, enabled: !_editable), buildFontRadioItem("Center-align text", TextAlign.center, _textAlign, _changeTextAlign, icon: Icons.format_align_center, enabled: !_editable),
buildFontRadioItem("Right-align text", new TextStyle(textAlign: TextAlign.right), _textStyle, _changeTextStyle, icon: Icons.format_align_right, enabled: !_editable), buildFontRadioItem("Right-align text", TextAlign.right, _textAlign, _changeTextAlign, icon: Icons.format_align_right, enabled: !_editable),
new Divider(), new Divider(),
new DrawerItem( new DrawerItem(
icon: Icons.dvr, icon: Icons.dvr,
...@@ -205,9 +204,9 @@ class CardCollectionState extends State<CardCollection> { ...@@ -205,9 +204,9 @@ class CardCollectionState extends State<CardCollection> {
}); });
} }
void _changeTextStyle(TextStyle newTextStyle) { void _changeTextAlign(TextAlign newTextAlign) {
setState(() { setState(() {
_textStyle = newTextStyle; _textAlign = newTextAlign;
}); });
} }
...@@ -260,14 +259,14 @@ class CardCollectionState extends State<CardCollection> { ...@@ -260,14 +259,14 @@ class CardCollectionState extends State<CardCollection> {
); );
} }
Widget buildFontRadioItem(String label, TextStyle itemValue, TextStyle currentValue, ValueChanged<TextStyle> onChanged, { IconData icon, bool enabled: true }) { Widget buildFontRadioItem(String label, TextAlign itemValue, TextAlign currentValue, ValueChanged<TextAlign> onChanged, { IconData icon, bool enabled: true }) {
return new DrawerItem( return new DrawerItem(
icon: icon, icon: icon,
onPressed: enabled ? () { onChanged(itemValue); } : null, onPressed: enabled ? () { onChanged(itemValue); } : null,
child: new Row( child: new Row(
children: <Widget>[ children: <Widget>[
new Flexible(child: new Text(label)), new Flexible(child: new Text(label)),
new Radio<TextStyle>( new Radio<TextAlign>(
value: itemValue, value: itemValue,
groupValue: currentValue, groupValue: currentValue,
onChanged: enabled ? onChanged : null onChanged: enabled ? onChanged : null
...@@ -319,16 +318,17 @@ class CardCollectionState extends State<CardCollection> { ...@@ -319,16 +318,17 @@ class CardCollectionState extends State<CardCollection> {
} }
) )
) )
: new DefaultTextStyle( : new DefaultTextStyle.inherit(
style: DefaultTextStyle.of(context).merge(cardLabelStyle).merge(_textStyle).copyWith( context: context,
style: cardLabelStyle.copyWith(
fontSize: _varyFontSizes ? 5.0 + index : null fontSize: _varyFontSizes ? 5.0 + index : null
), ),
child: new Column( child: new Column(
children: <Widget>[
new Text(cardModel.inputValue.text)
],
crossAxisAlignment: CrossAxisAlignment.stretch, crossAxisAlignment: CrossAxisAlignment.stretch,
mainAxisAlignment: MainAxisAlignment.center mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
new Text(cardModel.inputValue.text, textAlign: _textAlign)
]
) )
) )
) )
...@@ -379,7 +379,12 @@ class CardCollectionState extends State<CardCollection> { ...@@ -379,7 +379,12 @@ class CardCollectionState extends State<CardCollection> {
child: new Row( child: new Row(
children: <Widget>[ children: <Widget>[
leftArrowIcon, leftArrowIcon,
new Flexible(child: new Text(backgroundMessage, style: backgroundTextStyle)), new Flexible(
child: new Text(backgroundMessage,
style: backgroundTextStyle,
textAlign: TextAlign.center
)
),
rightArrowIcon rightArrowIcon
] ]
) )
......
...@@ -98,7 +98,8 @@ class ExampleDragSource extends StatelessWidget { ...@@ -98,7 +98,8 @@ class ExampleDragSource extends StatelessWidget {
size *= kHeavyMultiplier; size *= kHeavyMultiplier;
Widget contents = new DefaultTextStyle( Widget contents = new DefaultTextStyle(
style: Theme.of(context).textTheme.body1.copyWith(textAlign: TextAlign.center), style: Theme.of(context).textTheme.body1,
textAlign: TextAlign.center,
child: new Dot( child: new Dot(
color: color, color: color,
size: size, size: size,
...@@ -185,10 +186,8 @@ class MovableBall extends StatelessWidget { ...@@ -185,10 +186,8 @@ class MovableBall extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
Widget ball = new DefaultTextStyle( Widget ball = new DefaultTextStyle(
style: Theme.of(context).textTheme.body1.copyWith( style: Typography.white.body1,
textAlign: TextAlign.center, textAlign: TextAlign.center,
color: Colors.white
),
child: new Dot( child: new Dot(
key: kBallKey, key: kBallKey,
color: Colors.blue[700], color: Colors.blue[700],
......
...@@ -4,15 +4,14 @@ ...@@ -4,15 +4,14 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
final TextStyle _kTextStyle = new TextStyle(
color: Colors.indigo[400],
fontSize: 24.0
);
class ModalBottomSheetDemo extends StatelessWidget { class ModalBottomSheetDemo extends StatelessWidget {
static const String routeName = '/modal-bottom-sheet'; static const String routeName = '/modal-bottom-sheet';
final TextStyle textStyle = new TextStyle(
color: Colors.indigo[400],
fontSize: 24.0,
textAlign: TextAlign.center
);
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return new Scaffold( return new Scaffold(
...@@ -25,7 +24,10 @@ class ModalBottomSheetDemo extends StatelessWidget { ...@@ -25,7 +24,10 @@ class ModalBottomSheetDemo extends StatelessWidget {
return new Container( return new Container(
child: new Padding( child: new Padding(
padding: const EdgeInsets.all(32.0), padding: const EdgeInsets.all(32.0),
child: new Text('This is the modal bottom sheet. Click anywhere to dismiss.', style: textStyle) child: new Text('This is the modal bottom sheet. Click anywhere to dismiss.',
style: _kTextStyle,
textAlign: TextAlign.center
)
) )
); );
}); });
......
...@@ -4,6 +4,11 @@ ...@@ -4,6 +4,11 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
final TextStyle _kTextStyle = new TextStyle(
color: Colors.indigo[400],
fontSize: 24.0
);
class PersistentBottomSheetDemo extends StatefulWidget { class PersistentBottomSheetDemo extends StatefulWidget {
static const String routeName = '/persistent-bottom-sheet'; static const String routeName = '/persistent-bottom-sheet';
...@@ -14,12 +19,6 @@ class PersistentBottomSheetDemo extends StatefulWidget { ...@@ -14,12 +19,6 @@ class PersistentBottomSheetDemo extends StatefulWidget {
class _PersistentBottomSheetDemoState extends State<PersistentBottomSheetDemo> { class _PersistentBottomSheetDemoState extends State<PersistentBottomSheetDemo> {
final GlobalKey<ScaffoldState> _scaffoldKey = new GlobalKey<ScaffoldState>(); final GlobalKey<ScaffoldState> _scaffoldKey = new GlobalKey<ScaffoldState>();
final TextStyle textStyle = new TextStyle(
color: Colors.indigo[400],
fontSize: 24.0,
textAlign: TextAlign.center
);
VoidCallback _showBottomSheetCallback; VoidCallback _showBottomSheetCallback;
@override @override
...@@ -40,7 +39,10 @@ class _PersistentBottomSheetDemoState extends State<PersistentBottomSheetDemo> { ...@@ -40,7 +39,10 @@ class _PersistentBottomSheetDemoState extends State<PersistentBottomSheetDemo> {
), ),
child: new Padding( child: new Padding(
padding: const EdgeInsets.all(32.0), padding: const EdgeInsets.all(32.0),
child: new Text('This is a Material persistent bottom sheet. Drag downwards to dismiss it.', style: textStyle) child: new Text('This is a Material persistent bottom sheet. Drag downwards to dismiss it.',
style: _kTextStyle,
textAlign: TextAlign.center
)
) )
); );
}) })
......
...@@ -72,18 +72,18 @@ class _TabsFabDemoState extends State<TabsFabDemo> { ...@@ -72,18 +72,18 @@ class _TabsFabDemoState extends State<TabsFabDemo> {
Widget buildTabView(_Page page) { Widget buildTabView(_Page page) {
return new Builder( return new Builder(
builder: (BuildContext context) { builder: (BuildContext context) {
final TextStyle textStyle = new TextStyle(
color: page.labelColor,
fontSize: 32.0,
textAlign: TextAlign.center
);
return new Container( return new Container(
key: new ValueKey<String>(page.label), key: new ValueKey<String>(page.label),
padding: const EdgeInsets.fromLTRB(48.0, 48.0, 48.0, 96.0), padding: const EdgeInsets.fromLTRB(48.0, 48.0, 48.0, 96.0),
child: new Card( child: new Card(
child: new Center( child: new Center(
child: new Text(page.label, style: textStyle) child: new Text(page.label,
style: new TextStyle(
color: page.labelColor,
fontSize: 32.0
),
textAlign: TextAlign.center
)
) )
) )
); );
......
...@@ -100,18 +100,18 @@ class StockRow extends StatelessWidget { ...@@ -100,18 +100,18 @@ class StockRow extends StatelessWidget {
new Flexible( new Flexible(
child: new Text( child: new Text(
lastSale, lastSale,
style: const TextStyle(textAlign: TextAlign.right) textAlign: TextAlign.right
) )
), ),
new Flexible( new Flexible(
child: new Text( child: new Text(
changeInPrice, changeInPrice,
style: const TextStyle(textAlign: TextAlign.right) textAlign: TextAlign.right
) )
), ),
], ],
crossAxisAlignment: CrossAxisAlignment.baseline, crossAxisAlignment: CrossAxisAlignment.baseline,
textBaseline: DefaultTextStyle.of(context).textBaseline textBaseline: DefaultTextStyle.of(context).style.textBaseline
) )
), ),
] ]
......
...@@ -52,7 +52,7 @@ class StockSymbolView extends StatelessWidget { ...@@ -52,7 +52,7 @@ class StockSymbolView extends StatelessWidget {
), ),
new RichText( new RichText(
text: new TextSpan( text: new TextSpan(
style: DefaultTextStyle.of(context).merge(new TextStyle(fontSize: 8.0)), style: DefaultTextStyle.of(context).style.merge(new TextStyle(fontSize: 8.0)),
text: 'Prices may be delayed by ', text: 'Prices may be delayed by ',
children: <TextSpan>[ children: <TextSpan>[
new TextSpan(text: 'several', style: new TextStyle(fontStyle: FontStyle.italic)), new TextSpan(text: 'several', style: new TextStyle(fontStyle: FontStyle.italic)),
......
...@@ -16,7 +16,6 @@ const TextStyle _errorTextStyle = const TextStyle( ...@@ -16,7 +16,6 @@ const TextStyle _errorTextStyle = const TextStyle(
fontFamily: 'monospace', fontFamily: 'monospace',
fontSize: 48.0, fontSize: 48.0,
fontWeight: FontWeight.w900, fontWeight: FontWeight.w900,
textAlign: TextAlign.right,
decoration: TextDecoration.underline, decoration: TextDecoration.underline,
decorationColor: const Color(0xFFFFFF00), decorationColor: const Color(0xFFFFFF00),
decorationStyle: TextDecorationStyle.double decorationStyle: TextDecorationStyle.double
......
...@@ -274,7 +274,7 @@ List<TextPainter> _initPainters(List<String> labels) { ...@@ -274,7 +274,7 @@ List<TextPainter> _initPainters(List<String> labels) {
for (int i = 0; i < painters.length; ++i) { for (int i = 0; i < painters.length; ++i) {
String label = labels[i]; String label = labels[i];
painters[i] = new TextPainter( painters[i] = new TextPainter(
new TextSpan(style: style, text: label) text: new TextSpan(style: style, text: label)
)..layout(); )..layout();
} }
return painters; return painters;
......
...@@ -30,8 +30,11 @@ class TextPainter { ...@@ -30,8 +30,11 @@ class TextPainter {
/// ///
/// The text argument is optional but [text] must be non-null before calling /// The text argument is optional but [text] must be non-null before calling
/// [layout]. /// [layout].
TextPainter([ TextSpan text ]) { TextPainter({
this.text = text; TextSpan text,
TextAlign textAlign
}) : _text = text, _textAlign = textAlign {
assert(text == null || text.debugAssertValid());
} }
ui.Paragraph _paragraph; ui.Paragraph _paragraph;
...@@ -45,15 +48,19 @@ class TextPainter { ...@@ -45,15 +48,19 @@ class TextPainter {
if (_text == value) if (_text == value)
return; return;
_text = value; _text = value;
if (_text != null) { _paragraph = null;
ui.ParagraphBuilder builder = new ui.ParagraphBuilder(); _needsLayout = true;
_text.build(builder); }
_paragraph = builder.build(_text.style?.paragraphStyle ?? new ui.ParagraphStyle());
_needsLayout = true; /// How the text should be aligned horizontally.
} else { TextAlign get textAlign => _textAlign;
_paragraph = null; TextAlign _textAlign;
_needsLayout = false; void set textAlign(TextAlign value) {
} if (_textAlign == value)
return;
_textAlign = value;
_paragraph = null;
_needsLayout = true;
} }
// Unfortunately, using full precision floating point here causes bad layouts // Unfortunately, using full precision floating point here causes bad layouts
...@@ -129,9 +136,17 @@ class TextPainter { ...@@ -129,9 +136,17 @@ class TextPainter {
/// width as possible while still being greater than or equal to minWidth and /// width as possible while still being greater than or equal to minWidth and
/// less than or equal to maxWidth. /// less than or equal to maxWidth.
void layout({ double minWidth: 0.0, double maxWidth: double.INFINITY }) { void layout({ double minWidth: 0.0, double maxWidth: double.INFINITY }) {
assert(_text != null);
if (!_needsLayout && minWidth == _lastMinWidth && maxWidth == _lastMaxWidth) if (!_needsLayout && minWidth == _lastMinWidth && maxWidth == _lastMaxWidth)
return; return;
_needsLayout = false; _needsLayout = false;
if (_paragraph == null) {
ui.ParagraphBuilder builder = new ui.ParagraphBuilder();
_text.build(builder);
ui.ParagraphStyle paragraphStyle = _text.style?.getParagraphStyle(textAlign: textAlign);
paragraphStyle ??= new ui.ParagraphStyle();
_paragraph = builder.build(paragraphStyle);
}
_lastMinWidth = minWidth; _lastMinWidth = minWidth;
_lastMaxWidth = maxWidth; _lastMaxWidth = maxWidth;
_paragraph.layout(new ui.ParagraphConstraints(width: maxWidth)); _paragraph.layout(new ui.ParagraphConstraints(width: maxWidth));
......
...@@ -18,7 +18,6 @@ class TextStyle { ...@@ -18,7 +18,6 @@ class TextStyle {
this.fontStyle, this.fontStyle,
this.letterSpacing, this.letterSpacing,
this.wordSpacing, this.wordSpacing,
this.textAlign,
this.textBaseline, this.textBaseline,
this.height, this.height,
this.decoration, this.decoration,
...@@ -50,10 +49,6 @@ class TextStyle { ...@@ -50,10 +49,6 @@ class TextStyle {
/// The amount of space (in logical pixels) to add at each sequence of white-space (i.e. between each word). /// The amount of space (in logical pixels) to add at each sequence of white-space (i.e. between each word).
final double wordSpacing; final double wordSpacing;
/// How the text should be aligned (applies only to the outermost
/// StyledTextSpan, which establishes the container for the text).
final TextAlign textAlign;
/// The baseline to use for aligning the text. /// The baseline to use for aligning the text.
final TextBaseline textBaseline; final TextBaseline textBaseline;
...@@ -82,7 +77,6 @@ class TextStyle { ...@@ -82,7 +77,6 @@ class TextStyle {
FontStyle fontStyle, FontStyle fontStyle,
double letterSpacing, double letterSpacing,
double wordSpacing, double wordSpacing,
TextAlign textAlign,
TextBaseline textBaseline, TextBaseline textBaseline,
double height, double height,
TextDecoration decoration, TextDecoration decoration,
...@@ -98,7 +92,6 @@ class TextStyle { ...@@ -98,7 +92,6 @@ class TextStyle {
fontStyle: fontStyle != null ? fontStyle : this.fontStyle, fontStyle: fontStyle != null ? fontStyle : this.fontStyle,
letterSpacing: letterSpacing != null ? letterSpacing : this.letterSpacing, letterSpacing: letterSpacing != null ? letterSpacing : this.letterSpacing,
wordSpacing: wordSpacing != null ? wordSpacing : this.wordSpacing, wordSpacing: wordSpacing != null ? wordSpacing : this.wordSpacing,
textAlign: textAlign != null ? textAlign : this.textAlign,
textBaseline: textBaseline != null ? textBaseline : this.textBaseline, textBaseline: textBaseline != null ? textBaseline : this.textBaseline,
height: height != null ? height : this.height, height: height != null ? height : this.height,
decoration: decoration != null ? decoration : this.decoration, decoration: decoration != null ? decoration : this.decoration,
...@@ -122,7 +115,6 @@ class TextStyle { ...@@ -122,7 +115,6 @@ class TextStyle {
fontStyle: other.fontStyle, fontStyle: other.fontStyle,
letterSpacing: other.letterSpacing, letterSpacing: other.letterSpacing,
wordSpacing: other.wordSpacing, wordSpacing: other.wordSpacing,
textAlign: other.textAlign,
textBaseline: other.textBaseline, textBaseline: other.textBaseline,
height: other.height, height: other.height,
decoration: other.decoration, decoration: other.decoration,
...@@ -146,7 +138,6 @@ class TextStyle { ...@@ -146,7 +138,6 @@ class TextStyle {
fontStyle: t < 0.5 ? begin.fontStyle : end.fontStyle, fontStyle: t < 0.5 ? begin.fontStyle : end.fontStyle,
letterSpacing: ui.lerpDouble(begin.letterSpacing ?? end.letterSpacing, end.letterSpacing ?? begin.letterSpacing, t), letterSpacing: ui.lerpDouble(begin.letterSpacing ?? end.letterSpacing, end.letterSpacing ?? begin.letterSpacing, t),
wordSpacing: ui.lerpDouble(begin.wordSpacing ?? end.wordSpacing, end.wordSpacing ?? begin.wordSpacing, t), wordSpacing: ui.lerpDouble(begin.wordSpacing ?? end.wordSpacing, end.wordSpacing ?? begin.wordSpacing, t),
textAlign: t < 0.5 ? begin.textAlign : end.textAlign,
textBaseline: t < 0.5 ? begin.textBaseline : end.textBaseline, textBaseline: t < 0.5 ? begin.textBaseline : end.textBaseline,
height: ui.lerpDouble(begin.height ?? end.height, end.height ?? begin.height, t), height: ui.lerpDouble(begin.height ?? end.height, end.height ?? begin.height, t),
decoration: t < 0.5 ? begin.decoration : end.decoration, decoration: t < 0.5 ? begin.decoration : end.decoration,
...@@ -173,7 +164,7 @@ class TextStyle { ...@@ -173,7 +164,7 @@ class TextStyle {
} }
/// The style information for paragraphs, encoded for use by `dart:ui`. /// The style information for paragraphs, encoded for use by `dart:ui`.
ui.ParagraphStyle get paragraphStyle { ui.ParagraphStyle getParagraphStyle({ TextAlign textAlign }) {
return new ui.ParagraphStyle( return new ui.ParagraphStyle(
textAlign: textAlign, textAlign: textAlign,
textBaseline: textBaseline, textBaseline: textBaseline,
...@@ -200,7 +191,6 @@ class TextStyle { ...@@ -200,7 +191,6 @@ class TextStyle {
fontStyle == typedOther.fontStyle && fontStyle == typedOther.fontStyle &&
letterSpacing == typedOther.letterSpacing && letterSpacing == typedOther.letterSpacing &&
wordSpacing == typedOther.wordSpacing && wordSpacing == typedOther.wordSpacing &&
textAlign == typedOther.textAlign &&
textBaseline == typedOther.textBaseline && textBaseline == typedOther.textBaseline &&
height == typedOther.height && height == typedOther.height &&
decoration == typedOther.decoration && decoration == typedOther.decoration &&
...@@ -219,7 +209,6 @@ class TextStyle { ...@@ -219,7 +209,6 @@ class TextStyle {
fontStyle, fontStyle,
letterSpacing, letterSpacing,
wordSpacing, wordSpacing,
textAlign,
textBaseline, textBaseline,
height, height,
decoration, decoration,
...@@ -283,19 +272,6 @@ class TextStyle { ...@@ -283,19 +272,6 @@ class TextStyle {
result.add('${prefix}letterSpacing: ${letterSpacing}x'); result.add('${prefix}letterSpacing: ${letterSpacing}x');
if (wordSpacing != null) if (wordSpacing != null)
result.add('${prefix}wordSpacing: ${wordSpacing}x'); result.add('${prefix}wordSpacing: ${wordSpacing}x');
if (textAlign != null) {
switch (textAlign) {
case TextAlign.left:
result.add('${prefix}align: left');
break;
case TextAlign.right:
result.add('${prefix}align: right');
break;
case TextAlign.center:
result.add('${prefix}align: center');
break;
}
}
if (textBaseline != null) { if (textBaseline != null) {
switch (textBaseline) { switch (textBaseline) {
case TextBaseline.alphabetic: case TextBaseline.alphabetic:
......
...@@ -287,8 +287,9 @@ class RenderChildView extends RenderBox { ...@@ -287,8 +287,9 @@ class RenderChildView extends RenderBox {
_child._setChildProperties(_physicalWidth, _physicalHeight, scale); _child._setChildProperties(_physicalWidth, _physicalHeight, scale);
assert(() { assert(() {
if (_view == null) { if (_view == null) {
_debugErrorMessage ??= new TextPainter() _debugErrorMessage ??= new TextPainter(
..text = new TextSpan(text: 'Child view are supported only when running in Mojo shell.'); text: new TextSpan(text: 'Child views are supported only when running in Mojo shell.')
);
_debugErrorMessage.layout(minWidth: size.width, maxWidth: size.width); _debugErrorMessage.layout(minWidth: size.width, maxWidth: size.width);
} }
return true; return true;
......
...@@ -42,7 +42,7 @@ class RenderEditableLine extends RenderBox { ...@@ -42,7 +42,7 @@ class RenderEditableLine extends RenderBox {
this.onSelectionChanged, this.onSelectionChanged,
Offset paintOffset: Offset.zero, Offset paintOffset: Offset.zero,
this.onPaintOffsetUpdateNeeded this.onPaintOffsetUpdateNeeded
}) : _textPainter = new TextPainter(text), }) : _textPainter = new TextPainter(text: text),
_cursorColor = cursorColor, _cursorColor = cursorColor,
_showCursor = showCursor, _showCursor = showCursor,
_selection = selection, _selection = selection,
......
...@@ -11,9 +11,9 @@ import 'semantics.dart'; ...@@ -11,9 +11,9 @@ import 'semantics.dart';
/// A render object that displays a paragraph of text /// A render object that displays a paragraph of text
class RenderParagraph extends RenderBox { class RenderParagraph extends RenderBox {
RenderParagraph( RenderParagraph(TextSpan text, {
TextSpan text TextAlign textAlign
) : _textPainter = new TextPainter(text) { }) : _textPainter = new TextPainter(text: text, textAlign: textAlign) {
assert(text != null); assert(text != null);
assert(text.debugAssertValid()); assert(text.debugAssertValid());
} }
...@@ -23,13 +23,22 @@ class RenderParagraph extends RenderBox { ...@@ -23,13 +23,22 @@ class RenderParagraph extends RenderBox {
/// The text to display /// The text to display
TextSpan get text => _textPainter.text; TextSpan get text => _textPainter.text;
void set text(TextSpan value) { void set text(TextSpan value) {
assert(value.debugAssertValid()); assert(value != null);
if (_textPainter.text == value) if (_textPainter.text == value)
return; return;
_textPainter.text = value; _textPainter.text = value;
markNeedsLayout(); markNeedsLayout();
} }
/// How the text should be aligned horizontally.
TextAlign get textAlign => _textPainter.textAlign;
void set textAlign(TextAlign value) {
if (_textPainter.textAlign == value)
return;
_textPainter.textAlign = value;
markNeedsPaint();
}
void _layoutText(BoxConstraints constraints) { void _layoutText(BoxConstraints constraints) {
assert(constraints != null); assert(constraints != null);
assert(constraints.debugAssertIsValid()); assert(constraints.debugAssertIsValid());
...@@ -101,6 +110,9 @@ class RenderParagraph extends RenderBox { ...@@ -101,6 +110,9 @@ class RenderParagraph extends RenderBox {
// //
// TODO(abarth): Make computing the min/max intrinsic width/height // TODO(abarth): Make computing the min/max intrinsic width/height
// a non-destructive operation. // a non-destructive operation.
//
// If you remove this call, make sure that changing the textAlign still
// works properly.
_layoutText(constraints); _layoutText(constraints);
_textPainter.paint(context.canvas, offset); _textPainter.paint(context.canvas, offset);
} }
......
...@@ -15,7 +15,6 @@ const TextStyle _kTextStyles = const TextStyle( ...@@ -15,7 +15,6 @@ const TextStyle _kTextStyles = const TextStyle(
color: const Color(0xFFFFFFFF), color: const Color(0xFFFFFFFF),
fontSize: _kHeight * 0.85, fontSize: _kHeight * 0.85,
fontWeight: FontWeight.w900, fontWeight: FontWeight.w900,
textAlign: TextAlign.center,
height: 1.0 height: 1.0
); );
...@@ -64,9 +63,10 @@ class BannerPainter extends CustomPainter { ...@@ -64,9 +63,10 @@ class BannerPainter extends CustomPainter {
..drawRect(_kRect, paintBanner); ..drawRect(_kRect, paintBanner);
final double width = _kOffset * 2.0; final double width = _kOffset * 2.0;
final TextPainter textPainter = new TextPainter() final TextPainter textPainter = new TextPainter(
..text = new TextSpan(style: _kTextStyles, text: message) text: new TextSpan(style: _kTextStyles, text: message),
..layout(minWidth: width, maxWidth: width); textAlign: TextAlign.center
)..layout(minWidth: width, maxWidth: width);
textPainter.paint(canvas, _kRect.topLeft.toOffset() + new Offset(0.0, (_kRect.height - textPainter.height) / 2.0)); textPainter.paint(canvas, _kRect.topLeft.toOffset() + new Offset(0.0, (_kRect.height - textPainter.height) / 2.0));
} }
......
...@@ -1904,40 +1904,84 @@ class RichText extends LeafRenderObjectWidget { ...@@ -1904,40 +1904,84 @@ class RichText extends LeafRenderObjectWidget {
/// Creates a paragraph of rich text. /// Creates a paragraph of rich text.
/// ///
/// The [text] argument is required to be non-null. /// The [text] argument is required to be non-null.
RichText({ Key key, this.text }) : super(key: key) { RichText({ Key key, this.text, this.textAlign }) : super(key: key) {
assert(text != null); assert(text != null);
} }
/// The text to display in this widget. /// The text to display in this widget.
final TextSpan text; final TextSpan text;
/// How the text should be aligned horizontally.
final TextAlign textAlign;
@override @override
RenderParagraph createRenderObject(BuildContext context) => new RenderParagraph(text); RenderParagraph createRenderObject(BuildContext context) {
return new RenderParagraph(text, textAlign: textAlign);
}
@override @override
void updateRenderObject(BuildContext context, RenderParagraph renderObject) { void updateRenderObject(BuildContext context, RenderParagraph renderObject) {
renderObject.text = text; renderObject
..text = text
..textAlign = textAlign;
} }
} }
/// The text style to apply to descendant [Text] widgets without explicit style. /// The text style to apply to descendant [Text] widgets without explicit style.
class DefaultTextStyle extends InheritedWidget { class DefaultTextStyle extends InheritedWidget {
/// Creates a default text style for the given subtree.
///
/// Consider using [DefaultTextStyle.inherit] to inherit styling information
/// from a the current default text style for a given [BuildContext].
DefaultTextStyle({ DefaultTextStyle({
Key key, Key key,
this.style, this.style,
this.textAlign,
Widget child Widget child
}) : super(key: key, child: child) { }) : super(key: key, child: child) {
assert(style != null); assert(style != null);
assert(child != null); assert(child != null);
} }
/// A const-constructible default text style that provides fallback values.
///
/// Returned from [of] when the given [BuildContext] doesn't have an enclosing default text style.
const DefaultTextStyle.fallback() : style = const TextStyle(), textAlign = null;
/// Creates a default text style that inherits from the given [BuildContext].
///
/// The given [style] is merged with the [style] from the default text style
/// for the given [BuildContext] and, if non-null, the given [textAlign]
/// replaces the [textAlign] from the default text style for the given
/// [BuildContext].
factory DefaultTextStyle.inherit({
Key key,
BuildContext context,
TextStyle style,
TextAlign textAlign,
Widget child
}) {
DefaultTextStyle parent = DefaultTextStyle.of(context);
return new DefaultTextStyle(
key: key,
style: parent.style.merge(style),
textAlign: textAlign ?? parent.textAlign,
child: child
);
}
/// The text style to apply. /// The text style to apply.
final TextStyle style; final TextStyle style;
/// The style from the closest instance of this class that encloses the given context. /// How the text should be aligned horizontally.
static TextStyle of(BuildContext context) { final TextAlign textAlign;
DefaultTextStyle result = context.inheritFromWidgetOfExactType(DefaultTextStyle);
return result?.style ?? const TextStyle(); /// The closest instance of this class that encloses the given context.
///
/// If no such instance exists, returns an instance created by
/// [DefaultTextStyle.fallback], which contains fallback values.
static DefaultTextStyle of(BuildContext context) {
return context.inheritFromWidgetOfExactType(DefaultTextStyle) ?? const DefaultTextStyle.fallback();
} }
@override @override
...@@ -1975,7 +2019,7 @@ class Text extends StatelessWidget { ...@@ -1975,7 +2019,7 @@ class Text extends StatelessWidget {
/// ///
/// If the [style] argument is null, the text will use the style from the /// If the [style] argument is null, the text will use the style from the
/// closest enclosing [DefaultTextStyle]. /// closest enclosing [DefaultTextStyle].
Text(this.data, { Key key, this.style }) : super(key: key) { Text(this.data, { Key key, this.style, this.textAlign }) : super(key: key) {
assert(data != null); assert(data != null);
} }
...@@ -1989,18 +2033,26 @@ class Text extends StatelessWidget { ...@@ -1989,18 +2033,26 @@ class Text extends StatelessWidget {
/// replace the closest enclosing [DefaultTextStyle]. /// replace the closest enclosing [DefaultTextStyle].
final TextStyle style; final TextStyle style;
TextStyle _getEffectiveStyle(BuildContext context) { /// How the text should be aligned horizontally.
if (style == null || style.inherit) final TextAlign textAlign;
return DefaultTextStyle.of(context).merge(style);
else
return style;
}
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
DefaultTextStyle defaultTextStyle;
TextStyle effectiveTextStyle = style;
if (style == null || style.inherit) {
defaultTextStyle ??= DefaultTextStyle.of(context);
effectiveTextStyle = defaultTextStyle.style.merge(style);
}
TextAlign effectiveTextAlign = textAlign;
if (effectiveTextAlign == null) {
defaultTextStyle ??= DefaultTextStyle.of(context);
effectiveTextAlign = defaultTextStyle.textAlign;
}
return new RichText( return new RichText(
textAlign: effectiveTextAlign,
text: new TextSpan( text: new TextSpan(
style: _getEffectiveStyle(context), style: effectiveTextStyle,
text: data text: data
) )
); );
......
...@@ -146,8 +146,7 @@ class _SemanticsDebuggerEntry { ...@@ -146,8 +146,7 @@ class _SemanticsDebuggerEntry {
static const TextStyle textStyles = const TextStyle( static const TextStyle textStyles = const TextStyle(
color: const Color(0xFF000000), color: const Color(0xFF000000),
fontSize: 10.0, fontSize: 10.0,
height: 0.8, height: 0.8
textAlign: TextAlign.center
); );
TextPainter textPainter; TextPainter textPainter;
...@@ -185,6 +184,7 @@ class _SemanticsDebuggerEntry { ...@@ -185,6 +184,7 @@ class _SemanticsDebuggerEntry {
textPainter ??= new TextPainter(); textPainter ??= new TextPainter();
textPainter textPainter
..text = new TextSpan(style: textStyles, text: message) ..text = new TextSpan(style: textStyles, text: message)
..textAlign = TextAlign.center
..layout(maxWidth: rect.width); ..layout(maxWidth: rect.width);
} else { } else {
textPainter = null; textPainter = null;
......
...@@ -387,7 +387,7 @@ class _Block { ...@@ -387,7 +387,7 @@ class _Block {
if (listIndents.last == 'ul') { if (listIndents.last == 'ul') {
bullet = new Text( bullet = new Text(
'•', '•',
style: new TextStyle(textAlign: TextAlign.center) textAlign: TextAlign.center
); );
} }
else { else {
...@@ -395,7 +395,7 @@ class _Block { ...@@ -395,7 +395,7 @@ class _Block {
padding: new EdgeInsets.only(right: 5.0), padding: new EdgeInsets.only(right: 5.0),
child: new Text( child: new Text(
"${blockPosition + 1}.", "${blockPosition + 1}.",
style: new TextStyle(textAlign: TextAlign.right) textAlign: TextAlign.right
) )
); );
} }
......
...@@ -3,47 +3,46 @@ part of flutter_sprites; ...@@ -3,47 +3,46 @@ part of flutter_sprites;
/// Labels are used to display a string of text in a the node tree. To align /// Labels are used to display a string of text in a the node tree. To align
/// the label, the textAlign property of the [TextStyle] can be set. /// the label, the textAlign property of the [TextStyle] can be set.
class Label extends Node { class Label extends Node {
/// Creates a new Label with the provided [_text] and [_textStyle]. /// Creates a new Label with the provided [text] and [textStyle].
Label(this._text, [this._textStyle]) { Label(this._text, {
if (_textStyle == null) { TextStyle textStyle,
_textStyle = new TextStyle(); TextAlign textAlign
} }) : _textStyle = textStyle ?? const TextStyle(),
} textAlign = textAlign ?? TextAlign.left;
String _text;
/// The text being drawn by the label. /// The text being drawn by the label.
String get text => _text; String get text => _text;
String _text;
void set text(String text) { void set text(String text) {
_text = text; _text = text;
_painter = null; _painter = null;
} }
TextStyle _textStyle;
/// The style to draw the text in. /// The style to draw the text in.
TextStyle get textStyle => _textStyle; TextStyle get textStyle => _textStyle;
TextStyle _textStyle;
void set textStyle(TextStyle textStyle) { void set textStyle(TextStyle textStyle) {
_textStyle = textStyle; _textStyle = textStyle;
_painter = null; _painter = null;
} }
/// How the text should be aligned horizontally.
TextAlign textAlign;
TextPainter _painter; TextPainter _painter;
double _width; double _width;
@override @override
void paint(Canvas canvas) { void paint(Canvas canvas) {
if (_painter == null) { if (_painter == null) {
_painter = new TextPainter(new TextSpan(style: _textStyle, text: _text)) _painter = new TextPainter(text: new TextSpan(style: _textStyle, text: _text))
..layout(); ..layout();
} }
Offset offset = Offset.zero; Offset offset = Offset.zero;
if (_textStyle.textAlign == TextAlign.center) { if (textAlign == TextAlign.center) {
offset = new Offset(-_width / 2.0, 0.0); offset = new Offset(-_width / 2.0, 0.0);
} else if (_textStyle.textAlign == TextAlign.right) { } else if (textAlign == TextAlign.right) {
offset = new Offset(-_width, 0.0); offset = new Offset(-_width, 0.0);
} }
......
...@@ -174,7 +174,7 @@ class ChartPainter { ...@@ -174,7 +174,7 @@ class ChartPainter {
style: _textTheme.body1, style: _textTheme.body1,
text: '${gridline.value}' text: '${gridline.value}'
); );
gridline.labelPainter = new TextPainter(text) gridline.labelPainter = new TextPainter(text: text)
..layout(maxWidth: _rect.width); ..layout(maxWidth: _rect.width);
_horizontalGridlines.add(gridline); _horizontalGridlines.add(gridline);
yScaleWidth = math.max(yScaleWidth, gridline.labelPainter.maxIntrinsicWidth); yScaleWidth = math.max(yScaleWidth, gridline.labelPainter.maxIntrinsicWidth);
...@@ -220,7 +220,7 @@ class ChartPainter { ...@@ -220,7 +220,7 @@ class ChartPainter {
style: _textTheme.body1, style: _textTheme.body1,
text: '${data.indicatorText}' text: '${data.indicatorText}'
); );
_indicator.labelPainter = new TextPainter(text) _indicator.labelPainter = new TextPainter(text: text)
..layout(maxWidth: markerRect.width); ..layout(maxWidth: markerRect.width);
_indicator.labelPosition = new Point( _indicator.labelPosition = new Point(
((_indicator.start.x + _indicator.end.x) / 2.0) - _indicator.labelPainter.maxIntrinsicWidth / 2.0, ((_indicator.start.x + _indicator.end.x) / 2.0) - _indicator.labelPainter.maxIntrinsicWidth / 2.0,
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment