Merge pull request #1503 from abarth/simplify_scaffold
Simplify Scaffold
diff --git a/examples/address_book/lib/main.dart b/examples/address_book/lib/main.dart
index 26c0e4a..0c66e80 100644
--- a/examples/address_book/lib/main.dart
+++ b/examples/address_book/lib/main.dart
@@ -81,7 +81,7 @@
Widget build(BuildContext context) {
return new Scaffold(
- toolbar: buildToolBar(context),
+ toolBar: buildToolBar(context),
body: buildBody(context),
floatingActionButton: buildFloatingActionButton(context)
);
diff --git a/examples/demo_launcher/lib/main.dart b/examples/demo_launcher/lib/main.dart
index 2bbef23..5f466f4 100644
--- a/examples/demo_launcher/lib/main.dart
+++ b/examples/demo_launcher/lib/main.dart
@@ -192,7 +192,7 @@
class DemoHome extends StatelessComponent {
Widget build(BuildContext context) {
return new Scaffold(
- toolbar: new ToolBar(center: new Text('Sky Demos')),
+ toolBar: new ToolBar(center: new Text('Sky Demos')),
body: new Material(
type: MaterialType.canvas,
child: new DemoList()
diff --git a/examples/fitness/lib/feed.dart b/examples/fitness/lib/feed.dart
index eb78b29..cf075f0 100644
--- a/examples/fitness/lib/feed.dart
+++ b/examples/fitness/lib/feed.dart
@@ -219,7 +219,7 @@
Widget build(BuildContext context) {
return new Scaffold(
- toolbar: buildToolBar(),
+ toolBar: buildToolBar(),
body: buildBody(),
snackBar: new Placeholder(key: _snackBarPlaceholderKey),
floatingActionButton: buildFloatingActionButton()
diff --git a/examples/fitness/lib/meal.dart b/examples/fitness/lib/meal.dart
index e66fb9f..f7e94f0 100644
--- a/examples/fitness/lib/meal.dart
+++ b/examples/fitness/lib/meal.dart
@@ -105,7 +105,7 @@
Widget build(BuildContext context) {
return new Scaffold(
- toolbar: buildToolBar(),
+ toolBar: buildToolBar(),
body: buildBody()
);
}
diff --git a/examples/fitness/lib/measurement.dart b/examples/fitness/lib/measurement.dart
index 975d276..5adbca1 100644
--- a/examples/fitness/lib/measurement.dart
+++ b/examples/fitness/lib/measurement.dart
@@ -200,7 +200,7 @@
Widget build(BuildContext context) {
return new Scaffold(
- toolbar: buildToolBar(),
+ toolBar: buildToolBar(),
body: buildBody(context),
snackBar: new Placeholder(key: _snackBarPlaceholderKey)
);
diff --git a/examples/fitness/lib/settings.dart b/examples/fitness/lib/settings.dart
index 27cb9a0..9831818 100644
--- a/examples/fitness/lib/settings.dart
+++ b/examples/fitness/lib/settings.dart
@@ -122,7 +122,7 @@
Widget build(BuildContext context) {
return new Scaffold(
- toolbar: buildToolBar(),
+ toolBar: buildToolBar(),
body: buildSettingsPane(context)
);
}
diff --git a/examples/mine_digger/lib/main.dart b/examples/mine_digger/lib/main.dart
index 4c78fe3..112d5a3 100644
--- a/examples/mine_digger/lib/main.dart
+++ b/examples/mine_digger/lib/main.dart
@@ -182,7 +182,7 @@
return new Title(
title: 'Mine Digger',
child: new Scaffold(
- toolbar: buildToolBar(context),
+ toolBar: buildToolBar(context),
body: new Container(
child: new Center(child: board),
decoration: new BoxDecoration(backgroundColor: Colors.grey[50])
diff --git a/examples/stocks/lib/stock_home.dart b/examples/stocks/lib/stock_home.dart
index 9c914b7..106f457 100644
--- a/examples/stocks/lib/stock_home.dart
+++ b/examples/stocks/lib/stock_home.dart
@@ -238,7 +238,7 @@
Widget build(BuildContext context) {
return new Scaffold(
- toolbar: _isSearching ? buildSearchBar() : buildToolBar(),
+ toolBar: _isSearching ? buildSearchBar() : buildToolBar(),
body: buildTabNavigator(),
snackBar: new Placeholder(key: _snackBarPlaceholderKey),
floatingActionButton: buildFloatingActionButton()
diff --git a/examples/stocks/lib/stock_settings.dart b/examples/stocks/lib/stock_settings.dart
index 269afe1..3686a73 100644
--- a/examples/stocks/lib/stock_settings.dart
+++ b/examples/stocks/lib/stock_settings.dart
@@ -119,7 +119,7 @@
Widget build(BuildContext context) {
return new Scaffold(
- toolbar: buildToolBar(context),
+ toolBar: buildToolBar(context),
body: buildSettingsPane(context)
);
}
diff --git a/examples/stocks/lib/stock_symbol_viewer.dart b/examples/stocks/lib/stock_symbol_viewer.dart
index ab57b15..f2407c0 100644
--- a/examples/stocks/lib/stock_symbol_viewer.dart
+++ b/examples/stocks/lib/stock_symbol_viewer.dart
@@ -25,7 +25,7 @@
TextStyle headings = Theme.of(context).text.body2;
return new Scaffold(
- toolbar: new ToolBar(
+ toolBar: new ToolBar(
left: new IconButton(
icon: 'navigation/arrow_back',
onPressed: config.navigator.pop
diff --git a/examples/widgets/card_collection.dart b/examples/widgets/card_collection.dart
index fb0458b..359b3db 100644
--- a/examples/widgets/card_collection.dart
+++ b/examples/widgets/card_collection.dart
@@ -342,7 +342,7 @@
}
return new Scaffold(
- toolbar: buildToolBar(),
+ toolBar: buildToolBar(),
body: body
);
}
diff --git a/examples/widgets/date_picker.dart b/examples/widgets/date_picker.dart
index 5e64a4a..48d8e30 100644
--- a/examples/widgets/date_picker.dart
+++ b/examples/widgets/date_picker.dart
@@ -34,7 +34,7 @@
),
child: new Stack([
new Scaffold(
- toolbar: new ToolBar(center: new Text("Date Picker")),
+ toolBar: new ToolBar(center: new Text("Date Picker")),
body: new Material(
child: new Row(
[new Text(_dateTime.toString())],
diff --git a/examples/widgets/drag_and_drop.dart b/examples/widgets/drag_and_drop.dart
index f35934c..8a7829d 100644
--- a/examples/widgets/drag_and_drop.dart
+++ b/examples/widgets/drag_and_drop.dart
@@ -101,7 +101,7 @@
class DragAndDropAppState extends State<DragAndDropApp> {
Widget build(BuildContext context) {
return new Scaffold(
- toolbar: new ToolBar(
+ toolBar: new ToolBar(
center: new Text('Drag and Drop Flutter Demo')
),
body: new Material(
diff --git a/examples/widgets/ensure_visible.dart b/examples/widgets/ensure_visible.dart
index 4bb5d94..ddd1891 100644
--- a/examples/widgets/ensure_visible.dart
+++ b/examples/widgets/ensure_visible.dart
@@ -89,7 +89,7 @@
child: new Title(
title: 'Cards',
child: new Scaffold(
- toolbar: new ToolBar(center: new Text('Tap a Card')),
+ toolBar: new ToolBar(center: new Text('Tap a Card')),
body: cardCollection
)
)
diff --git a/examples/widgets/overlay_geometry.dart b/examples/widgets/overlay_geometry.dart
index 6aa66e9..cdbc56d 100644
--- a/examples/widgets/overlay_geometry.dart
+++ b/examples/widgets/overlay_geometry.dart
@@ -138,7 +138,7 @@
Widget build(BuildContext context) {
List<Widget> layers = <Widget>[
new Scaffold(
- toolbar: new ToolBar(center: new Text('Tap a Card')),
+ toolBar: new ToolBar(center: new Text('Tap a Card')),
body: new Container(
padding: const EdgeDims.symmetric(vertical: 12.0, horizontal: 8.0),
decoration: new BoxDecoration(backgroundColor: Theme.of(context).primarySwatch[50]),
diff --git a/examples/widgets/pageable_list.dart b/examples/widgets/pageable_list.dart
index e68ebbc..4ad845d 100644
--- a/examples/widgets/pageable_list.dart
+++ b/examples/widgets/pageable_list.dart
@@ -149,7 +149,7 @@
return new IconTheme(
data: const IconThemeData(color: IconThemeColor.white),
child: new Scaffold(
- toolbar: buildToolBar(),
+ toolBar: buildToolBar(),
body: buildBody(context)
)
);
diff --git a/examples/widgets/progress_indicator.dart b/examples/widgets/progress_indicator.dart
index b4b2b41..a83de62 100644
--- a/examples/widgets/progress_indicator.dart
+++ b/examples/widgets/progress_indicator.dart
@@ -103,7 +103,7 @@
child: new Title(
title: 'Progress Indicators',
child: new Scaffold(
- toolbar: new ToolBar(center: new Text('Progress Indicators')),
+ toolBar: new ToolBar(center: new Text('Progress Indicators')),
body: new DefaultTextStyle(
style: Theme.of(context).text.title,
child: body
diff --git a/examples/widgets/scale.dart b/examples/widgets/scale.dart
index 679de95..6265470 100644
--- a/examples/widgets/scale.dart
+++ b/examples/widgets/scale.dart
@@ -59,7 +59,7 @@
return new Theme(
data: new ThemeData.dark(),
child: new Scaffold(
- toolbar: new ToolBar(
+ toolBar: new ToolBar(
center: new Text('Scale Demo')),
body: new Material(
type: MaterialType.canvas,
diff --git a/examples/widgets/sector.dart b/examples/widgets/sector.dart
index c8a01db..d32d399 100644
--- a/examples/widgets/sector.dart
+++ b/examples/widgets/sector.dart
@@ -124,7 +124,7 @@
child: new Title(
title: 'Sector Layout',
child: new Scaffold(
- toolbar: new ToolBar(
+ toolBar: new ToolBar(
center: new Text('Sector Layout in a Widget Tree')
),
body: buildBody()
diff --git a/examples/widgets/styled_text.dart b/examples/widgets/styled_text.dart
index 94197cb..a21da29 100644
--- a/examples/widgets/styled_text.dart
+++ b/examples/widgets/styled_text.dart
@@ -106,7 +106,7 @@
color: Colors.grey[50],
child: interactiveBody
),
- toolbar: new ToolBar(
+ toolBar: new ToolBar(
center: new Text('Hal and Dave')
)
)
diff --git a/examples/widgets/tabs.dart b/examples/widgets/tabs.dart
index 0b36e8a..540b332 100644
--- a/examples/widgets/tabs.dart
+++ b/examples/widgets/tabs.dart
@@ -131,7 +131,7 @@
);
return new Scaffold(
- toolbar: toolbar,
+ toolBar: toolbar,
body: tabNavigator
);
}
diff --git a/packages/flutter/lib/src/material/constants.dart b/packages/flutter/lib/src/material/constants.dart
index f33eb1a..6ae28e7 100644
--- a/packages/flutter/lib/src/material/constants.dart
+++ b/packages/flutter/lib/src/material/constants.dart
@@ -14,6 +14,7 @@
// Mobile Portrait: 56dp
// Tablet/Desktop: 64dp
const double kToolBarHeight = 56.0;
+const double kSnackBarHeight = 52.0;
const double kMaterialDrawerHeight = 140.0;
const double kScrollbarSize = 10.0;
diff --git a/packages/flutter/lib/src/widgets/scaffold.dart b/packages/flutter/lib/src/widgets/scaffold.dart
index bff2d0d..bd02c3c 100644
--- a/packages/flutter/lib/src/widgets/scaffold.dart
+++ b/packages/flutter/lib/src/widgets/scaffold.dart
@@ -6,247 +6,88 @@
import 'package:sky/material.dart';
import 'package:sky/rendering.dart';
+import 'package:sky/src/widgets/basic.dart';
import 'package:sky/src/widgets/framework.dart';
-// Slots are painted in this order and hit tested in reverse of this order
-enum _ScaffoldSlots {
- body,
- statusBar,
- toolbar,
- snackBar,
- floatingActionButton,
- drawer
-}
-
-class _RenderScaffold extends RenderBox {
-
- _RenderScaffold({
- RenderBox body,
- RenderBox statusBar,
- RenderBox toolbar,
- RenderBox snackBar,
- RenderBox floatingActionButton,
- RenderBox drawer
- }) {
- this[_ScaffoldSlots.body] = body;
- this[_ScaffoldSlots.statusBar] = statusBar;
- this[_ScaffoldSlots.toolbar] = toolbar;
- this[_ScaffoldSlots.snackBar] = snackBar;
- this[_ScaffoldSlots.floatingActionButton] = floatingActionButton;
- this[_ScaffoldSlots.drawer] = drawer;
- }
-
- Map<_ScaffoldSlots, RenderBox> _slots = new Map<_ScaffoldSlots, RenderBox>();
- RenderBox operator[] (_ScaffoldSlots slot) => _slots[slot];
- void operator[]= (_ScaffoldSlots slot, RenderBox value) {
- RenderBox old = _slots[slot];
- if (old == value)
- return;
- if (old != null)
- dropChild(old);
- if (value == null) {
- _slots.remove(slot);
- } else {
- _slots[slot] = value;
- adoptChild(value);
- }
- markNeedsLayout();
- }
-
- void attachChildren() {
- for (_ScaffoldSlots slot in _ScaffoldSlots.values) {
- RenderBox box = _slots[slot];
- if (box != null)
- box.attach();
- }
- }
-
- void detachChildren() {
- for (_ScaffoldSlots slot in _ScaffoldSlots.values) {
- RenderBox box = _slots[slot];
- if (box != null)
- box.detach();
- }
- }
-
- void visitChildren(RenderObjectVisitor visitor) {
- for (_ScaffoldSlots slot in _ScaffoldSlots.values) {
- RenderBox box = _slots[slot];
- if (box != null)
- visitor(box);
- }
- }
-
- _ScaffoldSlots remove(RenderBox child) {
- assert(child != null);
- for (_ScaffoldSlots slot in _ScaffoldSlots.values) {
- if (_slots[slot] == child) {
- this[slot] = null;
- return slot;
- }
- }
- return null;
- }
-
- bool get sizedByParent => true;
- void performResize() {
- size = constraints.biggest;
- assert(!size.isInfinite);
- }
-
- // TODO(eseidel): These change based on device size!
- // http://www.google.com/design/spec/layout/metrics-keylines.html#metrics-keylines-keylines-spacing
- static const kButtonX = 16.0; // left from right edge of body
- static const kButtonY = 16.0; // up from bottom edge of body
-
- void performLayout() {
- double bodyHeight = size.height;
- double bodyPosition = 0.0;
- double fabOffset = 0.0;
- if (_slots[_ScaffoldSlots.statusBar] != null) {
- RenderBox statusBar = _slots[_ScaffoldSlots.statusBar];
- statusBar.layout(new BoxConstraints.tight(new Size(size.width, kStatusBarHeight)));
- assert(statusBar.parentData is BoxParentData);
- statusBar.parentData.position = new Point(0.0, size.height - kStatusBarHeight);
- bodyHeight -= kStatusBarHeight;
- }
- if (_slots[_ScaffoldSlots.toolbar] != null) {
- RenderBox toolbar = _slots[_ScaffoldSlots.toolbar];
- double toolbarHeight = kToolBarHeight + sky.view.paddingTop;
- toolbar.layout(new BoxConstraints.tight(new Size(size.width, toolbarHeight)));
- assert(toolbar.parentData is BoxParentData);
- toolbar.parentData.position = Point.origin;
- bodyPosition += toolbarHeight;
- bodyHeight -= toolbarHeight;
- }
- if (_slots[_ScaffoldSlots.body] != null) {
- RenderBox body = _slots[_ScaffoldSlots.body];
- body.layout(new BoxConstraints.tight(new Size(size.width, bodyHeight)));
- assert(body.parentData is BoxParentData);
- body.parentData.position = new Point(0.0, bodyPosition);
- }
- if (_slots[_ScaffoldSlots.snackBar] != null) {
- RenderBox snackBar = _slots[_ScaffoldSlots.snackBar];
- // TODO(jackson): On tablet/desktop, minWidth = 288, maxWidth = 568
- snackBar.layout(
- new BoxConstraints(minWidth: size.width, maxWidth: size.width, minHeight: 0.0, maxHeight: bodyHeight),
- parentUsesSize: true
- );
- assert(snackBar.parentData is BoxParentData);
- snackBar.parentData.position = new Point(0.0, bodyPosition + bodyHeight - snackBar.size.height);
- fabOffset += snackBar.size.height;
- }
- if (_slots[_ScaffoldSlots.floatingActionButton] != null) {
- RenderBox floatingActionButton = _slots[_ScaffoldSlots.floatingActionButton];
- Size area = new Size(size.width - kButtonX, size.height - kButtonY);
- floatingActionButton.layout(new BoxConstraints.loose(area), parentUsesSize: true);
- assert(floatingActionButton.parentData is BoxParentData);
- floatingActionButton.parentData.position = (area - floatingActionButton.size).toPoint() + new Offset(0.0, -fabOffset);
- }
- if (_slots[_ScaffoldSlots.drawer] != null) {
- RenderBox drawer = _slots[_ScaffoldSlots.drawer];
- drawer.layout(new BoxConstraints(minWidth: 0.0, maxWidth: size.width, minHeight: size.height, maxHeight: size.height));
- assert(drawer.parentData is BoxParentData);
- drawer.parentData.position = Point.origin;
- }
- }
-
- void paint(PaintingContext context, Offset offset) {
- for (_ScaffoldSlots slot in _ScaffoldSlots.values) {
- RenderBox box = _slots[slot];
- if (box != null) {
- assert(box.parentData is BoxParentData);
- context.paintChild(box, box.parentData.position + offset);
- }
- }
- }
-
- void hitTestChildren(HitTestResult result, { Point position }) {
- for (_ScaffoldSlots slot in _ScaffoldSlots.values.reversed) {
- RenderBox box = _slots[slot];
- if (box != null) {
- assert(box.parentData is BoxParentData);
- if (box.hitTest(result, position: (position - box.parentData.position).toPoint()))
- return;
- }
- }
- }
-
- String debugDescribeChildren(String prefix) {
- return _slots.keys.map((slot) => '${prefix}${slot}: ${_slots[slot].toStringDeep(prefix)}').join();
- }
-}
-
-class Scaffold extends RenderObjectWidget {
+class Scaffold extends StatelessComponent {
Scaffold({
Key key,
- Widget body,
- Widget statusBar,
- Widget toolbar,
- Widget snackBar,
- Widget floatingActionButton,
- Widget drawer
- }) : super(key: key) {
- _children[_ScaffoldSlots.body] = body;
- _children[_ScaffoldSlots.statusBar] = statusBar;
- _children[_ScaffoldSlots.toolbar] = toolbar;
- _children[_ScaffoldSlots.snackBar] = snackBar;
- _children[_ScaffoldSlots.floatingActionButton] = floatingActionButton;
- _children[_ScaffoldSlots.drawer] = drawer;
- }
+ this.body,
+ this.statusBar,
+ this.toolBar,
+ this.snackBar,
+ this.floatingActionButton
+ }) : super(key: key);
- final Map<_ScaffoldSlots, Widget> _children = new Map<_ScaffoldSlots, Widget>();
+ final Widget body;
+ final Widget statusBar;
+ final Widget toolBar;
+ final Widget snackBar;
+ final Widget floatingActionButton;
- _RenderScaffold createRenderObject() => new _RenderScaffold();
+ Widget build(BuildContext context) {
+ double toolBarHeight = 0.0;
+ if (toolBar != null)
+ toolBarHeight = kToolBarHeight + sky.view.paddingTop;
- _ScaffoldElement createElement() => new _ScaffoldElement(this);
-}
+ double statusBarHeight = 0.0;
+ if (statusBar != null)
+ statusBarHeight = kStatusBarHeight;
-class _ScaffoldElement extends RenderObjectElement<Scaffold> {
- _ScaffoldElement(Scaffold widget) : super(widget);
+ List<Widget> children = <Widget>[];
- Map<_ScaffoldSlots, Element> _children;
-
- _RenderScaffold get renderObject => super.renderObject;
-
- void visitChildren(ElementVisitor visitor) {
- for (_ScaffoldSlots slot in _ScaffoldSlots.values) {
- Element element = _children[slot];
- if (element != null)
- visitor(element);
+ if (body != null) {
+ children.add(new Positioned(
+ top: toolBarHeight, right: 0.0, bottom: statusBarHeight, left: 0.0,
+ child: body
+ ));
}
- }
- void mount(Element parent, dynamic newSlot) {
- super.mount(parent, newSlot);
- _children = new Map<_ScaffoldSlots, Element>();
- for (_ScaffoldSlots slot in _ScaffoldSlots.values) {
- Element newChild = widget._children[slot]?.createElement();
- _children[slot] = newChild;
- newChild?.mount(this, slot);
+ if (statusBar != null) {
+ children.add(new Positioned(
+ right: 0.0, bottom: 0.0, left: 0.0,
+ child: new SizedBox(
+ height: statusBarHeight,
+ child: statusBar
+ )
+ ));
}
- }
- void update(Scaffold newWidget) {
- super.update(newWidget);
- assert(widget == newWidget);
- for (_ScaffoldSlots slot in _ScaffoldSlots.values) {
- _children[slot] = updateChild(_children[slot], widget._children[slot], slot);
- assert((_children[slot] == null) == (widget._children[slot] == null));
+ if (toolBar != null) {
+ children.add(new Positioned(
+ top: 0.0, right: 0.0, left: 0.0,
+ child: new SizedBox(
+ height: toolBarHeight,
+ child: toolBar
+ )
+ ));
}
- }
- void insertChildRenderObject(RenderObject child, _ScaffoldSlots slot) {
- renderObject[slot] = child;
- }
+ if (snackBar != null || floatingActionButton != null) {
+ List<Widget> floatingChildren = <Widget>[];
- void moveChildRenderObject(RenderObject child, dynamic slot) {
- removeChildRenderObject(child);
- insertChildRenderObject(child, slot);
- }
+ if (floatingActionButton != null) {
+ floatingChildren.add(new Padding(
+ // TODO(eseidel): These change based on device size!
+ padding: const EdgeDims.only(right: 16.0, bottom: 16.0),
+ child: floatingActionButton
+ ));
+ }
- void removeChildRenderObject(RenderObject child) {
- assert(renderObject == child.parent);
- renderObject.remove(child);
+ // TODO(jackson): On tablet/desktop, minWidth = 288, maxWidth = 568
+ if (snackBar != null) {
+ floatingChildren.add(new ConstrainedBox(
+ constraints: const BoxConstraints(maxHeight: kSnackBarHeight),
+ child: snackBar
+ ));
+ }
+
+ children.add(new Positioned(
+ right: 0.0, bottom: statusBarHeight, left: 0.0,
+ child: new Column(floatingChildren, alignItems: FlexAlignItems.end)
+ ));
+ }
+
+ return new Stack(children);
}
}
diff --git a/packages/flutter/lib/src/widgets/snack_bar.dart b/packages/flutter/lib/src/widgets/snack_bar.dart
index cf2d55d..3db720d 100644
--- a/packages/flutter/lib/src/widgets/snack_bar.dart
+++ b/packages/flutter/lib/src/widgets/snack_bar.dart
@@ -15,7 +15,6 @@
import 'package:sky/src/widgets/theme.dart';
import 'package:sky/src/widgets/transitions.dart';
-const double _kSnackHeight = 52.0;
const double _kSideMargins = 24.0;
const double _kVerticalPadding = 14.0;
const Color _kSnackBackground = const Color(0xFF323232);
@@ -72,14 +71,14 @@
performance: performance,
height: new AnimatedValue<double>(
0.0,
- end: _kSnackHeight,
+ end: kSnackBarHeight,
curve: easeIn,
reverseCurve: easeOut
),
child: new ClipRect(
child: new OverflowBox(
- minHeight: _kSnackHeight,
- maxHeight: _kSnackHeight,
+ minHeight: kSnackBarHeight,
+ maxHeight: kSnackBarHeight,
child: new Material(
level: 2,
color: _kSnackBackground,