| 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> _descendentsWithPaintingCanvases = new List<RenderObject>()
; // used by RenderObject._updatePaintingCanvas() to find out which RenderObject
s to ask to paint |
| 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 assert(!_descendentsWithPaintingCanvases.contains(child)); |
| 36 _descendentsWithPaintingCanvases.add(child); |
| 37 drawPaintingNode(child._paintingNode, point); |
| 38 } else { |
| 39 child._paintOnCanvas(this, point.toOffset()); |
| 40 } |
| 34 } | 41 } |
| 35 } | 42 } |
| 36 | 43 |
| 37 abstract class Constraints { | 44 abstract class Constraints { |
| 38 const Constraints(); | 45 const Constraints(); |
| 39 bool get isTight; | 46 bool get isTight; |
| 40 } | 47 } |
| 41 | 48 |
| 42 abstract class RenderObject extends AbstractNode implements HitTestTarget { | 49 abstract class RenderObject extends AbstractNode implements HitTestTarget { |
| 43 | 50 |
| (...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 132 _cleanRelayoutSubtreeRootChildren(); | 139 _cleanRelayoutSubtreeRootChildren(); |
| 133 } | 140 } |
| 134 } | 141 } |
| 135 void _cleanRelayoutSubtreeRootChildren() { } // workaround for lack of inter-c
lass mixins in Dart | 142 void _cleanRelayoutSubtreeRootChildren() { } // workaround for lack of inter-c
lass mixins in Dart |
| 136 void scheduleInitialLayout() { | 143 void scheduleInitialLayout() { |
| 137 assert(attached); | 144 assert(attached); |
| 138 assert(parent == null); | 145 assert(parent == null); |
| 139 assert(_relayoutSubtreeRoot == null); | 146 assert(_relayoutSubtreeRoot == null); |
| 140 _relayoutSubtreeRoot = this; | 147 _relayoutSubtreeRoot = this; |
| 141 _nodesNeedingLayout.add(this); | 148 _nodesNeedingLayout.add(this); |
| 149 _nodesNeedingPaint.add(this); |
| 142 scheduler.ensureVisualUpdate(); | 150 scheduler.ensureVisualUpdate(); |
| 143 } | 151 } |
| 144 static void flushLayout() { | 152 static void flushLayout() { |
| 145 sky.tracing.begin('RenderObject.flushLayout'); | 153 sky.tracing.begin('RenderObject.flushLayout'); |
| 146 _debugDoingLayout = true; | 154 _debugDoingLayout = true; |
| 147 try { | 155 try { |
| 148 List<RenderObject> dirtyNodes = _nodesNeedingLayout; | 156 List<RenderObject> dirtyNodes = _nodesNeedingLayout; |
| 149 _nodesNeedingLayout = new List<RenderObject>(); | 157 _nodesNeedingLayout = new List<RenderObject>(); |
| 150 dirtyNodes..sort((a, b) => a.depth - b.depth)..forEach((node) { | 158 dirtyNodes..sort((a, b) => a.depth - b.depth)..forEach((node) { |
| 151 if (node._needsLayout && node.attached) | 159 if (node._needsLayout && node.attached) |
| 152 node.layoutWithoutResize(); | 160 node.layoutWithoutResize(); |
| 153 }); | 161 }); |
| 154 } finally { | 162 } finally { |
| 155 _debugDoingLayout = false; | 163 _debugDoingLayout = false; |
| 156 sky.tracing.end('RenderObject.flushLayout'); | 164 sky.tracing.end('RenderObject.flushLayout'); |
| 157 } | 165 } |
| 158 } | 166 } |
| 159 void layoutWithoutResize() { | 167 void layoutWithoutResize() { |
| 160 try { | 168 try { |
| 161 assert(_relayoutSubtreeRoot == this); | 169 assert(_relayoutSubtreeRoot == this); |
| 162 _debugCanParentUseSize = false; | 170 _debugCanParentUseSize = false; |
| 163 _debugDoingThisLayout = true; | 171 _debugDoingThisLayout = true; |
| 164 RenderObject debugPreviousActiveLayout = _debugActiveLayout; | 172 RenderObject debugPreviousActiveLayout = _debugActiveLayout; |
| 165 _debugActiveLayout = this; | 173 _debugActiveLayout = this; |
| 166 performLayout(); | 174 performLayout(); |
| 167 _debugActiveLayout = debugPreviousActiveLayout; | 175 _debugActiveLayout = debugPreviousActiveLayout; |
| 168 _debugDoingThisLayout = false; | 176 _debugDoingThisLayout = false; |
| 169 _debugCanParentUseSize = null; | 177 _debugCanParentUseSize = null; |
| 170 } catch (e, stack) { | 178 } catch (e) { |
| 171 print('Exception raised during layout:\n${e}\nContext:\n${this}'); | 179 print('Exception raised during layout:\n${e}\nContext:\n${this}'); |
| 172 print(stack); | |
| 173 return; | 180 return; |
| 174 } | 181 } |
| 175 _needsLayout = false; | 182 _needsLayout = false; |
| 176 markNeedsPaint(); | 183 markNeedsPaint(); |
| 177 } | 184 } |
| 178 void layout(Constraints constraints, { bool parentUsesSize: false }) { | 185 void layout(Constraints constraints, { bool parentUsesSize: false }) { |
| 179 final parent = this.parent; // TODO(ianh): Remove this once the analyzer is
cleverer | 186 final parent = this.parent; // TODO(ianh): Remove this once the analyzer is
cleverer |
| 180 RenderObject relayoutSubtreeRoot; | 187 RenderObject relayoutSubtreeRoot; |
| 181 if (!parentUsesSize || sizedByParent || constraints.isTight || parent is! Re
nderObject) | 188 if (!parentUsesSize || sizedByParent || constraints.isTight || parent is! Re
nderObject) |
| 182 relayoutSubtreeRoot = this; | 189 relayoutSubtreeRoot = this; |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 232 | 239 |
| 233 void rotate({ | 240 void rotate({ |
| 234 int oldAngle, // 0..3 | 241 int oldAngle, // 0..3 |
| 235 int newAngle, // 0..3 | 242 int newAngle, // 0..3 |
| 236 Duration time | 243 Duration time |
| 237 }) { } | 244 }) { } |
| 238 | 245 |
| 239 | 246 |
| 240 // PAINTING | 247 // PAINTING |
| 241 | 248 |
| 242 static bool debugDoingPaint = false; | 249 static List<RenderObject> _nodesNeedingPaint = new List<RenderObject>(); |
| 250 static bool _debugDoingPaint = false; |
| 251 static bool get debugDoingPaint => _debugDoingPaint; |
| 252 static void set debugDoingPaint(bool debug) { |
| 253 _debugDoingPaint = debug; |
| 254 } |
| 255 |
| 256 final sky.PaintingNode _paintingNode = new sky.PaintingNode(); |
| 257 sky.PaintingNode get paintingNode { |
| 258 assert(createNewDisplayList); |
| 259 return _paintingNode; |
| 260 } |
| 261 bool _needsPaint = true; |
| 262 bool get needsPaint => _needsPaint; |
| 263 bool get createNewDisplayList => false; |
| 264 |
| 243 void markNeedsPaint() { | 265 void markNeedsPaint() { |
| 244 assert(!debugDoingPaint); | 266 assert(!debugDoingPaint); |
| 245 scheduler.ensureVisualUpdate(); | 267 if (!attached) return; // Don't try painting things that aren't in the hiera
rchy |
| 268 if (_needsPaint) return; |
| 269 if (createNewDisplayList) { |
| 270 _needsPaint = true; |
| 271 _nodesNeedingPaint.add(this); |
| 272 scheduler.ensureVisualUpdate(); |
| 273 } else { |
| 274 assert(parent != null); // parent always exists on this path because the r
oot node is a RenderView, which sets createNewDisplayList. |
| 275 if (parent is RenderObject) { |
| 276 (parent as RenderObject).markNeedsPaint(); // TODO(ianh): remove the cas
t once the analyzer is cleverer |
| 277 } |
| 278 } |
| 246 } | 279 } |
| 280 |
| 281 static void flushPaint() { |
| 282 try { |
| 283 _debugDoingPaint = true; |
| 284 List<RenderObject> dirtyNodes = _nodesNeedingPaint; |
| 285 _nodesNeedingPaint = new List<RenderObject>(); |
| 286 for (RenderObject node in dirtyNodes..sort((a, b) => a.depth - b.depth)) { |
| 287 if (node._needsPaint && node.attached) |
| 288 node._updatePaintingCanvas(); |
| 289 }; |
| 290 assert(_nodesNeedingPaint.length == 0); |
| 291 } catch (e) { |
| 292 print('Exception raised during flushPaint:\n${e}'); |
| 293 } finally { |
| 294 _debugDoingPaint = false; |
| 295 } |
| 296 } |
| 297 |
| 298 void _updatePaintingCanvas() { |
| 299 assert(!_needsLayout); |
| 300 assert(createNewDisplayList); |
| 301 sky.PictureRecorder recorder = new sky.PictureRecorder(); |
| 302 PaintingCanvas canvas = new PaintingCanvas(recorder, paintBounds); |
| 303 _needsPaint = false; |
| 304 try { |
| 305 _paintOnCanvas(canvas, Offset.zero); |
| 306 } catch (e) { |
| 307 print('Exception raised during _updatePaintingCanvas:\n${e}\nContext:\n${t
his}'); |
| 308 return; |
| 309 } |
| 310 assert(!_needsLayout); // check that the paint() method didn't mark us dirty
again |
| 311 assert(!_needsPaint); // check that the paint() method didn't mark us dirty
again |
| 312 _paintingNode.setBackingDrawable(recorder.endRecordingAsDrawable()); |
| 313 |
| 314 if (canvas._descendentsWithPaintingCanvases != null) { |
| 315 for (RenderObject node in canvas._descendentsWithPaintingCanvases) { |
| 316 assert(node.attached == attached); |
| 317 if (node._needsPaint) |
| 318 node._updatePaintingCanvas(); |
| 319 }; |
| 320 } |
| 321 } |
| 322 |
| 323 void _paintOnCanvas(PaintingCanvas canvas, Offset offset) { |
| 324 _needsPaint = false; |
| 325 paint(canvas, offset); |
| 326 assert(!_needsPaint); |
| 327 } |
| 328 |
| 329 Rect get paintBounds; |
| 330 |
| 247 void paint(PaintingCanvas canvas, Offset offset) { } | 331 void paint(PaintingCanvas canvas, Offset offset) { } |
| 248 | 332 |
| 249 | 333 |
| 250 // EVENTS | 334 // EVENTS |
| 251 | 335 |
| 252 void handleEvent(sky.Event event, HitTestEntry entry) { | 336 void handleEvent(sky.Event event, HitTestEntry entry) { |
| 253 // override this if you have a client, to hand it to the client | 337 // override this if you have a client, to hand it to the client |
| 254 // override this if you want to do anything with the event | 338 // override this if you want to do anything with the event |
| 255 } | 339 } |
| 256 | 340 |
| (...skipping 273 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 530 int count = 1; | 614 int count = 1; |
| 531 ChildType child = _firstChild; | 615 ChildType child = _firstChild; |
| 532 while (child != null) { | 616 while (child != null) { |
| 533 result += '${prefix}child ${count}: ${child.toString(prefix)}'; | 617 result += '${prefix}child ${count}: ${child.toString(prefix)}'; |
| 534 count += 1; | 618 count += 1; |
| 535 child = child.parentData.nextSibling; | 619 child = child.parentData.nextSibling; |
| 536 } | 620 } |
| 537 return result; | 621 return result; |
| 538 } | 622 } |
| 539 } | 623 } |
| OLD | NEW |