OLD | NEW |
| (Empty) |
1 // Copyright 2015 The Chromium Authors. All rights reserved. | |
2 // Use of this source code is governed by a BSD-style license that can be | |
3 // found in the LICENSE file. | |
4 | |
5 import '../rendering/box.dart'; | |
6 import '../rendering/object.dart'; | |
7 import '../theme2/view_configuration.dart'; | |
8 import 'ui_node.dart'; | |
9 | |
10 enum ScaffoldSlots { | |
11 toolbar, | |
12 body, | |
13 statusBar, | |
14 drawer, | |
15 floatingActionButton | |
16 } | |
17 | |
18 class RenderScaffold extends RenderBox { | |
19 | |
20 RenderScaffold({ | |
21 RenderBox toolbar, | |
22 RenderBox body, | |
23 RenderBox statusBar, | |
24 RenderBox drawer, | |
25 RenderBox floatingActionButton | |
26 }) { | |
27 this[ScaffoldSlots.toolbar] = toolbar; | |
28 this[ScaffoldSlots.body] = body; | |
29 this[ScaffoldSlots.statusBar] = statusBar; | |
30 this[ScaffoldSlots.drawer] = drawer; | |
31 this[ScaffoldSlots.floatingActionButton] = floatingActionButton; | |
32 } | |
33 | |
34 Map<ScaffoldSlots, RenderBox> _slots = new Map<ScaffoldSlots, RenderBox>(); | |
35 RenderBox operator[] (ScaffoldSlots slot) => _slots[slot]; | |
36 void operator[]= (ScaffoldSlots slot, RenderBox value) { | |
37 RenderBox old = _slots[slot]; | |
38 if (old == value) | |
39 return; | |
40 if (old != null) | |
41 dropChild(old); | |
42 _slots[slot] = value; | |
43 if (value != null) | |
44 adoptChild(value); | |
45 markNeedsLayout(); | |
46 } | |
47 | |
48 void attachChildren() { | |
49 for (ScaffoldSlots slot in ScaffoldSlots.values) { | |
50 RenderBox box = _slots[slot]; | |
51 if (box != null) | |
52 box.attach(); | |
53 } | |
54 } | |
55 | |
56 void detachChildren() { | |
57 for (ScaffoldSlots slot in ScaffoldSlots.values) { | |
58 RenderBox box = _slots[slot]; | |
59 if (box != null) | |
60 box.detach(); | |
61 } | |
62 } | |
63 | |
64 ScaffoldSlots remove(RenderBox child) { | |
65 assert(child != null); | |
66 for (ScaffoldSlots slot in ScaffoldSlots.values) { | |
67 if (_slots[slot] == child) { | |
68 this[slot] = null; | |
69 return slot; | |
70 } | |
71 } | |
72 return null; | |
73 } | |
74 | |
75 bool get sizedByParent => true; | |
76 void performResize() { | |
77 size = constraints.constrain(Size.infinite); | |
78 assert(size.width < double.INFINITY); | |
79 assert(size.height < double.INFINITY); | |
80 } | |
81 | |
82 // TODO(eseidel): These change based on device size! | |
83 // http://www.google.com/design/spec/layout/metrics-keylines.html#metrics-keyl
ines-keylines-spacing | |
84 static const kButtonX = 16.0; // left from right edge of body | |
85 static const kButtonY = 16.0; // up from bottom edge of body | |
86 | |
87 void performLayout() { | |
88 double bodyHeight = size.height; | |
89 double bodyPosition = 0.0; | |
90 if (_slots[ScaffoldSlots.toolbar] != null) { | |
91 RenderBox toolbar = _slots[ScaffoldSlots.toolbar]; | |
92 double toolbarHeight = kToolBarHeight + kNotificationAreaHeight; | |
93 toolbar.layout(new BoxConstraints.tight(new Size(size.width, toolbarHeight
))); | |
94 assert(toolbar.parentData is BoxParentData); | |
95 toolbar.parentData.position = Point.origin; | |
96 bodyPosition += toolbarHeight; | |
97 bodyHeight -= toolbarHeight; | |
98 } | |
99 if (_slots[ScaffoldSlots.statusBar] != null) { | |
100 RenderBox statusBar = _slots[ScaffoldSlots.statusBar]; | |
101 statusBar.layout(new BoxConstraints.tight(new Size(size.width, kStatusBarH
eight))); | |
102 assert(statusBar.parentData is BoxParentData); | |
103 statusBar.parentData.position = new Point(0.0, size.height - kStatusBarHei
ght); | |
104 bodyHeight -= kStatusBarHeight; | |
105 } | |
106 if (_slots[ScaffoldSlots.body] != null) { | |
107 RenderBox body = _slots[ScaffoldSlots.body]; | |
108 body.layout(new BoxConstraints.tight(new Size(size.width, bodyHeight))); | |
109 assert(body.parentData is BoxParentData); | |
110 body.parentData.position = new Point(0.0, bodyPosition); | |
111 } | |
112 if (_slots[ScaffoldSlots.drawer] != null) { | |
113 RenderBox drawer = _slots[ScaffoldSlots.drawer]; | |
114 drawer.layout(new BoxConstraints(minWidth: 0.0, maxWidth: size.width, minH
eight: size.height, maxHeight: size.height)); | |
115 assert(drawer.parentData is BoxParentData); | |
116 drawer.parentData.position = Point.origin; | |
117 } | |
118 if (_slots[ScaffoldSlots.floatingActionButton] != null) { | |
119 RenderBox floatingActionButton = _slots[ScaffoldSlots.floatingActionButton
]; | |
120 Size area = new Size(size.width - kButtonX, size.height - kButtonY); | |
121 floatingActionButton.layout(new BoxConstraints.loose(area)); | |
122 assert(floatingActionButton.parentData is BoxParentData); | |
123 floatingActionButton.parentData.position = (area - floatingActionButton.si
ze).toPoint(); | |
124 } | |
125 } | |
126 | |
127 void paint(RenderObjectDisplayList canvas) { | |
128 for (ScaffoldSlots slot in [ScaffoldSlots.body, ScaffoldSlots.statusBar, Sca
ffoldSlots.toolbar, ScaffoldSlots.floatingActionButton, ScaffoldSlots.drawer]) { | |
129 RenderBox box = _slots[slot]; | |
130 if (box != null) { | |
131 assert(box.parentData is BoxParentData); | |
132 canvas.paintChild(box, box.parentData.position); | |
133 } | |
134 } | |
135 } | |
136 | |
137 void hitTestChildren(HitTestResult result, { Point position }) { | |
138 for (ScaffoldSlots slot in [ScaffoldSlots.drawer, ScaffoldSlots.floatingActi
onButton, ScaffoldSlots.toolbar, ScaffoldSlots.statusBar, ScaffoldSlots.body]) { | |
139 RenderBox box = _slots[slot]; | |
140 if (box != null) { | |
141 assert(box.parentData is BoxParentData); | |
142 if (new Rect.fromPointAndSize(box.parentData.position, box.size).contain
s(position)) { | |
143 if (box.hitTest(result, position: (position - box.parentData.position)
.toPoint())) | |
144 return; | |
145 } | |
146 } | |
147 } | |
148 } | |
149 | |
150 String debugDescribeChildren(String prefix) { | |
151 return _slots.keys.map((slot) => '${prefix}${slot}: ${_slots[slot].toString(
prefix)}').join(); | |
152 } | |
153 } | |
154 | |
155 class Scaffold extends RenderObjectWrapper { | |
156 | |
157 // static final Style _style = new Style(''' | |
158 // ${typography.typeface}; | |
159 // ${typography.black.body1};'''); | |
160 | |
161 Scaffold({ | |
162 Object key, | |
163 UINode toolbar, | |
164 UINode body, | |
165 UINode statusBar, | |
166 UINode drawer, | |
167 UINode floatingActionButton | |
168 }) : _toolbar = toolbar, | |
169 _body = body, | |
170 _statusBar = statusBar, | |
171 _drawer = drawer, | |
172 _floatingActionButton = floatingActionButton, | |
173 super(key: key); | |
174 | |
175 UINode _toolbar; | |
176 UINode _body; | |
177 UINode _statusBar; | |
178 UINode _drawer; | |
179 UINode _floatingActionButton; | |
180 | |
181 RenderScaffold get root { RenderScaffold result = super.root; return result; } | |
182 RenderScaffold createNode() => new RenderScaffold(); | |
183 | |
184 void insert(RenderObjectWrapper child, ScaffoldSlots slot) { | |
185 root[slot] = child != null ? child.root : null; | |
186 } | |
187 | |
188 void removeChild(UINode node) { | |
189 assert(node != null); | |
190 root.remove(node.root); | |
191 super.removeChild(node); | |
192 } | |
193 | |
194 void remove() { | |
195 if (_toolbar != null) | |
196 removeChild(_toolbar); | |
197 if (_body != null) | |
198 removeChild(_body); | |
199 if (_statusBar != null) | |
200 removeChild(_statusBar); | |
201 if (_drawer != null) | |
202 removeChild(_drawer); | |
203 if (_floatingActionButton != null) | |
204 removeChild(_floatingActionButton); | |
205 super.remove(); | |
206 } | |
207 | |
208 void syncRenderObject(UINode old) { | |
209 super.syncRenderObject(old); | |
210 _toolbar = syncChild(_toolbar, old is Scaffold ? old._toolbar : null, Scaffo
ldSlots.toolbar); | |
211 _body = syncChild(_body, old is Scaffold ? old._body : null, ScaffoldSlots.b
ody); | |
212 _statusBar = syncChild(_statusBar, old is Scaffold ? old._statusBar : null,
ScaffoldSlots.statusBar); | |
213 _drawer = syncChild(_drawer, old is Scaffold ? old._drawer : null, ScaffoldS
lots.drawer); | |
214 _floatingActionButton = syncChild(_floatingActionButton, old is Scaffold ? o
ld._floatingActionButton : null, ScaffoldSlots.floatingActionButton); | |
215 } | |
216 | |
217 } | |
OLD | NEW |