Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(223)

Side by Side Diff: sky/sdk/lib/rendering/box.dart

Issue 1219113003: Make popup menus line up to their baseline per the Material spec. (Closed) Base URL: https://github.com/domokit/mojo.git@master
Patch Set: Created 5 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « sky/sdk/lib/rendering/block.dart ('k') | sky/sdk/lib/rendering/flex.dart » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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 bool debugAncestorsAlreadyClearedBaselineCache() {
366 if (!_ancestorUsesBaseline)
367 return true; // we haven't yet been asked for a baseline even once, so the re's nothing for us to do
368 RenderBox node = this;
abarth-chromium 2015/07/01 18:22:59 Is it possible to execute this line of code?
369 while (node._ancestorUsesBaseline) {
370 if (node._cachedBaselines != null && node._cachedBaselines.isNotEmpty)
371 return false;
372 assert(node.parent != null);
373 if (node.parent is! RenderBox) {
374 assert(node.parent is RenderObject);
375 break;
376 }
377 node = node.parent;
378 }
379 if (node is RenderBox) {
380 assert(!node._ancestorUsesBaseline);
381 if (node._cachedBaselines != null && node._cachedBaselines.isNotEmpty)
382 return false;
383 }
384 return true;
385 }
386 void markNeedsLayout() {
387 assert(!RenderObject.debugDoingLayout);
388 assert(!RenderObject.debugDoingPaint);
389 if (_cachedBaselines != null && _cachedBaselines.isNotEmpty) {
390 _cachedBaselines.clear();
391 if (_ancestorUsesBaseline) {
392 final parent = this.parent; // TODO(ianh): Remove this once the analyzer is cleverer
393 assert(parent is RenderObject);
394 parent.markNeedsLayout();
395 // Now that they're dirty, we can forget that they used the
396 // baseline. If they use it again, then we'll set the bit
397 // again, and if we get dirty again, we'll notify them again.
398 _ancestorUsesBaseline = false;
399 assert(parent == this.parent); // TODO(ianh): Remove this once the analy zer is cleverer
400 }
401 } else {
402 assert(debugAncestorsAlreadyClearedBaselineCache());
403 }
404 super.markNeedsLayout();
405 }
329 void performResize() { 406 void performResize() {
330 // default behaviour for subclasses that have sizedByParent = true 407 // default behaviour for subclasses that have sizedByParent = true
331 size = constraints.constrain(Size.zero); 408 size = constraints.constrain(Size.zero);
332 assert(!size.isInfinite); 409 assert(!size.isInfinite);
333 } 410 }
334 void performLayout() { 411 void performLayout() {
335 // descendants have to either override performLayout() to set both 412 // descendants have to either override performLayout() to set both
336 // width and height and lay out children, or, set sizedByParent to 413 // width and height and lay out children, or, set sizedByParent to
337 // true so that performResize()'s logic above does its thing. 414 // true so that performResize()'s logic above does its thing.
338 assert(sizedByParent); 415 assert(sizedByParent);
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after
403 return child.getMinIntrinsicHeight(constraints); 480 return child.getMinIntrinsicHeight(constraints);
404 return super.getMinIntrinsicHeight(constraints); 481 return super.getMinIntrinsicHeight(constraints);
405 } 482 }
406 483
407 double getMaxIntrinsicHeight(BoxConstraints constraints) { 484 double getMaxIntrinsicHeight(BoxConstraints constraints) {
408 if (child != null) 485 if (child != null)
409 return child.getMaxIntrinsicHeight(constraints); 486 return child.getMaxIntrinsicHeight(constraints);
410 return super.getMaxIntrinsicHeight(constraints); 487 return super.getMaxIntrinsicHeight(constraints);
411 } 488 }
412 489
413 double getDistanceToActualBaseline(TextBaseline baseline) { 490 double computeDistanceToActualBaseline(TextBaseline baseline) {
414 if (child != null) 491 if (child != null)
415 return child.getDistanceToActualBaseline(baseline); 492 return child.getDistanceToActualBaseline(baseline);
416 return super.getDistanceToActualBaseline(baseline); 493 return super.computeDistanceToActualBaseline(baseline);
417 } 494 }
418 495
419 void performLayout() { 496 void performLayout() {
420 if (child != null) { 497 if (child != null) {
421 child.layout(constraints, parentUsesSize: true); 498 child.layout(constraints, parentUsesSize: true);
422 size = child.size; 499 size = child.size;
423 } else { 500 } else {
424 performResize(); 501 performResize();
425 } 502 }
426 } 503 }
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
487 size = child.size; 564 size = child.size;
488 } else { 565 } else {
489 size = _additionalConstraints.apply(constraints).constrain(Size.zero); 566 size = _additionalConstraints.apply(constraints).constrain(Size.zero);
490 } 567 }
491 } 568 }
492 569
493 String debugDescribeSettings(String prefix) => '${super.debugDescribeSettings( prefix)}${prefix}additionalConstraints: ${additionalConstraints}\n'; 570 String debugDescribeSettings(String prefix) => '${super.debugDescribeSettings( prefix)}${prefix}additionalConstraints: ${additionalConstraints}\n';
494 } 571 }
495 572
496 class RenderShrinkWrapWidth extends RenderProxyBox { 573 class RenderShrinkWrapWidth extends RenderProxyBox {
574
575 // This class will attempt to size its child to the child's maximum
576 // intrinsic width, snapped to a multiple of the stepWidth, if one
577 // is provided, and given the provided constraints; and will then
578 // adopt the child's resulting dimensions.
579
580 // Note: laying out this class is relatively expensive. Avoid using
581 // it where possible.
582
497 RenderShrinkWrapWidth({ 583 RenderShrinkWrapWidth({
498 double stepWidth, 584 double stepWidth,
499 double stepHeight, 585 double stepHeight,
500 RenderBox child 586 RenderBox child
501 }) : _stepWidth = stepWidth, _stepHeight = stepHeight, super(child); 587 }) : _stepWidth = stepWidth, _stepHeight = stepHeight, super(child);
502 588
503 double _stepWidth; 589 double _stepWidth;
504 double get stepWidth => _stepWidth; 590 double get stepWidth => _stepWidth;
505 void set stepWidth(double value) { 591 void set stepWidth(double value) {
506 if (value == _stepWidth) 592 if (value == _stepWidth)
(...skipping 11 matching lines...) Expand all
518 markNeedsLayout(); 604 markNeedsLayout();
519 } 605 }
520 606
521 static double applyStep(double input, double step) { 607 static double applyStep(double input, double step) {
522 if (step == null) 608 if (step == null)
523 return input; 609 return input;
524 return (input / step).ceil() * step; 610 return (input / step).ceil() * step;
525 } 611 }
526 612
527 BoxConstraints _getInnerConstraints(BoxConstraints constraints) { 613 BoxConstraints _getInnerConstraints(BoxConstraints constraints) {
614 if (constraints.hasTightWidth)
615 return constraints;
528 double width = child.getMaxIntrinsicWidth(constraints); 616 double width = child.getMaxIntrinsicWidth(constraints);
529 assert(width == constraints.constrainWidth(width)); 617 assert(width == constraints.constrainWidth(width));
530 return constraints.applyWidth(width); 618 return constraints.applyWidth(applyStep(width, _stepWidth));
531 } 619 }
532 620
533 double getMinIntrinsicWidth(BoxConstraints constraints) { 621 double getMinIntrinsicWidth(BoxConstraints constraints) {
534 if (child == null) 622 return getMaxIntrinsicWidth(constraints);
535 return constraints.constrainWidth(0.0);
536 double childResult = child.getMinIntrinsicWidth(constraints);
537 return constraints.constrainWidth(applyStep(childResult, _stepWidth));
538 } 623 }
539 624
540 double getMaxIntrinsicWidth(BoxConstraints constraints) { 625 double getMaxIntrinsicWidth(BoxConstraints constraints) {
541 if (child == null) 626 if (child == null)
542 return constraints.constrainWidth(0.0); 627 return constraints.constrainWidth(0.0);
543 double childResult = child.getMaxIntrinsicWidth(constraints); 628 double childResult = child.getMaxIntrinsicWidth(constraints);
544 return constraints.constrainWidth(applyStep(childResult, _stepWidth)); 629 return constraints.constrainWidth(applyStep(childResult, _stepWidth));
545 } 630 }
546 631
547 double getMinIntrinsicHeight(BoxConstraints constraints) { 632 double getMinIntrinsicHeight(BoxConstraints constraints) {
548 if (child == null) 633 if (child == null)
549 return constraints.constrainWidth(0.0); 634 return constraints.constrainWidth(0.0);
550 double childResult = child.getMinIntrinsicHeight(_getInnerConstraints(constr aints)); 635 double childResult = child.getMinIntrinsicHeight(_getInnerConstraints(constr aints));
551 return constraints.constrainHeight(applyStep(childResult, _stepHeight)); 636 return constraints.constrainHeight(applyStep(childResult, _stepHeight));
552 } 637 }
553 638
554 double getMaxIntrinsicHeight(BoxConstraints constraints) { 639 double getMaxIntrinsicHeight(BoxConstraints constraints) {
555 if (child == null) 640 if (child == null)
556 return constraints.constrainWidth(0.0); 641 return constraints.constrainWidth(0.0);
557 double childResult = child.getMaxIntrinsicHeight(_getInnerConstraints(constr aints)); 642 double childResult = child.getMaxIntrinsicHeight(_getInnerConstraints(constr aints));
558 return constraints.constrainHeight(applyStep(childResult, _stepHeight)); 643 return constraints.constrainHeight(applyStep(childResult, _stepHeight));
559 } 644 }
560 645
561 void performLayout() { 646 void performLayout() {
562 if (child != null) { 647 if (child != null) {
563 child.layout(_getInnerConstraints(constraints), parentUsesSize: true); 648 BoxConstraints childConstraints = _getInnerConstraints(constraints);
564 size = new Size(applyStep(child.size.width, _stepWidth), applyStep(child.s ize.height, _stepHeight)); 649 if (_stepHeight != null)
650 childConstraints.applyHeight(getMaxIntrinsicHeight(childConstraints));
651 child.layout(childConstraints, parentUsesSize: true);
652 size = child.size;
565 } else { 653 } else {
566 performResize(); 654 performResize();
567 } 655 }
568 } 656 }
657
658 String debugDescribeSettings(String prefix) => '${super.debugDescribeSettings( prefix)}${prefix}stepWidth: ${stepWidth}\n${prefix}stepHeight: ${stepHeight}\n';
659
569 } 660 }
570 661
571 class RenderOpacity extends RenderProxyBox { 662 class RenderOpacity extends RenderProxyBox {
572 RenderOpacity({ RenderBox child, double opacity }) 663 RenderOpacity({ RenderBox child, double opacity })
573 : this._opacity = opacity, super(child) { 664 : this._opacity = opacity, super(child) {
574 assert(opacity >= 0.0 && opacity <= 1.0); 665 assert(opacity >= 0.0 && opacity <= 1.0);
575 } 666 }
576 667
577 double _opacity; 668 double _opacity;
578 double get opacity => _opacity; 669 double get opacity => _opacity;
(...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after
712 } 803 }
713 804
714 abstract class RenderShiftedBox extends RenderBox with RenderObjectWithChildMixi n<RenderBox> { 805 abstract class RenderShiftedBox extends RenderBox with RenderObjectWithChildMixi n<RenderBox> {
715 806
716 // Abstract class for one-child-layout render boxes 807 // Abstract class for one-child-layout render boxes
717 808
718 RenderShiftedBox(RenderBox child) { 809 RenderShiftedBox(RenderBox child) {
719 this.child = child; 810 this.child = child;
720 } 811 }
721 812
722 void paint(PaintingCanvas canvas, Offset offset) { 813 double getMinIntrinsicWidth(BoxConstraints constraints) {
723 if (child != null) 814 if (child != null)
724 canvas.paintChild(child, child.parentData.position + offset); 815 return child.getMinIntrinsicWidth(constraints);
816 return super.getMinIntrinsicWidth(constraints);
725 } 817 }
726 818
727 double getDistanceToActualBaseline(TextBaseline baseline) { 819 double getMaxIntrinsicWidth(BoxConstraints constraints) {
820 if (child != null)
821 return child.getMaxIntrinsicWidth(constraints);
822 return super.getMaxIntrinsicWidth(constraints);
823 }
824
825 double getMinIntrinsicHeight(BoxConstraints constraints) {
826 if (child != null)
827 return child.getMinIntrinsicHeight(constraints);
828 return super.getMinIntrinsicHeight(constraints);
829 }
830
831 double getMaxIntrinsicHeight(BoxConstraints constraints) {
832 if (child != null)
833 return child.getMaxIntrinsicHeight(constraints);
834 return super.getMaxIntrinsicHeight(constraints);
835 }
836
837 double computeDistanceToActualBaseline(TextBaseline baseline) {
728 double result; 838 double result;
729 if (child != null) { 839 if (child != null) {
730 assert(!needsLayout); 840 assert(!needsLayout);
731 result = child.getDistanceToActualBaseline(baseline); 841 result = child.getDistanceToActualBaseline(baseline);
732 assert(child.parentData is BoxParentData); 842 assert(child.parentData is BoxParentData);
733 if (result != null) 843 if (result != null)
734 result += child.parentData.position.y; 844 result += child.parentData.position.y;
735 } else { 845 } else {
736 result = super.getDistanceToActualBaseline(baseline); 846 result = super.computeDistanceToActualBaseline(baseline);
737 } 847 }
738 return result; 848 return result;
739 } 849 }
740 850
851 void paint(PaintingCanvas canvas, Offset offset) {
852 if (child != null)
853 canvas.paintChild(child, child.parentData.position + offset);
854 }
855
741 void hitTestChildren(HitTestResult result, { Point position }) { 856 void hitTestChildren(HitTestResult result, { Point position }) {
742 if (child != null) { 857 if (child != null) {
743 assert(child.parentData is BoxParentData); 858 assert(child.parentData is BoxParentData);
744 Rect childBounds = child.parentData.position & child.size; 859 Rect childBounds = child.parentData.position & child.size;
745 if (childBounds.contains(position)) { 860 if (childBounds.contains(position)) {
746 child.hitTest(result, position: new Point(position.x - child.parentData. position.x, 861 child.hitTest(result, position: new Point(position.x - child.parentData. position.x,
747 position.y - child.parentD ata.position.y)); 862 position.y - child.parentD ata.position.y));
748 } 863 }
749 } 864 }
750 } 865 }
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
813 padding.left + child.size.width + padding.right, 928 padding.left + child.size.width + padding.right,
814 padding.top + child.size.height + padding.bottom 929 padding.top + child.size.height + padding.bottom
815 )); 930 ));
816 } 931 }
817 932
818 String debugDescribeSettings(String prefix) => '${super.debugDescribeSettings( prefix)}${prefix}padding: ${padding}\n'; 933 String debugDescribeSettings(String prefix) => '${super.debugDescribeSettings( prefix)}${prefix}padding: ${padding}\n';
819 } 934 }
820 935
821 class RenderPositionedBox extends RenderShiftedBox { 936 class RenderPositionedBox extends RenderShiftedBox {
822 937
938 // This box aligns a child box within itself. It's only useful for
939 // children that don't always size to fit their parent. For example,
940 // to align a box at the bottom right, you would pass this box a
941 // tight constraint that is bigger than the child's natural size,
942 // with horizontal and vertical set to 1.0.
943
823 RenderPositionedBox({ 944 RenderPositionedBox({
824 RenderBox child, 945 RenderBox child,
825 double horizontal: 0.5, 946 double horizontal: 0.5,
826 double vertical: 0.5 947 double vertical: 0.5
827 }) : _horizontal = horizontal, 948 }) : _horizontal = horizontal,
828 _vertical = vertical, 949 _vertical = vertical,
829 super(child) { 950 super(child) {
830 assert(horizontal != null); 951 assert(horizontal != null);
831 assert(vertical != null); 952 assert(vertical != null);
832 } 953 }
(...skipping 11 matching lines...) Expand all
844 double _vertical; 965 double _vertical;
845 double get vertical => _vertical; 966 double get vertical => _vertical;
846 void set vertical (double value) { 967 void set vertical (double value) {
847 assert(value != null); 968 assert(value != null);
848 if (_vertical == value) 969 if (_vertical == value)
849 return; 970 return;
850 _vertical = value; 971 _vertical = value;
851 markNeedsLayout(); 972 markNeedsLayout();
852 } 973 }
853 974
854 double getMinIntrinsicWidth(BoxConstraints constraints) { 975 void performLayout() {
855 if (child != null) 976 if (child != null) {
856 return child.getMinIntrinsicWidth(constraints); 977 child.layout(constraints.loosen(), parentUsesSize: true);
857 return super.getMinIntrinsicWidth(constraints); 978 size = constraints.constrain(child.size);
979 assert(child.parentData is BoxParentData);
980 Offset delta = size - child.size;
981 child.parentData.position = (delta.scale(horizontal, vertical)).toPoint();
982 } else {
983 performResize();
984 }
858 } 985 }
859 986
860 double getMaxIntrinsicWidth(BoxConstraints constraints) { 987 String debugDescribeSettings(String prefix) => '${super.debugDescribeSettings( prefix)}${prefix}horizontal: ${horizontal}\n${prefix}vertical: ${vertical}\n';
861 if (child != null) 988 }
862 return child.getMaxIntrinsicWidth(constraints); 989
863 return super.getMaxIntrinsicWidth(constraints); 990 class RenderBaseline extends RenderShiftedBox {
991
992 RenderBaseline({
993 RenderBox child,
994 double baseline,
995 TextBaseline baselineType
996 }) : _baseline = baseline,
997 _baselineType = baselineType,
998 super(child) {
999 assert(baseline != null);
1000 assert(baselineType != null);
864 } 1001 }
865 1002
866 double getMinIntrinsicHeight(BoxConstraints constraints) { 1003 double _baseline;
867 if (child != null) 1004 double get baseline => _baseline;
868 return child.getMinIntrinsicHeight(constraints); 1005 void set baseline (double value) {
869 return super.getMinIntrinsicHeight(constraints); 1006 assert(value != null);
1007 if (_baseline == value)
1008 return;
1009 _baseline = value;
1010 markNeedsLayout();
870 } 1011 }
871 1012
872 double getMaxIntrinsicHeight(BoxConstraints constraints) { 1013 TextBaseline _baselineType;
873 if (child != null) 1014 TextBaseline get baselineType => _baselineType;
874 return child.getMaxIntrinsicHeight(constraints); 1015 void set baselineType (TextBaseline value) {
875 return super.getMaxIntrinsicHeight(constraints); 1016 assert(value != null);
1017 if (_baselineType == value)
1018 return;
1019 _baselineType = value;
1020 markNeedsLayout();
876 } 1021 }
877 1022
878 void performLayout() { 1023 void performLayout() {
879 if (child != null) { 1024 if (child != null) {
880 child.layout(constraints.loosen(), parentUsesSize: true); 1025 child.layout(constraints.loosen(), parentUsesSize: true);
881 size = constraints.constrain(child.size); 1026 size = constraints.constrain(child.size);
882 assert(child.parentData is BoxParentData); 1027 assert(child.parentData is BoxParentData);
883 Offset delta = size - child.size; 1028 double delta = baseline - child.getDistanceToBaseline(baselineType);
884 child.parentData.position = (delta.scale(horizontal, vertical)).toPoint(); 1029 child.parentData.position = new Point(0.0, delta);
885 } else { 1030 } else {
886 performResize(); 1031 performResize();
887 } 1032 }
888 } 1033 }
889 1034
890 String debugDescribeSettings(String prefix) => '${super.debugDescribeSettings( prefix)}${prefix}horizontal: ${horizontal}\n${prefix}vertical: ${vertical}\n'; 1035 String debugDescribeSettings(String prefix) => '${super.debugDescribeSettings( prefix)}${prefix}baseline: ${baseline}\nbaselineType: ${baselineType}';
891 } 1036 }
892 1037
893 class RenderImage extends RenderBox { 1038 class RenderImage extends RenderBox {
894 1039
895 RenderImage(String url, Size dimensions) { 1040 RenderImage(String url, Size dimensions) {
896 requestedSize = dimensions; 1041 requestedSize = dimensions;
897 src = url; 1042 src = url;
898 } 1043 }
899 1044
900 sky.Image _image; 1045 sky.Image _image;
(...skipping 347 matching lines...) Expand 10 before | Expand all | Expand 10 after
1248 } 1393 }
1249 1394
1250 } 1395 }
1251 1396
1252 // HELPER METHODS FOR RENDERBOX CONTAINERS 1397 // HELPER METHODS FOR RENDERBOX CONTAINERS
1253 abstract class RenderBoxContainerDefaultsMixin<ChildType extends RenderBox, Pare ntDataType extends ContainerParentDataMixin<ChildType>> implements ContainerRend erObjectMixin<ChildType, ParentDataType> { 1398 abstract class RenderBoxContainerDefaultsMixin<ChildType extends RenderBox, Pare ntDataType extends ContainerParentDataMixin<ChildType>> implements ContainerRend erObjectMixin<ChildType, ParentDataType> {
1254 1399
1255 // This class, by convention, doesn't override any members of the superclass. 1400 // This class, by convention, doesn't override any members of the superclass.
1256 // It only provides helper functions that subclasses can call. 1401 // It only provides helper functions that subclasses can call.
1257 1402
1258 double defaultGetDistanceToFirstActualBaseline(TextBaseline baseline) { 1403 double defaultComputeDistanceToFirstActualBaseline(TextBaseline baseline) {
1259 assert(!needsLayout); 1404 assert(!needsLayout);
1260 RenderBox child = firstChild; 1405 RenderBox child = firstChild;
1261 while (child != null) { 1406 while (child != null) {
1262 assert(child.parentData is ParentDataType); 1407 assert(child.parentData is ParentDataType);
1263 double result = child.getDistanceToActualBaseline(baseline); 1408 double result = child.getDistanceToActualBaseline(baseline);
1264 if (result != null) 1409 if (result != null)
1265 return result + child.parentData.position.y; 1410 return result + child.parentData.position.y;
1266 child = child.parentData.nextSibling; 1411 child = child.parentData.nextSibling;
1267 } 1412 }
1268 return null; 1413 return null;
1269 } 1414 }
1270 1415
1271 double defaultGetDistanceToHighestActualBaseline(TextBaseline baseline) { 1416 double defaultComputeDistanceToHighestActualBaseline(TextBaseline baseline) {
1272 assert(!needsLayout); 1417 assert(!needsLayout);
1273 double result; 1418 double result;
1274 RenderBox child = firstChild; 1419 RenderBox child = firstChild;
1275 while (child != null) { 1420 while (child != null) {
1276 assert(child.parentData is ParentDataType); 1421 assert(child.parentData is ParentDataType);
1277 double candidate = child.getDistanceToActualBaseline(baseline); 1422 double candidate = child.getDistanceToActualBaseline(baseline);
1278 if (candidate != null) { 1423 if (candidate != null) {
1279 candidate += child.parentData.position.x; 1424 candidate += child.parentData.position.x;
1280 if (result != null) 1425 if (result != null)
1281 result = math.min(result, candidate); 1426 result = math.min(result, candidate);
(...skipping 22 matching lines...) Expand all
1304 1449
1305 void defaultPaint(PaintingCanvas canvas, Offset offset) { 1450 void defaultPaint(PaintingCanvas canvas, Offset offset) {
1306 RenderBox child = firstChild; 1451 RenderBox child = firstChild;
1307 while (child != null) { 1452 while (child != null) {
1308 assert(child.parentData is ParentDataType); 1453 assert(child.parentData is ParentDataType);
1309 canvas.paintChild(child, child.parentData.position + offset); 1454 canvas.paintChild(child, child.parentData.position + offset);
1310 child = child.parentData.nextSibling; 1455 child = child.parentData.nextSibling;
1311 } 1456 }
1312 } 1457 }
1313 } 1458 }
OLDNEW
« no previous file with comments | « sky/sdk/lib/rendering/block.dart ('k') | sky/sdk/lib/rendering/flex.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698