Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(156)

Side by Side Diff: sky/sdk/lib/widgets/scaffold.dart

Issue 1216613004: Initial implementation of SnackBar (Closed) Base URL: git@github.com:domokit/mojo.git@master
Patch Set: Created 5 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2015 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 import 'dart:math' as math;
6
5 import '../rendering/box.dart'; 7 import '../rendering/box.dart';
6 import '../rendering/object.dart'; 8 import '../rendering/object.dart';
7 import '../theme/view_configuration.dart'; 9 import '../theme/view_configuration.dart';
8 import 'widget.dart'; 10 import 'widget.dart';
9 11
12 // Slots are painted in this order and hit tested in reverse of this order
10 enum ScaffoldSlots { 13 enum ScaffoldSlots {
11 toolbar,
12 body, 14 body,
13 statusBar, 15 statusBar,
14 drawer, 16 toolbar,
15 floatingActionButton 17 snackBar,
18 floatingActionButton,
19 drawer
16 } 20 }
17 21
18 class RenderScaffold extends RenderBox { 22 class RenderScaffold extends RenderBox {
19 23
20 RenderScaffold({ 24 RenderScaffold({
21 RenderBox toolbar,
22 RenderBox body, 25 RenderBox body,
23 RenderBox statusBar, 26 RenderBox statusBar,
24 RenderBox drawer, 27 RenderBox toolbar,
25 RenderBox floatingActionButton 28 RenderBox snackBar,
29 RenderBox floatingActionButton,
30 RenderBox drawer
26 }) { 31 }) {
27 this[ScaffoldSlots.toolbar] = toolbar;
28 this[ScaffoldSlots.body] = body; 32 this[ScaffoldSlots.body] = body;
29 this[ScaffoldSlots.statusBar] = statusBar; 33 this[ScaffoldSlots.statusBar] = statusBar;
34 this[ScaffoldSlots.toolbar] = toolbar;
35 this[ScaffoldSlots.snackBar] = snackBar;
36 this[ScaffoldSlots.floatingActionButton] = floatingActionButton;
30 this[ScaffoldSlots.drawer] = drawer; 37 this[ScaffoldSlots.drawer] = drawer;
31 this[ScaffoldSlots.floatingActionButton] = floatingActionButton;
32 } 38 }
33 39
34 Map<ScaffoldSlots, RenderBox> _slots = new Map<ScaffoldSlots, RenderBox>(); 40 Map<ScaffoldSlots, RenderBox> _slots = new Map<ScaffoldSlots, RenderBox>();
35 RenderBox operator[] (ScaffoldSlots slot) => _slots[slot]; 41 RenderBox operator[] (ScaffoldSlots slot) => _slots[slot];
36 void operator[]= (ScaffoldSlots slot, RenderBox value) { 42 void operator[]= (ScaffoldSlots slot, RenderBox value) {
37 RenderBox old = _slots[slot]; 43 RenderBox old = _slots[slot];
38 if (old == value) 44 if (old == value)
39 return; 45 return;
40 if (old != null) 46 if (old != null)
41 dropChild(old); 47 dropChild(old);
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
82 } 88 }
83 89
84 // TODO(eseidel): These change based on device size! 90 // TODO(eseidel): These change based on device size!
85 // http://www.google.com/design/spec/layout/metrics-keylines.html#metrics-keyl ines-keylines-spacing 91 // http://www.google.com/design/spec/layout/metrics-keylines.html#metrics-keyl ines-keylines-spacing
86 static const kButtonX = 16.0; // left from right edge of body 92 static const kButtonX = 16.0; // left from right edge of body
87 static const kButtonY = 16.0; // up from bottom edge of body 93 static const kButtonY = 16.0; // up from bottom edge of body
88 94
89 void performLayout() { 95 void performLayout() {
90 double bodyHeight = size.height; 96 double bodyHeight = size.height;
91 double bodyPosition = 0.0; 97 double bodyPosition = 0.0;
98 if (_slots[ScaffoldSlots.statusBar] != null) {
99 RenderBox statusBar = _slots[ScaffoldSlots.statusBar];
100 statusBar.layout(new BoxConstraints.tight(new Size(size.width, kStatusBarH eight)));
101 assert(statusBar.parentData is BoxParentData);
102 statusBar.parentData.position = new Point(0.0, size.height - kStatusBarHei ght);
103 bodyHeight -= kStatusBarHeight;
104 }
92 if (_slots[ScaffoldSlots.toolbar] != null) { 105 if (_slots[ScaffoldSlots.toolbar] != null) {
93 RenderBox toolbar = _slots[ScaffoldSlots.toolbar]; 106 RenderBox toolbar = _slots[ScaffoldSlots.toolbar];
94 double toolbarHeight = kToolBarHeight + kNotificationAreaHeight; 107 double toolbarHeight = kToolBarHeight + kNotificationAreaHeight;
95 toolbar.layout(new BoxConstraints.tight(new Size(size.width, toolbarHeight ))); 108 toolbar.layout(new BoxConstraints.tight(new Size(size.width, toolbarHeight )));
96 assert(toolbar.parentData is BoxParentData); 109 assert(toolbar.parentData is BoxParentData);
97 toolbar.parentData.position = Point.origin; 110 toolbar.parentData.position = Point.origin;
98 bodyPosition += toolbarHeight; 111 bodyPosition += toolbarHeight;
99 bodyHeight -= toolbarHeight; 112 bodyHeight -= toolbarHeight;
100 } 113 }
101 if (_slots[ScaffoldSlots.statusBar] != null) {
102 RenderBox statusBar = _slots[ScaffoldSlots.statusBar];
103 statusBar.layout(new BoxConstraints.tight(new Size(size.width, kStatusBarH eight)));
104 assert(statusBar.parentData is BoxParentData);
105 statusBar.parentData.position = new Point(0.0, size.height - kStatusBarHei ght);
106 bodyHeight -= kStatusBarHeight;
107 }
108 if (_slots[ScaffoldSlots.body] != null) { 114 if (_slots[ScaffoldSlots.body] != null) {
109 RenderBox body = _slots[ScaffoldSlots.body]; 115 RenderBox body = _slots[ScaffoldSlots.body];
110 body.layout(new BoxConstraints.tight(new Size(size.width, bodyHeight))); 116 body.layout(new BoxConstraints.tight(new Size(size.width, bodyHeight)));
111 assert(body.parentData is BoxParentData); 117 assert(body.parentData is BoxParentData);
112 body.parentData.position = new Point(0.0, bodyPosition); 118 body.parentData.position = new Point(0.0, bodyPosition);
113 } 119 }
120 double snackBarHeight = 0.0;
121 if (_slots[ScaffoldSlots.snackBar] != null) {
122 RenderBox snackBar = _slots[ScaffoldSlots.snackBar];
123 // TODO(jackson): On tablet/desktop, minWidth = 288, maxWidth = 568
124 snackBar.layout(new BoxConstraints(minWidth: size.width, maxWidth: size.wi dth, minHeight: 0.0, maxHeight: size.height),
125 parentUsesSize: true);
126 assert(snackBar.parentData is BoxParentData);
127 snackBar.parentData.position = new Point(0.0, size.height - snackBar.size. height);
128 snackBarHeight = snackBar.size.height;
129 }
130 if (_slots[ScaffoldSlots.floatingActionButton] != null) {
131 RenderBox floatingActionButton = _slots[ScaffoldSlots.floatingActionButton ];
132 Size area = new Size(size.width - kButtonX, size.height - kButtonY - snack BarHeight);
133 floatingActionButton.layout(new BoxConstraints.loose(area), parentUsesSize : true);
134 assert(floatingActionButton.parentData is BoxParentData);
135 floatingActionButton.parentData.position = (area - floatingActionButton.si ze).toPoint();
136 }
114 if (_slots[ScaffoldSlots.drawer] != null) { 137 if (_slots[ScaffoldSlots.drawer] != null) {
115 RenderBox drawer = _slots[ScaffoldSlots.drawer]; 138 RenderBox drawer = _slots[ScaffoldSlots.drawer];
116 drawer.layout(new BoxConstraints(minWidth: 0.0, maxWidth: size.width, minH eight: size.height, maxHeight: size.height)); 139 drawer.layout(new BoxConstraints(minWidth: 0.0, maxWidth: size.width, minH eight: size.height, maxHeight: size.height));
117 assert(drawer.parentData is BoxParentData); 140 assert(drawer.parentData is BoxParentData);
118 drawer.parentData.position = Point.origin; 141 drawer.parentData.position = Point.origin;
119 } 142 }
120 if (_slots[ScaffoldSlots.floatingActionButton] != null) {
121 RenderBox floatingActionButton = _slots[ScaffoldSlots.floatingActionButton ];
122 Size area = new Size(size.width - kButtonX, size.height - kButtonY);
123 floatingActionButton.layout(new BoxConstraints.loose(area), parentUsesSize : true);
124 assert(floatingActionButton.parentData is BoxParentData);
125 floatingActionButton.parentData.position = (area - floatingActionButton.si ze).toPoint();
126 }
127 } 143 }
128 144
129 void paint(PaintingCanvas canvas, Offset offset) { 145 void paint(PaintingCanvas canvas, Offset offset) {
130 for (ScaffoldSlots slot in [ScaffoldSlots.body, ScaffoldSlots.statusBar, Sca ffoldSlots.toolbar, ScaffoldSlots.floatingActionButton, ScaffoldSlots.drawer]) { 146 for (ScaffoldSlots slot in ScaffoldSlots.values) {
131 RenderBox box = _slots[slot]; 147 RenderBox box = _slots[slot];
132 if (box != null) { 148 if (box != null) {
133 assert(box.parentData is BoxParentData); 149 assert(box.parentData is BoxParentData);
134 canvas.paintChild(box, box.parentData.position + offset); 150 canvas.paintChild(box, box.parentData.position + offset);
135 } 151 }
136 } 152 }
137 } 153 }
138 154
139 void hitTestChildren(HitTestResult result, { Point position }) { 155 void hitTestChildren(HitTestResult result, { Point position }) {
140 for (ScaffoldSlots slot in [ScaffoldSlots.drawer, ScaffoldSlots.floatingActi onButton, ScaffoldSlots.toolbar, ScaffoldSlots.statusBar, ScaffoldSlots.body]) { 156 for (ScaffoldSlots slot in ScaffoldSlots.values.reversed) {
141 RenderBox box = _slots[slot]; 157 RenderBox box = _slots[slot];
142 if (box != null) { 158 if (box != null) {
143 assert(box.parentData is BoxParentData); 159 assert(box.parentData is BoxParentData);
144 if ((box.parentData.position & box.size).contains(position)) { 160 if ((box.parentData.position & box.size).contains(position)) {
145 if (box.hitTest(result, position: (position - box.parentData.position) .toPoint())) 161 if (box.hitTest(result, position: (position - box.parentData.position) .toPoint()))
146 return; 162 return;
147 } 163 }
148 } 164 }
149 } 165 }
150 } 166 }
151 167
152 String debugDescribeChildren(String prefix) { 168 String debugDescribeChildren(String prefix) {
153 return _slots.keys.map((slot) => '${prefix}${slot}: ${_slots[slot].toString( prefix)}').join(); 169 return _slots.keys.map((slot) => '${prefix}${slot}: ${_slots[slot].toString( prefix)}').join();
154 } 170 }
155 } 171 }
156 172
157 class Scaffold extends RenderObjectWrapper { 173 class Scaffold extends RenderObjectWrapper {
158 174
159 // static final Style _style = new Style('''
160 // ${typography.typeface};
161 // ${typography.black.body1};''');
162
163 Scaffold({ 175 Scaffold({
164 String key, 176 String key,
165 Widget toolbar,
166 Widget body, 177 Widget body,
167 Widget statusBar, 178 Widget statusBar,
168 Widget drawer, 179 Widget toolbar,
169 Widget floatingActionButton 180 Widget snackBar,
170 }) : _toolbar = toolbar, 181 Widget floatingActionButton,
171 _body = body, 182 Widget drawer
172 _statusBar = statusBar, 183 }) : super(key: key) {
173 _drawer = drawer, 184 this[ScaffoldSlots.body] = body;
174 _floatingActionButton = floatingActionButton, 185 this[ScaffoldSlots.statusBar] = statusBar;
175 super(key: key); 186 this[ScaffoldSlots.toolbar] = toolbar;
187 this[ScaffoldSlots.snackBar] = snackBar;
188 this[ScaffoldSlots.floatingActionButton] = floatingActionButton;
189 this[ScaffoldSlots.drawer] = drawer;
190 }
176 191
177 Widget _toolbar; 192 Map<ScaffoldSlots, Widget> _slots = new Map<ScaffoldSlots, Widget>();
178 Widget _body; 193 Widget operator[] (ScaffoldSlots slot) => _slots[slot];
179 Widget _statusBar; 194 void operator[]= (ScaffoldSlots slot, Widget value) {
180 Widget _drawer; 195 _slots[slot] = value;
181 Widget _floatingActionButton; 196 }
182 197
183 RenderScaffold get root => super.root; 198 RenderScaffold get root => super.root;
184 RenderScaffold createNode() => new RenderScaffold(); 199 RenderScaffold createNode() => new RenderScaffold();
185 200
186 void walkChildren(WidgetTreeWalker walker) { 201 void walkChildren(WidgetTreeWalker walker) {
187 if (_toolbar != null) 202 for (ScaffoldSlots slot in ScaffoldSlots.values) {
188 walker(_toolbar); 203 Widget widget = _slots[slot];
189 if (_body != null) 204 if (widget != null)
190 walker(_body); 205 walker(widget);
191 if (_statusBar != null) 206 }
192 walker(_statusBar);
193 if (_drawer != null)
194 walker(_drawer);
195 if (_floatingActionButton != null)
196 walker(_floatingActionButton);
197 } 207 }
198 208
199 void insertChildRoot(RenderObjectWrapper child, ScaffoldSlots slot) { 209 void insertChildRoot(RenderObjectWrapper child, ScaffoldSlots slot) {
200 root[slot] = child != null ? child.root : null; 210 root[slot] = child != null ? child.root : null;
201 } 211 }
202 212
203 void detachChildRoot(RenderObjectWrapper child) { 213 void detachChildRoot(RenderObjectWrapper child) {
204 final root = this.root; // TODO(ianh): Remove this once the analyzer is clev erer 214 final root = this.root; // TODO(ianh): Remove this once the analyzer is clev erer
205 assert(root is RenderScaffold); 215 assert(root is RenderScaffold);
206 assert(root == child.root.parent); 216 assert(root == child.root.parent);
207 root.remove(child.root); 217 root.remove(child.root);
208 assert(root == this.root); // TODO(ianh): Remove this once the analyzer is c leverer 218 assert(root == this.root); // TODO(ianh): Remove this once the analyzer is c leverer
209 } 219 }
210 220
211 void remove() { 221 void remove() {
212 walkChildren((Widget child) => removeChild(child)); 222 walkChildren((Widget child) => removeChild(child));
213 super.remove(); 223 super.remove();
214 } 224 }
215 225
216 void syncRenderObject(Widget old) { 226 void syncRenderObject(Widget old) {
217 super.syncRenderObject(old); 227 super.syncRenderObject(old);
218 _toolbar = syncChild(_toolbar, old is Scaffold ? old._toolbar : null, Scaffo ldSlots.toolbar); 228 for (ScaffoldSlots slot in ScaffoldSlots.values) {
219 _body = syncChild(_body, old is Scaffold ? old._body : null, ScaffoldSlots.b ody); 229 Widget widget = this[slot];
220 _statusBar = syncChild(_statusBar, old is Scaffold ? old._statusBar : null, ScaffoldSlots.statusBar); 230 this[slot] = syncChild(widget, old is Scaffold ? old[slot] : null, slot);
221 _drawer = syncChild(_drawer, old is Scaffold ? old._drawer : null, ScaffoldS lots.drawer); 231 }
222 _floatingActionButton = syncChild(_floatingActionButton, old is Scaffold ? o ld._floatingActionButton : null, ScaffoldSlots.floatingActionButton);
223 } 232 }
224 233
225 } 234 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698