提交 518ecd24 编写于 作者: E Eric Seidel

Add support for text styles.

This is a completion of Hans's WIP patch:
https://codereview.chromium.org/1176133002/

Makes it possible for us to style text in fn2 apps.

The title style in the toolbar doesn't look quite right
but as far as I can tell its the same color as the
old typography code produced.  Will need further investigation.

Fixes #213

R=abarth@chromium.org, jackson@google.com

Review URL: https://codereview.chromium.org/1178913003.
上级 77dd41ad
......@@ -28,8 +28,10 @@ LayoutRoot::LayoutRoot()
, m_maxHeight(0)
{
m_settings = Settings::create();
m_settings->setDefaultFixedFontSize(13);
m_settings->setDefaultFontSize(16);
// Using 14px default to match Material Design English Body1:
// http://www.google.com/design/spec/style/typography.html#typography-typeface
m_settings->setDefaultFixedFontSize(14);
m_settings->setDefaultFontSize(14);
m_frameHost = FrameHost::createDummy(m_settings.get());
m_frame = LocalFrame::create(nullptr, m_frameHost.get());
m_frame->createView(IntSize(), Color::white, false);
......
......@@ -4,7 +4,9 @@
import 'package:sky/framework/editing2/input.dart';
import 'package:sky/framework/rendering/box.dart';
import 'package:sky/framework/rendering/paragraph.dart';
import 'package:sky/framework/theme2/colors.dart' as colors;
import 'package:sky/framework/theme2/typography.dart' as typography;
import 'package:sky/framework/widgets/drawer.dart';
import 'package:sky/framework/widgets/drawer_header.dart';
import 'package:sky/framework/widgets/floating_action_button.dart';
......@@ -28,9 +30,6 @@ enum StockMode { optimistic, pessimistic }
class StocksApp extends App {
// static final Style _titleStyle = new Style('''
// ${typography.white.title};''');
List<Stock> _stocks = [];
StocksApp({ RenderView renderViewOverride }) : super(renderViewOverride: renderViewOverride) {
......@@ -157,7 +156,7 @@ class StocksApp extends App {
left: new IconButton(
icon: 'navigation/menu_white',
onGestureTap: (_) => _drawerController.toggle()),
center: new Text('Stocks'),
center: new Text('Stocks', style: typography.white.title),
right: [
new IconButton(
icon: 'action/search_white',
......
......@@ -5,8 +5,10 @@
import 'dart:sky' as sky;
import 'package:sky/framework/rendering/box.dart';
import 'package:sky/framework/widgets/wrappers.dart';
import 'package:sky/framework/theme2/typography.dart' as typography;
import 'package:sky/framework/widgets/ink_well.dart';
import 'package:sky/framework/widgets/wrappers.dart';
import 'package:sky/framework/rendering/paragraph.dart';
import 'stock_arrow.dart';
import 'stock_data.dart';
......@@ -31,9 +33,12 @@ class StockRow extends Component {
margin: const EdgeDims.only(right: 5.0)),
new FlexExpandingChild(new Text(stock.symbol), flex: 2, key: "symbol"),
// TODO(hansmuller): text-align: right
new FlexExpandingChild(new Text(lastSale), key: "lastSale"),
// TODO(hansmuller): text-align: right, ${typography.black.caption};
new FlexExpandingChild(new Text(changeInPrice), key: "changeInPrice")
new FlexExpandingChild(new Text(lastSale,
style: const TextStyle(textAlign: TextAlign.right)),
key: "lastSale"),
new FlexExpandingChild(new Text(changeInPrice,
style: typography.black.caption.copyWith(textAlign: TextAlign.right)),
key: "changeInPrice")
];
// TODO(hansmuller): An explicit |height| shouldn't be needed
......
......@@ -11,6 +11,64 @@ class RenderInline extends RenderObject {
String data;
}
enum FontWeight {
light, // 300
regular, // 400
medium, // 500
}
enum TextAlign {
left,
right,
center
}
class TextStyle {
const TextStyle({
this.color,
this.fontSize,
this.fontWeight,
this.textAlign
});
final Color color;
final double fontSize; // in pixels
final FontWeight fontWeight;
final TextAlign textAlign;
TextStyle copyWith({
Color color,
double fontSize,
FontWeight fontWeight,
TextAlign textAlign
}) {
return new TextStyle(
color: color != null ? color : this.color,
fontSize: fontSize != null ? fontSize : this.fontSize,
fontWeight: fontWeight != null ? fontWeight : this.fontWeight,
textAlign: textAlign != null ? textAlign : this.textAlign
);
}
bool operator ==(other) {
return other is TextStyle &&
color == other.color &&
fontSize == other.fontSize &&
fontWeight == other.fontWeight &&
textAlign == other.textAlign;
}
int get hashCode {
// Use Quiver: https://github.com/domokit/mojo/issues/236
int value = 373;
value = 37 * value + color.hashCode;
value = 37 * value + fontSize.hashCode;
value = 37 * value + fontWeight.hashCode;
value = 37 * value + textAlign.hashCode;
return value;
}
}
// Unfortunately, using full precision floating point here causes bad layouts
// because floating point math isn't associative. If we add and subtract
// padding, for example, we'll get different values when we estimate sizes and
......@@ -26,8 +84,9 @@ class RenderParagraph extends RenderBox {
RenderParagraph({
String text,
Color color
}) : _color = color {
Color color,
TextStyle style
}) : _style = style {
_layoutRoot.rootElement = _document.createElement('p');
this.text = text;
}
......@@ -41,12 +100,13 @@ class RenderParagraph extends RenderBox {
markNeedsLayout();
}
Color _color = const Color(0xFF000000);
Color get color => _color;
void set color (Color value) {
if (_color != value) {
_color = value;
markNeedsPaint();
TextStyle _style;
TextStyle get style => _style;
void set style (TextStyle value) {
if (_style != value) {
// TODO(hansmuller): decide if a new layout or paint is needed
markNeedsLayout();
_style = value;
}
}
......@@ -106,9 +166,30 @@ class RenderParagraph extends RenderBox {
if (_constraintsForCurrentLayout != constraints && constraints != null)
_layout(constraints);
if (_color != null) {
_layoutRoot.rootElement.style['color'] =
'rgba(${_color.red}, ${_color.green}, ${_color.blue}, ${_color.alpha / 255.0 })';
if (style != null) {
var cssStyle = _layoutRoot.rootElement.style;
if (style.color != null) {
Color c = style.color;
cssStyle['color'] =
'rgba(${c.red}, ${c.green}, ${c.blue}, ${c.alpha / 255.0})';
}
if (style.fontSize != null) {
cssStyle['font-size'] = "${style.fontSize}px";
}
if (style.fontWeight != null) {
cssStyle['font-weight'] = const {
FontWeight.light: '300',
FontWeight.regular: '400',
FontWeight.medium: '500',
}[style.fontWeight];
}
if (style.textAlign != null) {
cssStyle['text-align'] = const {
TextAlign.left: 'left',
TextAlign.right: 'right',
TextAlign.center: 'center',
}[style.textAlign];
}
}
_layoutRoot.paint(canvas);
}
......
......@@ -4,53 +4,50 @@
// See http://www.google.com/design/spec/style/typography.html
const String _display4 = 'font-size: 112px; font-weight: 300';
const String _display3 = 'font-size: 56px; font-weight: 400';
const String _display2 = 'font-size: 45px; font-weight: 400';
const String _display1 = 'font-size: 34px; font-weight: 400';
const String _headline = 'font-size: 24px; font-weight: 400';
const String _title = 'font-size: 20px; font-weight: 500';
const String _subhead = 'font-size: 16px; font-weight: 400';
const String _body2 = 'font-size: 14px; font-weight: 500';
const String _body1 = 'font-size: 14px; font-weight: 400';
const String _caption = 'font-size: 12px; font-weight: 400';
const String _button = 'font-size: 14px; font-weight: 500';
class _Black {
final String display4 = 'color: #757575; ${_display4}'; // 54%
final String display3 = 'color: #757575; ${_display3}'; // 54%
final String display2 = 'color: #757575; ${_display2}'; // 54%
final String display1 = 'color: #757575; ${_display1}'; // 54%
final String headline = 'color: #212121; ${_headline}'; // 87%
final String title = 'color: #212121; ${_title}'; // 87%
final String subhead = 'color: #212121; ${_subhead}'; // 87%
final String body2 = 'color: #212121; ${_body2}'; // 87%
final String body1 = 'color: #212121; ${_body1}'; // 87%
final String caption = 'color: #757575; ${_caption}'; // 54%
final String button = 'color: #212121; ${_button}'; // 87%
const _Black();
import 'dart:sky';
import '../rendering/paragraph.dart';
// TODO(eseidel): Font weights are supposed to be language relative!
// These values are for English-like text.
class _TextTheme {
_TextTheme(Color color54, Color color87)
: display4 = new TextStyle(fontSize: 112.0, fontWeight: FontWeight.light, color: color54),
display3 = new TextStyle(fontSize: 56.0, fontWeight: FontWeight.regular, color: color54),
display2 = new TextStyle(fontSize: 45.0, fontWeight: FontWeight.regular, color: color54),
display1 = new TextStyle(fontSize: 34.0, fontWeight: FontWeight.regular, color: color54),
headline = new TextStyle(fontSize: 24.0, fontWeight: FontWeight.regular, color: color87),
title = new TextStyle(fontSize: 20.0, fontWeight: FontWeight.medium, color: color87),
subhead = new TextStyle(fontSize: 16.0, fontWeight: FontWeight.regular, color: color87),
body2 = new TextStyle(fontSize: 14.0, fontWeight: FontWeight.medium, color: color87),
body1 = new TextStyle(fontSize: 14.0, fontWeight: FontWeight.regular, color: color87),
caption = new TextStyle(fontSize: 12.0, fontWeight: FontWeight.regular, color: color54),
button = new TextStyle(fontSize: 14.0, fontWeight: FontWeight.medium, color: color87);
final TextStyle display4;
final TextStyle display3;
final TextStyle display2;
final TextStyle display1;
final TextStyle headline;
final TextStyle title;
final TextStyle subhead;
final TextStyle body2;
final TextStyle body1;
final TextStyle caption;
final TextStyle button;
}
const _Black black = const _Black();
class _White {
final String display4 = 'color: #8A8A8A; ${_display4}'; // 54%
final String display3 = 'color: #8A8A8A; ${_display3}'; // 54%
final String display2 = 'color: #8A8A8A; ${_display2}'; // 54%
final String display1 = 'color: #8A8A8A; ${_display1}'; // 54%
final String headline = 'color: #DEDEDE; ${_headline}'; // 87%
final String title = 'color: #DEDEDE; ${_title}'; // 87%
final String subhead = 'color: #DEDEDE; ${_subhead}'; // 87%
final String body2 = 'color: #DEDEDE; ${_body2}'; // 87%
final String body1 = 'color: #DEDEDE; ${_body1}'; // 87%
final String caption = 'color: #8A8A8A; ${_caption}'; // 54%
final String button = 'color: #DEDEDE; ${_button}'; // 87%
const _White();
}
const _White white = const _White();
final _TextTheme black = new _TextTheme(
const Color(0xFF757575),
const Color(0xFF212121)
);
final _TextTheme white = new _TextTheme(
const Color(0xFF8A8A8A),
const Color(0xFFDEDEDE)
);
// TODO(abarth): Maybe this should be hard-coded in Scaffold?
const String typeface = 'font-family: sans-serif';
......@@ -744,7 +744,6 @@ abstract class MultiChildRenderObjectWrapper extends RenderObjectWrapper {
}
class UINodeAppView extends AppView {
UINodeAppView({ RenderView renderViewOverride: null })
......@@ -771,7 +770,7 @@ class UINodeAppView extends AppView {
if (target is EventListenerNode)
target._handleEvent(event);
target = target._parent;
}
}
}
}
......@@ -856,5 +855,4 @@ class RenderObjectToUINodeAdapter extends AbstractUINodeRoot {
}
UINode build() => builder();
}
}
\ No newline at end of file
......@@ -331,16 +331,18 @@ class FlexExpandingChild extends ParentDataNode {
class Paragraph extends RenderObjectWrapper {
Paragraph({ Object key, this.text }) : super(key: key);
Paragraph({ Object key, this.text, this.style }) : super(key: key);
RenderParagraph get root { RenderParagraph result = super.root; return result; }
RenderParagraph createNode() => new RenderParagraph(text: text);
RenderParagraph createNode() => new RenderParagraph(text: text, style: style);
final String text;
final TextStyle style;
void syncRenderObject(UINode old) {
super.syncRenderObject(old);
root.text = text;
root.style = style;
}
void insert(RenderObjectWrapper child, dynamic slot) {
......@@ -351,10 +353,11 @@ class Paragraph extends RenderObjectWrapper {
}
class Text extends Component {
Text(this.data) : super(key: '*text*');
Text(this.data, { TextStyle this.style }) : super(key: '*text*');
final String data;
final TextStyle style;
bool get interchangeable => true;
UINode build() => new Paragraph(text: data);
UINode build() => new Paragraph(text: data, style: style);
}
class Image extends RenderObjectWrapper {
......
......@@ -31,7 +31,7 @@ PAINT FOR FRAME #2 ----------------------------------------------
2 | | | | | | | TestDisplayList() constructor: 800.0 x 600.0
2 | | | | | | | paintChild RenderImage at Point(8.0, 8.0)
2 | | | | | | | | TestDisplayList() constructor: 800.0 x 600.0
2 | | | | | | paintChild RenderPadding at Point(40.0, 18.5)
2 | | | | | | paintChild RenderPadding at Point(40.0, 20.0)
2 | | | | | | | TestDisplayList() constructor: 800.0 x 600.0
2 | | | | | | | paintChild RenderParagraph at Point(24.0, 0.0)
2 | | | | | | | | TestDisplayList() constructor: 800.0 x 600.0
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册