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

Side by Side Diff: sky/sdk/lib/framework/layout2.dart

Issue 1143153011: Refactor padding out of RenderBlock. (Closed) Base URL: https://github.com/domokit/mojo.git@master
Patch Set: Created 5 years, 6 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/examples/raw/simple_render_tree.dart ('k') | no next file » | 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 'node.dart'; 5 import 'node.dart';
6 import 'dart:sky' as sky; 6 import 'dart:sky' as sky;
7 7
8 // ABSTRACT LAYOUT 8 // ABSTRACT LAYOUT
9 9
10 class ParentData { 10 class ParentData {
(...skipping 244 matching lines...) Expand 10 before | Expand all | Expand 10 after
255 class HitTestResult { 255 class HitTestResult {
256 final List<RenderNode> path = new List<RenderNode>(); 256 final List<RenderNode> path = new List<RenderNode>();
257 257
258 RenderNode get result => path.first; 258 RenderNode get result => path.first;
259 259
260 void add(RenderNode node) { 260 void add(RenderNode node) {
261 path.add(node); 261 path.add(node);
262 } 262 }
263 } 263 }
264 264
265
266 // GENERIC MIXIN FOR RENDER NODES WITH ONE CHILD
267
265 abstract class RenderNodeWithChildMixin<ChildType extends RenderNode> { 268 abstract class RenderNodeWithChildMixin<ChildType extends RenderNode> {
266 ChildType _child; 269 ChildType _child;
267 ChildType get child => _child; 270 ChildType get child => _child;
268 void set child (ChildType value) { 271 void set child (ChildType value) {
269 if (_child != null) 272 if (_child != null)
270 dropChild(_child); 273 dropChild(_child);
271 _child = value; 274 _child = value;
272 if (_child != null) 275 if (_child != null)
273 adoptChild(_child); 276 adoptChild(_child);
274 markNeedsLayout(); 277 markNeedsLayout();
275 } 278 }
276 } 279 }
277 280
278 // GENERIC MIXIN FOR RENDER NODES THAT TAKE A LIST OF CHILDREN 281
282 // GENERIC MIXIN FOR RENDER NODES WITH A LIST OF CHILDREN
279 283
280 abstract class ContainerParentDataMixin<ChildType extends RenderNode> { 284 abstract class ContainerParentDataMixin<ChildType extends RenderNode> {
281 ChildType previousSibling; 285 ChildType previousSibling;
282 ChildType nextSibling; 286 ChildType nextSibling;
283 void detachSiblings() { 287 void detachSiblings() {
284 if (previousSibling != null) { 288 if (previousSibling != null) {
285 assert(previousSibling.parentData is ContainerParentDataMixin<ChildType>); 289 assert(previousSibling.parentData is ContainerParentDataMixin<ChildType>);
286 assert(previousSibling != this); 290 assert(previousSibling != this);
287 assert(previousSibling.parentData.nextSibling == this); 291 assert(previousSibling.parentData.nextSibling == this);
288 previousSibling.parentData.nextSibling = nextSibling; 292 previousSibling.parentData.nextSibling = nextSibling;
(...skipping 134 matching lines...) Expand 10 before | Expand all | Expand 10 after
423 assert(child.parentData is ParentDataType); 427 assert(child.parentData is ParentDataType);
424 return child.parentData.nextSibling; 428 return child.parentData.nextSibling;
425 } 429 }
426 430
427 } 431 }
428 432
429 433
430 // GENERIC BOX RENDERING 434 // GENERIC BOX RENDERING
431 // Anything that has a concept of x, y, width, height is going to derive from th is 435 // Anything that has a concept of x, y, width, height is going to derive from th is
432 436
437 class EdgeDims {
438 // used for e.g. padding
439 const EdgeDims(this.top, this.right, this.bottom, this.left);
440 final double top;
441 final double right;
442 final double bottom;
443 final double left;
444 operator ==(EdgeDims other) => (top == other.top) ||
445 (right == other.right) ||
446 (bottom == other.bottom) ||
447 (left == other.left);
448 }
449
433 class BoxConstraints { 450 class BoxConstraints {
434 const BoxConstraints({ 451 const BoxConstraints({
435 this.minWidth: 0.0, 452 this.minWidth: 0.0,
436 this.maxWidth: double.INFINITY, 453 this.maxWidth: double.INFINITY,
437 this.minHeight: 0.0, 454 this.minHeight: 0.0,
438 this.maxHeight: double.INFINITY}); 455 this.maxHeight: double.INFINITY});
439 456
440 const BoxConstraints.tight({ double width: 0.0, double height: 0.0 }) 457 const BoxConstraints.tight({ double width: 0.0, double height: 0.0 })
441 : minWidth = width, 458 : minWidth = width,
442 maxWidth = width, 459 maxWidth = width,
443 minHeight = height, 460 minHeight = height,
444 maxHeight = height; 461 maxHeight = height;
445 462
463 BoxConstraints deflate(EdgeDims edges) {
464 assert(edges != null);
465 return new BoxConstraints(
466 minWidth: minWidth,
467 maxWidth: maxWidth - (edges.left + edges.right),
468 minHeight: minHeight,
469 maxHeight: maxHeight - (edges.top + edges.bottom)
470 );
471 }
472
446 final double minWidth; 473 final double minWidth;
447 final double maxWidth; 474 final double maxWidth;
448 final double minHeight; 475 final double minHeight;
449 final double maxHeight; 476 final double maxHeight;
450 477
451 double constrainWidth(double width) { 478 double constrainWidth(double width) {
452 return clamp(min: minWidth, max: maxWidth, value: width); 479 return clamp(min: minWidth, max: maxWidth, value: width);
453 } 480 }
454 481
455 double constrainHeight(double height) { 482 double constrainHeight(double height) {
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
505 hitTestChildren(result, x: x, y: y); 532 hitTestChildren(result, x: x, y: y);
506 result.add(this); 533 result.add(this);
507 return true; 534 return true;
508 } 535 }
509 void hitTestChildren(HitTestResult result, { double x, double y }) { } 536 void hitTestChildren(HitTestResult result, { double x, double y }) { }
510 537
511 double width; 538 double width;
512 double height; 539 double height;
513 } 540 }
514 541
542 class RenderPadding extends RenderBox with RenderNodeWithChildMixin<RenderBox> {
543
544 RenderPadding(EdgeDims padding, RenderBox child) {
545 assert(padding != null);
546 this.padding = padding;
547 this.child = child;
548 }
549
550 EdgeDims _padding;
551 EdgeDims get padding => _padding;
552 void set padding (EdgeDims value) {
553 assert(value != null);
554 if (_padding != value) {
555 _padding = value;
556 markNeedsLayout();
557 }
558 }
559
560 BoxDimensions getIntrinsicDimensions(BoxConstraints constraints) {
561 assert(padding != null);
562 constraints = constraints.deflate(padding);
563 if (child == null)
564 return super.getIntrinsicDimensions(constraints);
565 return child.getIntrinsicDimensions(constraints);
566 }
567
568 void layout(BoxConstraints constraints, { RenderNode relayoutSubtreeRoot }) {
569 assert(padding != null);
570 constraints = constraints.deflate(padding);
571 if (child == null) {
572 width = constraints.constrainWidth(padding.left + padding.right);
573 height = constraints.constrainHeight(padding.top + padding.bottom);
574 return;
575 }
576 if (relayoutSubtreeRoot != null)
577 saveRelayoutSubtreeRoot(relayoutSubtreeRoot);
578 else
579 relayoutSubtreeRoot = this;
580 child.layout(constraints, relayoutSubtreeRoot: relayoutSubtreeRoot);
581 assert(child.parentData is BoxParentData);
582 child.parentData.x = padding.left;
583 child.parentData.y = padding.top;
584 width = constraints.constrainWidth(padding.left + child.width + padding.righ t);
585 height = constraints.constrainHeight(padding.top + child.height + padding.bo ttom);
586 }
587
588 void paint(RenderNodeDisplayList canvas) {
589 if (child != null)
590 canvas.paintChild(child, child.parentData.x, child.parentData.y);
591 }
abarth-chromium 2015/05/27 23:50:03 hitTestChildren?
592
593 }
594
515 // This must be immutable, because we won't notice when it changes 595 // This must be immutable, because we won't notice when it changes
516 class BoxDecoration { 596 class BoxDecoration {
517 const BoxDecoration({ 597 const BoxDecoration({
518 this.backgroundColor 598 this.backgroundColor
519 }); 599 });
520 600
521 final int backgroundColor; 601 final int backgroundColor;
522 } 602 }
523 603
524 class RenderDecoratedBox extends RenderBox { 604 class RenderDecoratedBox extends RenderBox {
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after
606 _width = newWidth; 686 _width = newWidth;
607 _height = newHeight; 687 _height = newHeight;
608 relayout(); 688 relayout();
609 } else { 689 } else {
610 layoutDone(); 690 layoutDone();
611 } 691 }
612 } 692 }
613 693
614 void relayout() { 694 void relayout() {
615 if (child != null) { 695 if (child != null) {
616 child.layout(new BoxConstraints( 696 child.layout(new BoxConstraints.tight(width: width, height: height));
617 minWidth: width,
618 maxWidth: width,
619 minHeight: height,
620 maxHeight: height
621 ));
622 assert(child.width == width); 697 assert(child.width == width);
623 assert(child.height == height); 698 assert(child.height == height);
624 } 699 }
625 layoutDone(); 700 layoutDone();
626 } 701 }
627 702
628 void rotate({ int oldAngle, int newAngle, Duration time }) { 703 void rotate({ int oldAngle, int newAngle, Duration time }) {
629 assert(false); // nobody tells the screen to rotate, the whole rotate() danc e is started from our layout() 704 assert(false); // nobody tells the screen to rotate, the whole rotate() danc e is started from our layout()
630 } 705 }
631 706
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
677 while (child != null) { 752 while (child != null) {
678 assert(child.parentData is BoxParentData); 753 assert(child.parentData is BoxParentData);
679 canvas.paintChild(child, child.parentData.x, child.parentData.y); 754 canvas.paintChild(child, child.parentData.x, child.parentData.y);
680 child = child.parentData.nextSibling; 755 child = child.parentData.nextSibling;
681 } 756 }
682 } 757 }
683 } 758 }
684 759
685 // BLOCK LAYOUT MANAGER 760 // BLOCK LAYOUT MANAGER
686 761
687 class EdgeDims {
688 // used for e.g. padding
689 const EdgeDims(this.top, this.right, this.bottom, this.left);
690 final double top;
691 final double right;
692 final double bottom;
693 final double left;
694 operator ==(EdgeDims other) => (top == other.top) ||
695 (right == other.right) ||
696 (bottom == other.bottom) ||
697 (left == other.left);
698 }
699
700 class BlockParentData extends BoxParentData with ContainerParentDataMixin<Render Box> { } 762 class BlockParentData extends BoxParentData with ContainerParentDataMixin<Render Box> { }
701 763
702 class RenderBlock extends RenderDecoratedBox with ContainerRenderNodeMixin<Rende rBox, BlockParentData>, 764 class RenderBlock extends RenderDecoratedBox with ContainerRenderNodeMixin<Rende rBox, BlockParentData>,
703 RenderBoxContainerDefaultsMixi n<RenderBox, BlockParentData> { 765 RenderBoxContainerDefaultsMixi n<RenderBox, BlockParentData> {
704 // lays out RenderBox children in a vertical stack 766 // lays out RenderBox children in a vertical stack
705 // uses the maximum width provided by the parent 767 // uses the maximum width provided by the parent
706 // sizes itself to the height of its child stack 768 // sizes itself to the height of its child stack
707 769
708 RenderBlock({ 770 RenderBlock({
709 BoxDecoration decoration, 771 BoxDecoration decoration
710 EdgeDims padding: const EdgeDims(0.0, 0.0, 0.0, 0.0) 772 }) : super(decoration);
711 }) : super(decoration), _padding = padding;
712
713 EdgeDims _padding;
714 EdgeDims get padding => _padding;
715 void set padding (EdgeDims value) {
716 assert(value != null);
717 if (_padding != value) {
718 _padding = value;
719 markNeedsLayout();
720 }
721 }
722 773
723 void setParentData(RenderBox child) { 774 void setParentData(RenderBox child) {
724 if (child.parentData is! BlockParentData) 775 if (child.parentData is! BlockParentData)
725 child.parentData = new BlockParentData(); 776 child.parentData = new BlockParentData();
726 } 777 }
727 778
728 // override this to report what dimensions you would have if you 779 // override this to report what dimensions you would have if you
729 // were laid out with the given constraints this can walk the tree 780 // were laid out with the given constraints this can walk the tree
730 // if it must, but it should be as cheap as possible; just get the 781 // if it must, but it should be as cheap as possible; just get the
731 // dimensions and nothing else (e.g. don't calculate hypothetical 782 // dimensions and nothing else (e.g. don't calculate hypothetical
732 // child positions if they're not needed to determine dimensions) 783 // child positions if they're not needed to determine dimensions)
733 BoxDimensions getIntrinsicDimensions(BoxConstraints constraints) { 784 BoxDimensions getIntrinsicDimensions(BoxConstraints constraints) {
734 double outerHeight = _padding.top + _padding.bottom; 785 double outerHeight = 0.0;
735 double outerWidth = constraints.constrainWidth(constraints.maxWidth); 786 double outerWidth = constraints.constrainWidth(constraints.maxWidth);
736 assert(outerWidth < double.INFINITY); 787 assert(outerWidth < double.INFINITY);
737 double innerWidth = outerWidth - (_padding.left + _padding.right); 788 double innerWidth = outerWidth;
738 RenderBox child = firstChild; 789 RenderBox child = firstChild;
739 BoxConstraints innerConstraints = new BoxConstraints(minWidth: innerWidth, 790 BoxConstraints innerConstraints = new BoxConstraints(minWidth: innerWidth,
740 maxWidth: innerWidth); 791 maxWidth: innerWidth);
741 while (child != null) { 792 while (child != null) {
742 outerHeight += child.getIntrinsicDimensions(innerConstraints).height; 793 outerHeight += child.getIntrinsicDimensions(innerConstraints).height;
743 assert(child.parentData is BlockParentData); 794 assert(child.parentData is BlockParentData);
744 child = child.parentData.nextSibling; 795 child = child.parentData.nextSibling;
745 } 796 }
746 797
747 return new BoxDimensions(width: outerWidth, 798 return new BoxDimensions(width: outerWidth,
(...skipping 11 matching lines...) Expand all
759 _constraints = constraints; 810 _constraints = constraints;
760 internalLayout(relayoutSubtreeRoot); 811 internalLayout(relayoutSubtreeRoot);
761 } 812 }
762 813
763 void relayout() { 814 void relayout() {
764 internalLayout(this); 815 internalLayout(this);
765 } 816 }
766 817
767 void internalLayout(RenderNode relayoutSubtreeRoot) { 818 void internalLayout(RenderNode relayoutSubtreeRoot) {
768 assert(_constraints != null); 819 assert(_constraints != null);
769 double y = _padding.top; 820 double y = 0.0;
770 double innerWidth = width - (_padding.left + _padding.right); 821 double innerWidth = width;
771 RenderBox child = firstChild; 822 RenderBox child = firstChild;
772 while (child != null) { 823 while (child != null) {
773 child.layout(new BoxConstraints(minWidth: innerWidth, maxWidth: innerWidth ), 824 child.layout(new BoxConstraints(minWidth: innerWidth, maxWidth: innerWidth ),
774 relayoutSubtreeRoot: relayoutSubtreeRoot); 825 relayoutSubtreeRoot: relayoutSubtreeRoot);
775 assert(child.parentData is BlockParentData); 826 assert(child.parentData is BlockParentData);
776 child.parentData.x = _padding.left; 827 child.parentData.x = 0.0;
777 child.parentData.y = y; 828 child.parentData.y = y;
778 y += child.height; 829 y += child.height;
779 child = child.parentData.nextSibling; 830 child = child.parentData.nextSibling;
780 } 831 }
781 height = _constraints.constrainHeight(y + _padding.bottom); 832 height = _constraints.constrainHeight(y);
782 layoutDone(); 833 layoutDone();
783 } 834 }
784 835
785 void hitTestChildren(HitTestResult result, { double x, double y }) { 836 void hitTestChildren(HitTestResult result, { double x, double y }) {
786 defaultHitTestChildren(result, x: x, y: y); 837 defaultHitTestChildren(result, x: x, y: y);
787 } 838 }
788 839
789 void paint(RenderNodeDisplayList canvas) { 840 void paint(RenderNodeDisplayList canvas) {
790 super.paint(canvas); 841 super.paint(canvas);
791 defaultPaint(canvas); 842 defaultPaint(canvas);
(...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after
917 968
918 void hitTestChildren(HitTestResult result, { double x, double y }) { 969 void hitTestChildren(HitTestResult result, { double x, double y }) {
919 defaultHitTestChildren(result, x: x, y: y); 970 defaultHitTestChildren(result, x: x, y: y);
920 } 971 }
921 972
922 void paint(RenderNodeDisplayList canvas) { 973 void paint(RenderNodeDisplayList canvas) {
923 super.paint(canvas); 974 super.paint(canvas);
924 defaultPaint(canvas); 975 defaultPaint(canvas);
925 } 976 }
926 } 977 }
OLDNEW
« no previous file with comments | « sky/examples/raw/simple_render_tree.dart ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698