| 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, Size, Rect, Color, Paint, Path; | 7 import 'dart:sky' show Point, 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 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 73 assert(child.parentData != null); | 73 assert(child.parentData != null); |
| 74 child.parentData.detach(); | 74 child.parentData.detach(); |
| 75 child._cleanRelayoutSubtreeRoot(); | 75 child._cleanRelayoutSubtreeRoot(); |
| 76 super.dropChild(child); | 76 super.dropChild(child); |
| 77 markNeedsLayout(); | 77 markNeedsLayout(); |
| 78 } | 78 } |
| 79 | 79 |
| 80 static List<RenderObject> _nodesNeedingLayout = new List<RenderObject>(); | 80 static List<RenderObject> _nodesNeedingLayout = new List<RenderObject>(); |
| 81 static bool _debugDoingLayout = false; | 81 static bool _debugDoingLayout = false; |
| 82 static bool get debugDoingLayout => _debugDoingLayout; | 82 static bool get debugDoingLayout => _debugDoingLayout; |
| 83 bool _debugDoingThisResize = false; |
| 84 bool get debugDoingThisResize => _debugDoingThisResize; |
| 85 bool _debugDoingThisLayout = false; |
| 86 bool get debugDoingThisLayout => _debugDoingThisLayout; |
| 87 static RenderObject _debugActiveLayout = null; |
| 88 static RenderObject get debugActiveLayout => _debugActiveLayout; |
| 89 bool _debugCanParentUseSize; |
| 90 bool get debugCanParentUseSize => _debugCanParentUseSize; |
| 83 bool _needsLayout = true; | 91 bool _needsLayout = true; |
| 84 bool get needsLayout => _needsLayout; | 92 bool get needsLayout => _needsLayout; |
| 85 RenderObject _relayoutSubtreeRoot; | 93 RenderObject _relayoutSubtreeRoot; |
| 86 Constraints _constraints; | 94 Constraints _constraints; |
| 87 Constraints get constraints => _constraints; | 95 Constraints get constraints => _constraints; |
| 96 bool debugDoesMeetConstraints(); // override this in a subclass to verify that
your state matches the constraints object |
| 88 bool debugAncestorsAlreadyMarkedNeedsLayout() { | 97 bool debugAncestorsAlreadyMarkedNeedsLayout() { |
| 89 if (_relayoutSubtreeRoot == null) | 98 if (_relayoutSubtreeRoot == null) |
| 90 return true; // we haven't yet done layout even once, so there's nothing f
or us to do | 99 return true; // we haven't yet done layout even once, so there's nothing f
or us to do |
| 91 RenderObject node = this; | 100 RenderObject node = this; |
| 92 while (node != _relayoutSubtreeRoot) { | 101 while (node != _relayoutSubtreeRoot) { |
| 93 assert(node._relayoutSubtreeRoot == _relayoutSubtreeRoot); | 102 assert(node._relayoutSubtreeRoot == _relayoutSubtreeRoot); |
| 94 assert(node.parent != null); | 103 assert(node.parent != null); |
| 95 node = node.parent as RenderObject; | 104 node = node.parent as RenderObject; |
| 96 if (!node._needsLayout) | 105 if (!node._needsLayout) |
| 97 return false; | 106 return false; |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 145 node.layoutWithoutResize(); | 154 node.layoutWithoutResize(); |
| 146 }); | 155 }); |
| 147 } finally { | 156 } finally { |
| 148 _debugDoingLayout = false; | 157 _debugDoingLayout = false; |
| 149 sky.tracing.end('RenderObject.flushLayout'); | 158 sky.tracing.end('RenderObject.flushLayout'); |
| 150 } | 159 } |
| 151 } | 160 } |
| 152 void layoutWithoutResize() { | 161 void layoutWithoutResize() { |
| 153 try { | 162 try { |
| 154 assert(_relayoutSubtreeRoot == this); | 163 assert(_relayoutSubtreeRoot == this); |
| 164 _debugCanParentUseSize = false; |
| 165 _debugDoingThisLayout = true; |
| 166 RenderObject debugPreviousActiveLayout = _debugActiveLayout; |
| 167 _debugActiveLayout = this; |
| 155 performLayout(); | 168 performLayout(); |
| 169 _debugActiveLayout = debugPreviousActiveLayout; |
| 170 _debugDoingThisLayout = false; |
| 171 _debugCanParentUseSize = null; |
| 156 } catch (e, stack) { | 172 } catch (e, stack) { |
| 157 print('Exception raised during layout of ${this}: ${e}'); | 173 print('Exception raised during layout of ${this}: ${e}'); |
| 158 print(stack); | 174 print(stack); |
| 159 return; | 175 return; |
| 160 } | 176 } |
| 161 _needsLayout = false; | 177 _needsLayout = false; |
| 162 } | 178 } |
| 163 void layout(Constraints constraints, { bool parentUsesSize: false }) { | 179 void layout(Constraints constraints, { bool parentUsesSize: false }) { |
| 164 final parent = this.parent; // TODO(ianh): Remove this once the analyzer is
cleverer | 180 final parent = this.parent; // TODO(ianh): Remove this once the analyzer is
cleverer |
| 165 RenderObject relayoutSubtreeRoot; | 181 RenderObject relayoutSubtreeRoot; |
| 166 if (!parentUsesSize || sizedByParent || constraints.isTight || parent is! Re
nderObject) | 182 if (!parentUsesSize || sizedByParent || constraints.isTight || parent is! Re
nderObject) |
| 167 relayoutSubtreeRoot = this; | 183 relayoutSubtreeRoot = this; |
| 168 else | 184 else |
| 169 relayoutSubtreeRoot = parent._relayoutSubtreeRoot; | 185 relayoutSubtreeRoot = parent._relayoutSubtreeRoot; |
| 170 assert(parent == this.parent); // TODO(ianh): Remove this once the analyzer
is cleverer | 186 assert(parent == this.parent); // TODO(ianh): Remove this once the analyzer
is cleverer |
| 171 if (!needsLayout && constraints == _constraints && relayoutSubtreeRoot == _r
elayoutSubtreeRoot) | 187 if (!needsLayout && constraints == _constraints && relayoutSubtreeRoot == _r
elayoutSubtreeRoot) |
| 172 return; | 188 return; |
| 173 _constraints = constraints; | 189 _constraints = constraints; |
| 174 _relayoutSubtreeRoot = relayoutSubtreeRoot; | 190 _relayoutSubtreeRoot = relayoutSubtreeRoot; |
| 175 if (sizedByParent) | 191 _debugCanParentUseSize = parentUsesSize; |
| 192 if (sizedByParent) { |
| 193 _debugDoingThisResize = true; |
| 176 performResize(); | 194 performResize(); |
| 195 _debugDoingThisResize = false; |
| 196 } |
| 197 _debugDoingThisLayout = true; |
| 198 RenderObject debugPreviousActiveLayout = _debugActiveLayout; |
| 199 _debugActiveLayout = this; |
| 177 performLayout(); | 200 performLayout(); |
| 201 _debugActiveLayout = debugPreviousActiveLayout; |
| 202 _debugDoingThisLayout = false; |
| 203 _debugCanParentUseSize = null; |
| 204 assert(debugDoesMeetConstraints()); |
| 178 _needsLayout = false; | 205 _needsLayout = false; |
| 179 markNeedsPaint(); | 206 markNeedsPaint(); |
| 180 assert(parent == this.parent); // TODO(ianh): Remove this once the analyzer
is cleverer | 207 assert(parent == this.parent); // TODO(ianh): Remove this once the analyzer
is cleverer |
| 181 } | 208 } |
| 182 bool get sizedByParent => false; // return true if the constraints are the onl
y input to the sizing algorithm (in particular, child nodes have no impact) | 209 bool get sizedByParent => false; // return true if the constraints are the onl
y input to the sizing algorithm (in particular, child nodes have no impact) |
| 183 void performResize(); // set the local dimensions, using only the constraints
(only called if sizedByParent is true) | 210 void performResize(); // set the local dimensions, using only the constraints
(only called if sizedByParent is true) |
| 184 void performLayout(); | 211 void performLayout(); |
| 185 // Override this to perform relayout without your parent's | 212 // Override this to perform relayout without your parent's |
| 186 // involvement. | 213 // involvement. |
| 187 // | 214 // |
| (...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 243 // // For each child that intersects x,y, in z-order starting from the top, | 270 // // For each child that intersects x,y, in z-order starting from the top, |
| 244 // // call hitTest() for that child, passing it /result/, and the coordinate
s | 271 // // call hitTest() for that child, passing it /result/, and the coordinate
s |
| 245 // // converted to the child's coordinate origin, and stop at the first chil
d | 272 // // converted to the child's coordinate origin, and stop at the first chil
d |
| 246 // // that returns true. | 273 // // that returns true. |
| 247 // // Then, add yourself to /result/, and return true. | 274 // // Then, add yourself to /result/, and return true. |
| 248 // } | 275 // } |
| 249 // You must not add yourself to /result/ if you return false. | 276 // You must not add yourself to /result/ if you return false. |
| 250 | 277 |
| 251 | 278 |
| 252 String toString([String prefix = '']) { | 279 String toString([String prefix = '']) { |
| 280 RenderObject debugPreviousActiveLayout = _debugActiveLayout; |
| 281 _debugActiveLayout = null; |
| 253 String header = '${runtimeType}'; | 282 String header = '${runtimeType}'; |
| 254 if (_relayoutSubtreeRoot != null && _relayoutSubtreeRoot != this) { | 283 if (_relayoutSubtreeRoot != null && _relayoutSubtreeRoot != this) { |
| 255 int count = 1; | 284 int count = 1; |
| 256 RenderObject target = parent; | 285 RenderObject target = parent; |
| 257 while (target != null && target != _relayoutSubtreeRoot) { | 286 while (target != null && target != _relayoutSubtreeRoot) { |
| 258 target = target.parent as RenderObject; | 287 target = target.parent as RenderObject; |
| 259 count += 1; | 288 count += 1; |
| 260 } | 289 } |
| 261 header += ' relayoutSubtreeRoot=up$count'; | 290 header += ' relayoutSubtreeRoot=up$count'; |
| 262 } | 291 } |
| 263 if (_needsLayout) | 292 if (_needsLayout) |
| 264 header += ' NEEDS-LAYOUT'; | 293 header += ' NEEDS-LAYOUT'; |
| 265 if (!attached) | 294 if (!attached) |
| 266 header += ' DETACHED'; | 295 header += ' DETACHED'; |
| 267 prefix += ' '; | 296 prefix += ' '; |
| 268 return '${header}\n${debugDescribeSettings(prefix)}${debugDescribeChildren(p
refix)}'; | 297 String result = '${header}\n${debugDescribeSettings(prefix)}${debugDescribeC
hildren(prefix)}'; |
| 298 _debugActiveLayout = debugPreviousActiveLayout; |
| 299 return result; |
| 269 } | 300 } |
| 270 String debugDescribeSettings(String prefix) => '${prefix}parentData: ${parentD
ata}\n${prefix}constraints: ${constraints}\n'; | 301 String debugDescribeSettings(String prefix) => '${prefix}parentData: ${parentD
ata}\n${prefix}constraints: ${constraints}\n'; |
| 271 String debugDescribeChildren(String prefix) => ''; | 302 String debugDescribeChildren(String prefix) => ''; |
| 272 | 303 |
| 273 } | 304 } |
| 274 | 305 |
| 275 double clamp({ double min: 0.0, double value: 0.0, double max: double.INFINITY }
) { | 306 double clamp({ double min: 0.0, double value: 0.0, double max: double.INFINITY }
) { |
| 276 assert(min != null); | 307 assert(min != null); |
| 277 assert(value != null); | 308 assert(value != null); |
| 278 assert(max != null); | 309 assert(max != null); |
| (...skipping 215 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 494 int count = 1; | 525 int count = 1; |
| 495 ChildType child = _firstChild; | 526 ChildType child = _firstChild; |
| 496 while (child != null) { | 527 while (child != null) { |
| 497 result += '${prefix}child ${count}: ${child.toString(prefix)}'; | 528 result += '${prefix}child ${count}: ${child.toString(prefix)}'; |
| 498 count += 1; | 529 count += 1; |
| 499 child = child.parentData.nextSibling; | 530 child = child.parentData.nextSibling; |
| 500 } | 531 } |
| 501 return result; | 532 return result; |
| 502 } | 533 } |
| 503 } | 534 } |
| OLD | NEW |