Index: sky/sdk/lib/framework/components2/scaffold.dart |
diff --git a/sky/sdk/lib/framework/components2/scaffold.dart b/sky/sdk/lib/framework/components2/scaffold.dart |
index 0b4e4ce61f71f4f11190787a0ed0c7472e2646a9..bbc7ba78d40d76aec8553fd2f4b8aa0ef875ded2 100644 |
--- a/sky/sdk/lib/framework/components2/scaffold.dart |
+++ b/sky/sdk/lib/framework/components2/scaffold.dart |
@@ -4,65 +4,228 @@ |
import '../fn2.dart'; |
import '../layout2.dart'; |
-import 'drawer.dart'; |
-import 'floating_action_button.dart'; |
import '../theme/typography.dart' as typography; |
-class Scaffold extends Component { |
- static final Style _style = new Style(''' |
- ${typography.typeface}; |
- ${typography.black.body1};'''); |
+// RenderNode |
+class RenderScaffold extends RenderDecoratedBox { |
- static final Style _mainStyle = new Style(''' |
- height: -webkit-fill-available;'''); |
+ RenderScaffold({ |
+ BoxDecoration decoration, |
+ RenderBox toolbar, |
+ RenderBox body, |
+ RenderBox statusbar, |
+ RenderBox drawer, |
+ RenderBox floatingActionButton |
+ }) : super(decoration) { |
+ this.toolbar = toolbar; |
+ this.body = body; |
+ this.statusbar = statusbar; |
+ this.drawer = drawer; |
+ this.floatingActionButton = floatingActionButton; |
+ } |
+ |
+ RenderBox _toolbar; |
+ RenderBox get toolbar => _toolbar; |
+ void set toolbar (RenderBox value) { |
+ if (_toolbar != null) |
+ dropChild(_toolbar); |
+ _toolbar = value; |
+ if (_toolbar != null) |
+ adoptChild(_toolbar); |
+ markNeedsLayout(); |
+ } |
+ |
+ RenderBox _body; |
+ RenderBox get body => _body; |
+ void set body (RenderBox value) { |
+ if (_body != null) |
+ dropChild(_body); |
+ _body = value; |
+ if (_body != null) |
+ adoptChild(_body); |
+ markNeedsLayout(); |
+ } |
+ |
+ RenderBox _statusbar; |
+ RenderBox get statusbar => _statusbar; |
+ void set statusbar (RenderBox value) { |
+ if (_statusbar != null) |
+ dropChild(_statusbar); |
+ _statusbar = value; |
+ if (_statusbar != null) |
+ adoptChild(_statusbar); |
+ markNeedsLayout(); |
+ } |
+ |
+ RenderBox _drawer; |
+ RenderBox get drawer => _drawer; |
+ void set drawer (RenderBox value) { |
+ if (_drawer != null) |
+ dropChild(_drawer); |
+ _drawer = value; |
+ if (_drawer != null) |
+ adoptChild(_drawer); |
+ markNeedsLayout(); |
+ } |
+ |
+ RenderBox _floatingActionButton; |
+ RenderBox get floatingActionButton => _floatingActionButton; |
+ void set floatingActionButton (RenderBox value) { |
+ if (_floatingActionButton != null) |
+ dropChild(_floatingActionButton); |
+ _floatingActionButton = value; |
+ if (_floatingActionButton != null) |
+ adoptChild(_floatingActionButton); |
+ markNeedsLayout(); |
+ } |
+ |
+ void layout(BoxConstraints constraints, { RenderNode relayoutSubtreeRoot }) { |
+ width = constraints.constrainWidth(double.INFINITY); |
+ assert(width < double.INFINITY); |
+ height = constraints.constrainHeight(double.INFINITY); |
+ assert(height < double.INFINITY); |
+ relayout(); |
+ } |
- static final FlexBoxParentData _contentParentData = new FlexBoxParentData()..flex = 1; |
+ static const kToolbarHeight = 100.0; |
+ static const kStatusbarHeight = 50.0; |
+ static const kButtonX = -16.0; // from right edge of body |
+ static const kButtonY = -16.0; // from bottom edge of body |
- static final Style _fabStyle = new Style(''' |
- position: absolute; |
- bottom: 16px; |
- right: 16px;'''); |
+ void relayout() { |
+ double bodyHeight = height; |
+ double bodyPosition = 0.0; |
+ if (toolbar != null) { |
+ print("laying out toolbar..."); |
+ toolbar.layout(new BoxConstraints.tight(width: width, height: kToolbarHeight)); |
+ assert(toolbar.parentData is BoxParentData); |
+ toolbar.parentData.x = 0.0; |
+ toolbar.parentData.y = 0.0; |
+ print("...at ${toolbar.parentData.x},${toolbar.parentData.y} dim ${toolbar.width}x${toolbar.height}"); |
+ bodyPosition = kToolbarHeight; |
+ bodyHeight -= kToolbarHeight; |
+ } |
+ if (statusbar != null) { |
+ statusbar.layout(new BoxConstraints.tight(width: width, height: kStatusbarHeight)); |
+ assert(statusbar.parentData is BoxParentData); |
+ statusbar.parentData.x = 0.0; |
+ statusbar.parentData.y = height - kStatusbarHeight; |
+ bodyHeight -= kStatusbarHeight; |
+ } |
+ if (body != null) { |
+ body.layout(new BoxConstraints.tight(width: width, height: bodyHeight)); |
+ assert(body.parentData is BoxParentData); |
+ body.parentData.x = 0.0; |
+ body.parentData.y = bodyPosition; |
+ } |
+ if (drawer != null) { |
+ drawer.layout(new BoxConstraints(minWidth: 0.0, maxWidth: width, minHeight: height, maxHeight: height)); |
+ assert(drawer.parentData is BoxParentData); |
+ drawer.parentData.x = 0.0; |
+ drawer.parentData.y = 0.0; |
+ } |
+ if (floatingActionButton != null) { |
+ floatingActionButton.layout(new BoxConstraints(minWidth: 0.0, maxWidth: width, minHeight: height, maxHeight: height)); |
+ assert(floatingActionButton.parentData is BoxParentData); |
+ floatingActionButton.parentData.x = width - xButtonX; |
+ floatingActionButton.parentData.y = bodyPosition + bodyHeight - kButtonY; |
+ } |
+ layoutDone(); |
+ } |
+ |
+ void paint(RenderNodeDisplayList canvas) { |
+ if (body != null) |
+ canvas.paintChild(body, (body.parentData as BoxParentData).x, (body.parentData as BoxParentData).y); |
+ if (statusbar != null) |
+ canvas.paintChild(statusbar, (statusbar.parentData as BoxParentData).x, (statusbar.parentData as BoxParentData).y); |
+ if (toolbar != null) |
+ canvas.paintChild(toolbar, (toolbar.parentData as BoxParentData).x, (toolbar.parentData as BoxParentData).y); |
+ if (floatingActionButton != null) |
+ canvas.paintChild(floatingActionButton, (floatingActionButton.parentData as BoxParentData).x, (floatingActionButton.parentData as BoxParentData).y); |
+ if (drawer != null) |
+ canvas.paintChild(drawer, (drawer.parentData as BoxParentData).x, (drawer.parentData as BoxParentData).y); |
+ } |
- static final Style _drawerStyle = new Style(''' |
- position: absolute; |
- top: 0; |
- left: 0; |
- bottom: 0; |
- right: 0;'''); |
+ void hitTestChildren(HitTestResult result, { double x, double y }) { |
+ assert(floatingActionButton == null || floatingActionButton.parentData is BoxParentData); |
+ assert(statusBar == null || statusBar.parentData is BoxParentData); |
+ if ((drawer != null) && (x < drawer.width)) { |
+ drawer.hitTest(result, x: x, y: y); |
+ } else if ((floatingActionButton != null) && (x >= floatingActionButton.parentData.x) && (x < floatingActionButton.parentData.x + floatingActionButton.width) |
+ && (y >= floatingActionButton.parentData.y) && (y < floatingActionButton.parentData.y + floatingActionButton.height)) { |
+ floatingActionButton.hitTest(result, x: x-floatingActionButton.parentData.x, y: y-floatingActionButton.parentData.y); |
+ } else if ((toolbar != null) && (y < toolbar.height)) { |
+ toolbar.hitTest(result, x: x, y: y); |
+ } else if ((statusbar != null) && (y > statusbar.parentData.y)) { |
+ statusbar.hitTest(result, x: x, y: y-statusbar.parentData.y); |
+ } else { |
+ body.hitTest(result, x: x, y: y-body.parentData.y); |
+ } |
+ } |
+ |
+} |
- UINode header; |
- UINode content; |
- FloatingActionButton fab; |
- Drawer drawer; |
- List<UINode> overlays; |
+class Scaffold extends RenderNodeWrapper { |
+ |
+ // static final Style _style = new Style(''' |
+ // ${typography.typeface}; |
+ // ${typography.black.body1};'''); |
Scaffold({ |
Object key, |
- this.header, |
- this.content, |
- this.fab, |
+ this.toolbar, |
+ this.body, |
+ this.statusbar, |
this.drawer, |
- this.overlays |
- }) : super(key: key); |
+ this.floatingActionButton |
+ }) : super( |
+ key: key |
+ ); |
- UINode build() { |
- List<UINode> children = [ |
- new FlexContainer( |
- key: 'Main', |
- direction: FlexDirection.Column, |
- style: _mainStyle, |
- children: [header, new ParentDataNode(content, _contentParentData)]) |
- ]; |
+ final UINode toolbar; |
+ final UINode body; |
+ final UINode statusbar; |
+ final UINode drawer; |
+ final UINode floatingActionButton; |
- if (fab != null) |
- children.add(new StyleNode(fab, _fabStyle)); |
+ RenderScaffold root; |
+ RenderScaffold createNode() => new RenderScaffold(); |
- if (drawer != null) |
- children.add(new StyleNode(drawer, _drawerStyle)); |
+ static final Scaffold _emptyScaffold = new Scaffold(); |
+ RenderNodeWrapper get emptyNode => _emptyScaffold; |
+ |
+ void insert(RenderNodeWrapper child, dynamic slot) { |
+ switch (slot) { |
+ case #toolbar: root.toolbar = toolbar == null ? null : toolbar.root; break; |
+ case #body: root.body = body == null ? null : body.root; break; |
+ case #statusbar: root.statusbar = statusbar == null ? null : statusbar.root; break; |
+ case #drawer: root.drawer = drawer == null ? null : drawer.root; break; |
+ case #floatingActionButton: root.floatingActionButton = floatingActionButton == null ? null : floatingActionButton.root; break; |
+ default: assert(false); |
+ } |
+ } |
- if (overlays != null) |
- children.addAll(overlays); |
+ void removeChild(UINode node) { |
+ if (node == root.toolbar) |
+ root.toolbar = null; |
+ if (node == root.body) |
+ root.body = null; |
+ if (node == root.statusbar) |
+ root.statusbar = null; |
+ if (node == root.drawer) |
+ root.drawer = null; |
+ if (node == root.floatingActionButton) |
+ root.floatingActionButton = null; |
+ super.removeChild(node); |
+ } |
- return new Container(style: _style, children: children); |
+ void syncRenderNode(UINode old) { |
+ super.syncRenderNode(old); |
+ syncChild(toolbar, old is Scaffold ? old.toolbar : null, #toolbar); |
+ syncChild(body, old is Scaffold ? old.body : null, #body); |
+ syncChild(statusbar, old is Scaffold ? old.statusbar : null, #statusbar); |
+ syncChild(drawer, old is Scaffold ? old.drawer : null, #drawer); |
+ syncChild(floatingActionButton, old is Scaffold ? old.floatingActionButton : null, #floatingActionButton); |
} |
+ |
} |