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.
This commit is contained in:
parent
8f4a5659b0
commit
ee903af03f
@ -32,13 +32,12 @@ class CardCollectionState extends State<CardCollection> {
|
||||
static const double kCardMargins = 8.0;
|
||||
static const double kFixedCardHeight = 100.0;
|
||||
|
||||
final TextStyle backgroundTextStyle =
|
||||
Typography.white.title.copyWith(textAlign: TextAlign.center);
|
||||
final TextStyle backgroundTextStyle = Typography.white.title;
|
||||
|
||||
Map<int, Color> _primaryColor = Colors.deepPurple;
|
||||
List<CardModel> _cardModels;
|
||||
DismissDirection _dismissDirection = DismissDirection.horizontal;
|
||||
TextStyle _textStyle = new TextStyle(textAlign: TextAlign.center);
|
||||
TextAlign _textAlign = TextAlign.center;
|
||||
bool _editable = false;
|
||||
bool _snapToCenter = false;
|
||||
bool _fixedSizeCards = false;
|
||||
@ -143,9 +142,9 @@ class CardCollectionState extends State<CardCollection> {
|
||||
buildDrawerDirectionRadioItem("Dismiss left", DismissDirection.endToStart, _dismissDirection, _changeDismissDirection, icon: Icons.arrow_back),
|
||||
buildDrawerDirectionRadioItem("Dismiss right", DismissDirection.startToEnd, _dismissDirection, _changeDismissDirection, icon: Icons.arrow_forward),
|
||||
new Divider(),
|
||||
buildFontRadioItem("Left-align text", new TextStyle(textAlign: TextAlign.left), _textStyle, _changeTextStyle, 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("Right-align text", new TextStyle(textAlign: TextAlign.right), _textStyle, _changeTextStyle, icon: Icons.format_align_right, enabled: !_editable),
|
||||
buildFontRadioItem("Left-align text", TextAlign.left, _textAlign, _changeTextAlign, icon: Icons.format_align_left, enabled: !_editable),
|
||||
buildFontRadioItem("Center-align text", TextAlign.center, _textAlign, _changeTextAlign, icon: Icons.format_align_center, enabled: !_editable),
|
||||
buildFontRadioItem("Right-align text", TextAlign.right, _textAlign, _changeTextAlign, icon: Icons.format_align_right, enabled: !_editable),
|
||||
new Divider(),
|
||||
new DrawerItem(
|
||||
icon: Icons.dvr,
|
||||
@ -205,9 +204,9 @@ class CardCollectionState extends State<CardCollection> {
|
||||
});
|
||||
}
|
||||
|
||||
void _changeTextStyle(TextStyle newTextStyle) {
|
||||
void _changeTextAlign(TextAlign newTextAlign) {
|
||||
setState(() {
|
||||
_textStyle = newTextStyle;
|
||||
_textAlign = newTextAlign;
|
||||
});
|
||||
}
|
||||
|
||||
@ -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(
|
||||
icon: icon,
|
||||
onPressed: enabled ? () { onChanged(itemValue); } : null,
|
||||
child: new Row(
|
||||
children: <Widget>[
|
||||
new Flexible(child: new Text(label)),
|
||||
new Radio<TextStyle>(
|
||||
new Radio<TextAlign>(
|
||||
value: itemValue,
|
||||
groupValue: currentValue,
|
||||
onChanged: enabled ? onChanged : null
|
||||
@ -319,16 +318,17 @@ class CardCollectionState extends State<CardCollection> {
|
||||
}
|
||||
)
|
||||
)
|
||||
: new DefaultTextStyle(
|
||||
style: DefaultTextStyle.of(context).merge(cardLabelStyle).merge(_textStyle).copyWith(
|
||||
: new DefaultTextStyle.inherit(
|
||||
context: context,
|
||||
style: cardLabelStyle.copyWith(
|
||||
fontSize: _varyFontSizes ? 5.0 + index : null
|
||||
),
|
||||
child: new Column(
|
||||
children: <Widget>[
|
||||
new Text(cardModel.inputValue.text)
|
||||
],
|
||||
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> {
|
||||
child: new Row(
|
||||
children: <Widget>[
|
||||
leftArrowIcon,
|
||||
new Flexible(child: new Text(backgroundMessage, style: backgroundTextStyle)),
|
||||
new Flexible(
|
||||
child: new Text(backgroundMessage,
|
||||
style: backgroundTextStyle,
|
||||
textAlign: TextAlign.center
|
||||
)
|
||||
),
|
||||
rightArrowIcon
|
||||
]
|
||||
)
|
||||
|
@ -98,7 +98,8 @@ class ExampleDragSource extends StatelessWidget {
|
||||
size *= kHeavyMultiplier;
|
||||
|
||||
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(
|
||||
color: color,
|
||||
size: size,
|
||||
@ -185,10 +186,8 @@ class MovableBall extends StatelessWidget {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
Widget ball = new DefaultTextStyle(
|
||||
style: Theme.of(context).textTheme.body1.copyWith(
|
||||
textAlign: TextAlign.center,
|
||||
color: Colors.white
|
||||
),
|
||||
style: Typography.white.body1,
|
||||
textAlign: TextAlign.center,
|
||||
child: new Dot(
|
||||
key: kBallKey,
|
||||
color: Colors.blue[700],
|
||||
|
@ -4,15 +4,14 @@
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
final TextStyle _kTextStyle = new TextStyle(
|
||||
color: Colors.indigo[400],
|
||||
fontSize: 24.0
|
||||
);
|
||||
|
||||
class ModalBottomSheetDemo extends StatelessWidget {
|
||||
static const String routeName = '/modal-bottom-sheet';
|
||||
|
||||
final TextStyle textStyle = new TextStyle(
|
||||
color: Colors.indigo[400],
|
||||
fontSize: 24.0,
|
||||
textAlign: TextAlign.center
|
||||
);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return new Scaffold(
|
||||
@ -25,7 +24,10 @@ class ModalBottomSheetDemo extends StatelessWidget {
|
||||
return new Container(
|
||||
child: new Padding(
|
||||
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 @@
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
final TextStyle _kTextStyle = new TextStyle(
|
||||
color: Colors.indigo[400],
|
||||
fontSize: 24.0
|
||||
);
|
||||
|
||||
class PersistentBottomSheetDemo extends StatefulWidget {
|
||||
static const String routeName = '/persistent-bottom-sheet';
|
||||
|
||||
@ -14,12 +19,6 @@ class PersistentBottomSheetDemo extends StatefulWidget {
|
||||
class _PersistentBottomSheetDemoState extends State<PersistentBottomSheetDemo> {
|
||||
final GlobalKey<ScaffoldState> _scaffoldKey = new GlobalKey<ScaffoldState>();
|
||||
|
||||
final TextStyle textStyle = new TextStyle(
|
||||
color: Colors.indigo[400],
|
||||
fontSize: 24.0,
|
||||
textAlign: TextAlign.center
|
||||
);
|
||||
|
||||
VoidCallback _showBottomSheetCallback;
|
||||
|
||||
@override
|
||||
@ -40,7 +39,10 @@ class _PersistentBottomSheetDemoState extends State<PersistentBottomSheetDemo> {
|
||||
),
|
||||
child: new Padding(
|
||||
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> {
|
||||
Widget buildTabView(_Page page) {
|
||||
return new Builder(
|
||||
builder: (BuildContext context) {
|
||||
final TextStyle textStyle = new TextStyle(
|
||||
color: page.labelColor,
|
||||
fontSize: 32.0,
|
||||
textAlign: TextAlign.center
|
||||
);
|
||||
|
||||
return new Container(
|
||||
key: new ValueKey<String>(page.label),
|
||||
padding: const EdgeInsets.fromLTRB(48.0, 48.0, 48.0, 96.0),
|
||||
child: new Card(
|
||||
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 {
|
||||
new Flexible(
|
||||
child: new Text(
|
||||
lastSale,
|
||||
style: const TextStyle(textAlign: TextAlign.right)
|
||||
textAlign: TextAlign.right
|
||||
)
|
||||
),
|
||||
new Flexible(
|
||||
child: new Text(
|
||||
changeInPrice,
|
||||
style: const TextStyle(textAlign: TextAlign.right)
|
||||
textAlign: TextAlign.right
|
||||
)
|
||||
),
|
||||
],
|
||||
crossAxisAlignment: CrossAxisAlignment.baseline,
|
||||
textBaseline: DefaultTextStyle.of(context).textBaseline
|
||||
textBaseline: DefaultTextStyle.of(context).style.textBaseline
|
||||
)
|
||||
),
|
||||
]
|
||||
|
@ -52,7 +52,7 @@ class StockSymbolView extends StatelessWidget {
|
||||
),
|
||||
new RichText(
|
||||
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 ',
|
||||
children: <TextSpan>[
|
||||
new TextSpan(text: 'several', style: new TextStyle(fontStyle: FontStyle.italic)),
|
||||
|
@ -16,7 +16,6 @@ const TextStyle _errorTextStyle = const TextStyle(
|
||||
fontFamily: 'monospace',
|
||||
fontSize: 48.0,
|
||||
fontWeight: FontWeight.w900,
|
||||
textAlign: TextAlign.right,
|
||||
decoration: TextDecoration.underline,
|
||||
decorationColor: const Color(0xFFFFFF00),
|
||||
decorationStyle: TextDecorationStyle.double
|
||||
|
@ -274,7 +274,7 @@ List<TextPainter> _initPainters(List<String> labels) {
|
||||
for (int i = 0; i < painters.length; ++i) {
|
||||
String label = labels[i];
|
||||
painters[i] = new TextPainter(
|
||||
new TextSpan(style: style, text: label)
|
||||
text: new TextSpan(style: style, text: label)
|
||||
)..layout();
|
||||
}
|
||||
return painters;
|
||||
|
@ -30,8 +30,11 @@ class TextPainter {
|
||||
///
|
||||
/// The text argument is optional but [text] must be non-null before calling
|
||||
/// [layout].
|
||||
TextPainter([ TextSpan text ]) {
|
||||
this.text = text;
|
||||
TextPainter({
|
||||
TextSpan text,
|
||||
TextAlign textAlign
|
||||
}) : _text = text, _textAlign = textAlign {
|
||||
assert(text == null || text.debugAssertValid());
|
||||
}
|
||||
|
||||
ui.Paragraph _paragraph;
|
||||
@ -45,15 +48,19 @@ class TextPainter {
|
||||
if (_text == value)
|
||||
return;
|
||||
_text = value;
|
||||
if (_text != null) {
|
||||
ui.ParagraphBuilder builder = new ui.ParagraphBuilder();
|
||||
_text.build(builder);
|
||||
_paragraph = builder.build(_text.style?.paragraphStyle ?? new ui.ParagraphStyle());
|
||||
_needsLayout = true;
|
||||
} else {
|
||||
_paragraph = null;
|
||||
_needsLayout = false;
|
||||
}
|
||||
_paragraph = null;
|
||||
_needsLayout = true;
|
||||
}
|
||||
|
||||
/// How the text should be aligned horizontally.
|
||||
TextAlign get textAlign => _textAlign;
|
||||
TextAlign _textAlign;
|
||||
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
|
||||
@ -129,9 +136,17 @@ class TextPainter {
|
||||
/// width as possible while still being greater than or equal to minWidth and
|
||||
/// less than or equal to maxWidth.
|
||||
void layout({ double minWidth: 0.0, double maxWidth: double.INFINITY }) {
|
||||
assert(_text != null);
|
||||
if (!_needsLayout && minWidth == _lastMinWidth && maxWidth == _lastMaxWidth)
|
||||
return;
|
||||
_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;
|
||||
_lastMaxWidth = maxWidth;
|
||||
_paragraph.layout(new ui.ParagraphConstraints(width: maxWidth));
|
||||
|
@ -18,7 +18,6 @@ class TextStyle {
|
||||
this.fontStyle,
|
||||
this.letterSpacing,
|
||||
this.wordSpacing,
|
||||
this.textAlign,
|
||||
this.textBaseline,
|
||||
this.height,
|
||||
this.decoration,
|
||||
@ -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).
|
||||
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.
|
||||
final TextBaseline textBaseline;
|
||||
|
||||
@ -82,7 +77,6 @@ class TextStyle {
|
||||
FontStyle fontStyle,
|
||||
double letterSpacing,
|
||||
double wordSpacing,
|
||||
TextAlign textAlign,
|
||||
TextBaseline textBaseline,
|
||||
double height,
|
||||
TextDecoration decoration,
|
||||
@ -98,7 +92,6 @@ class TextStyle {
|
||||
fontStyle: fontStyle != null ? fontStyle : this.fontStyle,
|
||||
letterSpacing: letterSpacing != null ? letterSpacing : this.letterSpacing,
|
||||
wordSpacing: wordSpacing != null ? wordSpacing : this.wordSpacing,
|
||||
textAlign: textAlign != null ? textAlign : this.textAlign,
|
||||
textBaseline: textBaseline != null ? textBaseline : this.textBaseline,
|
||||
height: height != null ? height : this.height,
|
||||
decoration: decoration != null ? decoration : this.decoration,
|
||||
@ -122,7 +115,6 @@ class TextStyle {
|
||||
fontStyle: other.fontStyle,
|
||||
letterSpacing: other.letterSpacing,
|
||||
wordSpacing: other.wordSpacing,
|
||||
textAlign: other.textAlign,
|
||||
textBaseline: other.textBaseline,
|
||||
height: other.height,
|
||||
decoration: other.decoration,
|
||||
@ -146,7 +138,6 @@ class TextStyle {
|
||||
fontStyle: t < 0.5 ? begin.fontStyle : end.fontStyle,
|
||||
letterSpacing: ui.lerpDouble(begin.letterSpacing ?? end.letterSpacing, end.letterSpacing ?? begin.letterSpacing, 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,
|
||||
height: ui.lerpDouble(begin.height ?? end.height, end.height ?? begin.height, t),
|
||||
decoration: t < 0.5 ? begin.decoration : end.decoration,
|
||||
@ -173,7 +164,7 @@ class TextStyle {
|
||||
}
|
||||
|
||||
/// The style information for paragraphs, encoded for use by `dart:ui`.
|
||||
ui.ParagraphStyle get paragraphStyle {
|
||||
ui.ParagraphStyle getParagraphStyle({ TextAlign textAlign }) {
|
||||
return new ui.ParagraphStyle(
|
||||
textAlign: textAlign,
|
||||
textBaseline: textBaseline,
|
||||
@ -200,7 +191,6 @@ class TextStyle {
|
||||
fontStyle == typedOther.fontStyle &&
|
||||
letterSpacing == typedOther.letterSpacing &&
|
||||
wordSpacing == typedOther.wordSpacing &&
|
||||
textAlign == typedOther.textAlign &&
|
||||
textBaseline == typedOther.textBaseline &&
|
||||
height == typedOther.height &&
|
||||
decoration == typedOther.decoration &&
|
||||
@ -219,7 +209,6 @@ class TextStyle {
|
||||
fontStyle,
|
||||
letterSpacing,
|
||||
wordSpacing,
|
||||
textAlign,
|
||||
textBaseline,
|
||||
height,
|
||||
decoration,
|
||||
@ -283,19 +272,6 @@ class TextStyle {
|
||||
result.add('${prefix}letterSpacing: ${letterSpacing}x');
|
||||
if (wordSpacing != null)
|
||||
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) {
|
||||
switch (textBaseline) {
|
||||
case TextBaseline.alphabetic:
|
||||
|
@ -287,8 +287,9 @@ class RenderChildView extends RenderBox {
|
||||
_child._setChildProperties(_physicalWidth, _physicalHeight, scale);
|
||||
assert(() {
|
||||
if (_view == null) {
|
||||
_debugErrorMessage ??= new TextPainter()
|
||||
..text = new TextSpan(text: 'Child view are supported only when running in Mojo shell.');
|
||||
_debugErrorMessage ??= new TextPainter(
|
||||
text: new TextSpan(text: 'Child views are supported only when running in Mojo shell.')
|
||||
);
|
||||
_debugErrorMessage.layout(minWidth: size.width, maxWidth: size.width);
|
||||
}
|
||||
return true;
|
||||
|
@ -42,7 +42,7 @@ class RenderEditableLine extends RenderBox {
|
||||
this.onSelectionChanged,
|
||||
Offset paintOffset: Offset.zero,
|
||||
this.onPaintOffsetUpdateNeeded
|
||||
}) : _textPainter = new TextPainter(text),
|
||||
}) : _textPainter = new TextPainter(text: text),
|
||||
_cursorColor = cursorColor,
|
||||
_showCursor = showCursor,
|
||||
_selection = selection,
|
||||
|
@ -11,9 +11,9 @@ import 'semantics.dart';
|
||||
/// A render object that displays a paragraph of text
|
||||
class RenderParagraph extends RenderBox {
|
||||
|
||||
RenderParagraph(
|
||||
TextSpan text
|
||||
) : _textPainter = new TextPainter(text) {
|
||||
RenderParagraph(TextSpan text, {
|
||||
TextAlign textAlign
|
||||
}) : _textPainter = new TextPainter(text: text, textAlign: textAlign) {
|
||||
assert(text != null);
|
||||
assert(text.debugAssertValid());
|
||||
}
|
||||
@ -23,13 +23,22 @@ class RenderParagraph extends RenderBox {
|
||||
/// The text to display
|
||||
TextSpan get text => _textPainter.text;
|
||||
void set text(TextSpan value) {
|
||||
assert(value.debugAssertValid());
|
||||
assert(value != null);
|
||||
if (_textPainter.text == value)
|
||||
return;
|
||||
_textPainter.text = value;
|
||||
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) {
|
||||
assert(constraints != null);
|
||||
assert(constraints.debugAssertIsValid());
|
||||
@ -101,6 +110,9 @@ class RenderParagraph extends RenderBox {
|
||||
//
|
||||
// TODO(abarth): Make computing the min/max intrinsic width/height
|
||||
// a non-destructive operation.
|
||||
//
|
||||
// If you remove this call, make sure that changing the textAlign still
|
||||
// works properly.
|
||||
_layoutText(constraints);
|
||||
_textPainter.paint(context.canvas, offset);
|
||||
}
|
||||
|
@ -15,7 +15,6 @@ const TextStyle _kTextStyles = const TextStyle(
|
||||
color: const Color(0xFFFFFFFF),
|
||||
fontSize: _kHeight * 0.85,
|
||||
fontWeight: FontWeight.w900,
|
||||
textAlign: TextAlign.center,
|
||||
height: 1.0
|
||||
);
|
||||
|
||||
@ -64,9 +63,10 @@ class BannerPainter extends CustomPainter {
|
||||
..drawRect(_kRect, paintBanner);
|
||||
|
||||
final double width = _kOffset * 2.0;
|
||||
final TextPainter textPainter = new TextPainter()
|
||||
..text = new TextSpan(style: _kTextStyles, text: message)
|
||||
..layout(minWidth: width, maxWidth: width);
|
||||
final TextPainter textPainter = new TextPainter(
|
||||
text: new TextSpan(style: _kTextStyles, text: message),
|
||||
textAlign: TextAlign.center
|
||||
)..layout(minWidth: width, maxWidth: width);
|
||||
|
||||
textPainter.paint(canvas, _kRect.topLeft.toOffset() + new Offset(0.0, (_kRect.height - textPainter.height) / 2.0));
|
||||
}
|
||||
|
@ -1904,40 +1904,84 @@ class RichText extends LeafRenderObjectWidget {
|
||||
/// Creates a paragraph of rich text.
|
||||
///
|
||||
/// 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);
|
||||
}
|
||||
|
||||
/// The text to display in this widget.
|
||||
final TextSpan text;
|
||||
|
||||
/// How the text should be aligned horizontally.
|
||||
final TextAlign textAlign;
|
||||
|
||||
@override
|
||||
RenderParagraph createRenderObject(BuildContext context) => new RenderParagraph(text);
|
||||
RenderParagraph createRenderObject(BuildContext context) {
|
||||
return new RenderParagraph(text, textAlign: textAlign);
|
||||
}
|
||||
|
||||
@override
|
||||
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.
|
||||
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({
|
||||
Key key,
|
||||
this.style,
|
||||
this.textAlign,
|
||||
Widget child
|
||||
}) : super(key: key, child: child) {
|
||||
assert(style != 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.
|
||||
final TextStyle style;
|
||||
|
||||
/// The style from the closest instance of this class that encloses the given context.
|
||||
static TextStyle of(BuildContext context) {
|
||||
DefaultTextStyle result = context.inheritFromWidgetOfExactType(DefaultTextStyle);
|
||||
return result?.style ?? const TextStyle();
|
||||
/// How the text should be aligned horizontally.
|
||||
final TextAlign textAlign;
|
||||
|
||||
/// 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
|
||||
@ -1975,7 +2019,7 @@ class Text extends StatelessWidget {
|
||||
///
|
||||
/// If the [style] argument is null, the text will use the style from the
|
||||
/// 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);
|
||||
}
|
||||
|
||||
@ -1989,18 +2033,26 @@ class Text extends StatelessWidget {
|
||||
/// replace the closest enclosing [DefaultTextStyle].
|
||||
final TextStyle style;
|
||||
|
||||
TextStyle _getEffectiveStyle(BuildContext context) {
|
||||
if (style == null || style.inherit)
|
||||
return DefaultTextStyle.of(context).merge(style);
|
||||
else
|
||||
return style;
|
||||
}
|
||||
/// How the text should be aligned horizontally.
|
||||
final TextAlign textAlign;
|
||||
|
||||
@override
|
||||
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(
|
||||
textAlign: effectiveTextAlign,
|
||||
text: new TextSpan(
|
||||
style: _getEffectiveStyle(context),
|
||||
style: effectiveTextStyle,
|
||||
text: data
|
||||
)
|
||||
);
|
||||
|
@ -146,8 +146,7 @@ class _SemanticsDebuggerEntry {
|
||||
static const TextStyle textStyles = const TextStyle(
|
||||
color: const Color(0xFF000000),
|
||||
fontSize: 10.0,
|
||||
height: 0.8,
|
||||
textAlign: TextAlign.center
|
||||
height: 0.8
|
||||
);
|
||||
|
||||
TextPainter textPainter;
|
||||
@ -185,6 +184,7 @@ class _SemanticsDebuggerEntry {
|
||||
textPainter ??= new TextPainter();
|
||||
textPainter
|
||||
..text = new TextSpan(style: textStyles, text: message)
|
||||
..textAlign = TextAlign.center
|
||||
..layout(maxWidth: rect.width);
|
||||
} else {
|
||||
textPainter = null;
|
||||
|
@ -387,7 +387,7 @@ class _Block {
|
||||
if (listIndents.last == 'ul') {
|
||||
bullet = new Text(
|
||||
'•',
|
||||
style: new TextStyle(textAlign: TextAlign.center)
|
||||
textAlign: TextAlign.center
|
||||
);
|
||||
}
|
||||
else {
|
||||
@ -395,7 +395,7 @@ class _Block {
|
||||
padding: new EdgeInsets.only(right: 5.0),
|
||||
child: new Text(
|
||||
"${blockPosition + 1}.",
|
||||
style: new TextStyle(textAlign: TextAlign.right)
|
||||
textAlign: TextAlign.right
|
||||
)
|
||||
);
|
||||
}
|
||||
|
@ -3,47 +3,46 @@ part of flutter_sprites;
|
||||
/// 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.
|
||||
class Label extends Node {
|
||||
/// Creates a new Label with the provided [_text] and [_textStyle].
|
||||
Label(this._text, [this._textStyle]) {
|
||||
if (_textStyle == null) {
|
||||
_textStyle = new TextStyle();
|
||||
}
|
||||
}
|
||||
|
||||
String _text;
|
||||
/// Creates a new Label with the provided [text] and [textStyle].
|
||||
Label(this._text, {
|
||||
TextStyle textStyle,
|
||||
TextAlign textAlign
|
||||
}) : _textStyle = textStyle ?? const TextStyle(),
|
||||
textAlign = textAlign ?? TextAlign.left;
|
||||
|
||||
/// The text being drawn by the label.
|
||||
String get text => _text;
|
||||
|
||||
String _text;
|
||||
void set text(String text) {
|
||||
_text = text;
|
||||
_painter = null;
|
||||
}
|
||||
|
||||
TextStyle _textStyle;
|
||||
|
||||
/// The style to draw the text in.
|
||||
TextStyle get textStyle => _textStyle;
|
||||
|
||||
TextStyle _textStyle;
|
||||
void set textStyle(TextStyle textStyle) {
|
||||
_textStyle = textStyle;
|
||||
_painter = null;
|
||||
}
|
||||
|
||||
/// How the text should be aligned horizontally.
|
||||
TextAlign textAlign;
|
||||
|
||||
TextPainter _painter;
|
||||
double _width;
|
||||
|
||||
@override
|
||||
void paint(Canvas canvas) {
|
||||
if (_painter == null) {
|
||||
_painter = new TextPainter(new TextSpan(style: _textStyle, text: _text))
|
||||
_painter = new TextPainter(text: new TextSpan(style: _textStyle, text: _text))
|
||||
..layout();
|
||||
}
|
||||
|
||||
Offset offset = Offset.zero;
|
||||
if (_textStyle.textAlign == TextAlign.center) {
|
||||
if (textAlign == TextAlign.center) {
|
||||
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);
|
||||
}
|
||||
|
||||
|
@ -174,7 +174,7 @@ class ChartPainter {
|
||||
style: _textTheme.body1,
|
||||
text: '${gridline.value}'
|
||||
);
|
||||
gridline.labelPainter = new TextPainter(text)
|
||||
gridline.labelPainter = new TextPainter(text: text)
|
||||
..layout(maxWidth: _rect.width);
|
||||
_horizontalGridlines.add(gridline);
|
||||
yScaleWidth = math.max(yScaleWidth, gridline.labelPainter.maxIntrinsicWidth);
|
||||
@ -220,7 +220,7 @@ class ChartPainter {
|
||||
style: _textTheme.body1,
|
||||
text: '${data.indicatorText}'
|
||||
);
|
||||
_indicator.labelPainter = new TextPainter(text)
|
||||
_indicator.labelPainter = new TextPainter(text: text)
|
||||
..layout(maxWidth: markerRect.width);
|
||||
_indicator.labelPosition = new Point(
|
||||
((_indicator.start.x + _indicator.end.x) / 2.0) - _indicator.labelPainter.maxIntrinsicWidth / 2.0,
|
||||
|
Loading…
x
Reference in New Issue
Block a user