mirror of
https://github.com/flutter/flutter.git
synced 2026-02-20 02:29:02 +08:00
Add a new Theme widget to control color and text color of apps
R=abarth@chromium.org, abarth, hixie Review URL: https://codereview.chromium.org/1194743003.
This commit is contained in:
parent
8a5bd9b676
commit
884b4e36dc
@ -3,8 +3,12 @@
|
||||
// found in the LICENSE file.
|
||||
|
||||
import 'package:sky/rendering/sky_binding.dart';
|
||||
import 'package:sky/theme/colors.dart' as colors;
|
||||
import 'package:sky/theme/theme_data.dart';
|
||||
import 'package:sky/theme/typography.dart' as typography;
|
||||
import 'package:sky/widgets/basic.dart';
|
||||
import 'package:sky/widgets/navigator.dart';
|
||||
import 'package:sky/widgets/theme.dart';
|
||||
import 'package:sky/widgets/widget.dart';
|
||||
|
||||
import 'stock_data.dart';
|
||||
@ -46,7 +50,10 @@ class StocksApp extends App {
|
||||
}
|
||||
|
||||
Widget build() {
|
||||
return new Navigator(_navigationState);
|
||||
return new Theme(
|
||||
data: new ThemeData(color: colors.Purple, text: typography.white),
|
||||
child: new Navigator(_navigationState)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -169,8 +169,7 @@ class StockHome extends Component {
|
||||
new IconButton(
|
||||
icon: 'navigation/more_vert_white',
|
||||
onPressed: _handleMenuShow)
|
||||
],
|
||||
backgroundColor: colors.Purple[500]
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@ -3,13 +3,13 @@
|
||||
// found in the LICENSE file.
|
||||
|
||||
import 'package:sky/theme/colors.dart' as colors;
|
||||
import 'package:sky/theme/typography.dart' as typography;
|
||||
import 'package:sky/widgets/basic.dart';
|
||||
import 'package:sky/widgets/checkbox.dart';
|
||||
import 'package:sky/widgets/icon_button.dart';
|
||||
import 'package:sky/widgets/menu_item.dart';
|
||||
import 'package:sky/widgets/navigator.dart';
|
||||
import 'package:sky/widgets/scaffold.dart';
|
||||
import 'package:sky/widgets/theme.dart';
|
||||
import 'package:sky/widgets/tool_bar.dart';
|
||||
|
||||
class StockSettings extends Component {
|
||||
@ -30,8 +30,7 @@ class StockSettings extends Component {
|
||||
left: new IconButton(
|
||||
icon: 'navigation/arrow_back_white',
|
||||
onPressed: _navigator.pop),
|
||||
center: new Text('Settings', style: typography.white.title),
|
||||
backgroundColor: colors.Purple[500]
|
||||
center: new Text('Settings', style: Theme.of(this).text.title)
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@ -7,13 +7,15 @@ import 'dart:math' as math;
|
||||
import 'package:sky/rendering/box.dart';
|
||||
import 'package:sky/rendering/flex.dart';
|
||||
import 'package:sky/rendering/sky_binding.dart';
|
||||
import 'package:sky/theme/colors.dart';
|
||||
import 'package:sky/theme/colors.dart' as colors;
|
||||
import 'package:sky/theme/edges.dart';
|
||||
import 'package:sky/theme/typography.dart';
|
||||
import 'package:sky/theme/theme_data.dart';
|
||||
import 'package:sky/theme/typography.dart' as typography;
|
||||
import 'package:sky/widgets/basic.dart';
|
||||
import 'package:sky/widgets/material.dart';
|
||||
import 'package:sky/widgets/raised_button.dart';
|
||||
import 'package:sky/widgets/scaffold.dart';
|
||||
import 'package:sky/widgets/theme.dart';
|
||||
import 'package:sky/widgets/tool_bar.dart';
|
||||
import 'package:sky/widgets/widget.dart';
|
||||
|
||||
@ -74,61 +76,63 @@ class SectorApp extends App {
|
||||
}
|
||||
|
||||
Widget build() {
|
||||
return new Scaffold(
|
||||
toolbar: new ToolBar(
|
||||
center: new Text('Sector Layout in a Widget Tree', style: white.title),
|
||||
backgroundColor: Blue[500]),
|
||||
body: new Material(
|
||||
edge: MaterialEdge.canvas,
|
||||
child: new Flex([
|
||||
new Container(
|
||||
padding: new EdgeDims.symmetric(horizontal: 8.0, vertical: 25.0),
|
||||
child: new Flex([
|
||||
new RaisedButton(
|
||||
enabled: enabledAdd,
|
||||
child: new ShrinkWrapWidth(
|
||||
child: new Flex([
|
||||
new Container(
|
||||
padding: new EdgeDims.all(4.0),
|
||||
margin: new EdgeDims.only(right: 10.0),
|
||||
child: new WidgetToRenderBoxAdapter(sectorAddIcon)
|
||||
),
|
||||
new Text('ADD SECTOR'),
|
||||
])
|
||||
return new Theme(
|
||||
data: new ThemeData(color: colors.Blue, text: typography.white),
|
||||
child: new Scaffold(
|
||||
toolbar: new ToolBar(
|
||||
center: new Text('Sector Layout in a Widget Tree', style: typography.white.title)),
|
||||
body: new Material(
|
||||
edge: MaterialEdge.canvas,
|
||||
child: new Flex([
|
||||
new Container(
|
||||
padding: new EdgeDims.symmetric(horizontal: 8.0, vertical: 25.0),
|
||||
child: new Flex([
|
||||
new RaisedButton(
|
||||
enabled: enabledAdd,
|
||||
child: new ShrinkWrapWidth(
|
||||
child: new Flex([
|
||||
new Container(
|
||||
padding: new EdgeDims.all(4.0),
|
||||
margin: new EdgeDims.only(right: 10.0),
|
||||
child: new WidgetToRenderBoxAdapter(sectorAddIcon)
|
||||
),
|
||||
new Text('ADD SECTOR'),
|
||||
])
|
||||
),
|
||||
onPressed: addSector
|
||||
),
|
||||
onPressed: addSector
|
||||
new RaisedButton(
|
||||
enabled: enabledRemove,
|
||||
child: new ShrinkWrapWidth(
|
||||
child: new Flex([
|
||||
new Container(
|
||||
padding: new EdgeDims.all(4.0),
|
||||
margin: new EdgeDims.only(right: 10.0),
|
||||
child: new WidgetToRenderBoxAdapter(sectorRemoveIcon)
|
||||
),
|
||||
new Text('REMOVE SECTOR'),
|
||||
])
|
||||
),
|
||||
onPressed: removeSector
|
||||
)
|
||||
],
|
||||
justifyContent: FlexJustifyContent.spaceAround
|
||||
)
|
||||
),
|
||||
new Flexible(
|
||||
child: new Container(
|
||||
margin: new EdgeDims.all(8.0),
|
||||
decoration: new BoxDecoration(
|
||||
border: new Border.all(new BorderSide(color: new Color(0xFF000000)))
|
||||
),
|
||||
new RaisedButton(
|
||||
enabled: enabledRemove,
|
||||
child: new ShrinkWrapWidth(
|
||||
child: new Flex([
|
||||
new Container(
|
||||
padding: new EdgeDims.all(4.0),
|
||||
margin: new EdgeDims.only(right: 10.0),
|
||||
child: new WidgetToRenderBoxAdapter(sectorRemoveIcon)
|
||||
),
|
||||
new Text('REMOVE SECTOR'),
|
||||
])
|
||||
),
|
||||
onPressed: removeSector
|
||||
)
|
||||
],
|
||||
justifyContent: FlexJustifyContent.spaceAround
|
||||
)
|
||||
),
|
||||
new Flexible(
|
||||
child: new Container(
|
||||
margin: new EdgeDims.all(8.0),
|
||||
decoration: new BoxDecoration(
|
||||
border: new Border.all(new BorderSide(color: new Color(0xFF000000)))
|
||||
),
|
||||
padding: new EdgeDims.all(8.0),
|
||||
child: new WidgetToRenderBoxAdapter(sectors)
|
||||
)
|
||||
),
|
||||
],
|
||||
direction: FlexDirection.vertical,
|
||||
justifyContent: FlexJustifyContent.spaceBetween
|
||||
padding: new EdgeDims.all(8.0),
|
||||
child: new WidgetToRenderBoxAdapter(sectors)
|
||||
)
|
||||
),
|
||||
],
|
||||
direction: FlexDirection.vertical,
|
||||
justifyContent: FlexJustifyContent.spaceBetween
|
||||
)
|
||||
)
|
||||
)
|
||||
);
|
||||
|
||||
@ -7,10 +7,12 @@ import 'package:sky/rendering/box.dart';
|
||||
import 'package:sky/rendering/flex.dart';
|
||||
import 'package:sky/rendering/sky_binding.dart';
|
||||
import 'package:sky/theme/colors.dart';
|
||||
import 'package:sky/theme/theme_data.dart';
|
||||
import 'package:sky/theme/typography.dart';
|
||||
import 'package:sky/widgets/basic.dart';
|
||||
import 'package:sky/widgets/material.dart';
|
||||
import 'package:sky/widgets/scaffold.dart';
|
||||
import 'package:sky/widgets/theme.dart';
|
||||
import 'package:sky/widgets/tool_bar.dart';
|
||||
import 'package:sky/widgets/widget.dart';
|
||||
|
||||
@ -105,11 +107,13 @@ HAL: This mission is too important for me to allow you to jeopardize it.''';
|
||||
onPointerDown: toggleToTextFunction
|
||||
);
|
||||
|
||||
return new Scaffold(
|
||||
body: new Material(child: interactiveBody),
|
||||
toolbar: new ToolBar(
|
||||
center: new Text('Hal and Dave', style: white.title),
|
||||
backgroundColor: Blue[500]
|
||||
return new Theme(
|
||||
data: new ThemeData(color: Blue, text: white),
|
||||
child: new Scaffold(
|
||||
body: new Material(child: interactiveBody),
|
||||
toolbar: new ToolBar(
|
||||
center: new Text('Hal and Dave', style: white.title)
|
||||
)
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
@ -90,6 +90,7 @@ dart_pkg("sdk") {
|
||||
"lib/theme/colors.dart",
|
||||
"lib/theme/edges.dart",
|
||||
"lib/theme/shadows.dart",
|
||||
"lib/theme/theme_data.dart",
|
||||
"lib/theme/typography.dart",
|
||||
"lib/theme/view_configuration.dart",
|
||||
"lib/widgets/animated_component.dart",
|
||||
@ -118,6 +119,7 @@ dart_pkg("sdk") {
|
||||
"lib/widgets/scaffold.dart",
|
||||
"lib/widgets/scrollable.dart",
|
||||
"lib/widgets/switch.dart",
|
||||
"lib/widgets/theme.dart",
|
||||
"lib/widgets/toggleable.dart",
|
||||
"lib/widgets/tool_bar.dart",
|
||||
"lib/widgets/widget.dart",
|
||||
|
||||
13
sdk/lib/theme/theme_data.dart
Normal file
13
sdk/lib/theme/theme_data.dart
Normal file
@ -0,0 +1,13 @@
|
||||
// Copyright 2015 The Chromium Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
import 'dart:sky';
|
||||
|
||||
import 'typography.dart';
|
||||
|
||||
class ThemeData {
|
||||
const ThemeData({ this.text, this.color });
|
||||
final TextTheme text;
|
||||
final Map<int, Color> color;
|
||||
}
|
||||
@ -10,8 +10,8 @@ import '../painting/text_style.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)
|
||||
class TextTheme {
|
||||
TextTheme._(Color color54, Color color87)
|
||||
: display4 = new TextStyle(fontSize: 112.0, fontWeight: FontWeight.w100, color: color54),
|
||||
display3 = new TextStyle(fontSize: 56.0, fontWeight: FontWeight.w400, color: color54),
|
||||
display2 = new TextStyle(fontSize: 45.0, fontWeight: FontWeight.w400, color: color54),
|
||||
@ -38,13 +38,13 @@ class _TextTheme {
|
||||
}
|
||||
|
||||
|
||||
final _TextTheme black = new _TextTheme(
|
||||
final TextTheme black = new TextTheme._(
|
||||
const Color(0xFF757575),
|
||||
const Color(0xFF212121)
|
||||
);
|
||||
|
||||
|
||||
final _TextTheme white = new _TextTheme(
|
||||
final TextTheme white = new TextTheme._(
|
||||
const Color(0xFF8A8A8A),
|
||||
const Color(0xFFDEDEDE)
|
||||
);
|
||||
|
||||
@ -4,7 +4,7 @@
|
||||
|
||||
import 'dart:sky' as sky;
|
||||
|
||||
import 'package:sky/theme/colors.dart' as colors;
|
||||
import 'package:sky/widgets/theme.dart';
|
||||
|
||||
import 'basic.dart';
|
||||
import 'toggleable.dart';
|
||||
@ -12,8 +12,6 @@ export 'toggleable.dart' show ValueChanged;
|
||||
|
||||
const double _kMidpoint = 0.5;
|
||||
const sky.Color _kUncheckedColor = const sky.Color(0x8A000000);
|
||||
// TODO(jackson): This should change colors with the theme
|
||||
sky.Color _kCheckedColor = colors.Purple[500];
|
||||
const double _kEdgeSize = 20.0;
|
||||
const double _kEdgeRadius = 1.0;
|
||||
|
||||
@ -59,10 +57,11 @@ class Checkbox extends Toggleable {
|
||||
|
||||
// Solid filled rrect
|
||||
paint.setStyle(sky.PaintingStyle.strokeAndFill);
|
||||
Color themeColor = Theme.of(this).color[500];
|
||||
paint.color = new Color.fromARGB((t * 255).floor(),
|
||||
_kCheckedColor.red,
|
||||
_kCheckedColor.green,
|
||||
_kCheckedColor.blue);
|
||||
themeColor.red,
|
||||
themeColor.green,
|
||||
themeColor.blue);
|
||||
canvas.drawRRect(rrect, paint);
|
||||
|
||||
// White inner check
|
||||
|
||||
@ -181,6 +181,19 @@ class Scaffold extends RenderObjectWrapper {
|
||||
RenderScaffold get root => super.root;
|
||||
RenderScaffold createNode() => new RenderScaffold();
|
||||
|
||||
void walkChildren(WidgetTreeWalker walker) {
|
||||
if (_toolbar != null)
|
||||
walker(_toolbar);
|
||||
if (_body != null)
|
||||
walker(_body);
|
||||
if (_statusBar != null)
|
||||
walker(_statusBar);
|
||||
if (_drawer != null)
|
||||
walker(_drawer);
|
||||
if (_floatingActionButton != null)
|
||||
walker(_floatingActionButton);
|
||||
}
|
||||
|
||||
void insertChildRoot(RenderObjectWrapper child, ScaffoldSlots slot) {
|
||||
root[slot] = child != null ? child.root : null;
|
||||
}
|
||||
@ -194,16 +207,7 @@ class Scaffold extends RenderObjectWrapper {
|
||||
}
|
||||
|
||||
void remove() {
|
||||
if (_toolbar != null)
|
||||
removeChild(_toolbar);
|
||||
if (_body != null)
|
||||
removeChild(_body);
|
||||
if (_statusBar != null)
|
||||
removeChild(_statusBar);
|
||||
if (_drawer != null)
|
||||
removeChild(_drawer);
|
||||
if (_floatingActionButton != null)
|
||||
removeChild(_floatingActionButton);
|
||||
walkChildren((Widget child) => removeChild(child));
|
||||
super.remove();
|
||||
}
|
||||
|
||||
|
||||
28
sdk/lib/widgets/theme.dart
Normal file
28
sdk/lib/widgets/theme.dart
Normal file
@ -0,0 +1,28 @@
|
||||
// Copyright 2015 The Chromium Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
import 'package:sky/theme/theme_data.dart';
|
||||
import 'basic.dart';
|
||||
import 'widget.dart';
|
||||
|
||||
class Theme extends Inherited {
|
||||
|
||||
Theme({
|
||||
String key,
|
||||
this.data,
|
||||
Widget child
|
||||
}) : super(key: key, child: child) {
|
||||
assert(child != null);
|
||||
assert(data != null);
|
||||
}
|
||||
|
||||
final ThemeData data;
|
||||
|
||||
static ThemeData of(Component component) {
|
||||
Theme theme = component.inheritedOfType(Theme);
|
||||
// If you hit this assert, you need to wrap your Component in a Theme
|
||||
assert(theme != null);
|
||||
return theme.data;
|
||||
}
|
||||
}
|
||||
@ -2,6 +2,8 @@
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
import 'package:sky/widgets/theme.dart';
|
||||
|
||||
import '../rendering/flex.dart';
|
||||
import '../theme/shadows.dart';
|
||||
import '../theme/view_configuration.dart';
|
||||
@ -48,7 +50,7 @@ class ToolBar extends Component {
|
||||
),
|
||||
padding: new EdgeDims.symmetric(horizontal: 8.0),
|
||||
decoration: new BoxDecoration(
|
||||
backgroundColor: backgroundColor,
|
||||
backgroundColor: backgroundColor == null ? Theme.of(this).color[500] : backgroundColor,
|
||||
boxShadow: shadows[2]
|
||||
)
|
||||
);
|
||||
|
||||
@ -18,14 +18,24 @@ export '../rendering/object.dart' show Point, Size, Rect, Color, Paint, Path;
|
||||
|
||||
final bool _shouldLogRenderDuration = false;
|
||||
|
||||
typedef void WidgetTreeWalker(Widget);
|
||||
|
||||
// All Effen nodes derive from Widget. All nodes have a _parent, a _key and
|
||||
// can be sync'd.
|
||||
abstract class Widget {
|
||||
|
||||
Widget({ String key }) : _key = key {
|
||||
assert(this is AbstractWidgetRoot || this is App || _inRenderDirtyComponents); // you should not build the UI tree ahead of time, build it only during build()
|
||||
assert(_isConstructedDuringBuild());
|
||||
}
|
||||
|
||||
// TODO(jackson): Remove this workaround for limitation of Dart mixins
|
||||
Widget._withKey(String key) : _key = key {
|
||||
assert(_isConstructedDuringBuild());
|
||||
}
|
||||
|
||||
// you should not build the UI tree ahead of time, build it only during build()
|
||||
bool _isConstructedDuringBuild() => this is AbstractWidgetRoot || this is App || _inRenderDirtyComponents;
|
||||
|
||||
String _key;
|
||||
String get key => _key;
|
||||
|
||||
@ -55,6 +65,9 @@ abstract class Widget {
|
||||
}
|
||||
}
|
||||
|
||||
// Override this if you have children and call walker on each child
|
||||
void walkChildren(WidgetTreeWalker walker) { }
|
||||
|
||||
static void _notifyMountStatusChanged() {
|
||||
try {
|
||||
sky.tracing.begin("Widget._notifyMountStatusChanged");
|
||||
@ -171,8 +184,16 @@ abstract class TagNode extends Widget {
|
||||
TagNode(Widget child, { String key })
|
||||
: this.child = child, super(key: key);
|
||||
|
||||
// TODO(jackson): Remove this workaround for limitation of Dart mixins
|
||||
TagNode._withKey(Widget child, String key)
|
||||
: this.child = child, super._withKey(key);
|
||||
|
||||
Widget child;
|
||||
|
||||
void walkChildren(WidgetTreeWalker walker) {
|
||||
walker(child);
|
||||
}
|
||||
|
||||
void _sync(Widget old, dynamic slot) {
|
||||
Widget oldChild = old == null ? null : (old as TagNode).child;
|
||||
child = syncChild(child, oldChild, slot);
|
||||
@ -200,6 +221,56 @@ class ParentDataNode extends TagNode {
|
||||
final ParentData parentData;
|
||||
}
|
||||
|
||||
abstract class _Heir implements Widget {
|
||||
Map<Type, Inherited> _traits;
|
||||
Inherited inheritedOfType(Type type) => _traits[type];
|
||||
|
||||
static _Heir _getHeirAncestor(Widget widget) {
|
||||
Widget ancestor = widget;
|
||||
while (ancestor != null && !(ancestor is _Heir)) {
|
||||
ancestor = ancestor.parent;
|
||||
}
|
||||
return ancestor as _Heir;
|
||||
}
|
||||
|
||||
void _updateTraitsFromParent(Widget parent) {
|
||||
_Heir ancestor = _getHeirAncestor(parent);
|
||||
if (ancestor == null || ancestor._traits == null) return;
|
||||
_updateTraits(ancestor._traits);
|
||||
}
|
||||
|
||||
void _updateTraitsRecursively(Widget widget) {
|
||||
if (widget is _Heir)
|
||||
widget._updateTraits(_traits);
|
||||
else
|
||||
widget.walkChildren(_updateTraitsRecursively);
|
||||
}
|
||||
|
||||
void _updateTraits(Map<Type, Inherited> newTraits) {
|
||||
if (newTraits != _traits) {
|
||||
_traits = newTraits;
|
||||
walkChildren(_updateTraitsRecursively);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
abstract class Inherited extends TagNode with _Heir {
|
||||
Inherited({ String key, Widget child }) : super._withKey(child, key) {
|
||||
_traits = new Map<Type, Inherited>();
|
||||
}
|
||||
|
||||
void set _traits(Map<Type, Inherited> value) {
|
||||
super._traits = new Map<Type, Inherited>.from(value)
|
||||
..[runtimeType] = this;
|
||||
}
|
||||
|
||||
// TODO(jackson): When Dart supports super in mixins we can move to _Heir
|
||||
void setParent(Widget parent) {
|
||||
_updateTraitsFromParent(parent);
|
||||
super.setParent(parent);
|
||||
}
|
||||
}
|
||||
|
||||
typedef void GestureEventListener(sky.GestureEvent e);
|
||||
typedef void PointerEventListener(sky.PointerEvent e);
|
||||
typedef void EventListener(sky.Event e);
|
||||
@ -291,13 +362,12 @@ class Listener extends TagNode {
|
||||
|
||||
}
|
||||
|
||||
|
||||
abstract class Component extends Widget {
|
||||
abstract class Component extends Widget with _Heir {
|
||||
|
||||
Component({ String key, bool stateful })
|
||||
: _stateful = stateful != null ? stateful : false,
|
||||
_order = _currentOrder + 1,
|
||||
super(key: key);
|
||||
super._withKey(key);
|
||||
|
||||
static Component _currentlyBuilding;
|
||||
bool get _isBuilding => _currentlyBuilding == this;
|
||||
@ -314,6 +384,12 @@ abstract class Component extends Widget {
|
||||
super.didMount();
|
||||
}
|
||||
|
||||
// TODO(jackson): When Dart supports super in mixins we can move to _Heir
|
||||
void setParent(Widget parent) {
|
||||
_updateTraitsFromParent(parent);
|
||||
super.setParent(parent);
|
||||
}
|
||||
|
||||
void remove() {
|
||||
assert(_built != null);
|
||||
assert(root != null);
|
||||
@ -573,6 +649,10 @@ abstract class OneChildRenderObjectWrapper extends RenderObjectWrapper {
|
||||
Widget _child;
|
||||
Widget get child => _child;
|
||||
|
||||
void walkChildren(WidgetTreeWalker walker) {
|
||||
walker(child);
|
||||
}
|
||||
|
||||
void syncRenderObject(RenderObjectWrapper old) {
|
||||
super.syncRenderObject(old);
|
||||
Widget oldChild = old == null ? null : (old as OneChildRenderObjectWrapper).child;
|
||||
@ -600,7 +680,6 @@ abstract class OneChildRenderObjectWrapper extends RenderObjectWrapper {
|
||||
removeChild(child);
|
||||
super.remove();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
abstract class MultiChildRenderObjectWrapper extends RenderObjectWrapper {
|
||||
@ -616,6 +695,11 @@ abstract class MultiChildRenderObjectWrapper extends RenderObjectWrapper {
|
||||
|
||||
final List<Widget> children;
|
||||
|
||||
void walkChildren(WidgetTreeWalker walker) {
|
||||
for(Widget child in children)
|
||||
walker(child);
|
||||
}
|
||||
|
||||
void insertChildRoot(RenderObjectWrapper child, dynamic slot) {
|
||||
final root = this.root; // TODO(ianh): Remove this once the analyzer is cleverer
|
||||
assert(slot == null || slot is RenderObject);
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user