| 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'; |
| (...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 63 setupParentData(child); | 63 setupParentData(child); |
| 64 super.adoptChild(child); | 64 super.adoptChild(child); |
| 65 markNeedsLayout(); | 65 markNeedsLayout(); |
| 66 } | 66 } |
| 67 void dropChild(RenderObject child) { // only for use by subclasses | 67 void dropChild(RenderObject child) { // only for use by subclasses |
| 68 assert(!debugDoingLayout); | 68 assert(!debugDoingLayout); |
| 69 assert(!debugDoingPaint); | 69 assert(!debugDoingPaint); |
| 70 assert(child != null); | 70 assert(child != null); |
| 71 assert(child.parentData != null); | 71 assert(child.parentData != null); |
| 72 child.parentData.detach(); | 72 child.parentData.detach(); |
| 73 child._cleanRelayoutSubtreeRoot(); | 73 child._maybeCleanParentDependencies(); |
| 74 super.dropChild(child); | 74 super.dropChild(child); |
| 75 markNeedsLayout(); | 75 markNeedsLayout(); |
| 76 } | 76 } |
| 77 | 77 |
| 78 static List<RenderObject> _nodesNeedingLayout = new List<RenderObject>(); | 78 static List<RenderObject> _nodesNeedingLayout = new List<RenderObject>(); |
| 79 static bool _debugDoingLayout = false; | 79 static bool _debugDoingLayout = false; |
| 80 static bool get debugDoingLayout => _debugDoingLayout; | 80 static bool get debugDoingLayout => _debugDoingLayout; |
| 81 bool _debugDoingThisResize = false; | 81 bool _debugDoingThisResize = false; |
| 82 bool get debugDoingThisResize => _debugDoingThisResize; | 82 bool get debugDoingThisResize => _debugDoingThisResize; |
| 83 bool _debugDoingThisLayout = false; | 83 bool _debugDoingThisLayout = false; |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 115 } | 115 } |
| 116 _needsLayout = true; | 116 _needsLayout = true; |
| 117 assert(_relayoutSubtreeRoot != null); | 117 assert(_relayoutSubtreeRoot != null); |
| 118 if (_relayoutSubtreeRoot != this) { | 118 if (_relayoutSubtreeRoot != this) { |
| 119 final parent = this.parent; // TODO(ianh): Remove this once the analyzer i
s cleverer | 119 final parent = this.parent; // TODO(ianh): Remove this once the analyzer i
s cleverer |
| 120 assert(parent is RenderObject); | 120 assert(parent is RenderObject); |
| 121 parent.markNeedsLayout(); | 121 parent.markNeedsLayout(); |
| 122 assert(parent == this.parent); // TODO(ianh): Remove this once the analyze
r is cleverer | 122 assert(parent == this.parent); // TODO(ianh): Remove this once the analyze
r is cleverer |
| 123 } else { | 123 } else { |
| 124 _nodesNeedingLayout.add(this); | 124 _nodesNeedingLayout.add(this); |
| 125 scheduler.ensureVisualUpdate(); | |
| 126 } | 125 } |
| 127 } | 126 } |
| 128 void _cleanRelayoutSubtreeRoot() { | 127 static bool _debugCleaningParentDependencies = false; |
| 129 if (_relayoutSubtreeRoot != this) { | 128 bool _debugSetCleaningParentDependencies(bool value) { |
| 130 _relayoutSubtreeRoot = null; | 129 _debugCleaningParentDependencies = value; |
| 131 _needsLayout = true; | 130 return true; |
| 132 _cleanRelayoutSubtreeRootChildren(); | |
| 133 } | |
| 134 } | 131 } |
| 135 void _cleanRelayoutSubtreeRootChildren() { } // workaround for lack of inter-c
lass mixins in Dart | 132 void _maybeCleanParentDependencies() { |
| 133 assert(_debugSetCleaningParentDependencies(true)); |
| 134 if (_relayoutSubtreeRoot != this) |
| 135 cleanParentDependencies(); |
| 136 assert(_debugSetCleaningParentDependencies(false)); |
| 137 } |
| 138 void cleanParentDependencies() { |
| 139 assert(_debugCleaningParentDependencies); |
| 140 assert(_relayoutSubtreeRoot != this); |
| 141 _relayoutSubtreeRoot = null; |
| 142 _needsLayout = true; |
| 143 _cleanParentDependenciesChildren(); |
| 144 } |
| 145 void _cleanParentDependenciesChildren() { } // workaround for lack of inter-cl
ass mixins in Dart |
| 136 void scheduleInitialLayout() { | 146 void scheduleInitialLayout() { |
| 137 assert(attached); | 147 assert(attached); |
| 138 assert(parent == null); | 148 assert(parent == null); |
| 139 assert(_relayoutSubtreeRoot == null); | 149 assert(_relayoutSubtreeRoot == null); |
| 140 _relayoutSubtreeRoot = this; | 150 _relayoutSubtreeRoot = this; |
| 141 _nodesNeedingLayout.add(this); | 151 _nodesNeedingLayout.add(this); |
| 142 scheduler.ensureVisualUpdate(); | 152 scheduler.ensureVisualUpdate(); |
| 143 } | 153 } |
| 144 static void flushLayout() { | 154 static void flushLayout() { |
| 145 sky.tracing.begin('RenderObject.flushLayout'); | 155 sky.tracing.begin('RenderObject.flushLayout'); |
| (...skipping 15 matching lines...) Expand all Loading... |
| 161 assert(_relayoutSubtreeRoot == this); | 171 assert(_relayoutSubtreeRoot == this); |
| 162 _debugCanParentUseSize = false; | 172 _debugCanParentUseSize = false; |
| 163 _debugDoingThisLayout = true; | 173 _debugDoingThisLayout = true; |
| 164 RenderObject debugPreviousActiveLayout = _debugActiveLayout; | 174 RenderObject debugPreviousActiveLayout = _debugActiveLayout; |
| 165 _debugActiveLayout = this; | 175 _debugActiveLayout = this; |
| 166 performLayout(); | 176 performLayout(); |
| 167 _debugActiveLayout = debugPreviousActiveLayout; | 177 _debugActiveLayout = debugPreviousActiveLayout; |
| 168 _debugDoingThisLayout = false; | 178 _debugDoingThisLayout = false; |
| 169 _debugCanParentUseSize = null; | 179 _debugCanParentUseSize = null; |
| 170 } catch (e, stack) { | 180 } catch (e, stack) { |
| 171 print('Exception raised during layout of ${this}: ${e}'); | 181 print('Exception "${e}" raised during layout of:\n${this}'); |
| 172 print(stack); | 182 print(stack); |
| 173 return; | 183 return; |
| 174 } | 184 } |
| 175 _needsLayout = false; | 185 _needsLayout = false; |
| 186 markNeedsPaint(); |
| 176 } | 187 } |
| 177 void layout(Constraints constraints, { bool parentUsesSize: false }) { | 188 void layout(Constraints constraints, { bool parentUsesSize: false }) { |
| 178 final parent = this.parent; // TODO(ianh): Remove this once the analyzer is
cleverer | 189 final parent = this.parent; // TODO(ianh): Remove this once the analyzer is
cleverer |
| 179 RenderObject relayoutSubtreeRoot; | 190 RenderObject relayoutSubtreeRoot; |
| 180 if (!parentUsesSize || sizedByParent || constraints.isTight || parent is! Re
nderObject) | 191 if (!parentUsesSize || sizedByParent || constraints.isTight || parent is! Re
nderObject) |
| 181 relayoutSubtreeRoot = this; | 192 relayoutSubtreeRoot = this; |
| 182 else | 193 else |
| 183 relayoutSubtreeRoot = parent._relayoutSubtreeRoot; | 194 relayoutSubtreeRoot = parent._relayoutSubtreeRoot; |
| 184 assert(parent == this.parent); // TODO(ianh): Remove this once the analyzer
is cleverer | 195 assert(parent == this.parent); // TODO(ianh): Remove this once the analyzer
is cleverer |
| 185 if (!needsLayout && constraints == _constraints && relayoutSubtreeRoot == _r
elayoutSubtreeRoot) | 196 if (!needsLayout && constraints == _constraints && relayoutSubtreeRoot == _r
elayoutSubtreeRoot) |
| (...skipping 24 matching lines...) Expand all Loading... |
| 210 // Override this to perform relayout without your parent's | 221 // Override this to perform relayout without your parent's |
| 211 // involvement. | 222 // involvement. |
| 212 // | 223 // |
| 213 // This is called during layout. If sizedByParent is true, then | 224 // This is called during layout. If sizedByParent is true, then |
| 214 // performLayout() should not change your dimensions, only do that | 225 // performLayout() should not change your dimensions, only do that |
| 215 // in performResize(). If sizedByParent is false, then set both | 226 // in performResize(). If sizedByParent is false, then set both |
| 216 // your dimensions and do your children's layout here. | 227 // your dimensions and do your children's layout here. |
| 217 // | 228 // |
| 218 // When calling layout() on your children, pass in | 229 // When calling layout() on your children, pass in |
| 219 // "parentUsesSize: true" if your size or layout is dependent on | 230 // "parentUsesSize: true" if your size or layout is dependent on |
| 220 // your child's size. | 231 // your child's size or intrinsic dimensions. |
| 221 | 232 |
| 222 // when the parent has rotated (e.g. when the screen has been turned | 233 // when the parent has rotated (e.g. when the screen has been turned |
| 223 // 90 degrees), immediately prior to layout() being called for the | 234 // 90 degrees), immediately prior to layout() being called for the |
| 224 // new dimensions, rotate() is called with the old and new angles. | 235 // new dimensions, rotate() is called with the old and new angles. |
| 225 // The next time paint() is called, the coordinate space will have | 236 // The next time paint() is called, the coordinate space will have |
| 226 // been rotated N quarter-turns clockwise, where: | 237 // been rotated N quarter-turns clockwise, where: |
| 227 // N = newAngle-oldAngle | 238 // N = newAngle-oldAngle |
| 228 // ...but the rendering is expected to remain the same, pixel for | 239 // ...but the rendering is expected to remain the same, pixel for |
| 229 // pixel, on the output device. Then, the layout() method or | 240 // pixel, on the output device. Then, the layout() method or |
| 230 // equivalent will be invoked. | 241 // equivalent will be invoked. |
| (...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 322 adoptChild(_child); | 333 adoptChild(_child); |
| 323 } | 334 } |
| 324 void attachChildren() { | 335 void attachChildren() { |
| 325 if (_child != null) | 336 if (_child != null) |
| 326 _child.attach(); | 337 _child.attach(); |
| 327 } | 338 } |
| 328 void detachChildren() { | 339 void detachChildren() { |
| 329 if (_child != null) | 340 if (_child != null) |
| 330 _child.detach(); | 341 _child.detach(); |
| 331 } | 342 } |
| 332 void _cleanRelayoutSubtreeRootChildren() { | 343 void _cleanParentDependenciesChildren() { |
| 333 if (_child != null) | 344 if (_child != null) |
| 334 _child._cleanRelayoutSubtreeRoot(); | 345 _child._maybeCleanParentDependencies(); |
| 335 } | 346 } |
| 336 String debugDescribeChildren(String prefix) { | 347 String debugDescribeChildren(String prefix) { |
| 337 if (child != null) | 348 if (child != null) |
| 338 return '${prefix}child: ${child.toString(prefix)}'; | 349 return '${prefix}child: ${child.toString(prefix)}'; |
| 339 return ''; | 350 return ''; |
| 340 } | 351 } |
| 341 } | 352 } |
| 342 | 353 |
| 343 | 354 |
| 344 // GENERIC MIXIN FOR RENDER NODES WITH A LIST OF CHILDREN | 355 // GENERIC MIXIN FOR RENDER NODES WITH A LIST OF CHILDREN |
| (...skipping 156 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 501 } | 512 } |
| 502 } | 513 } |
| 503 void detachChildren() { | 514 void detachChildren() { |
| 504 ChildType child = _firstChild; | 515 ChildType child = _firstChild; |
| 505 while (child != null) { | 516 while (child != null) { |
| 506 child.detach(); | 517 child.detach(); |
| 507 assert(child.parentData is ParentDataType); | 518 assert(child.parentData is ParentDataType); |
| 508 child = child.parentData.nextSibling; | 519 child = child.parentData.nextSibling; |
| 509 } | 520 } |
| 510 } | 521 } |
| 511 void _cleanRelayoutSubtreeRootChildren() { | 522 void _cleanParentDependenciesChildren() { |
| 512 ChildType child = _firstChild; | 523 ChildType child = _firstChild; |
| 513 while (child != null) { | 524 while (child != null) { |
| 514 child._cleanRelayoutSubtreeRoot(); | 525 child._maybeCleanParentDependencies(); |
| 515 assert(child.parentData is ParentDataType); | 526 assert(child.parentData is ParentDataType); |
| 516 child = child.parentData.nextSibling; | 527 child = child.parentData.nextSibling; |
| 517 } | 528 } |
| 518 } | 529 } |
| 519 | 530 |
| 520 ChildType get firstChild => _firstChild; | 531 ChildType get firstChild => _firstChild; |
| 521 ChildType get lastChild => _lastChild; | 532 ChildType get lastChild => _lastChild; |
| 522 ChildType childAfter(ChildType child) { | 533 ChildType childAfter(ChildType child) { |
| 523 assert(child.parentData is ParentDataType); | 534 assert(child.parentData is ParentDataType); |
| 524 return child.parentData.nextSibling; | 535 return child.parentData.nextSibling; |
| 525 } | 536 } |
| 526 | 537 |
| 527 String debugDescribeChildren(String prefix) { | 538 String debugDescribeChildren(String prefix) { |
| 528 String result = ''; | 539 String result = ''; |
| 529 int count = 1; | 540 int count = 1; |
| 530 ChildType child = _firstChild; | 541 ChildType child = _firstChild; |
| 531 while (child != null) { | 542 while (child != null) { |
| 532 result += '${prefix}child ${count}: ${child.toString(prefix)}'; | 543 result += '${prefix}child ${count}: ${child.toString(prefix)}'; |
| 533 count += 1; | 544 count += 1; |
| 534 child = child.parentData.nextSibling; | 545 child = child.parentData.nextSibling; |
| 535 } | 546 } |
| 536 return result; | 547 return result; |
| 537 } | 548 } |
| 538 } | 549 } |
| OLD | NEW |