Chromium Code Reviews| 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 |
| 295 Map<TextBaseline, double> _cachedBaselines; | |
| 296 RenderObject _baselineSubtreeRoot; | |
| 297 // getDistanceToBaseline() returns the distance from the | |
| 295 // y-coordinate of the position of the box to the y-coordinate of | 298 // 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 | 299 // the first given baseline in the box's contents. This is used by |
| 297 // certain layout models to align adjacent boxes on a common | 300 // certain layout models to align adjacent boxes on a common |
| 298 // baseline, regardless of padding, font size differences, etc. If | 301 // baseline, regardless of padding, font size differences, etc. If |
| 299 // there is no baseline, then it should return the distance from the | 302 // 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 | 303 // 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. | 304 // the bottom of the box, i.e., the height of the box. Only call |
| 302 // Only call this after layout has been performed. | 305 // this after layout has been performed. You are only allowed to |
| 306 // call this from the parent of this node, and only during | |
| 307 // performLayout(). | |
| 303 double getDistanceToBaseline(TextBaseline baseline) { | 308 double getDistanceToBaseline(TextBaseline baseline) { |
| 304 assert(!needsLayout); | 309 RenderObject client = parent; |
| 305 double result = getDistanceToActualBaseline(baseline); | 310 assert(client == RenderObject.debugActiveLayout); |
| 311 assert(client.debugDoingThisLayout); | |
| 312 if (_baselineSubtreeRoot != null) { | |
| 313 client = _baselineSubtreeRoot; | |
| 314 assert(client is! RenderBox || (client as RenderBox)._baselineSubtreeRoot == null); // TODO(ianh): Remove cast once the analyzer is cleverer | |
| 315 } else { | |
| 316 if (client is RenderBox && client._baselineSubtreeRoot != null) | |
| 317 client = (client as RenderBox)._baselineSubtreeRoot; // TODO(ianh): Remo ve cast once the analyzer is cleverer | |
| 318 } | |
| 319 double result = getDistanceToActualBaseline(baseline, client); | |
| 306 if (result == null) | 320 if (result == null) |
| 307 return size.height; | 321 return size.height; |
| 308 return result; | 322 return result; |
| 309 } | 323 } |
| 310 // getDistanceToActualBaseline() should return the distance from the | 324 // getDistanceToActualBaseline() must only be called from |
| 311 // y-coordinate of the position of the box to the y-coordinate of | 325 // getDistanceToBaseline() and computeDistanceToActualBaseline(). |
| 312 // the first given baseline in the box's contents, if any, or null | 326 // Do not call it directly from outside those two methods. |
| 313 // otherwise. | 327 double getDistanceToActualBaseline(TextBaseline baseline, RenderObject client) { |
| 314 double getDistanceToActualBaseline(TextBaseline baseline) { | |
| 315 assert(!needsLayout); | 328 assert(!needsLayout); |
| 329 assert(client != this); | |
| 330 _baselineSubtreeRoot = client; | |
| 331 if (_cachedBaselines == null) | |
| 332 _cachedBaselines = new Map<TextBaseline, double>(); | |
| 333 if (!_cachedBaselines.containsKey(baseline)) | |
| 334 _cachedBaselines[baseline] = computeDistanceToActualBaseline(baseline, cli ent); | |
|
abarth-chromium
2015/07/01 17:29:53
_cachedBaselines.putIfAbsent(...)
| |
| 335 return _cachedBaselines[baseline]; | |
| 336 } | |
| 337 // computeDistanceToActualBaseline() should return the distance from | |
| 338 // the y-coordinate of the position of the box to the y-coordinate | |
| 339 // of the first given baseline in the box's contents, if any, or | |
| 340 // null otherwise. This is the method that you should override in | |
| 341 // subclasses. If you defer to a child, you should call the child's | |
| 342 // getDistanceToActualBaseline(), passing it the same client. This | |
| 343 // method should not be called directly. Use getDistanceToBaseline() | |
| 344 // if you need to know the baseline of a child from performLayout(). | |
| 345 // If you need the baseline during paint, cache it during | |
| 346 // performLayout(). Use getDistanceToActualBaseline() if you are | |
| 347 // implementing computeDistanceToActualBaseline() and need to defer | |
| 348 // to a child. | |
| 349 double computeDistanceToActualBaseline(TextBaseline baseline, RenderObject cli ent) { | |
| 316 return null; | 350 return null; |
| 317 } | 351 } |
| 318 | 352 |
| 319 BoxConstraints get constraints => super.constraints; | 353 BoxConstraints get constraints => super.constraints; |
| 320 bool debugDoesMeetConstraints() { | 354 bool debugDoesMeetConstraints() { |
| 321 assert(constraints != null); | 355 assert(constraints != null); |
| 322 assert(_size != null); | 356 assert(_size != null); |
| 323 assert(!_size.isInfinite); | 357 assert(!_size.isInfinite); |
| 324 bool result = constraints.contains(_size); | 358 bool result = constraints.contains(_size); |
| 325 if (!result) | 359 if (!result) |
| 326 print("${this.runtimeType} does not meet its constraints. Constraints: $co nstraints, size: $_size"); | 360 print("${this.runtimeType} does not meet its constraints. Constraints: $co nstraints, size: $_size"); |
| 327 return result; | 361 return result; |
| 328 } | 362 } |
| 363 | |
| 364 void cleanParentDependencies() { | |
| 365 _baselineSubtreeRoot = null; | |
| 366 if (_cachedBaselines != null) | |
| 367 _cachedBaselines.clear(); | |
| 368 super.cleanParentDependencies(); | |
| 369 } | |
| 370 bool debugAncestorsAlreadyClearedBaselineCache() { | |
| 371 if (_baselineSubtreeRoot == null) | |
| 372 return true; // we haven't yet been asked for a baseline even once, so the re's nothing for us to do | |
| 373 RenderBox node = this; | |
| 374 while (node != _baselineSubtreeRoot) { | |
| 375 assert(node._baselineSubtreeRoot == _baselineSubtreeRoot); | |
| 376 if (node._cachedBaselines != null && node._cachedBaselines.isNotEmpty) | |
| 377 return false; | |
| 378 assert(node.parent != null); | |
| 379 if (node is! RenderBox) { | |
| 380 assert(node is RenderObject); | |
| 381 break; | |
| 382 } | |
| 383 node = node.parent as RenderBox; | |
| 384 } | |
| 385 if (node is RenderBox) { | |
| 386 assert(node._baselineSubtreeRoot == null); | |
| 387 if (node._cachedBaselines != null && node._cachedBaselines.isNotEmpty) | |
| 388 return false; | |
| 389 } | |
| 390 return true; | |
| 391 } | |
| 392 void markNeedsLayout() { | |
| 393 assert(!RenderObject.debugDoingLayout); | |
| 394 assert(!RenderObject.debugDoingPaint); | |
| 395 if (_cachedBaselines != null && _cachedBaselines.isNotEmpty) { | |
| 396 _cachedBaselines.clear(); | |
| 397 if (_baselineSubtreeRoot != null) { | |
| 398 assert(_baselineSubtreeRoot != this); | |
| 399 final parent = this.parent; // TODO(ianh): Remove this once the analyzer is cleverer | |
| 400 assert(parent is RenderObject); | |
| 401 parent.markNeedsLayout(); | |
| 402 assert(parent == this.parent); // TODO(ianh): Remove this once the analy zer is cleverer | |
| 403 } | |
| 404 } else { | |
| 405 assert(debugAncestorsAlreadyClearedBaselineCache()); | |
| 406 } | |
| 407 super.markNeedsLayout(); | |
| 408 } | |
| 329 void performResize() { | 409 void performResize() { |
| 330 // default behaviour for subclasses that have sizedByParent = true | 410 // default behaviour for subclasses that have sizedByParent = true |
| 331 size = constraints.constrain(Size.zero); | 411 size = constraints.constrain(Size.zero); |
| 332 assert(!size.isInfinite); | 412 assert(!size.isInfinite); |
| 333 } | 413 } |
| 334 void performLayout() { | 414 void performLayout() { |
| 335 // descendants have to either override performLayout() to set both | 415 // descendants have to either override performLayout() to set both |
| 336 // width and height and lay out children, or, set sizedByParent to | 416 // width and height and lay out children, or, set sizedByParent to |
| 337 // true so that performResize()'s logic above does its thing. | 417 // true so that performResize()'s logic above does its thing. |
| 338 assert(sizedByParent); | 418 assert(sizedByParent); |
| (...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 403 return child.getMinIntrinsicHeight(constraints); | 483 return child.getMinIntrinsicHeight(constraints); |
| 404 return super.getMinIntrinsicHeight(constraints); | 484 return super.getMinIntrinsicHeight(constraints); |
| 405 } | 485 } |
| 406 | 486 |
| 407 double getMaxIntrinsicHeight(BoxConstraints constraints) { | 487 double getMaxIntrinsicHeight(BoxConstraints constraints) { |
| 408 if (child != null) | 488 if (child != null) |
| 409 return child.getMaxIntrinsicHeight(constraints); | 489 return child.getMaxIntrinsicHeight(constraints); |
| 410 return super.getMaxIntrinsicHeight(constraints); | 490 return super.getMaxIntrinsicHeight(constraints); |
| 411 } | 491 } |
| 412 | 492 |
| 413 double getDistanceToActualBaseline(TextBaseline baseline) { | 493 double computeDistanceToActualBaseline(TextBaseline baseline, RenderObject cli ent) { |
| 414 if (child != null) | 494 if (child != null) |
| 415 return child.getDistanceToActualBaseline(baseline); | 495 return child.getDistanceToActualBaseline(baseline, client); |
| 416 return super.getDistanceToActualBaseline(baseline); | 496 return super.computeDistanceToActualBaseline(baseline, client); |
| 417 } | 497 } |
| 418 | 498 |
| 419 void performLayout() { | 499 void performLayout() { |
| 420 if (child != null) { | 500 if (child != null) { |
| 421 child.layout(constraints, parentUsesSize: true); | 501 child.layout(constraints, parentUsesSize: true); |
| 422 size = child.size; | 502 size = child.size; |
| 423 } else { | 503 } else { |
| 424 performResize(); | 504 performResize(); |
| 425 } | 505 } |
| 426 } | 506 } |
| (...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 487 size = child.size; | 567 size = child.size; |
| 488 } else { | 568 } else { |
| 489 size = _additionalConstraints.apply(constraints).constrain(Size.zero); | 569 size = _additionalConstraints.apply(constraints).constrain(Size.zero); |
| 490 } | 570 } |
| 491 } | 571 } |
| 492 | 572 |
| 493 String debugDescribeSettings(String prefix) => '${super.debugDescribeSettings( prefix)}${prefix}additionalConstraints: ${additionalConstraints}\n'; | 573 String debugDescribeSettings(String prefix) => '${super.debugDescribeSettings( prefix)}${prefix}additionalConstraints: ${additionalConstraints}\n'; |
| 494 } | 574 } |
| 495 | 575 |
| 496 class RenderShrinkWrapWidth extends RenderProxyBox { | 576 class RenderShrinkWrapWidth extends RenderProxyBox { |
| 577 | |
| 578 // This class will attempt to size its child to the child's maximum | |
| 579 // intrinsic width, snapped to a multiple of the stepWidth, if one | |
| 580 // is provided, and given the provided constraints; and will then | |
| 581 // adopt the child's resulting dimensions. | |
| 582 | |
| 583 // Note: laying out this class is relatively expensive. Avoid using | |
| 584 // it where possible. | |
| 585 | |
| 497 RenderShrinkWrapWidth({ | 586 RenderShrinkWrapWidth({ |
| 498 double stepWidth, | 587 double stepWidth, |
| 499 double stepHeight, | 588 double stepHeight, |
| 500 RenderBox child | 589 RenderBox child |
| 501 }) : _stepWidth = stepWidth, _stepHeight = stepHeight, super(child); | 590 }) : _stepWidth = stepWidth, _stepHeight = stepHeight, super(child); |
| 502 | 591 |
| 503 double _stepWidth; | 592 double _stepWidth; |
| 504 double get stepWidth => _stepWidth; | 593 double get stepWidth => _stepWidth; |
| 505 void set stepWidth(double value) { | 594 void set stepWidth(double value) { |
| 506 if (value == _stepWidth) | 595 if (value == _stepWidth) |
| (...skipping 11 matching lines...) Expand all Loading... | |
| 518 markNeedsLayout(); | 607 markNeedsLayout(); |
| 519 } | 608 } |
| 520 | 609 |
| 521 static double applyStep(double input, double step) { | 610 static double applyStep(double input, double step) { |
| 522 if (step == null) | 611 if (step == null) |
| 523 return input; | 612 return input; |
| 524 return (input / step).ceil() * step; | 613 return (input / step).ceil() * step; |
| 525 } | 614 } |
| 526 | 615 |
| 527 BoxConstraints _getInnerConstraints(BoxConstraints constraints) { | 616 BoxConstraints _getInnerConstraints(BoxConstraints constraints) { |
| 617 if (constraints.hasTightWidth) | |
| 618 return constraints; | |
| 528 double width = child.getMaxIntrinsicWidth(constraints); | 619 double width = child.getMaxIntrinsicWidth(constraints); |
| 529 assert(width == constraints.constrainWidth(width)); | 620 assert(width == constraints.constrainWidth(width)); |
| 530 return constraints.applyWidth(width); | 621 return constraints.applyWidth(applyStep(width, _stepWidth)); |
| 531 } | 622 } |
| 532 | 623 |
| 533 double getMinIntrinsicWidth(BoxConstraints constraints) { | 624 double getMinIntrinsicWidth(BoxConstraints constraints) { |
| 534 if (child == null) | 625 return getMaxIntrinsicWidth(constraints); |
| 535 return constraints.constrainWidth(0.0); | |
| 536 double childResult = child.getMinIntrinsicWidth(constraints); | |
| 537 return constraints.constrainWidth(applyStep(childResult, _stepWidth)); | |
| 538 } | 626 } |
| 539 | 627 |
| 540 double getMaxIntrinsicWidth(BoxConstraints constraints) { | 628 double getMaxIntrinsicWidth(BoxConstraints constraints) { |
| 541 if (child == null) | 629 if (child == null) |
| 542 return constraints.constrainWidth(0.0); | 630 return constraints.constrainWidth(0.0); |
| 543 double childResult = child.getMaxIntrinsicWidth(constraints); | 631 double childResult = child.getMaxIntrinsicWidth(constraints); |
| 544 return constraints.constrainWidth(applyStep(childResult, _stepWidth)); | 632 return constraints.constrainWidth(applyStep(childResult, _stepWidth)); |
| 545 } | 633 } |
| 546 | 634 |
| 547 double getMinIntrinsicHeight(BoxConstraints constraints) { | 635 double getMinIntrinsicHeight(BoxConstraints constraints) { |
| 548 if (child == null) | 636 if (child == null) |
| 549 return constraints.constrainWidth(0.0); | 637 return constraints.constrainWidth(0.0); |
| 550 double childResult = child.getMinIntrinsicHeight(_getInnerConstraints(constr aints)); | 638 double childResult = child.getMinIntrinsicHeight(_getInnerConstraints(constr aints)); |
| 551 return constraints.constrainHeight(applyStep(childResult, _stepHeight)); | 639 return constraints.constrainHeight(applyStep(childResult, _stepHeight)); |
| 552 } | 640 } |
| 553 | 641 |
| 554 double getMaxIntrinsicHeight(BoxConstraints constraints) { | 642 double getMaxIntrinsicHeight(BoxConstraints constraints) { |
| 555 if (child == null) | 643 if (child == null) |
| 556 return constraints.constrainWidth(0.0); | 644 return constraints.constrainWidth(0.0); |
| 557 double childResult = child.getMaxIntrinsicHeight(_getInnerConstraints(constr aints)); | 645 double childResult = child.getMaxIntrinsicHeight(_getInnerConstraints(constr aints)); |
| 558 return constraints.constrainHeight(applyStep(childResult, _stepHeight)); | 646 return constraints.constrainHeight(applyStep(childResult, _stepHeight)); |
| 559 } | 647 } |
| 560 | 648 |
| 561 void performLayout() { | 649 void performLayout() { |
| 562 if (child != null) { | 650 if (child != null) { |
| 563 child.layout(_getInnerConstraints(constraints), parentUsesSize: true); | 651 BoxConstraints childConstraints = _getInnerConstraints(constraints); |
| 564 size = new Size(applyStep(child.size.width, _stepWidth), applyStep(child.s ize.height, _stepHeight)); | 652 if (_stepHeight != null) |
| 653 childConstraints.applyHeight(getMaxIntrinsicHeight(childConstraints)); | |
| 654 child.layout(childConstraints, parentUsesSize: true); | |
| 655 size = child.size; | |
| 565 } else { | 656 } else { |
| 566 performResize(); | 657 performResize(); |
| 567 } | 658 } |
| 568 } | 659 } |
| 660 | |
| 661 String debugDescribeSettings(String prefix) => '${super.debugDescribeSettings( prefix)}${prefix}stepWidth: ${stepWidth}\n${prefix}stepHeight: ${stepHeight}\n'; | |
| 662 | |
| 569 } | 663 } |
| 570 | 664 |
| 571 class RenderOpacity extends RenderProxyBox { | 665 class RenderOpacity extends RenderProxyBox { |
| 572 RenderOpacity({ RenderBox child, double opacity }) | 666 RenderOpacity({ RenderBox child, double opacity }) |
| 573 : this._opacity = opacity, super(child) { | 667 : this._opacity = opacity, super(child) { |
| 574 assert(opacity >= 0.0 && opacity <= 1.0); | 668 assert(opacity >= 0.0 && opacity <= 1.0); |
| 575 } | 669 } |
| 576 | 670 |
| 577 double _opacity; | 671 double _opacity; |
| 578 double get opacity => _opacity; | 672 double get opacity => _opacity; |
| (...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 712 } | 806 } |
| 713 | 807 |
| 714 abstract class RenderShiftedBox extends RenderBox with RenderObjectWithChildMixi n<RenderBox> { | 808 abstract class RenderShiftedBox extends RenderBox with RenderObjectWithChildMixi n<RenderBox> { |
| 715 | 809 |
| 716 // Abstract class for one-child-layout render boxes | 810 // Abstract class for one-child-layout render boxes |
| 717 | 811 |
| 718 RenderShiftedBox(RenderBox child) { | 812 RenderShiftedBox(RenderBox child) { |
| 719 this.child = child; | 813 this.child = child; |
| 720 } | 814 } |
| 721 | 815 |
| 816 double getMinIntrinsicWidth(BoxConstraints constraints) { | |
| 817 if (child != null) | |
| 818 return child.getMinIntrinsicWidth(constraints); | |
| 819 return super.getMinIntrinsicWidth(constraints); | |
| 820 } | |
| 821 | |
| 822 double getMaxIntrinsicWidth(BoxConstraints constraints) { | |
| 823 if (child != null) | |
| 824 return child.getMaxIntrinsicWidth(constraints); | |
| 825 return super.getMaxIntrinsicWidth(constraints); | |
| 826 } | |
| 827 | |
| 828 double getMinIntrinsicHeight(BoxConstraints constraints) { | |
| 829 if (child != null) | |
| 830 return child.getMinIntrinsicHeight(constraints); | |
| 831 return super.getMinIntrinsicHeight(constraints); | |
| 832 } | |
| 833 | |
| 834 double getMaxIntrinsicHeight(BoxConstraints constraints) { | |
| 835 if (child != null) | |
| 836 return child.getMaxIntrinsicHeight(constraints); | |
| 837 return super.getMaxIntrinsicHeight(constraints); | |
| 838 } | |
| 839 | |
| 840 double computeDistanceToActualBaseline(TextBaseline baseline, RenderObject cli ent) { | |
| 841 double result; | |
| 842 if (child != null) { | |
| 843 assert(!needsLayout); | |
| 844 result = child.getDistanceToActualBaseline(baseline, client); | |
| 845 assert(child.parentData is BoxParentData); | |
| 846 if (result != null) | |
| 847 result += child.parentData.position.y; | |
| 848 } else { | |
| 849 result = super.computeDistanceToActualBaseline(baseline, client); | |
| 850 } | |
| 851 return result; | |
| 852 } | |
| 853 | |
| 722 void paint(PaintingCanvas canvas, Offset offset) { | 854 void paint(PaintingCanvas canvas, Offset offset) { |
| 723 if (child != null) | 855 if (child != null) |
| 724 canvas.paintChild(child, child.parentData.position + offset); | 856 canvas.paintChild(child, child.parentData.position + offset); |
| 725 } | 857 } |
| 726 | 858 |
| 727 double getDistanceToActualBaseline(TextBaseline baseline) { | |
| 728 double result; | |
| 729 if (child != null) { | |
| 730 assert(!needsLayout); | |
| 731 result = child.getDistanceToActualBaseline(baseline); | |
| 732 assert(child.parentData is BoxParentData); | |
| 733 if (result != null) | |
| 734 result += child.parentData.position.y; | |
| 735 } else { | |
| 736 result = super.getDistanceToActualBaseline(baseline); | |
| 737 } | |
| 738 return result; | |
| 739 } | |
| 740 | |
| 741 void hitTestChildren(HitTestResult result, { Point position }) { | 859 void hitTestChildren(HitTestResult result, { Point position }) { |
| 742 if (child != null) { | 860 if (child != null) { |
| 743 assert(child.parentData is BoxParentData); | 861 assert(child.parentData is BoxParentData); |
| 744 Rect childBounds = child.parentData.position & child.size; | 862 Rect childBounds = child.parentData.position & child.size; |
| 745 if (childBounds.contains(position)) { | 863 if (childBounds.contains(position)) { |
| 746 child.hitTest(result, position: new Point(position.x - child.parentData. position.x, | 864 child.hitTest(result, position: new Point(position.x - child.parentData. position.x, |
| 747 position.y - child.parentD ata.position.y)); | 865 position.y - child.parentD ata.position.y)); |
| 748 } | 866 } |
| 749 } | 867 } |
| 750 } | 868 } |
| (...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 813 padding.left + child.size.width + padding.right, | 931 padding.left + child.size.width + padding.right, |
| 814 padding.top + child.size.height + padding.bottom | 932 padding.top + child.size.height + padding.bottom |
| 815 )); | 933 )); |
| 816 } | 934 } |
| 817 | 935 |
| 818 String debugDescribeSettings(String prefix) => '${super.debugDescribeSettings( prefix)}${prefix}padding: ${padding}\n'; | 936 String debugDescribeSettings(String prefix) => '${super.debugDescribeSettings( prefix)}${prefix}padding: ${padding}\n'; |
| 819 } | 937 } |
| 820 | 938 |
| 821 class RenderPositionedBox extends RenderShiftedBox { | 939 class RenderPositionedBox extends RenderShiftedBox { |
| 822 | 940 |
| 941 // This box aligns a child box within itself. It's only useful for | |
| 942 // children that don't always size to fit their parent. For example, | |
| 943 // to align a box at the bottom right, you would pass this box a | |
| 944 // tight constraint that is bigger than the child's natural size, | |
| 945 // with horizontal and vertical set to 1.0. | |
| 946 | |
| 823 RenderPositionedBox({ | 947 RenderPositionedBox({ |
| 824 RenderBox child, | 948 RenderBox child, |
| 825 double horizontal: 0.5, | 949 double horizontal: 0.5, |
| 826 double vertical: 0.5 | 950 double vertical: 0.5 |
| 827 }) : _horizontal = horizontal, | 951 }) : _horizontal = horizontal, |
| 828 _vertical = vertical, | 952 _vertical = vertical, |
| 829 super(child) { | 953 super(child) { |
| 830 assert(horizontal != null); | 954 assert(horizontal != null); |
| 831 assert(vertical != null); | 955 assert(vertical != null); |
| 832 } | 956 } |
| (...skipping 11 matching lines...) Expand all Loading... | |
| 844 double _vertical; | 968 double _vertical; |
| 845 double get vertical => _vertical; | 969 double get vertical => _vertical; |
| 846 void set vertical (double value) { | 970 void set vertical (double value) { |
| 847 assert(value != null); | 971 assert(value != null); |
| 848 if (_vertical == value) | 972 if (_vertical == value) |
| 849 return; | 973 return; |
| 850 _vertical = value; | 974 _vertical = value; |
| 851 markNeedsLayout(); | 975 markNeedsLayout(); |
| 852 } | 976 } |
| 853 | 977 |
| 854 double getMinIntrinsicWidth(BoxConstraints constraints) { | 978 void performLayout() { |
| 855 if (child != null) | 979 if (child != null) { |
| 856 return child.getMinIntrinsicWidth(constraints); | 980 child.layout(constraints.loosen(), parentUsesSize: true); |
| 857 return super.getMinIntrinsicWidth(constraints); | 981 size = constraints.constrain(child.size); |
| 982 assert(child.parentData is BoxParentData); | |
| 983 Offset delta = size - child.size; | |
| 984 child.parentData.position = (delta.scale(horizontal, vertical)).toPoint(); | |
| 985 } else { | |
| 986 performResize(); | |
| 987 } | |
| 858 } | 988 } |
| 859 | 989 |
| 860 double getMaxIntrinsicWidth(BoxConstraints constraints) { | 990 String debugDescribeSettings(String prefix) => '${super.debugDescribeSettings( prefix)}${prefix}horizontal: ${horizontal}\n${prefix}vertical: ${vertical}\n'; |
| 861 if (child != null) | 991 } |
| 862 return child.getMaxIntrinsicWidth(constraints); | 992 |
| 863 return super.getMaxIntrinsicWidth(constraints); | 993 class RenderBaseline extends RenderShiftedBox { |
| 994 | |
| 995 RenderBaseline({ | |
| 996 RenderBox child, | |
| 997 double baseline, | |
| 998 TextBaseline baselineType | |
| 999 }) : _baseline = baseline, | |
| 1000 _baselineType = baselineType, | |
| 1001 super(child) { | |
| 1002 assert(baseline != null); | |
| 1003 assert(baselineType != null); | |
| 864 } | 1004 } |
| 865 | 1005 |
| 866 double getMinIntrinsicHeight(BoxConstraints constraints) { | 1006 double _baseline; |
| 867 if (child != null) | 1007 double get baseline => _baseline; |
| 868 return child.getMinIntrinsicHeight(constraints); | 1008 void set baseline (double value) { |
| 869 return super.getMinIntrinsicHeight(constraints); | 1009 assert(value != null); |
| 1010 if (_baseline == value) | |
| 1011 return; | |
| 1012 _baseline = value; | |
| 1013 markNeedsLayout(); | |
| 870 } | 1014 } |
| 871 | 1015 |
| 872 double getMaxIntrinsicHeight(BoxConstraints constraints) { | 1016 TextBaseline _baselineType; |
| 873 if (child != null) | 1017 TextBaseline get baselineType => _baselineType; |
| 874 return child.getMaxIntrinsicHeight(constraints); | 1018 void set baselineType (TextBaseline value) { |
| 875 return super.getMaxIntrinsicHeight(constraints); | 1019 assert(value != null); |
| 1020 if (_baselineType == value) | |
| 1021 return; | |
| 1022 _baselineType = value; | |
| 1023 markNeedsLayout(); | |
| 876 } | 1024 } |
| 877 | 1025 |
| 878 void performLayout() { | 1026 void performLayout() { |
| 879 if (child != null) { | 1027 if (child != null) { |
| 880 child.layout(constraints.loosen(), parentUsesSize: true); | 1028 child.layout(constraints.loosen(), parentUsesSize: true); |
| 881 size = constraints.constrain(child.size); | 1029 size = constraints.constrain(child.size); |
| 882 assert(child.parentData is BoxParentData); | 1030 assert(child.parentData is BoxParentData); |
| 883 Offset delta = size - child.size; | 1031 double delta = baseline - child.getDistanceToBaseline(baselineType); |
| 884 child.parentData.position = (delta.scale(horizontal, vertical)).toPoint(); | 1032 child.parentData.position = new Point(0.0, delta); |
| 885 } else { | 1033 } else { |
| 886 performResize(); | 1034 performResize(); |
| 887 } | 1035 } |
| 888 } | 1036 } |
| 889 | 1037 |
| 890 String debugDescribeSettings(String prefix) => '${super.debugDescribeSettings( prefix)}${prefix}horizontal: ${horizontal}\n${prefix}vertical: ${vertical}\n'; | 1038 String debugDescribeSettings(String prefix) => '${super.debugDescribeSettings( prefix)}${prefix}baseline: ${baseline}\nbaselineType: ${baselineType}'; |
| 891 } | 1039 } |
| 892 | 1040 |
| 893 class RenderImage extends RenderBox { | 1041 class RenderImage extends RenderBox { |
| 894 | 1042 |
| 895 RenderImage(String url, Size dimensions) { | 1043 RenderImage(String url, Size dimensions) { |
| 896 requestedSize = dimensions; | 1044 requestedSize = dimensions; |
| 897 src = url; | 1045 src = url; |
| 898 } | 1046 } |
| 899 | 1047 |
| 900 sky.Image _image; | 1048 sky.Image _image; |
| (...skipping 347 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1248 } | 1396 } |
| 1249 | 1397 |
| 1250 } | 1398 } |
| 1251 | 1399 |
| 1252 // HELPER METHODS FOR RENDERBOX CONTAINERS | 1400 // HELPER METHODS FOR RENDERBOX CONTAINERS |
| 1253 abstract class RenderBoxContainerDefaultsMixin<ChildType extends RenderBox, Pare ntDataType extends ContainerParentDataMixin<ChildType>> implements ContainerRend erObjectMixin<ChildType, ParentDataType> { | 1401 abstract class RenderBoxContainerDefaultsMixin<ChildType extends RenderBox, Pare ntDataType extends ContainerParentDataMixin<ChildType>> implements ContainerRend erObjectMixin<ChildType, ParentDataType> { |
| 1254 | 1402 |
| 1255 // This class, by convention, doesn't override any members of the superclass. | 1403 // This class, by convention, doesn't override any members of the superclass. |
| 1256 // It only provides helper functions that subclasses can call. | 1404 // It only provides helper functions that subclasses can call. |
| 1257 | 1405 |
| 1258 double defaultGetDistanceToFirstActualBaseline(TextBaseline baseline) { | 1406 double defaultComputeDistanceToFirstActualBaseline(TextBaseline baseline, Rend erObject client) { |
| 1259 assert(!needsLayout); | 1407 assert(!needsLayout); |
| 1260 RenderBox child = firstChild; | 1408 RenderBox child = firstChild; |
| 1261 while (child != null) { | 1409 while (child != null) { |
| 1262 assert(child.parentData is ParentDataType); | 1410 assert(child.parentData is ParentDataType); |
| 1263 double result = child.getDistanceToActualBaseline(baseline); | 1411 double result = child.getDistanceToActualBaseline(baseline, client); |
| 1264 if (result != null) | 1412 if (result != null) |
| 1265 return result + child.parentData.position.y; | 1413 return result + child.parentData.position.y; |
| 1266 child = child.parentData.nextSibling; | 1414 child = child.parentData.nextSibling; |
| 1267 } | 1415 } |
| 1268 return null; | 1416 return null; |
| 1269 } | 1417 } |
| 1270 | 1418 |
| 1271 double defaultGetDistanceToHighestActualBaseline(TextBaseline baseline) { | 1419 double defaultComputeDistanceToHighestActualBaseline(TextBaseline baseline, Re nderObject client) { |
| 1272 assert(!needsLayout); | 1420 assert(!needsLayout); |
| 1273 double result; | 1421 double result; |
| 1274 RenderBox child = firstChild; | 1422 RenderBox child = firstChild; |
| 1275 while (child != null) { | 1423 while (child != null) { |
| 1276 assert(child.parentData is ParentDataType); | 1424 assert(child.parentData is ParentDataType); |
| 1277 double candidate = child.getDistanceToActualBaseline(baseline); | 1425 double candidate = child.getDistanceToActualBaseline(baseline, client); |
| 1278 if (candidate != null) { | 1426 if (candidate != null) { |
| 1279 candidate += child.parentData.position.x; | 1427 candidate += child.parentData.position.x; |
| 1280 if (result != null) | 1428 if (result != null) |
| 1281 result = math.min(result, candidate); | 1429 result = math.min(result, candidate); |
| 1282 else | 1430 else |
| 1283 result = candidate; | 1431 result = candidate; |
| 1284 } | 1432 } |
| 1285 child = child.parentData.nextSibling; | 1433 child = child.parentData.nextSibling; |
| 1286 } | 1434 } |
| 1287 return result; | 1435 return result; |
| (...skipping 16 matching lines...) Expand all Loading... | |
| 1304 | 1452 |
| 1305 void defaultPaint(PaintingCanvas canvas, Offset offset) { | 1453 void defaultPaint(PaintingCanvas canvas, Offset offset) { |
| 1306 RenderBox child = firstChild; | 1454 RenderBox child = firstChild; |
| 1307 while (child != null) { | 1455 while (child != null) { |
| 1308 assert(child.parentData is ParentDataType); | 1456 assert(child.parentData is ParentDataType); |
| 1309 canvas.paintChild(child, child.parentData.position + offset); | 1457 canvas.paintChild(child, child.parentData.position + offset); |
| 1310 child = child.parentData.nextSibling; | 1458 child = child.parentData.nextSibling; |
| 1311 } | 1459 } |
| 1312 } | 1460 } |
| 1313 } | 1461 } |
| OLD | NEW |