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 '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 484 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
495 | 495 |
496 sky.Size size = new sky.Size(0.0, 0.0); | 496 sky.Size size = new sky.Size(0.0, 0.0); |
497 } | 497 } |
498 | 498 |
499 abstract class RenderProxyBox extends RenderBox with RenderNodeWithChildMixin<Re
nderBox> { | 499 abstract class RenderProxyBox extends RenderBox with RenderNodeWithChildMixin<Re
nderBox> { |
500 RenderProxyBox(RenderBox child) { | 500 RenderProxyBox(RenderBox child) { |
501 this.child = child; | 501 this.child = child; |
502 } | 502 } |
503 | 503 |
504 sky.Size getIntrinsicDimensions(BoxConstraints constraints) { | 504 sky.Size getIntrinsicDimensions(BoxConstraints constraints) { |
505 return child.getIntrinsicDimensions(constraints); | 505 if (child != null) |
| 506 return child.getIntrinsicDimensions(constraints); |
| 507 return super.getIntrinsicDimensions(constraints); |
506 } | 508 } |
507 | 509 |
508 void performLayout() { | 510 void performLayout() { |
509 child.layout(constraints, parentUsesSize: true); | 511 if (child != null) { |
510 size = child.size; | 512 child.layout(constraints, parentUsesSize: true); |
| 513 size = child.size; |
| 514 } else { |
| 515 performResize(); |
| 516 } |
511 } | 517 } |
512 | 518 |
513 void hitTestChildren(HitTestResult result, { sky.Point position }) { | 519 void hitTestChildren(HitTestResult result, { sky.Point position }) { |
514 child.hitTest(result, position: position); | 520 if (child != null) |
| 521 child.hitTest(result, position: position); |
| 522 else |
| 523 super.hitTestChildren(result, position: position); |
515 } | 524 } |
516 | 525 |
517 void paint(RenderNodeDisplayList canvas) { | 526 void paint(RenderNodeDisplayList canvas) { |
518 child.paint(canvas); | 527 if (child != null) |
| 528 child.paint(canvas); |
519 } | 529 } |
520 } | 530 } |
521 | 531 |
522 class RenderSizedBox extends RenderProxyBox { | 532 class RenderSizedBox extends RenderProxyBox { |
523 final sky.Size desiredSize; | 533 final sky.Size desiredSize; |
524 | 534 |
525 RenderSizedBox(RenderBox child, [this.desiredSize = const sky.Size.infinite()]
) | 535 RenderSizedBox({ |
526 : super(child); | 536 RenderBox child, |
| 537 this.desiredSize: const sky.Size.infinite() |
| 538 }) : super(child); |
527 | 539 |
528 sky.Size getIntrinsicDimensions(BoxConstraints constraints) { | 540 sky.Size getIntrinsicDimensions(BoxConstraints constraints) { |
529 return constraints.constrain(desiredSize); | 541 return constraints.constrain(desiredSize); |
530 } | 542 } |
531 | 543 |
532 void performLayout() { | 544 void performLayout() { |
533 size = constraints.constrain(desiredSize); | 545 size = constraints.constrain(desiredSize); |
534 child.layout(new BoxConstraints.tight(size)); | 546 child.layout(new BoxConstraints.tight(size)); |
535 } | 547 } |
536 } | 548 } |
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
596 | 608 |
597 // This must be immutable, because we won't notice when it changes | 609 // This must be immutable, because we won't notice when it changes |
598 class BoxDecoration { | 610 class BoxDecoration { |
599 const BoxDecoration({ | 611 const BoxDecoration({ |
600 this.backgroundColor | 612 this.backgroundColor |
601 }); | 613 }); |
602 | 614 |
603 final int backgroundColor; | 615 final int backgroundColor; |
604 } | 616 } |
605 | 617 |
606 class RenderDecoratedBox extends RenderBox { | 618 class RenderDecoratedBox extends RenderProxyBox { |
607 | 619 |
608 RenderDecoratedBox(BoxDecoration decoration) : _decoration = decoration; | 620 RenderDecoratedBox({ |
| 621 BoxDecoration decoration, |
| 622 RenderBox child |
| 623 }) : _decoration = decoration, super(child); |
609 | 624 |
610 BoxDecoration _decoration; | 625 BoxDecoration _decoration; |
611 BoxDecoration get decoration => _decoration; | 626 BoxDecoration get decoration => _decoration; |
612 void set decoration (BoxDecoration value) { | 627 void set decoration (BoxDecoration value) { |
613 if (value == _decoration) | 628 if (value == _decoration) |
614 return; | 629 return; |
615 _decoration = value; | 630 _decoration = value; |
616 markNeedsPaint(); | 631 markNeedsPaint(); |
617 } | 632 } |
618 | 633 |
619 void performLayout() { | |
620 size = constraints.constrain(new sky.Size.infinite()); | |
621 } | |
622 | |
623 void paint(RenderNodeDisplayList canvas) { | 634 void paint(RenderNodeDisplayList canvas) { |
624 assert(size.width != null); | 635 assert(size.width != null); |
625 assert(size.height != null); | 636 assert(size.height != null); |
626 | 637 |
627 if (_decoration == null) | 638 if (_decoration == null) |
628 return; | 639 return; |
629 | 640 |
630 if (_decoration.backgroundColor != null) { | 641 if (_decoration.backgroundColor != null) { |
631 sky.Paint paint = new sky.Paint()..color = _decoration.backgroundColor; | 642 sky.Paint paint = new sky.Paint()..color = _decoration.backgroundColor; |
632 canvas.drawRect(new sky.Rect.fromLTRB(0.0, 0.0, size.width, size.height),
paint); | 643 canvas.drawRect(new sky.Rect.fromLTRB(0.0, 0.0, size.width, size.height),
paint); |
633 } | 644 } |
634 } | 645 super.paint(canvas); |
635 } | |
636 | |
637 class RenderDecoratedCircle extends RenderDecoratedBox with RenderNodeWithChildM
ixin<RenderBox> { | |
638 RenderDecoratedCircle({ | |
639 BoxDecoration decoration, | |
640 RenderBox child | |
641 }) : super(decoration) { | |
642 this.child = child; | |
643 } | 646 } |
644 | 647 |
645 void paint(RenderNodeDisplayList canvas) { | |
646 assert(size.width != null); | |
647 assert(size.height != null); | |
648 | |
649 if (_decoration == null) | |
650 return; | |
651 | |
652 if (_decoration.backgroundColor != null) { | |
653 sky.Paint paint = new sky.Paint()..color = _decoration.backgroundColor; | |
654 canvas.drawCircle(0.0, 0.0, (size.width + size.height) / 2, paint); | |
655 } | |
656 } | |
657 } | 648 } |
658 | 649 |
659 | 650 |
660 // RENDER VIEW LAYOUT MANAGER | 651 // RENDER VIEW LAYOUT MANAGER |
661 | 652 |
662 class ViewConstraints { | 653 class ViewConstraints { |
663 | 654 |
664 const ViewConstraints({ | 655 const ViewConstraints({ |
665 this.width: 0.0, this.height: 0.0, this.orientation: null | 656 this.width: 0.0, this.height: 0.0, this.orientation: null |
666 }); | 657 }); |
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
762 canvas.paintChild(child, child.parentData.position); | 753 canvas.paintChild(child, child.parentData.position); |
763 child = child.parentData.nextSibling; | 754 child = child.parentData.nextSibling; |
764 } | 755 } |
765 } | 756 } |
766 } | 757 } |
767 | 758 |
768 // BLOCK LAYOUT MANAGER | 759 // BLOCK LAYOUT MANAGER |
769 | 760 |
770 class BlockParentData extends BoxParentData with ContainerParentDataMixin<Render
Box> { } | 761 class BlockParentData extends BoxParentData with ContainerParentDataMixin<Render
Box> { } |
771 | 762 |
772 class RenderBlock extends RenderDecoratedBox with ContainerRenderNodeMixin<Rende
rBox, BlockParentData>, | 763 class RenderBlock extends RenderBox with ContainerRenderNodeMixin<RenderBox, Blo
ckParentData>, |
773 RenderBoxContainerDefaultsMixi
n<RenderBox, BlockParentData> { | 764 RenderBoxContainerDefaultsMixin<RenderB
ox, BlockParentData> { |
774 // lays out RenderBox children in a vertical stack | 765 // lays out RenderBox children in a vertical stack |
775 // uses the maximum width provided by the parent | 766 // uses the maximum width provided by the parent |
776 // sizes itself to the height of its child stack | 767 // sizes itself to the height of its child stack |
777 | 768 |
778 RenderBlock({ | |
779 BoxDecoration decoration | |
780 }) : super(decoration); | |
781 | |
782 void setParentData(RenderBox child) { | 769 void setParentData(RenderBox child) { |
783 if (child.parentData is! BlockParentData) | 770 if (child.parentData is! BlockParentData) |
784 child.parentData = new BlockParentData(); | 771 child.parentData = new BlockParentData(); |
785 } | 772 } |
786 | 773 |
787 // override this to report what dimensions you would have if you | 774 // override this to report what dimensions you would have if you |
788 // were laid out with the given constraints this can walk the tree | 775 // were laid out with the given constraints this can walk the tree |
789 // if it must, but it should be as cheap as possible; just get the | 776 // if it must, but it should be as cheap as possible; just get the |
790 // dimensions and nothing else (e.g. don't calculate hypothetical | 777 // dimensions and nothing else (e.g. don't calculate hypothetical |
791 // child positions if they're not needed to determine dimensions) | 778 // child positions if they're not needed to determine dimensions) |
(...skipping 28 matching lines...) Expand all Loading... |
820 size = new sky.Size(width, constraints.constrainHeight(y)); | 807 size = new sky.Size(width, constraints.constrainHeight(y)); |
821 assert(size.width < double.INFINITY); | 808 assert(size.width < double.INFINITY); |
822 assert(size.height < double.INFINITY); | 809 assert(size.height < double.INFINITY); |
823 } | 810 } |
824 | 811 |
825 void hitTestChildren(HitTestResult result, { sky.Point position }) { | 812 void hitTestChildren(HitTestResult result, { sky.Point position }) { |
826 defaultHitTestChildren(result, position: position); | 813 defaultHitTestChildren(result, position: position); |
827 } | 814 } |
828 | 815 |
829 void paint(RenderNodeDisplayList canvas) { | 816 void paint(RenderNodeDisplayList canvas) { |
830 super.paint(canvas); | |
831 defaultPaint(canvas); | 817 defaultPaint(canvas); |
832 } | 818 } |
833 | 819 |
834 } | 820 } |
835 | 821 |
836 // FLEXBOX LAYOUT MANAGER | 822 // FLEXBOX LAYOUT MANAGER |
837 | 823 |
838 class FlexBoxParentData extends BoxParentData with ContainerParentDataMixin<Rend
erBox> { | 824 class FlexBoxParentData extends BoxParentData with ContainerParentDataMixin<Rend
erBox> { |
839 int flex; | 825 int flex; |
840 void merge(FlexBoxParentData other) { | 826 void merge(FlexBoxParentData other) { |
841 if (other.flex != null) | 827 if (other.flex != null) |
842 flex = other.flex; | 828 flex = other.flex; |
843 super.merge(other); | 829 super.merge(other); |
844 } | 830 } |
845 } | 831 } |
846 | 832 |
847 enum FlexDirection { Horizontal, Vertical } | 833 enum FlexDirection { Horizontal, Vertical } |
848 | 834 |
849 class RenderFlex extends RenderDecoratedBox with ContainerRenderNodeMixin<Render
Box, FlexBoxParentData>, | 835 class RenderFlex extends RenderBox with ContainerRenderNodeMixin<RenderBox, Flex
BoxParentData>, |
850 RenderBoxContainerDefaultsMixin
<RenderBox, BlockParentData> { | 836 RenderBoxContainerDefaultsMixin<RenderBo
x, BlockParentData> { |
851 // lays out RenderBox children using flexible layout | 837 // lays out RenderBox children using flexible layout |
852 | 838 |
853 RenderFlex({ | 839 RenderFlex({ |
854 BoxDecoration decoration, | |
855 FlexDirection direction: FlexDirection.Horizontal | 840 FlexDirection direction: FlexDirection.Horizontal |
856 }) : super(decoration), _direction = direction; | 841 }) : _direction = direction; |
857 | 842 |
858 FlexDirection _direction; | 843 FlexDirection _direction; |
859 FlexDirection get direction => _direction; | 844 FlexDirection get direction => _direction; |
860 void set direction (FlexDirection value) { | 845 void set direction (FlexDirection value) { |
861 if (_direction != value) { | 846 if (_direction != value) { |
862 _direction = value; | 847 _direction = value; |
863 markNeedsLayout(); | 848 markNeedsLayout(); |
864 } | 849 } |
865 } | 850 } |
866 | 851 |
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
938 } | 923 } |
939 child = child.parentData.nextSibling; | 924 child = child.parentData.nextSibling; |
940 } | 925 } |
941 } | 926 } |
942 | 927 |
943 void hitTestChildren(HitTestResult result, { sky.Point position }) { | 928 void hitTestChildren(HitTestResult result, { sky.Point position }) { |
944 defaultHitTestChildren(result, position: position); | 929 defaultHitTestChildren(result, position: position); |
945 } | 930 } |
946 | 931 |
947 void paint(RenderNodeDisplayList canvas) { | 932 void paint(RenderNodeDisplayList canvas) { |
948 super.paint(canvas); | |
949 defaultPaint(canvas); | 933 defaultPaint(canvas); |
950 } | 934 } |
951 } | 935 } |
952 | 936 |
953 class RenderInline extends RenderNode { | 937 class RenderInline extends RenderNode { |
954 String data; | 938 String data; |
955 | 939 |
956 RenderInline(this.data); | 940 RenderInline(this.data); |
957 } | 941 } |
958 | 942 |
959 class RenderParagraph extends RenderDecoratedBox { | 943 class RenderParagraph extends RenderBox { |
960 String text; | |
961 sky.LayoutRoot _layoutRoot = new sky.LayoutRoot(); | |
962 sky.Document _document; | |
963 | 944 |
964 RenderParagraph(String this.text) : | 945 RenderParagraph({ |
965 super(new BoxDecoration(backgroundColor: 0xFFFFFFFF)) { | 946 String text, |
966 _document = new sky.Document(); | 947 int color |
| 948 }) : _color = color { |
967 _layoutRoot.rootElement = _document.createElement('p'); | 949 _layoutRoot.rootElement = _document.createElement('p'); |
968 _layoutRoot.rootElement.appendChild(_document.createText(this.text)); | 950 this.text = text; |
| 951 } |
| 952 |
| 953 final sky.Document _document = new sky.Document(); |
| 954 final sky.LayoutRoot _layoutRoot = new sky.LayoutRoot(); |
| 955 |
| 956 String get text => (_layoutRoot.rootElement.firstChild as sky.Text).data; |
| 957 void set text (String value) { |
| 958 _layoutRoot.rootElement.setChild(_document.createText(value)); |
| 959 markNeedsLayout(); |
| 960 } |
| 961 |
| 962 int _color = 0xFF000000; |
| 963 int get color => _color; |
| 964 void set color (int value) { |
| 965 if (_color != value) { |
| 966 _color = value; |
| 967 markNeedsPaint(); |
| 968 } |
| 969 } |
| 970 |
| 971 sky.Size getIntrinsicDimensions(BoxConstraints constraints) { |
| 972 assert(false); |
| 973 return null; |
| 974 // we don't currently support this for RenderParagraph |
969 } | 975 } |
970 | 976 |
971 void performLayout() { | 977 void performLayout() { |
972 _layoutRoot.maxWidth = constraints.maxWidth; | 978 _layoutRoot.maxWidth = constraints.maxWidth; |
973 _layoutRoot.minWidth = constraints.minWidth; | 979 _layoutRoot.minWidth = constraints.minWidth; |
974 _layoutRoot.minHeight = constraints.minHeight; | 980 _layoutRoot.minHeight = constraints.minHeight; |
975 _layoutRoot.maxHeight = constraints.maxHeight; | 981 _layoutRoot.maxHeight = constraints.maxHeight; |
976 _layoutRoot.layout(); | 982 _layoutRoot.layout(); |
977 width = _layoutRoot.rootElement.width; | 983 size = constraints.constrain(new sky.Size(_layoutRoot.rootElement.width, _la
youtRoot.rootElement.height)); |
978 // TODO(eseidel): LayoutRoot will not expand to fill height. :( | |
979 height = _constraints.constrainHeight(_layoutRoot.rootElement.height); | |
980 } | |
981 | |
982 void hitTestChildren(HitTestResult result, { double x, double y }) { | |
983 // defaultHitTestChildren(result, x: x, y: y); | |
984 } | 984 } |
985 | 985 |
986 void paint(RenderNodeDisplayList canvas) { | 986 void paint(RenderNodeDisplayList canvas) { |
987 super.paint(canvas); | 987 // _layoutRoot.rootElement.style['color'] = 'rgba(' + ...color... + ')'; |
988 _layoutRoot.paint(canvas); | 988 _layoutRoot.paint(canvas); |
989 } | 989 } |
| 990 |
| 991 // we should probably expose a way to do precise (inter-glpyh) hit testing |
| 992 |
990 } | 993 } |
OLD | NEW |