| 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 | 7 |
| 8 import 'package:vector_math/vector_math.dart'; | 8 import 'package:vector_math/vector_math.dart'; |
| 9 | 9 |
| 10 import '../base/debug.dart'; | 10 import '../base/debug.dart'; |
| (...skipping 273 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 284 | 284 |
| 285 // getMaxIntrinsicHeight should return the smallest height beyond which | 285 // getMaxIntrinsicHeight should return the smallest height beyond which |
| 286 // increasing the height never decreases the width. | 286 // increasing the height never decreases the width. |
| 287 // If the layout algorithm used is width-in-height-out, i.e. the height | 287 // If the layout algorithm used is width-in-height-out, i.e. the height |
| 288 // depends on the width and not vice versa, then this will return the same | 288 // depends on the width and not vice versa, then this will return the same |
| 289 // as getMinIntrinsicHeight(). | 289 // as getMinIntrinsicHeight(). |
| 290 double getMaxIntrinsicHeight(BoxConstraints constraints) { | 290 double getMaxIntrinsicHeight(BoxConstraints constraints) { |
| 291 return constraints.constrainHeight(0.0); | 291 return constraints.constrainHeight(0.0); |
| 292 } | 292 } |
| 293 | 293 |
| 294 // getDistanceToBaseline() should return the distance from the | 294 Map<TextBaseline, double> _cachedBaselines; |
| 295 bool _ancestorUsesBaseline = false; |
| 296 static bool _debugDoingBaseline = false; |
| 297 static bool _debugSetDoingBaseline(bool value) { |
| 298 _debugDoingBaseline = value; |
| 299 return true; |
| 300 } |
| 301 // getDistanceToBaseline() returns the distance from the |
| 295 // y-coordinate of the position of the box to the y-coordinate of | 302 // y-coordinate of the position of the box to the y-coordinate of |
| 296 // the first given baseline in the box's contents. This is used by | 303 // the first given baseline in the box's contents. This is used by |
| 297 // certain layout models to align adjacent boxes on a common | 304 // certain layout models to align adjacent boxes on a common |
| 298 // baseline, regardless of padding, font size differences, etc. If | 305 // baseline, regardless of padding, font size differences, etc. If |
| 299 // there is no baseline, then it should return the distance from the | 306 // there is no baseline, then it returns the distance from the |
| 300 // y-coordinate of the position of the box to the y-coordinate of | 307 // y-coordinate of the position of the box to the y-coordinate of |
| 301 // the bottom of the box, i.e., the height of the box. | 308 // the bottom of the box, i.e., the height of the box. Only call |
| 302 // Only call this after layout has been performed. | 309 // this after layout has been performed. You are only allowed to |
| 310 // call this from the parent of this node, and only during |
| 311 // that parent's performLayout(). |
| 303 double getDistanceToBaseline(TextBaseline baseline) { | 312 double getDistanceToBaseline(TextBaseline baseline) { |
| 304 assert(!needsLayout); | 313 assert(!needsLayout); |
| 314 assert(!_debugDoingBaseline); |
| 315 final parent = this.parent; // TODO(ianh): Remove this once the analyzer is
cleverer |
| 316 assert(parent is RenderObject); |
| 317 assert(parent == RenderObject.debugActiveLayout); |
| 318 assert(parent.debugDoingThisLayout); |
| 319 assert(_debugSetDoingBaseline(true)); |
| 305 double result = getDistanceToActualBaseline(baseline); | 320 double result = getDistanceToActualBaseline(baseline); |
| 321 assert(_debugSetDoingBaseline(false)); |
| 322 assert(parent == this.parent); // TODO(ianh): Remove this once the analyzer
is cleverer |
| 306 if (result == null) | 323 if (result == null) |
| 307 return size.height; | 324 return size.height; |
| 308 return result; | 325 return result; |
| 309 } | 326 } |
| 310 // getDistanceToActualBaseline() should return the distance from the | 327 // getDistanceToActualBaseline() must only be called from |
| 311 // y-coordinate of the position of the box to the y-coordinate of | 328 // getDistanceToBaseline() and computeDistanceToActualBaseline(). Do |
| 312 // the first given baseline in the box's contents, if any, or null | 329 // not call it directly from outside those two methods. It just |
| 313 // otherwise. | 330 // calls computeDistanceToActualBaseline() and caches the result. |
| 314 double getDistanceToActualBaseline(TextBaseline baseline) { | 331 double getDistanceToActualBaseline(TextBaseline baseline) { |
| 315 assert(!needsLayout); | 332 assert(_debugDoingBaseline); |
| 333 _ancestorUsesBaseline = true; |
| 334 if (_cachedBaselines == null) |
| 335 _cachedBaselines = new Map<TextBaseline, double>(); |
| 336 _cachedBaselines.putIfAbsent(baseline, () => computeDistanceToActualBaseline
(baseline)); |
| 337 return _cachedBaselines[baseline]; |
| 338 } |
| 339 // computeDistanceToActualBaseline() should return the distance from |
| 340 // the y-coordinate of the position of the box to the y-coordinate |
| 341 // of the first given baseline in the box's contents, if any, or |
| 342 // null otherwise. This is the method that you should override in |
| 343 // subclasses. This method (computeDistanceToActualBaseline()) |
| 344 // should not be called directly. Use getDistanceToBaseline() if you |
| 345 // need to know the baseline of a child from performLayout(). If you |
| 346 // need the baseline during paint, cache it during performLayout(). |
| 347 // Use getDistanceToActualBaseline() if you are implementing |
| 348 // computeDistanceToActualBaseline() and need to defer to a child. |
| 349 double computeDistanceToActualBaseline(TextBaseline baseline) { |
| 350 assert(_debugDoingBaseline); |
| 316 return null; | 351 return null; |
| 317 } | 352 } |
| 318 | 353 |
| 319 BoxConstraints get constraints => super.constraints; | 354 BoxConstraints get constraints => super.constraints; |
| 320 bool debugDoesMeetConstraints() { | 355 bool debugDoesMeetConstraints() { |
| 321 assert(constraints != null); | 356 assert(constraints != null); |
| 322 assert(_size != null); | 357 assert(_size != null); |
| 323 assert(!_size.isInfinite); | 358 assert(!_size.isInfinite); |
| 324 bool result = constraints.contains(_size); | 359 bool result = constraints.contains(_size); |
| 325 if (!result) | 360 if (!result) |
| 326 print("${this.runtimeType} does not meet its constraints. Constraints: $co
nstraints, size: $_size"); | 361 print("${this.runtimeType} does not meet its constraints. Constraints: $co
nstraints, size: $_size"); |
| 327 return result; | 362 return result; |
| 328 } | 363 } |
| 364 |
| 365 void markNeedsLayout() { |
| 366 if (_cachedBaselines != null && _cachedBaselines.isNotEmpty) { |
| 367 // if we have cached data, then someone must have used our data |
| 368 assert(_ancestorUsesBaseline); |
| 369 final parent = this.parent; // TODO(ianh): Remove this once the analyzer i
s cleverer |
| 370 assert(parent is RenderObject); |
| 371 parent.markNeedsLayout(); |
| 372 assert(parent == this.parent); // TODO(ianh): Remove this once the analyze
r is cleverer |
| 373 // Now that they're dirty, we can forget that they used the |
| 374 // baseline. If they use it again, then we'll set the bit |
| 375 // again, and if we get dirty again, we'll notify them again. |
| 376 _ancestorUsesBaseline = false; |
| 377 _cachedBaselines.clear(); |
| 378 } else { |
| 379 // if we've never cached any data, then nobody can have used it |
| 380 assert(!_ancestorUsesBaseline); |
| 381 } |
| 382 super.markNeedsLayout(); |
| 383 } |
| 329 void performResize() { | 384 void performResize() { |
| 330 // default behaviour for subclasses that have sizedByParent = true | 385 // default behaviour for subclasses that have sizedByParent = true |
| 331 size = constraints.constrain(Size.zero); | 386 size = constraints.constrain(Size.zero); |
| 332 assert(!size.isInfinite); | 387 assert(!size.isInfinite); |
| 333 } | 388 } |
| 334 void performLayout() { | 389 void performLayout() { |
| 335 // descendants have to either override performLayout() to set both | 390 // descendants have to either override performLayout() to set both |
| 336 // width and height and lay out children, or, set sizedByParent to | 391 // width and height and lay out children, or, set sizedByParent to |
| 337 // true so that performResize()'s logic above does its thing. | 392 // true so that performResize()'s logic above does its thing. |
| 338 assert(sizedByParent); | 393 assert(sizedByParent); |
| (...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 403 return child.getMinIntrinsicHeight(constraints); | 458 return child.getMinIntrinsicHeight(constraints); |
| 404 return super.getMinIntrinsicHeight(constraints); | 459 return super.getMinIntrinsicHeight(constraints); |
| 405 } | 460 } |
| 406 | 461 |
| 407 double getMaxIntrinsicHeight(BoxConstraints constraints) { | 462 double getMaxIntrinsicHeight(BoxConstraints constraints) { |
| 408 if (child != null) | 463 if (child != null) |
| 409 return child.getMaxIntrinsicHeight(constraints); | 464 return child.getMaxIntrinsicHeight(constraints); |
| 410 return super.getMaxIntrinsicHeight(constraints); | 465 return super.getMaxIntrinsicHeight(constraints); |
| 411 } | 466 } |
| 412 | 467 |
| 413 double getDistanceToActualBaseline(TextBaseline baseline) { | 468 double computeDistanceToActualBaseline(TextBaseline baseline) { |
| 414 if (child != null) | 469 if (child != null) |
| 415 return child.getDistanceToActualBaseline(baseline); | 470 return child.getDistanceToActualBaseline(baseline); |
| 416 return super.getDistanceToActualBaseline(baseline); | 471 return super.computeDistanceToActualBaseline(baseline); |
| 417 } | 472 } |
| 418 | 473 |
| 419 void performLayout() { | 474 void performLayout() { |
| 420 if (child != null) { | 475 if (child != null) { |
| 421 child.layout(constraints, parentUsesSize: true); | 476 child.layout(constraints, parentUsesSize: true); |
| 422 size = child.size; | 477 size = child.size; |
| 423 } else { | 478 } else { |
| 424 performResize(); | 479 performResize(); |
| 425 } | 480 } |
| 426 } | 481 } |
| (...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 487 size = child.size; | 542 size = child.size; |
| 488 } else { | 543 } else { |
| 489 size = _additionalConstraints.apply(constraints).constrain(Size.zero); | 544 size = _additionalConstraints.apply(constraints).constrain(Size.zero); |
| 490 } | 545 } |
| 491 } | 546 } |
| 492 | 547 |
| 493 String debugDescribeSettings(String prefix) => '${super.debugDescribeSettings(
prefix)}${prefix}additionalConstraints: ${additionalConstraints}\n'; | 548 String debugDescribeSettings(String prefix) => '${super.debugDescribeSettings(
prefix)}${prefix}additionalConstraints: ${additionalConstraints}\n'; |
| 494 } | 549 } |
| 495 | 550 |
| 496 class RenderShrinkWrapWidth extends RenderProxyBox { | 551 class RenderShrinkWrapWidth extends RenderProxyBox { |
| 552 |
| 553 // This class will attempt to size its child to the child's maximum |
| 554 // intrinsic width, snapped to a multiple of the stepWidth, if one |
| 555 // is provided, and given the provided constraints; and will then |
| 556 // adopt the child's resulting dimensions. |
| 557 |
| 558 // Note: laying out this class is relatively expensive. Avoid using |
| 559 // it where possible. |
| 560 |
| 497 RenderShrinkWrapWidth({ | 561 RenderShrinkWrapWidth({ |
| 498 double stepWidth, | 562 double stepWidth, |
| 499 double stepHeight, | 563 double stepHeight, |
| 500 RenderBox child | 564 RenderBox child |
| 501 }) : _stepWidth = stepWidth, _stepHeight = stepHeight, super(child); | 565 }) : _stepWidth = stepWidth, _stepHeight = stepHeight, super(child); |
| 502 | 566 |
| 503 double _stepWidth; | 567 double _stepWidth; |
| 504 double get stepWidth => _stepWidth; | 568 double get stepWidth => _stepWidth; |
| 505 void set stepWidth(double value) { | 569 void set stepWidth(double value) { |
| 506 if (value == _stepWidth) | 570 if (value == _stepWidth) |
| (...skipping 11 matching lines...) Expand all Loading... |
| 518 markNeedsLayout(); | 582 markNeedsLayout(); |
| 519 } | 583 } |
| 520 | 584 |
| 521 static double applyStep(double input, double step) { | 585 static double applyStep(double input, double step) { |
| 522 if (step == null) | 586 if (step == null) |
| 523 return input; | 587 return input; |
| 524 return (input / step).ceil() * step; | 588 return (input / step).ceil() * step; |
| 525 } | 589 } |
| 526 | 590 |
| 527 BoxConstraints _getInnerConstraints(BoxConstraints constraints) { | 591 BoxConstraints _getInnerConstraints(BoxConstraints constraints) { |
| 592 if (constraints.hasTightWidth) |
| 593 return constraints; |
| 528 double width = child.getMaxIntrinsicWidth(constraints); | 594 double width = child.getMaxIntrinsicWidth(constraints); |
| 529 assert(width == constraints.constrainWidth(width)); | 595 assert(width == constraints.constrainWidth(width)); |
| 530 return constraints.applyWidth(width); | 596 return constraints.applyWidth(applyStep(width, _stepWidth)); |
| 531 } | 597 } |
| 532 | 598 |
| 533 double getMinIntrinsicWidth(BoxConstraints constraints) { | 599 double getMinIntrinsicWidth(BoxConstraints constraints) { |
| 534 if (child == null) | 600 return getMaxIntrinsicWidth(constraints); |
| 535 return constraints.constrainWidth(0.0); | |
| 536 double childResult = child.getMinIntrinsicWidth(constraints); | |
| 537 return constraints.constrainWidth(applyStep(childResult, _stepWidth)); | |
| 538 } | 601 } |
| 539 | 602 |
| 540 double getMaxIntrinsicWidth(BoxConstraints constraints) { | 603 double getMaxIntrinsicWidth(BoxConstraints constraints) { |
| 541 if (child == null) | 604 if (child == null) |
| 542 return constraints.constrainWidth(0.0); | 605 return constraints.constrainWidth(0.0); |
| 543 double childResult = child.getMaxIntrinsicWidth(constraints); | 606 double childResult = child.getMaxIntrinsicWidth(constraints); |
| 544 return constraints.constrainWidth(applyStep(childResult, _stepWidth)); | 607 return constraints.constrainWidth(applyStep(childResult, _stepWidth)); |
| 545 } | 608 } |
| 546 | 609 |
| 547 double getMinIntrinsicHeight(BoxConstraints constraints) { | 610 double getMinIntrinsicHeight(BoxConstraints constraints) { |
| 548 if (child == null) | 611 if (child == null) |
| 549 return constraints.constrainWidth(0.0); | 612 return constraints.constrainWidth(0.0); |
| 550 double childResult = child.getMinIntrinsicHeight(_getInnerConstraints(constr
aints)); | 613 double childResult = child.getMinIntrinsicHeight(_getInnerConstraints(constr
aints)); |
| 551 return constraints.constrainHeight(applyStep(childResult, _stepHeight)); | 614 return constraints.constrainHeight(applyStep(childResult, _stepHeight)); |
| 552 } | 615 } |
| 553 | 616 |
| 554 double getMaxIntrinsicHeight(BoxConstraints constraints) { | 617 double getMaxIntrinsicHeight(BoxConstraints constraints) { |
| 555 if (child == null) | 618 if (child == null) |
| 556 return constraints.constrainWidth(0.0); | 619 return constraints.constrainWidth(0.0); |
| 557 double childResult = child.getMaxIntrinsicHeight(_getInnerConstraints(constr
aints)); | 620 double childResult = child.getMaxIntrinsicHeight(_getInnerConstraints(constr
aints)); |
| 558 return constraints.constrainHeight(applyStep(childResult, _stepHeight)); | 621 return constraints.constrainHeight(applyStep(childResult, _stepHeight)); |
| 559 } | 622 } |
| 560 | 623 |
| 561 void performLayout() { | 624 void performLayout() { |
| 562 if (child != null) { | 625 if (child != null) { |
| 563 child.layout(_getInnerConstraints(constraints), parentUsesSize: true); | 626 BoxConstraints childConstraints = _getInnerConstraints(constraints); |
| 564 size = new Size(applyStep(child.size.width, _stepWidth), applyStep(child.s
ize.height, _stepHeight)); | 627 if (_stepHeight != null) |
| 628 childConstraints.applyHeight(getMaxIntrinsicHeight(childConstraints)); |
| 629 child.layout(childConstraints, parentUsesSize: true); |
| 630 size = child.size; |
| 565 } else { | 631 } else { |
| 566 performResize(); | 632 performResize(); |
| 567 } | 633 } |
| 568 } | 634 } |
| 635 |
| 636 String debugDescribeSettings(String prefix) => '${super.debugDescribeSettings(
prefix)}${prefix}stepWidth: ${stepWidth}\n${prefix}stepHeight: ${stepHeight}\n'; |
| 637 |
| 569 } | 638 } |
| 570 | 639 |
| 571 class RenderOpacity extends RenderProxyBox { | 640 class RenderOpacity extends RenderProxyBox { |
| 572 RenderOpacity({ RenderBox child, double opacity }) | 641 RenderOpacity({ RenderBox child, double opacity }) |
| 573 : this._opacity = opacity, super(child) { | 642 : this._opacity = opacity, super(child) { |
| 574 assert(opacity >= 0.0 && opacity <= 1.0); | 643 assert(opacity >= 0.0 && opacity <= 1.0); |
| 575 } | 644 } |
| 576 | 645 |
| 577 double _opacity; | 646 double _opacity; |
| 578 double get opacity => _opacity; | 647 double get opacity => _opacity; |
| (...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 712 } | 781 } |
| 713 | 782 |
| 714 abstract class RenderShiftedBox extends RenderBox with RenderObjectWithChildMixi
n<RenderBox> { | 783 abstract class RenderShiftedBox extends RenderBox with RenderObjectWithChildMixi
n<RenderBox> { |
| 715 | 784 |
| 716 // Abstract class for one-child-layout render boxes | 785 // Abstract class for one-child-layout render boxes |
| 717 | 786 |
| 718 RenderShiftedBox(RenderBox child) { | 787 RenderShiftedBox(RenderBox child) { |
| 719 this.child = child; | 788 this.child = child; |
| 720 } | 789 } |
| 721 | 790 |
| 722 void paint(PaintingCanvas canvas, Offset offset) { | 791 double getMinIntrinsicWidth(BoxConstraints constraints) { |
| 723 if (child != null) | 792 if (child != null) |
| 724 canvas.paintChild(child, child.parentData.position + offset); | 793 return child.getMinIntrinsicWidth(constraints); |
| 794 return super.getMinIntrinsicWidth(constraints); |
| 725 } | 795 } |
| 726 | 796 |
| 727 double getDistanceToActualBaseline(TextBaseline baseline) { | 797 double getMaxIntrinsicWidth(BoxConstraints constraints) { |
| 798 if (child != null) |
| 799 return child.getMaxIntrinsicWidth(constraints); |
| 800 return super.getMaxIntrinsicWidth(constraints); |
| 801 } |
| 802 |
| 803 double getMinIntrinsicHeight(BoxConstraints constraints) { |
| 804 if (child != null) |
| 805 return child.getMinIntrinsicHeight(constraints); |
| 806 return super.getMinIntrinsicHeight(constraints); |
| 807 } |
| 808 |
| 809 double getMaxIntrinsicHeight(BoxConstraints constraints) { |
| 810 if (child != null) |
| 811 return child.getMaxIntrinsicHeight(constraints); |
| 812 return super.getMaxIntrinsicHeight(constraints); |
| 813 } |
| 814 |
| 815 double computeDistanceToActualBaseline(TextBaseline baseline) { |
| 728 double result; | 816 double result; |
| 729 if (child != null) { | 817 if (child != null) { |
| 730 assert(!needsLayout); | 818 assert(!needsLayout); |
| 731 result = child.getDistanceToActualBaseline(baseline); | 819 result = child.getDistanceToActualBaseline(baseline); |
| 732 assert(child.parentData is BoxParentData); | 820 assert(child.parentData is BoxParentData); |
| 733 if (result != null) | 821 if (result != null) |
| 734 result += child.parentData.position.y; | 822 result += child.parentData.position.y; |
| 735 } else { | 823 } else { |
| 736 result = super.getDistanceToActualBaseline(baseline); | 824 result = super.computeDistanceToActualBaseline(baseline); |
| 737 } | 825 } |
| 738 return result; | 826 return result; |
| 739 } | 827 } |
| 740 | 828 |
| 829 void paint(PaintingCanvas canvas, Offset offset) { |
| 830 if (child != null) |
| 831 canvas.paintChild(child, child.parentData.position + offset); |
| 832 } |
| 833 |
| 741 void hitTestChildren(HitTestResult result, { Point position }) { | 834 void hitTestChildren(HitTestResult result, { Point position }) { |
| 742 if (child != null) { | 835 if (child != null) { |
| 743 assert(child.parentData is BoxParentData); | 836 assert(child.parentData is BoxParentData); |
| 744 Rect childBounds = child.parentData.position & child.size; | 837 Rect childBounds = child.parentData.position & child.size; |
| 745 if (childBounds.contains(position)) { | 838 if (childBounds.contains(position)) { |
| 746 child.hitTest(result, position: new Point(position.x - child.parentData.
position.x, | 839 child.hitTest(result, position: new Point(position.x - child.parentData.
position.x, |
| 747 position.y - child.parentD
ata.position.y)); | 840 position.y - child.parentD
ata.position.y)); |
| 748 } | 841 } |
| 749 } | 842 } |
| 750 } | 843 } |
| (...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 813 padding.left + child.size.width + padding.right, | 906 padding.left + child.size.width + padding.right, |
| 814 padding.top + child.size.height + padding.bottom | 907 padding.top + child.size.height + padding.bottom |
| 815 )); | 908 )); |
| 816 } | 909 } |
| 817 | 910 |
| 818 String debugDescribeSettings(String prefix) => '${super.debugDescribeSettings(
prefix)}${prefix}padding: ${padding}\n'; | 911 String debugDescribeSettings(String prefix) => '${super.debugDescribeSettings(
prefix)}${prefix}padding: ${padding}\n'; |
| 819 } | 912 } |
| 820 | 913 |
| 821 class RenderPositionedBox extends RenderShiftedBox { | 914 class RenderPositionedBox extends RenderShiftedBox { |
| 822 | 915 |
| 916 // This box aligns a child box within itself. It's only useful for |
| 917 // children that don't always size to fit their parent. For example, |
| 918 // to align a box at the bottom right, you would pass this box a |
| 919 // tight constraint that is bigger than the child's natural size, |
| 920 // with horizontal and vertical set to 1.0. |
| 921 |
| 823 RenderPositionedBox({ | 922 RenderPositionedBox({ |
| 824 RenderBox child, | 923 RenderBox child, |
| 825 double horizontal: 0.5, | 924 double horizontal: 0.5, |
| 826 double vertical: 0.5 | 925 double vertical: 0.5 |
| 827 }) : _horizontal = horizontal, | 926 }) : _horizontal = horizontal, |
| 828 _vertical = vertical, | 927 _vertical = vertical, |
| 829 super(child) { | 928 super(child) { |
| 830 assert(horizontal != null); | 929 assert(horizontal != null); |
| 831 assert(vertical != null); | 930 assert(vertical != null); |
| 832 } | 931 } |
| (...skipping 11 matching lines...) Expand all Loading... |
| 844 double _vertical; | 943 double _vertical; |
| 845 double get vertical => _vertical; | 944 double get vertical => _vertical; |
| 846 void set vertical (double value) { | 945 void set vertical (double value) { |
| 847 assert(value != null); | 946 assert(value != null); |
| 848 if (_vertical == value) | 947 if (_vertical == value) |
| 849 return; | 948 return; |
| 850 _vertical = value; | 949 _vertical = value; |
| 851 markNeedsLayout(); | 950 markNeedsLayout(); |
| 852 } | 951 } |
| 853 | 952 |
| 854 double getMinIntrinsicWidth(BoxConstraints constraints) { | 953 void performLayout() { |
| 855 if (child != null) | 954 if (child != null) { |
| 856 return child.getMinIntrinsicWidth(constraints); | 955 child.layout(constraints.loosen(), parentUsesSize: true); |
| 857 return super.getMinIntrinsicWidth(constraints); | 956 size = constraints.constrain(child.size); |
| 957 assert(child.parentData is BoxParentData); |
| 958 Offset delta = size - child.size; |
| 959 child.parentData.position = (delta.scale(horizontal, vertical)).toPoint(); |
| 960 } else { |
| 961 performResize(); |
| 962 } |
| 858 } | 963 } |
| 859 | 964 |
| 860 double getMaxIntrinsicWidth(BoxConstraints constraints) { | 965 String debugDescribeSettings(String prefix) => '${super.debugDescribeSettings(
prefix)}${prefix}horizontal: ${horizontal}\n${prefix}vertical: ${vertical}\n'; |
| 861 if (child != null) | 966 } |
| 862 return child.getMaxIntrinsicWidth(constraints); | 967 |
| 863 return super.getMaxIntrinsicWidth(constraints); | 968 class RenderBaseline extends RenderShiftedBox { |
| 969 |
| 970 RenderBaseline({ |
| 971 RenderBox child, |
| 972 double baseline, |
| 973 TextBaseline baselineType |
| 974 }) : _baseline = baseline, |
| 975 _baselineType = baselineType, |
| 976 super(child) { |
| 977 assert(baseline != null); |
| 978 assert(baselineType != null); |
| 864 } | 979 } |
| 865 | 980 |
| 866 double getMinIntrinsicHeight(BoxConstraints constraints) { | 981 double _baseline; |
| 867 if (child != null) | 982 double get baseline => _baseline; |
| 868 return child.getMinIntrinsicHeight(constraints); | 983 void set baseline (double value) { |
| 869 return super.getMinIntrinsicHeight(constraints); | 984 assert(value != null); |
| 985 if (_baseline == value) |
| 986 return; |
| 987 _baseline = value; |
| 988 markNeedsLayout(); |
| 870 } | 989 } |
| 871 | 990 |
| 872 double getMaxIntrinsicHeight(BoxConstraints constraints) { | 991 TextBaseline _baselineType; |
| 873 if (child != null) | 992 TextBaseline get baselineType => _baselineType; |
| 874 return child.getMaxIntrinsicHeight(constraints); | 993 void set baselineType (TextBaseline value) { |
| 875 return super.getMaxIntrinsicHeight(constraints); | 994 assert(value != null); |
| 995 if (_baselineType == value) |
| 996 return; |
| 997 _baselineType = value; |
| 998 markNeedsLayout(); |
| 876 } | 999 } |
| 877 | 1000 |
| 878 void performLayout() { | 1001 void performLayout() { |
| 879 if (child != null) { | 1002 if (child != null) { |
| 880 child.layout(constraints.loosen(), parentUsesSize: true); | 1003 child.layout(constraints.loosen(), parentUsesSize: true); |
| 881 size = constraints.constrain(child.size); | 1004 size = constraints.constrain(child.size); |
| 882 assert(child.parentData is BoxParentData); | 1005 assert(child.parentData is BoxParentData); |
| 883 Offset delta = size - child.size; | 1006 double delta = baseline - child.getDistanceToBaseline(baselineType); |
| 884 child.parentData.position = (delta.scale(horizontal, vertical)).toPoint(); | 1007 child.parentData.position = new Point(0.0, delta); |
| 885 } else { | 1008 } else { |
| 886 performResize(); | 1009 performResize(); |
| 887 } | 1010 } |
| 888 } | 1011 } |
| 889 | 1012 |
| 890 String debugDescribeSettings(String prefix) => '${super.debugDescribeSettings(
prefix)}${prefix}horizontal: ${horizontal}\n${prefix}vertical: ${vertical}\n'; | 1013 String debugDescribeSettings(String prefix) => '${super.debugDescribeSettings(
prefix)}${prefix}baseline: ${baseline}\nbaselineType: ${baselineType}'; |
| 891 } | 1014 } |
| 892 | 1015 |
| 893 class RenderImage extends RenderBox { | 1016 class RenderImage extends RenderBox { |
| 894 | 1017 |
| 895 RenderImage(String url, Size dimensions) { | 1018 RenderImage(String url, Size dimensions) { |
| 896 requestedSize = dimensions; | 1019 requestedSize = dimensions; |
| 897 src = url; | 1020 src = url; |
| 898 } | 1021 } |
| 899 | 1022 |
| 900 sky.Image _image; | 1023 sky.Image _image; |
| (...skipping 347 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1248 } | 1371 } |
| 1249 | 1372 |
| 1250 } | 1373 } |
| 1251 | 1374 |
| 1252 // HELPER METHODS FOR RENDERBOX CONTAINERS | 1375 // HELPER METHODS FOR RENDERBOX CONTAINERS |
| 1253 abstract class RenderBoxContainerDefaultsMixin<ChildType extends RenderBox, Pare
ntDataType extends ContainerParentDataMixin<ChildType>> implements ContainerRend
erObjectMixin<ChildType, ParentDataType> { | 1376 abstract class RenderBoxContainerDefaultsMixin<ChildType extends RenderBox, Pare
ntDataType extends ContainerParentDataMixin<ChildType>> implements ContainerRend
erObjectMixin<ChildType, ParentDataType> { |
| 1254 | 1377 |
| 1255 // This class, by convention, doesn't override any members of the superclass. | 1378 // This class, by convention, doesn't override any members of the superclass. |
| 1256 // It only provides helper functions that subclasses can call. | 1379 // It only provides helper functions that subclasses can call. |
| 1257 | 1380 |
| 1258 double defaultGetDistanceToFirstActualBaseline(TextBaseline baseline) { | 1381 double defaultComputeDistanceToFirstActualBaseline(TextBaseline baseline) { |
| 1259 assert(!needsLayout); | 1382 assert(!needsLayout); |
| 1260 RenderBox child = firstChild; | 1383 RenderBox child = firstChild; |
| 1261 while (child != null) { | 1384 while (child != null) { |
| 1262 assert(child.parentData is ParentDataType); | 1385 assert(child.parentData is ParentDataType); |
| 1263 double result = child.getDistanceToActualBaseline(baseline); | 1386 double result = child.getDistanceToActualBaseline(baseline); |
| 1264 if (result != null) | 1387 if (result != null) |
| 1265 return result + child.parentData.position.y; | 1388 return result + child.parentData.position.y; |
| 1266 child = child.parentData.nextSibling; | 1389 child = child.parentData.nextSibling; |
| 1267 } | 1390 } |
| 1268 return null; | 1391 return null; |
| 1269 } | 1392 } |
| 1270 | 1393 |
| 1271 double defaultGetDistanceToHighestActualBaseline(TextBaseline baseline) { | 1394 double defaultComputeDistanceToHighestActualBaseline(TextBaseline baseline) { |
| 1272 assert(!needsLayout); | 1395 assert(!needsLayout); |
| 1273 double result; | 1396 double result; |
| 1274 RenderBox child = firstChild; | 1397 RenderBox child = firstChild; |
| 1275 while (child != null) { | 1398 while (child != null) { |
| 1276 assert(child.parentData is ParentDataType); | 1399 assert(child.parentData is ParentDataType); |
| 1277 double candidate = child.getDistanceToActualBaseline(baseline); | 1400 double candidate = child.getDistanceToActualBaseline(baseline); |
| 1278 if (candidate != null) { | 1401 if (candidate != null) { |
| 1279 candidate += child.parentData.position.x; | 1402 candidate += child.parentData.position.x; |
| 1280 if (result != null) | 1403 if (result != null) |
| 1281 result = math.min(result, candidate); | 1404 result = math.min(result, candidate); |
| (...skipping 22 matching lines...) Expand all Loading... |
| 1304 | 1427 |
| 1305 void defaultPaint(PaintingCanvas canvas, Offset offset) { | 1428 void defaultPaint(PaintingCanvas canvas, Offset offset) { |
| 1306 RenderBox child = firstChild; | 1429 RenderBox child = firstChild; |
| 1307 while (child != null) { | 1430 while (child != null) { |
| 1308 assert(child.parentData is ParentDataType); | 1431 assert(child.parentData is ParentDataType); |
| 1309 canvas.paintChild(child, child.parentData.position + offset); | 1432 canvas.paintChild(child, child.parentData.position + offset); |
| 1310 child = child.parentData.nextSibling; | 1433 child = child.parentData.nextSibling; |
| 1311 } | 1434 } |
| 1312 } | 1435 } |
| 1313 } | 1436 } |
| OLD | NEW |