blob: 79b772bd9291d862cc8113c6246c85362ce21197 [file] [log] [blame]
// 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 '../fn2.dart';
import '../theme/typography.dart' as typography;
import 'dart:sky' as sky;
import '../rendering/box.dart';
import '../rendering/node.dart';
// RenderNode
class RenderScaffold extends RenderBox {
RenderScaffold({
RenderBox toolbar,
RenderBox body,
RenderBox statusbar,
RenderBox drawer,
RenderBox floatingActionButton
}) {
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();
}
bool get sizedByParent => true;
void performResize() {
size = constraints.constrain(new sky.Size.infinite());
assert(size.width < double.INFINITY);
assert(size.height < double.INFINITY);
}
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
void performLayout() {
double bodyHeight = size.height;
double bodyPosition = 0.0;
if (toolbar != null) {
toolbar.layout(new BoxConstraints.tight(new sky.Size(size.width, kToolbarHeight)));
assert(toolbar.parentData is BoxParentData);
toolbar.parentData.position = new sky.Point(0.0, 0.0);
bodyPosition = kToolbarHeight;
bodyHeight -= kToolbarHeight;
}
if (statusbar != null) {
statusbar.layout(new BoxConstraints.tight(new sky.Size(size.width, kStatusbarHeight)));
assert(statusbar.parentData is BoxParentData);
statusbar.parentData.position = new sky.Point(0.0, size.height - kStatusbarHeight);
bodyHeight -= kStatusbarHeight;
}
if (body != null) {
body.layout(new BoxConstraints.tight(new sky.Size(size.width, bodyHeight)));
assert(body.parentData is BoxParentData);
body.parentData.position = new sky.Point(0.0, bodyPosition);
}
if (drawer != null) {
drawer.layout(new BoxConstraints(minWidth: 0.0, maxWidth: size.width, minHeight: size.height, maxHeight: size.height));
assert(drawer.parentData is BoxParentData);
drawer.parentData.position = new sky.Point(0.0, 0.0);
}
if (floatingActionButton != null) {
floatingActionButton.layout(new BoxConstraints(minWidth: 0.0, maxWidth: size.width, minHeight: size.height, maxHeight: size.height));
assert(floatingActionButton.parentData is BoxParentData);
floatingActionButton.parentData.position = new sky.Point(size.width - kButtonX, bodyPosition + bodyHeight - kButtonY);
}
}
void paint(RenderNodeDisplayList canvas) {
if (body != null)
canvas.paintChild(body, (body.parentData as BoxParentData).position);
if (statusbar != null)
canvas.paintChild(statusbar, (statusbar.parentData as BoxParentData).position);
if (toolbar != null)
canvas.paintChild(toolbar, (toolbar.parentData as BoxParentData).position);
if (floatingActionButton != null)
canvas.paintChild(floatingActionButton, (floatingActionButton.parentData as BoxParentData).position);
if (drawer != null)
canvas.paintChild(drawer, (drawer.parentData as BoxParentData).position);
}
void hitTestChildren(HitTestResult result, { sky.Point position }) {
assert(floatingActionButton == null || floatingActionButton.parentData is BoxParentData);
assert(statusbar == null || statusbar.parentData is BoxParentData);
if ((drawer != null) && (position.x < drawer.size.width)) {
drawer.hitTest(result, position: position);
} else if ((floatingActionButton != null) && (position.x >= floatingActionButton.parentData.position.x) && (position.x < floatingActionButton.parentData.position.x + floatingActionButton.size.width)
&& (position.y >= floatingActionButton.parentData.position.y) && (position.y < floatingActionButton.parentData.position.y + floatingActionButton.size.height)) {
floatingActionButton.hitTest(result, position: new sky.Point(position.x - floatingActionButton.parentData.position.x, position.y - floatingActionButton.parentData.position.y));
} else if ((toolbar != null) && (position.y < toolbar.size.height)) {
toolbar.hitTest(result, position: position);
} else if ((statusbar != null) && (position.y > statusbar.parentData.position.y)) {
statusbar.hitTest(result, position: new sky.Point(position.x, position.y - statusbar.parentData.position.y));
} else if (body != null) {
body.hitTest(result, position: new sky.Point(position.x, position.y - body.parentData.position.y));
}
}
}
class Scaffold extends RenderNodeWrapper {
// static final Style _style = new Style('''
// ${typography.typeface};
// ${typography.black.body1};''');
Scaffold({
Object key,
this.toolbar,
this.body,
this.statusbar,
this.drawer,
this.floatingActionButton
}) : super(
key: key
);
final UINode toolbar;
final UINode body;
final UINode statusbar;
final UINode drawer;
final UINode floatingActionButton;
RenderScaffold root;
RenderScaffold createNode() => new RenderScaffold();
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);
}
}
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);
}
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);
}
}