Commit 2514d8a6 authored by Adam Barth's avatar Adam Barth

Merge pull request #2135 from abarth/improve_text_span

Improve TextSpan
parents 586ab30c fb4dbf45
...@@ -14,24 +14,24 @@ void main() { ...@@ -14,24 +14,24 @@ void main() {
void addAlignmentRow(FlexAlignItems alignItems) { void addAlignmentRow(FlexAlignItems alignItems) {
TextStyle style = const TextStyle(color: const Color(0xFF000000)); TextStyle style = const TextStyle(color: const Color(0xFF000000));
RenderParagraph paragraph = new RenderParagraph(new StyledTextSpan(style, <TextSpan>[new PlainTextSpan('$alignItems')])); RenderParagraph paragraph = new RenderParagraph(new TextSpan(style: style, text: '$alignItems'));
table.add(new RenderPadding(child: paragraph, padding: new EdgeDims.only(top: 20.0))); table.add(new RenderPadding(child: paragraph, padding: new EdgeDims.only(top: 20.0)));
RenderFlex row = new RenderFlex(alignItems: alignItems, textBaseline: TextBaseline.alphabetic); RenderFlex row = new RenderFlex(alignItems: alignItems, textBaseline: TextBaseline.alphabetic);
style = new TextStyle(fontSize: 15.0, color: const Color(0xFF000000)); style = new TextStyle(fontSize: 15.0, color: const Color(0xFF000000));
row.add(new RenderDecoratedBox( row.add(new RenderDecoratedBox(
decoration: new BoxDecoration(backgroundColor: const Color(0x7FFFCCCC)), decoration: new BoxDecoration(backgroundColor: const Color(0x7FFFCCCC)),
child: new RenderParagraph(new StyledTextSpan(style, <TextSpan>[new PlainTextSpan('foo foo foo')])) child: new RenderParagraph(new TextSpan(style: style, text: 'foo foo foo'))
)); ));
style = new TextStyle(fontSize: 10.0, color: const Color(0xFF000000)); style = new TextStyle(fontSize: 10.0, color: const Color(0xFF000000));
row.add(new RenderDecoratedBox( row.add(new RenderDecoratedBox(
decoration: new BoxDecoration(backgroundColor: const Color(0x7FCCFFCC)), decoration: new BoxDecoration(backgroundColor: const Color(0x7FCCFFCC)),
child: new RenderParagraph(new StyledTextSpan(style, <TextSpan>[new PlainTextSpan('foo foo foo')])) child: new RenderParagraph(new TextSpan(style: style, text: 'foo foo foo'))
)); ));
RenderFlex subrow = new RenderFlex(alignItems: alignItems, textBaseline: TextBaseline.alphabetic); RenderFlex subrow = new RenderFlex(alignItems: alignItems, textBaseline: TextBaseline.alphabetic);
style = new TextStyle(fontSize: 25.0, color: const Color(0xFF000000)); style = new TextStyle(fontSize: 25.0, color: const Color(0xFF000000));
subrow.add(new RenderDecoratedBox( subrow.add(new RenderDecoratedBox(
decoration: new BoxDecoration(backgroundColor: const Color(0x7FCCCCFF)), decoration: new BoxDecoration(backgroundColor: const Color(0x7FCCCCFF)),
child: new RenderParagraph(new StyledTextSpan(style, <TextSpan>[new PlainTextSpan('foo foo foo foo')])) child: new RenderParagraph(new TextSpan(style: style, text: 'foo foo foo foo'))
)); ));
subrow.add(new RenderSolidColorBox(const Color(0x7FCCFFFF), desiredSize: new Size(30.0, 40.0))); subrow.add(new RenderSolidColorBox(const Color(0x7FCCFFFF), desiredSize: new Size(30.0, 40.0)));
row.add(subrow); row.add(subrow);
...@@ -48,7 +48,7 @@ void main() { ...@@ -48,7 +48,7 @@ void main() {
void addJustificationRow(FlexJustifyContent justify) { void addJustificationRow(FlexJustifyContent justify) {
const TextStyle style = const TextStyle(color: const Color(0xFF000000)); const TextStyle style = const TextStyle(color: const Color(0xFF000000));
RenderParagraph paragraph = new RenderParagraph(new StyledTextSpan(style, <TextSpan>[new PlainTextSpan('$justify')])); RenderParagraph paragraph = new RenderParagraph(new TextSpan(style: style, text: '$justify'));
table.add(new RenderPadding(child: paragraph, padding: new EdgeDims.only(top: 20.0))); table.add(new RenderPadding(child: paragraph, padding: new EdgeDims.only(top: 20.0)));
RenderFlex row = new RenderFlex(direction: FlexDirection.horizontal); RenderFlex row = new RenderFlex(direction: FlexDirection.horizontal);
row.add(new RenderSolidColorBox(const Color(0xFFFFCCCC), desiredSize: new Size(80.0, 60.0))); row.add(new RenderSolidColorBox(const Color(0xFFFFCCCC), desiredSize: new Size(80.0, 60.0)));
......
...@@ -16,7 +16,7 @@ void main() { ...@@ -16,7 +16,7 @@ void main() {
alignment: const FractionalOffset(0.5, 0.5), alignment: const FractionalOffset(0.5, 0.5),
// We use a RenderParagraph to display the text 'Hello, world.' without // We use a RenderParagraph to display the text 'Hello, world.' without
// any explicit styling. // any explicit styling.
child: new RenderParagraph(new PlainTextSpan('Hello, world.')) child: new RenderParagraph(new TextSpan(text: 'Hello, world.'))
) )
); );
} }
...@@ -97,9 +97,9 @@ class RenderDots extends RenderBox { ...@@ -97,9 +97,9 @@ class RenderDots extends RenderBox {
void main() { void main() {
// Create some styled text to tell the user to interact with the app. // Create some styled text to tell the user to interact with the app.
RenderParagraph paragraph = new RenderParagraph( RenderParagraph paragraph = new RenderParagraph(
new StyledTextSpan( new TextSpan(
new TextStyle(color: Colors.black87), style: new TextStyle(color: Colors.black87),
<TextSpan>[ new PlainTextSpan("Touch me!") ] text: "Touch me!"
) )
); );
// A stack is a render object that layers its children on top of each other. // A stack is a render object that layers its children on top of each other.
......
...@@ -34,9 +34,24 @@ final TextStyle _kUnderline = const TextStyle( ...@@ -34,9 +34,24 @@ final TextStyle _kUnderline = const TextStyle(
Widget toStyledText(String name, String text) { Widget toStyledText(String name, String text) {
TextStyle lineStyle = (name == "Dave") ? _kDaveStyle : _kHalStyle; TextStyle lineStyle = (name == "Dave") ? _kDaveStyle : _kHalStyle;
return new StyledText( return new RichText(
key: new Key(text), key: new Key(text),
elements: [lineStyle, [_kBold, [_kUnderline, name], ":"], text] text: new TextSpan(
style: lineStyle,
children: <TextSpan>[
new TextSpan(
style: _kBold,
children: <TextSpan>[
new TextSpan(
style: _kUnderline,
text: name
),
new TextSpan(text: ':')
]
),
new TextSpan(text: text)
]
)
); );
} }
......
...@@ -240,9 +240,7 @@ List<TextPainter> _initPainters(List<String> labels) { ...@@ -240,9 +240,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];
TextPainter painter = new TextPainter( TextPainter painter = new TextPainter(
new StyledTextSpan(style, [ new TextSpan(style: style, text: label)
new PlainTextSpan(label)
])
); );
painter painter
..maxWidth = double.INFINITY ..maxWidth = double.INFINITY
......
...@@ -9,92 +9,86 @@ import 'text_editing.dart'; ...@@ -9,92 +9,86 @@ import 'text_editing.dart';
import 'text_style.dart'; import 'text_style.dart';
/// An immutable span of text. /// An immutable span of text.
abstract class TextSpan { class TextSpan {
// This class must be immutable, because we won't notice when it changes. const TextSpan({
const TextSpan(); this.style,
void build(ui.ParagraphBuilder builder); this.text,
ui.ParagraphStyle get paragraphStyle => null; this.children
String toPlainText(); // for semantics });
String toString([String prefix = '']); // for debugging
} /// The style to apply to the text and the children.
final TextStyle style;
/// An immutable span of unstyled text.
class PlainTextSpan extends TextSpan {
const PlainTextSpan(this.text);
/// The text contained in the span. /// The text contained in the span.
///
/// If both text and children are non-null, the text will preceed the
/// children.
final String text; final String text;
void build(ui.ParagraphBuilder builder) { /// Additional spans to include as children.
assert(text != null); ///
builder.addText(text); /// If both text and children are non-null, the text will preceed the
} /// children.
bool operator ==(dynamic other) {
if (other is! PlainTextSpan)
return false;
final PlainTextSpan typedOther = other;
return text == typedOther.text;
}
int get hashCode => text.hashCode;
String toPlainText() => text;
String toString([String prefix = '']) => '$prefix$runtimeType: "$text"';
}
/// An immutable text span that applies a style to a list of children.
class StyledTextSpan extends TextSpan {
const StyledTextSpan(this.style, this.children);
/// The style to apply to the children.
final TextStyle style;
/// The children to which the style is applied.
final List<TextSpan> children; final List<TextSpan> children;
void build(ui.ParagraphBuilder builder) { void build(ui.ParagraphBuilder builder) {
assert(style != null); final bool hasStyle = style != null;
assert(children != null); if (hasStyle)
builder.pushStyle(style.textStyle); builder.pushStyle(style.textStyle);
for (TextSpan child in children) { if (text != null)
assert(child != null); builder.addText(text);
child.build(builder); if (children != null) {
for (TextSpan child in children) {
assert(child != null);
child.build(builder);
}
}
if (hasStyle)
builder.pop();
}
void writePlainText(StringBuffer result) {
if (text != null)
result.write(text);
if (children != null) {
for (TextSpan child in children)
child.writePlainText(result);
} }
builder.pop();
} }
ui.ParagraphStyle get paragraphStyle => style.paragraphStyle; String toString([String prefix = '']) {
StringBuffer buffer = new StringBuffer();
buffer.writeln('$prefix$runtimeType:');
String indent = '$prefix ';
buffer.writeln(style.toString(indent));
if (text != null)
buffer.writeln('$indent"$text"');
for (TextSpan child in children)
buffer.writeln(child.toString(indent));
return buffer.toString();
}
bool operator ==(dynamic other) { bool operator ==(dynamic other) {
if (identical(this, other)) if (identical(this, other))
return true; return true;
if (other is! StyledTextSpan) if (other is! TextSpan)
return false; return false;
final StyledTextSpan typedOther = other; final TextSpan typedOther = other;
if (style != typedOther.style || if (typedOther.text != text)
children.length != typedOther.children.length)
return false; return false;
for (int i = 0; i < children.length; ++i) { if (typedOther.style != style)
if (children[i] != typedOther.children[i]) return false;
return false; if ((typedOther.children == null) != (children == null))
return false;
if (children != null) {
for (int i = 0; i < children.length; ++i) {
if (typedOther.children[i] != children[i])
return false;
}
} }
return true; return true;
} }
int get hashCode => hashValues(style, text, hashList(children));
int get hashCode => hashValues(style, hashList(children));
String toPlainText() => children.map((TextSpan child) => child.toPlainText()).join();
String toString([String prefix = '']) {
List<String> result = <String>[];
result.add('$prefix$runtimeType:');
var indent = '$prefix ';
result.add('${style.toString(indent)}');
for (TextSpan child in children)
result.add(child.toString(indent));
return result.join('\n');
}
} }
/// An object that paints a [TextSpan] into a canvas. /// An object that paints a [TextSpan] into a canvas.
...@@ -115,7 +109,7 @@ class TextPainter { ...@@ -115,7 +109,7 @@ class TextPainter {
_text = value; _text = value;
ui.ParagraphBuilder builder = new ui.ParagraphBuilder(); ui.ParagraphBuilder builder = new ui.ParagraphBuilder();
_text.build(builder); _text.build(builder);
_paragraph = builder.build(_text.paragraphStyle ?? new ui.ParagraphStyle()); _paragraph = builder.build(_text.style?.paragraphStyle ?? new ui.ParagraphStyle());
_needsLayout = true; _needsLayout = true;
} }
......
...@@ -19,7 +19,7 @@ final String _kZeroWidthSpace = new String.fromCharCode(0x200B); ...@@ -19,7 +19,7 @@ final String _kZeroWidthSpace = new String.fromCharCode(0x200B);
/// A single line of editable text. /// A single line of editable text.
class RenderEditableLine extends RenderBox { class RenderEditableLine extends RenderBox {
RenderEditableLine({ RenderEditableLine({
StyledTextSpan text, TextSpan text,
Color cursorColor, Color cursorColor,
bool showCursor: false, bool showCursor: false,
Color selectionColor, Color selectionColor,
...@@ -49,12 +49,12 @@ class RenderEditableLine extends RenderBox { ...@@ -49,12 +49,12 @@ class RenderEditableLine extends RenderBox {
ValueChanged<TextSelection> onSelectionChanged; ValueChanged<TextSelection> onSelectionChanged;
/// The text to display /// The text to display
StyledTextSpan get text => _textPainter.text; TextSpan get text => _textPainter.text;
final TextPainter _textPainter; final TextPainter _textPainter;
void set text(StyledTextSpan value) { void set text(TextSpan value) {
if (_textPainter.text == value) if (_textPainter.text == value)
return; return;
StyledTextSpan oldStyledText = _textPainter.text; TextSpan oldStyledText = _textPainter.text;
if (oldStyledText.style != value.style) if (oldStyledText.style != value.style)
_layoutTemplate = null; _layoutTemplate = null;
_textPainter.text = value; _textPainter.text = value;
......
...@@ -100,7 +100,9 @@ class RenderParagraph extends RenderBox { ...@@ -100,7 +100,9 @@ class RenderParagraph extends RenderBox {
Iterable<SemanticAnnotator> getSemanticAnnotators() sync* { Iterable<SemanticAnnotator> getSemanticAnnotators() sync* {
yield (SemanticsNode node) { yield (SemanticsNode node) {
node.label = text.toPlainText(); StringBuffer buffer = new StringBuffer();
text.writePlainText(buffer);
node.label = buffer.toString();
}; };
} }
......
...@@ -1405,12 +1405,12 @@ class Flexible extends ParentDataWidget<Flex> { ...@@ -1405,12 +1405,12 @@ class Flexible extends ParentDataWidget<Flex> {
} }
} }
/// A raw paragraph of text. /// A paragraph of rich text.
/// ///
/// This class is rarely used directly. Instead, consider using [Text], which /// This class is rarely used directly. Instead, consider using [Text], which
/// integrates with [DefaultTextStyle]. /// integrates with [DefaultTextStyle].
class RawText extends LeafRenderObjectWidget { class RichText extends LeafRenderObjectWidget {
RawText({ Key key, this.text }) : super(key: key) { RichText({ Key key, this.text }) : super(key: key) {
assert(text != null); assert(text != null);
} }
...@@ -1418,45 +1418,11 @@ class RawText extends LeafRenderObjectWidget { ...@@ -1418,45 +1418,11 @@ class RawText extends LeafRenderObjectWidget {
RenderParagraph createRenderObject() => new RenderParagraph(text); RenderParagraph createRenderObject() => new RenderParagraph(text);
void updateRenderObject(RenderParagraph renderObject, RawText oldWidget) { void updateRenderObject(RenderParagraph renderObject, RichText oldWidget) {
renderObject.text = text; renderObject.text = text;
} }
} }
/// A convience widget for paragraphs of text with heterogeneous style.
///
/// The elements parameter is a recursive list of lists that matches the
/// following grammar:
///
/// `elements ::= "string" | [<text-style> <elements>*]``
///
/// Where "string" is text to display and text-style is an instance of
/// TextStyle. The text-style applies to all of the elements that follow.
class StyledText extends StatelessComponent {
StyledText({ this.elements, Key key }) : super(key: key) {
assert(_toSpan(elements) != null);
}
/// The recursive list of lists that describes the text and style to paint.
final dynamic elements;
TextSpan _toSpan(dynamic element) {
if (element is String)
return new PlainTextSpan(element);
if (element is Iterable) {
dynamic first = element.first;
if (first is! TextStyle)
throw new ArgumentError("First element of Iterable is a ${first.runtimeType} not a TextStyle");
return new StyledTextSpan(first, element.skip(1).map(_toSpan).toList());
}
throw new ArgumentError("Element is ${element.runtimeType} not a String or an Iterable");
}
Widget build(BuildContext context) {
return new RawText(text: _toSpan(elements));
}
}
/// 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 {
DefaultTextStyle({ DefaultTextStyle({
...@@ -1504,17 +1470,20 @@ class Text extends StatelessComponent { ...@@ -1504,17 +1470,20 @@ class Text extends StatelessComponent {
/// replace the closest enclosing [DefaultTextStyle]. /// replace the closest enclosing [DefaultTextStyle].
final TextStyle style; final TextStyle style;
TextStyle _getEffectiveStyle(BuildContext context) {
if (style == null || style.inherit)
return DefaultTextStyle.of(context)?.merge(style) ?? style;
else
return style;
}
Widget build(BuildContext context) { Widget build(BuildContext context) {
TextSpan text = new PlainTextSpan(data); return new RichText(
TextStyle combinedStyle; text: new TextSpan(
if (style == null || style.inherit) { style: _getEffectiveStyle(context),
combinedStyle = DefaultTextStyle.of(context)?.merge(style) ?? style; text: data
} else { )
combinedStyle = style; );
}
if (combinedStyle != null)
text = new StyledTextSpan(combinedStyle, <TextSpan>[text]);
return new RawText(text: text);
} }
void debugFillDescription(List<String> description) { void debugFillDescription(List<String> description) {
......
...@@ -25,7 +25,7 @@ class _CheckedModeBannerPainter extends CustomPainter { ...@@ -25,7 +25,7 @@ class _CheckedModeBannerPainter extends CustomPainter {
); );
static final TextPainter textPainter = new TextPainter() static final TextPainter textPainter = new TextPainter()
..text = new StyledTextSpan(kTextStyles, <TextSpan>[new PlainTextSpan('SLOW MODE')]) ..text = new TextSpan(style: kTextStyles, text: 'SLOW MODE')
..maxWidth = kOffset * 2.0 ..maxWidth = kOffset * 2.0
..maxHeight = kHeight ..maxHeight = kHeight
..layout(); ..layout();
......
...@@ -112,7 +112,7 @@ class InputValue { ...@@ -112,7 +112,7 @@ class InputValue {
return typedOther.text == text return typedOther.text == text
&& typedOther.selection == selection && typedOther.selection == selection
&& typedOther.composing == composing; && typedOther.composing == composing;
} }
int get hashCode => hashValues( int get hashCode => hashValues(
text.hashCode, text.hashCode,
...@@ -126,7 +126,7 @@ class InputValue { ...@@ -126,7 +126,7 @@ class InputValue {
TextRange composing TextRange composing
}) { }) {
return new InputValue ( return new InputValue (
text: text ?? this.text, text: text ?? this.text,
selection: selection ?? this.selection, selection: selection ?? this.selection,
composing: composing ?? this.composing composing: composing ?? this.composing
); );
...@@ -394,24 +394,27 @@ class _EditableLineWidget extends LeafRenderObjectWidget { ...@@ -394,24 +394,27 @@ class _EditableLineWidget extends LeafRenderObjectWidget {
..paintOffset = paintOffset; ..paintOffset = paintOffset;
} }
StyledTextSpan get _styledTextSpan { TextSpan get _styledTextSpan {
if (!hideText && value.composing.isValid) { if (!hideText && value.composing.isValid) {
TextStyle composingStyle = style.merge( TextStyle composingStyle = style.merge(
const TextStyle(decoration: TextDecoration.underline) const TextStyle(decoration: TextDecoration.underline)
); );
return new StyledTextSpan(style, <TextSpan>[ return new TextSpan(
new PlainTextSpan(value.composing.textBefore(value.text)), style: style,
new StyledTextSpan(composingStyle, <TextSpan>[ children: <TextSpan>[
new PlainTextSpan(value.composing.textInside(value.text)) new TextSpan(text: value.composing.textBefore(value.text)),
]), new TextSpan(
new PlainTextSpan(value.composing.textAfter(value.text)) style: composingStyle,
text: value.composing.textInside(value.text)
),
new TextSpan(text: value.composing.textAfter(value.text))
]); ]);
} }
String text = value.text; String text = value.text;
if (hideText) if (hideText)
text = new String.fromCharCodes(new List<int>.filled(text.length, 0x2022)); text = new String.fromCharCodes(new List<int>.filled(text.length, 0x2022));
return new StyledTextSpan(style, <TextSpan>[ new PlainTextSpan(text) ]); return new TextSpan(style: style, text: text);
} }
} }
...@@ -172,7 +172,7 @@ class _SemanticsDebuggerEntry { ...@@ -172,7 +172,7 @@ class _SemanticsDebuggerEntry {
message = message.trim(); message = message.trim();
if (message != '') { if (message != '') {
textPainter ??= new TextPainter(); textPainter ??= new TextPainter();
textPainter.text = new StyledTextSpan(textStyles, <TextSpan>[new PlainTextSpan(message)]); textPainter.text = new TextSpan(style: textStyles, text: message);
textPainter.maxWidth = rect.width; textPainter.maxWidth = rect.width;
textPainter.maxHeight = rect.height; textPainter.maxHeight = rect.height;
textPainter.layout(); textPainter.layout();
......
...@@ -15,11 +15,9 @@ class TestBlockPainter extends Painter { ...@@ -15,11 +15,9 @@ class TestBlockPainter extends Painter {
void main() { void main() {
test('block intrinsics', () { test('block intrinsics', () {
RenderParagraph paragraph = new RenderParagraph( RenderParagraph paragraph = new RenderParagraph(
new StyledTextSpan( new TextSpan(
new TextStyle( style: new TextStyle(height: 1.0),
height: 1.0 text: 'Hello World'
),
<TextSpan>[new PlainTextSpan('Hello World')]
) )
); );
const BoxConstraints unconstrained = const BoxConstraints(); const BoxConstraints unconstrained = const BoxConstraints();
......
...@@ -15,7 +15,7 @@ void main() { ...@@ -15,7 +15,7 @@ void main() {
root = new RenderPositionedBox( root = new RenderPositionedBox(
child: new RenderCustomPaint( child: new RenderCustomPaint(
child: child = text = new RenderParagraph(new PlainTextSpan('Hello World')), child: child = text = new RenderParagraph(new TextSpan(text: 'Hello World')),
painter: new TestCallbackPainter( painter: new TestCallbackPainter(
onPaint: () { onPaint: () {
baseline1 = child.getDistanceToBaseline(TextBaseline.alphabetic); baseline1 = child.getDistanceToBaseline(TextBaseline.alphabetic);
...@@ -29,7 +29,7 @@ void main() { ...@@ -29,7 +29,7 @@ void main() {
root = new RenderPositionedBox( root = new RenderPositionedBox(
child: new RenderCustomPaint( child: new RenderCustomPaint(
child: child = new RenderOverflowBox( child: child = new RenderOverflowBox(
child: text = new RenderParagraph(new PlainTextSpan('Hello World')), child: text = new RenderParagraph(new TextSpan(text: 'Hello World')),
maxHeight: height1 / 2.0, maxHeight: height1 / 2.0,
alignment: const FractionalOffset(0.0, 0.0) alignment: const FractionalOffset(0.0, 0.0)
), ),
......
...@@ -35,9 +35,7 @@ class Label extends Node { ...@@ -35,9 +35,7 @@ class Label extends Node {
void paint(Canvas canvas) { void paint(Canvas canvas) {
if (_painter == null) { if (_painter == null) {
PlainTextSpan textSpan = new PlainTextSpan(_text); _painter = new TextPainter(new TextSpan(style: _textStyle, text: _text));
StyledTextSpan styledTextSpan = new StyledTextSpan(_textStyle, <TextSpan>[textSpan]);
_painter = new TextPainter(styledTextSpan);
_painter.maxWidth = double.INFINITY; _painter.maxWidth = double.INFINITY;
_painter.minWidth = 0.0; _painter.minWidth = 0.0;
......
...@@ -166,9 +166,9 @@ class ChartPainter { ...@@ -166,9 +166,9 @@ class ChartPainter {
..value = _roundToPlaces(data.startY + stepSize * i, data.roundToPlaces); ..value = _roundToPlaces(data.startY + stepSize * i, data.roundToPlaces);
if (gridline.value < data.startY || gridline.value > data.endY) if (gridline.value < data.startY || gridline.value > data.endY)
continue; // TODO(jackson): Align things so this doesn't ever happen continue; // TODO(jackson): Align things so this doesn't ever happen
TextSpan text = new StyledTextSpan( TextSpan text = new TextSpan(
_textTheme.body1, style: _textTheme.body1,
[new PlainTextSpan("${gridline.value}")] text: '${gridline.value}'
); );
gridline.labelPainter = new TextPainter(text) gridline.labelPainter = new TextPainter(text)
..maxWidth = _rect.width ..maxWidth = _rect.width
...@@ -213,9 +213,9 @@ class ChartPainter { ...@@ -213,9 +213,9 @@ class ChartPainter {
..start = _convertPointToRectSpace(new Point(data.startX, data.indicatorLine), markerRect) ..start = _convertPointToRectSpace(new Point(data.startX, data.indicatorLine), markerRect)
..end = _convertPointToRectSpace(new Point(data.endX, data.indicatorLine), markerRect); ..end = _convertPointToRectSpace(new Point(data.endX, data.indicatorLine), markerRect);
if (data.indicatorText != null) { if (data.indicatorText != null) {
TextSpan text = new StyledTextSpan( TextSpan text = new TextSpan(
_textTheme.body1, style: _textTheme.body1,
<TextSpan>[new PlainTextSpan("${data.indicatorText}")] text: '${data.indicatorText}'
); );
_indicator.labelPainter = new TextPainter(text) _indicator.labelPainter = new TextPainter(text)
..maxWidth = markerRect.width ..maxWidth = markerRect.width
......
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