OLD | NEW |
1 library layout; | 1 library layout; |
2 | 2 |
3 // This version of layout.dart is an update to the other one, this one using new
APIs. | 3 // This version of layout.dart is an update to the other one, this one using new
APIs. |
4 // It will not work in a stock Sky setup currently. | 4 // It will not work in a stock Sky setup currently. |
5 | 5 |
6 import 'node.dart'; | 6 import 'node.dart'; |
7 | 7 |
8 import 'dart:sky' as sky; | 8 import 'dart:sky' as sky; |
9 | 9 |
10 // ABSTRACT LAYOUT | 10 // ABSTRACT LAYOUT |
(...skipping 14 matching lines...) Expand all Loading... |
25 double clamp({double min: 0.0, double value: 0.0, double max: double.INFINITY})
{ | 25 double clamp({double min: 0.0, double value: 0.0, double max: double.INFINITY})
{ |
26 if (value > max) | 26 if (value > max) |
27 value = max; | 27 value = max; |
28 if (value < min) | 28 if (value < min) |
29 value = min; | 29 value = min; |
30 return value; | 30 return value; |
31 } | 31 } |
32 | 32 |
33 class RenderNodeDisplayList extends sky.PictureRecorder { | 33 class RenderNodeDisplayList extends sky.PictureRecorder { |
34 RenderNodeDisplayList(double width, double height) : super(width, height); | 34 RenderNodeDisplayList(double width, double height) : super(width, height); |
| 35 List<RenderNode> _children; // used by _doPaint() to find out which RenderNode
s to ask to paint |
35 void paintChild(RenderNode child, double x, double y) { | 36 void paintChild(RenderNode child, double x, double y) { |
36 save(); | 37 if (child.createNewDisplayList) { |
37 translate(x, y); | 38 if (_children == null) |
38 child.paint(this); | 39 _children = new List<RenderNode>(); |
39 restore(); | 40 assert(!_children.contains(child)); |
| 41 _children.add(child); |
| 42 drawPaintNode(child._paintNode, transform: new Matrix.translate(x, y)); |
| 43 } else { |
| 44 save(); |
| 45 translate(x, y); |
| 46 child.paint(this); |
| 47 restore(); |
| 48 } |
40 } | 49 } |
41 } | 50 } |
42 | 51 |
| 52 class PaintOptions { |
| 53 Matrix transform = Matrix.IDENTITY; |
| 54 } |
| 55 |
43 abstract class RenderNode extends AbstractNode { | 56 abstract class RenderNode extends AbstractNode { |
44 | 57 |
45 // LAYOUT | 58 // LAYOUT |
46 | 59 |
47 // parentData is only for use by the RenderNode that actually lays this | 60 // parentData is only for use by the RenderNode that actually lays this |
48 // node out, and any other nodes who happen to know exactly what | 61 // node out, and any other nodes who happen to know exactly what |
49 // kind of node that is. | 62 // kind of node that is. |
50 ParentData parentData; | 63 ParentData parentData; |
51 void setupPos(RenderNode child) { | 64 void setupPos(RenderNode child) { |
52 // override this to setup .parentData correctly for your class | 65 // override this to setup .parentData correctly for your class |
(...skipping 162 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
215 // HIT TESTING | 228 // HIT TESTING |
216 | 229 |
217 void handlePointer(sky.PointerEvent event) { | 230 void handlePointer(sky.PointerEvent event) { |
218 // override this if you have children, to hand it to the appropriate child | 231 // override this if you have children, to hand it to the appropriate child |
219 // override this if you want to do anything with the pointer event | 232 // override this if you want to do anything with the pointer event |
220 } | 233 } |
221 | 234 |
222 | 235 |
223 // PAINTING | 236 // PAINTING |
224 | 237 |
| 238 static List<RenderNode> _nodesNeedingPaint = new List<RenderNode>(); |
225 static bool _debugDoingPaint = false; | 239 static bool _debugDoingPaint = false; |
| 240 PaintNode _paintNode; // only set if createNewDisplayList is true |
| 241 bool _needsPaint = true; |
| 242 bool get needsPaint => _needsPaint; |
| 243 bool get createNewDisplayList => false; |
226 void markNeedsPaint() { | 244 void markNeedsPaint() { |
227 assert(!_debugDoingPaint); | 245 assert(!_debugDoingPaint); |
228 var ancestor = this; | 246 if (_needsPaint) return; |
229 while (ancestor.parent != null) | 247 if (createNewDisplayList) { |
230 ancestor = ancestor.parent; | 248 _needsPaint = true; |
231 assert(ancestor is Screen); | 249 _nodesNeedingPaint.add(this); |
232 ancestor.paintFrame(); | 250 } else { |
| 251 assert(parent != null); |
| 252 parent.markNeedsPaint(); |
| 253 } |
233 } | 254 } |
| 255 static void flushPaint() { |
| 256 List<RenderNode> dirtyNodes = _nodesNeedingPaint; |
| 257 _nodesNeedingPaint = new List<RenderNode>(); |
| 258 dirtyNodes..sort((a, b) => a.depth - b.depth)..forEach((node) { |
| 259 if (node._needsPaint && node.attached) |
| 260 node._doPaint(); |
| 261 }); |
| 262 } |
| 263 void _doPaint() { |
| 264 assert(!_needsLayout); |
| 265 assert(createNewDisplayList); |
| 266 RenderNodeDisplayList newDisplayList = new RenderNodeDisplayList(); |
| 267 _needsPaint = false; |
| 268 try { |
| 269 paint(newDisplayList); |
| 270 } catch (e, stack) { |
| 271 print('Exception raised during paint of ${this}: ${e}'); |
| 272 print(stack); |
| 273 return; |
| 274 } |
| 275 assert(!_needsLayout); // check that the paint() method didn't mark us dirty
again |
| 276 assert(!_needsPaint); // check that the paint() method didn't mark us dirty
again |
| 277 _paintNode.setDisplayList(newDisplayList); |
| 278 if (newDisplayList._children != null) |
| 279 newDisplayList._children.forEach((node) { |
| 280 assert(node.attached == attached); |
| 281 if (node._needsPaint) |
| 282 node._doPaint(); |
| 283 }); |
| 284 } |
| 285 |
| 286 PaintOptions paintOptions; |
| 287 // only set this to a subclass of PaintOptions that this class of RenderNode k
nows how to deal with |
| 288 |
234 void paint(RenderNodeDisplayList canvas) { } | 289 void paint(RenderNodeDisplayList canvas) { } |
235 | 290 |
236 } | 291 } |
237 | 292 |
238 | 293 |
239 // GENERIC MIXIN FOR RENDER NODES THAT TAKE A LIST OF CHILDREN | 294 // GENERIC MIXIN FOR RENDER NODES THAT TAKE A LIST OF CHILDREN |
240 | 295 |
241 abstract class ContainerParentDataMixin<ChildType extends RenderNode> { | 296 abstract class ContainerParentDataMixin<ChildType extends RenderNode> { |
242 ChildType previousSibling; | 297 ChildType previousSibling; |
243 ChildType nextSibling; | 298 ChildType nextSibling; |
(...skipping 504 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
748 canvas.paintChild(body, (body.parentData as BoxParentData).x, (body.parentDa
ta as BoxParentData).y); | 803 canvas.paintChild(body, (body.parentData as BoxParentData).x, (body.parentDa
ta as BoxParentData).y); |
749 if (statusbar != null) | 804 if (statusbar != null) |
750 canvas.paintChild(statusbar, (statusbar.parentData as BoxParentData).x, (s
tatusbar.parentData as BoxParentData).y); | 805 canvas.paintChild(statusbar, (statusbar.parentData as BoxParentData).x, (s
tatusbar.parentData as BoxParentData).y); |
751 if (toolbar != null) | 806 if (toolbar != null) |
752 canvas.paintChild(toolbar, (toolbar.parentData as BoxParentData).x, (toolb
ar.parentData as BoxParentData).y); | 807 canvas.paintChild(toolbar, (toolbar.parentData as BoxParentData).x, (toolb
ar.parentData as BoxParentData).y); |
753 if (drawer != null) | 808 if (drawer != null) |
754 canvas.paintChild(drawer, (drawer.parentData as BoxParentData).x, (drawer.
parentData as BoxParentData).y); | 809 canvas.paintChild(drawer, (drawer.parentData as BoxParentData).x, (drawer.
parentData as BoxParentData).y); |
755 } | 810 } |
756 | 811 |
757 } | 812 } |
OLD | NEW |