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 |
| 8 import 'package:sky/framework/net/image_cache.dart' as image_cache; |
| 9 import 'package:vector_math/vector_math.dart'; |
| 10 |
| 11 import '../debug/utils.dart'; |
| 12 import '../painting/box_painter.dart'; |
7 import 'object.dart'; | 13 import 'object.dart'; |
8 import '../painting/box_painter.dart'; | |
9 import 'package:vector_math/vector_math.dart'; | |
10 import 'package:sky/framework/net/image_cache.dart' as image_cache; | |
11 | 14 |
12 export '../painting/box_painter.dart'; | 15 export '../painting/box_painter.dart'; |
13 | 16 |
14 // GENERIC BOX RENDERING | 17 // GENERIC BOX RENDERING |
15 // Anything that has a concept of x, y, width, height is going to derive from th
is | 18 // Anything that has a concept of x, y, width, height is going to derive from th
is |
16 | 19 |
| 20 // This class should only be used in debug builds |
| 21 class _DebugSize extends Size { |
| 22 _DebugSize(Size source, this._owner, this._canBeUsedByParent): super.copy(sour
ce); |
| 23 final RenderBox _owner; |
| 24 final bool _canBeUsedByParent; |
| 25 } |
| 26 |
17 class EdgeDims { | 27 class EdgeDims { |
18 // used for e.g. padding | 28 // used for e.g. padding |
19 const EdgeDims(this.top, this.right, this.bottom, this.left); | 29 const EdgeDims(this.top, this.right, this.bottom, this.left); |
20 const EdgeDims.all(double value) | 30 const EdgeDims.all(double value) |
21 : top = value, right = value, bottom = value, left = value; | 31 : top = value, right = value, bottom = value, left = value; |
22 const EdgeDims.only({ this.top: 0.0, | 32 const EdgeDims.only({ this.top: 0.0, |
23 this.right: 0.0, | 33 this.right: 0.0, |
24 this.bottom: 0.0, | 34 this.bottom: 0.0, |
25 this.left: 0.0 }); | 35 this.left: 0.0 }); |
26 const EdgeDims.symmetric({ double vertical: 0.0, | 36 const EdgeDims.symmetric({ double vertical: 0.0, |
(...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
146 | 156 |
147 double constrainWidth(double width) { | 157 double constrainWidth(double width) { |
148 return clamp(min: minWidth, max: maxWidth, value: width); | 158 return clamp(min: minWidth, max: maxWidth, value: width); |
149 } | 159 } |
150 | 160 |
151 double constrainHeight(double height) { | 161 double constrainHeight(double height) { |
152 return clamp(min: minHeight, max: maxHeight, value: height); | 162 return clamp(min: minHeight, max: maxHeight, value: height); |
153 } | 163 } |
154 | 164 |
155 Size constrain(Size size) { | 165 Size constrain(Size size) { |
156 return new Size(constrainWidth(size.width), constrainHeight(size.height)); | 166 Size result = new Size(constrainWidth(size.width), constrainHeight(size.heig
ht)); |
| 167 if (size is _DebugSize) |
| 168 result = new _DebugSize(result, size._owner, size._canBeUsedByParent); |
| 169 return result; |
157 } | 170 } |
158 | 171 |
159 bool get isInfinite => maxWidth >= double.INFINITY || maxHeight >= double.INFI
NITY; | 172 bool get isInfinite => maxWidth >= double.INFINITY || maxHeight >= double.INFI
NITY; |
160 | 173 |
161 int get hashCode { | 174 int get hashCode { |
162 int value = 373; | 175 int value = 373; |
163 value = 37 * value + minWidth.hashCode; | 176 value = 37 * value + minWidth.hashCode; |
164 value = 37 * value + maxWidth.hashCode; | 177 value = 37 * value + maxWidth.hashCode; |
165 value = 37 * value + minHeight.hashCode; | 178 value = 37 * value + minHeight.hashCode; |
166 value = 37 * value + maxHeight.hashCode; | 179 value = 37 * value + maxHeight.hashCode; |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
213 | 226 |
214 // getMaxIntrinsicHeight should return the smallest height beyond which | 227 // getMaxIntrinsicHeight should return the smallest height beyond which |
215 // increasing the height never decreases the width. | 228 // increasing the height never decreases the width. |
216 // If the layout algorithm used is width-in-height-out, i.e. the height | 229 // If the layout algorithm used is width-in-height-out, i.e. the height |
217 // depends on the width and not vice versa, then this will return the same | 230 // depends on the width and not vice versa, then this will return the same |
218 // as getMinIntrinsicHeight(). | 231 // as getMinIntrinsicHeight(). |
219 double getMaxIntrinsicHeight(BoxConstraints constraints) { | 232 double getMaxIntrinsicHeight(BoxConstraints constraints) { |
220 return constraints.constrainHeight(0.0); | 233 return constraints.constrainHeight(0.0); |
221 } | 234 } |
222 | 235 |
| 236 // This whole block should only be here in debug builds |
| 237 bool _debugDoingThisLayout = false; |
| 238 bool _debugCanParentUseSize; |
| 239 void layoutWithoutResize() { |
| 240 _debugDoingThisLayout = true; |
| 241 _debugCanParentUseSize = false; |
| 242 super.layoutWithoutResize(); |
| 243 _debugCanParentUseSize = null; |
| 244 _debugDoingThisLayout = false; |
| 245 } |
| 246 void layout(dynamic constraints, { bool parentUsesSize: false }) { |
| 247 _debugDoingThisLayout = true; |
| 248 _debugCanParentUseSize = parentUsesSize; |
| 249 super.layout(constraints, parentUsesSize: parentUsesSize); |
| 250 _debugCanParentUseSize = null; |
| 251 _debugDoingThisLayout = false; |
| 252 } |
| 253 |
223 BoxConstraints get constraints { BoxConstraints result = super.constraints; re
turn result; } | 254 BoxConstraints get constraints { BoxConstraints result = super.constraints; re
turn result; } |
224 void performResize() { | 255 void performResize() { |
225 // default behaviour for subclasses that have sizedByParent = true | 256 // default behaviour for subclasses that have sizedByParent = true |
226 size = constraints.constrain(Size.zero); | 257 size = constraints.constrain(Size.zero); |
227 assert(size.height < double.INFINITY); | 258 assert(size.height < double.INFINITY); |
228 assert(size.width < double.INFINITY); | 259 assert(size.width < double.INFINITY); |
229 } | 260 } |
230 void performLayout() { | 261 void performLayout() { |
231 // descendants have to either override performLayout() to set both | 262 // descendants have to either override performLayout() to set both |
232 // width and height and lay out children, or, set sizedByParent to | 263 // width and height and lay out children, or, set sizedByParent to |
233 // true so that performResize()'s logic above does its thing. | 264 // true so that performResize()'s logic above does its thing. |
234 assert(sizedByParent); | 265 assert(sizedByParent); |
235 } | 266 } |
236 | 267 |
237 bool hitTest(HitTestResult result, { Point position }) { | 268 bool hitTest(HitTestResult result, { Point position }) { |
238 hitTestChildren(result, position: position); | 269 hitTestChildren(result, position: position); |
239 result.add(new BoxHitTestEntry(this, position)); | 270 result.add(new BoxHitTestEntry(this, position)); |
240 return true; | 271 return true; |
241 } | 272 } |
242 void hitTestChildren(HitTestResult result, { Point position }) { } | 273 void hitTestChildren(HitTestResult result, { Point position }) { } |
243 | 274 |
| 275 // TODO(ianh): In non-debug builds, this should all just be: |
| 276 // Size size = Size.zero; |
| 277 // In debug builds, however: |
244 Size _size = Size.zero; | 278 Size _size = Size.zero; |
245 Size get size => _size; | 279 Size get size => _size; |
246 void set size(Size value) { | 280 void set size(Size value) { |
247 assert(RenderObject.debugDoingLayout); | 281 assert(RenderObject.debugDoingLayout); |
248 _size = value; | 282 assert(_debugDoingThisLayout); |
| 283 if (value is _DebugSize) { |
| 284 assert(value._canBeUsedByParent); |
| 285 assert(value._owner.parent == this); |
| 286 } |
| 287 _size = inDebugBuild ? new _DebugSize(value, this, _debugCanParentUseSize) :
value; |
249 } | 288 } |
250 | 289 |
251 String debugDescribeSettings(String prefix) => '${super.debugDescribeSettings(
prefix)}${prefix}size: ${size}\n'; | 290 String debugDescribeSettings(String prefix) => '${super.debugDescribeSettings(
prefix)}${prefix}size: ${size}\n'; |
252 } | 291 } |
253 | 292 |
254 class RenderProxyBox extends RenderBox with RenderObjectWithChildMixin<RenderBox
> { | 293 class RenderProxyBox extends RenderBox with RenderObjectWithChildMixin<RenderBox
> { |
255 | 294 |
256 // ProxyBox assumes the child will be at 0,0 and will have the same size | 295 // ProxyBox assumes the child will be at 0,0 and will have the same size |
257 | 296 |
258 RenderProxyBox([RenderBox child = null]) { | 297 RenderProxyBox([RenderBox child = null]) { |
(...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
387 } | 426 } |
388 | 427 |
389 double getMaxIntrinsicHeight(BoxConstraints constraints) { | 428 double getMaxIntrinsicHeight(BoxConstraints constraints) { |
390 if (child != null) | 429 if (child != null) |
391 return child.getMaxIntrinsicHeight(constraints.apply(_additionalConstraint
s)); | 430 return child.getMaxIntrinsicHeight(constraints.apply(_additionalConstraint
s)); |
392 return constraints.constrainHeight(0.0); | 431 return constraints.constrainHeight(0.0); |
393 } | 432 } |
394 | 433 |
395 void performLayout() { | 434 void performLayout() { |
396 if (child != null) { | 435 if (child != null) { |
397 child.layout(constraints.apply(_additionalConstraints)); | 436 child.layout(constraints.apply(_additionalConstraints), parentUsesSize: tr
ue); |
398 size = child.size; | 437 size = child.size; |
399 } else { | 438 } else { |
400 performResize(); | 439 performResize(); |
401 } | 440 } |
402 } | 441 } |
403 | 442 |
404 String debugDescribeSettings(String prefix) => '${super.debugDescribeSettings(
prefix)}${prefix}additionalConstraints: ${additionalConstraints}\n'; | 443 String debugDescribeSettings(String prefix) => '${super.debugDescribeSettings(
prefix)}${prefix}additionalConstraints: ${additionalConstraints}\n'; |
405 } | 444 } |
406 | 445 |
407 class RenderShrinkWrapWidth extends RenderProxyBox { | 446 class RenderShrinkWrapWidth extends RenderProxyBox { |
(...skipping 24 matching lines...) Expand all Loading... |
432 } | 471 } |
433 | 472 |
434 double getMaxIntrinsicHeight(BoxConstraints constraints) { | 473 double getMaxIntrinsicHeight(BoxConstraints constraints) { |
435 if (child != null) | 474 if (child != null) |
436 return child.getMaxIntrinsicHeight(_getInnerConstraints(constraints)); | 475 return child.getMaxIntrinsicHeight(_getInnerConstraints(constraints)); |
437 return constraints.constrainWidth(0.0); | 476 return constraints.constrainWidth(0.0); |
438 } | 477 } |
439 | 478 |
440 void performLayout() { | 479 void performLayout() { |
441 if (child != null) { | 480 if (child != null) { |
442 child.layout(_getInnerConstraints(constraints)); | 481 child.layout(_getInnerConstraints(constraints), parentUsesSize: true); |
443 size = child.size; | 482 size = child.size; |
444 } else { | 483 } else { |
445 performResize(); | 484 performResize(); |
446 } | 485 } |
447 } | 486 } |
448 } | 487 } |
449 | 488 |
450 class RenderOpacity extends RenderProxyBox { | 489 class RenderOpacity extends RenderProxyBox { |
451 RenderOpacity({ RenderBox child, double opacity }) | 490 RenderOpacity({ RenderBox child, double opacity }) |
452 : this._opacity = opacity, super(child) { | 491 : this._opacity = opacity, super(child) { |
(...skipping 203 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
656 } | 695 } |
657 | 696 |
658 double getMaxIntrinsicHeight(BoxConstraints constraints) { | 697 double getMaxIntrinsicHeight(BoxConstraints constraints) { |
659 if (child != null) | 698 if (child != null) |
660 return child.getMaxIntrinsicHeight(constraints); | 699 return child.getMaxIntrinsicHeight(constraints); |
661 return super.getMaxIntrinsicHeight(constraints); | 700 return super.getMaxIntrinsicHeight(constraints); |
662 } | 701 } |
663 | 702 |
664 void performLayout() { | 703 void performLayout() { |
665 if (child != null) { | 704 if (child != null) { |
666 child.layout(constraints.loosen()); | 705 child.layout(constraints.loosen(), parentUsesSize: true); |
667 size = constraints.constrain(child.size); | 706 size = constraints.constrain(child.size); |
668 assert(child.parentData is BoxParentData); | 707 assert(child.parentData is BoxParentData); |
669 Size delta = size - child.size; | 708 Size delta = size - child.size; |
670 child.parentData.position = new Point(delta.width * horizontal, delta.heig
ht * vertical); | 709 child.parentData.position = new Point(delta.width * horizontal, delta.heig
ht * vertical); |
671 } else { | 710 } else { |
672 performResize(); | 711 performResize(); |
673 } | 712 } |
674 } | 713 } |
675 | 714 |
676 String debugDescribeSettings(String prefix) => '${super.debugDescribeSettings(
prefix)}${prefix}horizontal: ${horizontal}\n${prefix}vertical: ${vertical}\n'; | 715 String debugDescribeSettings(String prefix) => '${super.debugDescribeSettings(
prefix)}${prefix}horizontal: ${horizontal}\n${prefix}vertical: ${vertical}\n'; |
(...skipping 362 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1039 | 1078 |
1040 void defaultPaint(RenderObjectDisplayList canvas) { | 1079 void defaultPaint(RenderObjectDisplayList canvas) { |
1041 RenderBox child = firstChild; | 1080 RenderBox child = firstChild; |
1042 while (child != null) { | 1081 while (child != null) { |
1043 assert(child.parentData is ParentDataType); | 1082 assert(child.parentData is ParentDataType); |
1044 canvas.paintChild(child, child.parentData.position); | 1083 canvas.paintChild(child, child.parentData.position); |
1045 child = child.parentData.nextSibling; | 1084 child = child.parentData.nextSibling; |
1046 } | 1085 } |
1047 } | 1086 } |
1048 } | 1087 } |
OLD | NEW |