Chromium Code Reviews| OLD | NEW |
|---|---|
| 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; | 5 import 'dart:math' as math; |
| 6 import 'dart:sky' as sky; | 6 import 'dart:sky' as sky; |
| 7 import 'dart:sky' show Point, Offset, Size, Rect, Color, Paint, Path; | 7 import 'dart:sky' show Point, Offset, Size, Rect, Color, Paint, Path; |
| 8 | 8 |
| 9 import '../base/hit_test.dart'; | 9 import '../base/hit_test.dart'; |
| 10 import '../base/node.dart'; | 10 import '../base/node.dart'; |
| 11 import '../base/scheduler.dart' as scheduler; | 11 import '../base/scheduler.dart' as scheduler; |
| 12 | 12 |
| 13 export 'dart:sky' show Point, Offset, Size, Rect, Color, Paint, Path; | 13 export 'dart:sky' show Point, Offset, Size, Rect, Color, Paint, Path; |
| 14 export '../base/hit_test.dart' show HitTestTarget, HitTestEntry, HitTestResult; | 14 export '../base/hit_test.dart' show HitTestTarget, HitTestEntry, HitTestResult; |
| 15 | 15 |
| 16 | 16 |
| 17 class ParentData { | 17 class ParentData { |
| 18 void detach() { | 18 void detach() { |
| 19 detachSiblings(); | 19 detachSiblings(); |
| 20 } | 20 } |
| 21 void detachSiblings() { } // workaround for lack of inter-class mixins in Dart | 21 void detachSiblings() { } // workaround for lack of inter-class mixins in Dart |
| 22 void merge(ParentData other) { | 22 void merge(ParentData other) { |
| 23 // override this in subclasses to merge in data from other into this | 23 // override this in subclasses to merge in data from other into this |
| 24 assert(other.runtimeType == this.runtimeType); | 24 assert(other.runtimeType == this.runtimeType); |
| 25 } | 25 } |
| 26 String toString() => '<none>'; | 26 String toString() => '<none>'; |
| 27 } | 27 } |
| 28 | 28 |
| 29 class PaintingCanvas extends sky.Canvas { | 29 class PaintingCanvas extends sky.Canvas { |
| 30 PaintingCanvas(sky.PictureRecorder recorder, Size bounds) : super(recorder, bo unds); | 30 PaintingCanvas(sky.PictureRecorder recorder, Rect bounds) : super(recorder, bo unds); |
| 31 | 31 |
| 32 List<RenderObject> _children; // used by _doPaint() to find out which RenderOb jects to ask to paint | |
|
Hixie
2015/07/02 00:19:54
rename this to _descendantsWithPaintNodes or some
iansf
2015/07/06 18:22:01
Done.
| |
| 32 void paintChild(RenderObject child, Point point) { | 33 void paintChild(RenderObject child, Point point) { |
| 33 child.paint(this, point.toOffset()); | 34 if (child.createNewDisplayList) { |
| 35 if (_children == null) | |
| 36 _children = new List<RenderObject>(); | |
| 37 assert(!_children.contains(child)); | |
| 38 _children.add(child); | |
| 39 | |
|
Hixie
2015/07/02 00:19:54
remove this blank line
iansf
2015/07/06 18:22:01
Done.
| |
| 40 translate(point.x, point.y); | |
| 41 drawPaintingNode(child._paintingNode); | |
| 42 translate(-point.x, -point.y); | |
| 43 } else { | |
| 44 child.performPaint(this, point.toOffset()); | |
| 45 } | |
| 34 } | 46 } |
| 35 } | 47 } |
| 36 | 48 |
| 37 abstract class Constraints { | 49 abstract class Constraints { |
| 38 const Constraints(); | 50 const Constraints(); |
| 39 bool get isTight; | 51 bool get isTight; |
| 40 } | 52 } |
| 41 | 53 |
| 42 abstract class RenderObject extends AbstractNode implements HitTestTarget { | 54 abstract class RenderObject extends AbstractNode implements HitTestTarget { |
| 43 | 55 |
| (...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 131 _cleanRelayoutSubtreeRootChildren(); | 143 _cleanRelayoutSubtreeRootChildren(); |
| 132 } | 144 } |
| 133 } | 145 } |
| 134 void _cleanRelayoutSubtreeRootChildren() { } // workaround for lack of inter-c lass mixins in Dart | 146 void _cleanRelayoutSubtreeRootChildren() { } // workaround for lack of inter-c lass mixins in Dart |
| 135 void scheduleInitialLayout() { | 147 void scheduleInitialLayout() { |
| 136 assert(attached); | 148 assert(attached); |
| 137 assert(parent == null); | 149 assert(parent == null); |
| 138 assert(_relayoutSubtreeRoot == null); | 150 assert(_relayoutSubtreeRoot == null); |
| 139 _relayoutSubtreeRoot = this; | 151 _relayoutSubtreeRoot = this; |
| 140 _nodesNeedingLayout.add(this); | 152 _nodesNeedingLayout.add(this); |
| 153 _nodesNeedingPaint.add(this); | |
| 141 scheduler.ensureVisualUpdate(); | 154 scheduler.ensureVisualUpdate(); |
| 142 } | 155 } |
| 143 static void flushLayout() { | 156 static void flushLayout() { |
| 144 sky.tracing.begin('RenderObject.flushLayout'); | 157 sky.tracing.begin('RenderObject.flushLayout'); |
| 145 _debugDoingLayout = true; | 158 _debugDoingLayout = true; |
| 146 try { | 159 try { |
| 147 List<RenderObject> dirtyNodes = _nodesNeedingLayout; | 160 List<RenderObject> dirtyNodes = _nodesNeedingLayout; |
| 148 _nodesNeedingLayout = new List<RenderObject>(); | 161 _nodesNeedingLayout = new List<RenderObject>(); |
| 149 dirtyNodes..sort((a, b) => a.depth - b.depth)..forEach((node) { | 162 dirtyNodes..sort((a, b) => a.depth - b.depth)..forEach((node) { |
| 150 if (node._needsLayout && node.attached) | 163 if (node._needsLayout && node.attached) |
| (...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 231 | 244 |
| 232 void rotate({ | 245 void rotate({ |
| 233 int oldAngle, // 0..3 | 246 int oldAngle, // 0..3 |
| 234 int newAngle, // 0..3 | 247 int newAngle, // 0..3 |
| 235 Duration time | 248 Duration time |
| 236 }) { } | 249 }) { } |
| 237 | 250 |
| 238 | 251 |
| 239 // PAINTING | 252 // PAINTING |
| 240 | 253 |
| 241 static bool debugDoingPaint = false; | 254 static List<RenderObject> _nodesNeedingPaint = new List<RenderObject>(); |
| 255 static bool _debugDoingPaint = false; | |
| 256 static bool get debugDoingPaint => _debugDoingPaint; | |
| 257 | |
| 258 sky.PaintingNode _paintingNode = new sky.PaintingNode(); // only set if create NewDisplayList is true | |
| 259 sky.PaintingNode get paintingNode => _paintingNode; | |
| 260 bool _needsPaint = true; | |
| 261 bool get needsPaint => _needsPaint; | |
| 262 bool get createNewDisplayList => true; | |
| 263 | |
| 242 void markNeedsPaint() { | 264 void markNeedsPaint() { |
| 243 assert(!debugDoingPaint); | 265 assert(!debugDoingPaint); |
| 244 scheduler.ensureVisualUpdate(); | 266 if (_needsPaint) return; |
| 267 if (createNewDisplayList) { | |
| 268 _needsPaint = true; | |
| 269 _nodesNeedingPaint.add(this); | |
| 270 | |
|
Hixie
2015/07/02 00:19:54
remove this random blank line :-)
iansf
2015/07/06 18:22:01
Done.
| |
| 271 scheduler.ensureVisualUpdate(); | |
| 272 } else if (parent != null) { | |
| 273 if (parent is RenderObject) { | |
| 274 (parent as RenderObject).markNeedsPaint(); // TODO(ianh): remove the cas t once the analyzer is cleverer | |
| 275 } | |
| 276 } | |
| 277 } | |
| 278 | |
| 279 static void flushPaint() { | |
| 280 _debugDoingPaint = true; | |
| 281 List<RenderObject> dirtyNodes = _nodesNeedingPaint; | |
| 282 _nodesNeedingPaint = new List<RenderObject>(); | |
| 283 dirtyNodes..sort((a, b) => a.depth - b.depth)..forEach((node) { | |
| 284 if (node._needsPaint && node.attached) | |
| 285 node._doPaint(); | |
| 286 }); | |
| 287 assert(_nodesNeedingPaint.length == 0); | |
| 288 _debugDoingPaint = false; | |
| 289 } | |
| 290 | |
| 291 void _doPaint() { | |
|
Hixie
2015/07/02 00:19:54
call this _paintOnPaintNode() or _updatePaintNode(
iansf
2015/07/06 18:22:01
Done.
| |
| 292 assert(!_needsLayout); | |
| 293 assert(createNewDisplayList); | |
| 294 sky.PictureRecorder recorder = new sky.PictureRecorder(); | |
| 295 PaintingCanvas canvas = new PaintingCanvas(recorder, paintBounds); | |
| 296 _needsPaint = false; | |
| 297 try { | |
| 298 performPaint(canvas, Point.origin.toOffset()); | |
|
Hixie
2015/07/02 00:19:54
use Offset.zero instead
iansf
2015/07/06 18:22:01
Done.
| |
| 299 } catch (e, stack) { | |
| 300 print('Exception raised during paint of ${this.runtimeType}: ${e}'); | |
|
Hixie
2015/07/02 00:19:54
make this match the style in layout()
iansf
2015/07/06 18:22:01
Done.
| |
| 301 print(stack); | |
| 302 return; | |
| 303 } | |
| 304 assert(!_needsLayout); // check that the paint() method didn't mark us dirty again | |
| 305 assert(!_needsPaint); // check that the paint() method didn't mark us dirty again | |
| 306 _paintingNode.setBackingDrawable(recorder.endRecordingAsDrawable()); | |
| 307 | |
| 308 if (canvas._children != null) { | |
| 309 canvas._children.forEach((node) { | |
| 310 assert(node.attached == attached); | |
| 311 if (node._needsPaint) | |
| 312 node._doPaint(); | |
| 313 }); | |
| 314 } | |
| 315 | |
| 316 } | |
| 317 | |
| 318 Rect get paintBounds; | |
|
Hixie
2015/07/02 00:19:54
move this below performPaint()
iansf
2015/07/06 18:22:01
Done.
| |
| 319 | |
| 320 void performPaint(PaintingCanvas canvas, Offset offset) { | |
|
Hixie
2015/07/02 00:19:54
call this _paintOnCanvas() or some such.
iansf
2015/07/06 18:22:01
Done.
| |
| 321 _needsPaint = false; | |
| 322 paint(canvas, offset); | |
| 323 assert(!_needsPaint); | |
| 324 } | |
| 325 | |
| 326 | |
| 245 } | 327 } |
| 246 void paint(PaintingCanvas canvas, Offset offset) { } | 328 void paint(PaintingCanvas canvas, Offset offset) { } |
| 247 | 329 |
| 248 | 330 |
| 249 // EVENTS | 331 // EVENTS |
| 250 | 332 |
| 251 void handleEvent(sky.Event event, HitTestEntry entry) { | 333 void handleEvent(sky.Event event, HitTestEntry entry) { |
| 252 // override this if you have a client, to hand it to the client | 334 // override this if you have a client, to hand it to the client |
| 253 // override this if you want to do anything with the event | 335 // override this if you want to do anything with the event |
| 254 } | 336 } |
| (...skipping 274 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 529 int count = 1; | 611 int count = 1; |
| 530 ChildType child = _firstChild; | 612 ChildType child = _firstChild; |
| 531 while (child != null) { | 613 while (child != null) { |
| 532 result += '${prefix}child ${count}: ${child.toString(prefix)}'; | 614 result += '${prefix}child ${count}: ${child.toString(prefix)}'; |
| 533 count += 1; | 615 count += 1; |
| 534 child = child.parentData.nextSibling; | 616 child = child.parentData.nextSibling; |
| 535 } | 617 } |
| 536 return result; | 618 return result; |
| 537 } | 619 } |
| 538 } | 620 } |
| OLD | NEW |