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

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

Issue 1151293002: WIP Flexbox Layout Manager for Sky framework. (Closed) Base URL: git@github.com:domokit/mojo.git@master
Patch Set: Initial WIP Created 5 years, 7 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 library layout; 1 library layout;
2 2
3 // This version of layout.dart is an update to the other one, this one using new APIs. 3 // This version of layout.dart is an update to the other one, this one using new APIs.
4 // It will not work in a stock Sky setup currently. 4 // It will not work in a stock Sky setup currently.
5 5
6 import 'node.dart'; 6 import 'node.dart';
7 7
8 import 'dart:sky' as sky; 8 import 'dart:sky' as sky;
9 9
10 // ABSTRACT LAYOUT 10 // ABSTRACT LAYOUT
(...skipping 443 matching lines...) Expand 10 before | Expand all | Expand 10 after
454 BoxDimensions getIntrinsicDimensions(BoxConstraints constraints) { 454 BoxDimensions getIntrinsicDimensions(BoxConstraints constraints) {
455 return new BoxDimensions.withConstraints(constraints); 455 return new BoxDimensions.withConstraints(constraints);
456 } 456 }
457 457
458 void layout(BoxConstraints constraints, { RenderNode relayoutSubtreeRoot }) { 458 void layout(BoxConstraints constraints, { RenderNode relayoutSubtreeRoot }) {
459 width = constraints.constrainWidth(0.0); 459 width = constraints.constrainWidth(0.0);
460 height = constraints.constrainHeight(0.0); 460 height = constraints.constrainHeight(0.0);
461 layoutDone(); 461 layoutDone();
462 } 462 }
463 463
464 bool handlePointer(sky.PointerEvent event, { double x: 0.0, double y: 0.0 }) {
465 // the x, y parameters have the top left of the node's box as the origin
466 RenderBox child = _lastChild;
467 while (child != null) {
468 assert(child.parentData is BoxParentData);
469 if ((x >= child.parentData.x) && (x < child.parentData.x + child.width) &&
470 (y >= child.parentData.y) && (y < child.parentData.y + child.height)) {
471 if (child.handlePointer(event, x: x-child.parentData.x, y: y-child.paren tData.y))
472 return true;
473 break;
474 }
475 child = child.parentData.previousSibling;
476 }
477 return super.handlePointer(event, x: x, y: y);
478 }
479
464 double width; 480 double width;
465 double height; 481 double height;
466 } 482 }
467 483
468 class BoxDecoration { 484 class BoxDecoration {
469 const BoxDecoration({ 485 const BoxDecoration({
470 this.backgroundColor 486 this.backgroundColor
471 }); 487 });
472 488
473 final int backgroundColor; 489 final int backgroundColor;
(...skipping 201 matching lines...) Expand 10 before | Expand all | Expand 10 after
675 assert(child.parentData is BlockParentData); 691 assert(child.parentData is BlockParentData);
676 child.parentData.x = _padding.left; 692 child.parentData.x = _padding.left;
677 child.parentData.y = y; 693 child.parentData.y = y;
678 y += child.height; 694 y += child.height;
679 child = child.parentData.nextSibling; 695 child = child.parentData.nextSibling;
680 } 696 }
681 height = clamp(min: _minHeight, value: y + _padding.bottom, max: _maxHeight) ; 697 height = clamp(min: _minHeight, value: y + _padding.bottom, max: _maxHeight) ;
682 layoutDone(); 698 layoutDone();
683 } 699 }
684 700
685 bool handlePointer(sky.PointerEvent event, { double x: 0.0, double y: 0.0 }) {
686 // the x, y parameters have the top left of the node's box as the origin
687 RenderBox child = _lastChild;
688 while (child != null) {
689 assert(child.parentData is BlockParentData);
690 if ((x >= child.parentData.x) && (x < child.parentData.x + child.width) &&
691 (y >= child.parentData.y) && (y < child.parentData.y + child.height)) {
692 if (child.handlePointer(event, x: x-child.parentData.x, y: y-child.paren tData.y))
693 return true;
694 break;
695 }
696 child = child.parentData.previousSibling;
697 }
698 return super.handlePointer(event, x: x, y: y);
699 }
700
701 void paint(RenderNodeDisplayList canvas) { 701 void paint(RenderNodeDisplayList canvas) {
702 super.paint(canvas); 702 super.paint(canvas);
703 RenderBox child = _firstChild; 703 RenderBox child = _firstChild;
704 while (child != null) { 704 while (child != null) {
705 assert(child.parentData is BlockParentData); 705 assert(child.parentData is BlockParentData);
706 canvas.paintChild(child, child.parentData.x, child.parentData.y); 706 canvas.paintChild(child, child.parentData.x, child.parentData.y);
707 child = child.parentData.nextSibling; 707 child = child.parentData.nextSibling;
708 } 708 }
709 } 709 }
710 710
711 } 711 }
712 712
713 class FlexBoxParentData extends BoxParentData { 713 // FLEXBOX LAYOUT MANAGER
714
715 class FlexBoxParentData extends BoxParentData with ContainerParentDataMixin<Rend erBox> {
714 int flex; 716 int flex;
715 void merge(FlexBoxParentData other) { 717 void merge(FlexBoxParentData other) {
716 if (other.flex != null) 718 if (other.flex != null)
717 flex = other.flex; 719 flex = other.flex;
718 super.merge(other); 720 super.merge(other);
719 } 721 }
720 } 722 }
721 723
722 enum FlexDirection { Row, Column } 724 enum FlexDirection { Row, Column }
723 725
724 // TODO(ianh): FlexBox 726 class RenderFlex extends RenderDecoratedBox with ContainerRenderNodeMixin<Render Box, FlexBoxParentData> {
727 // lays out RenderBox children in a vertical stack using flexible layout
728 // uses the maximum width and height provided by the parent
725 729
730 RenderFlex({
731 BoxDecoration decoration,
732 FlexDirection direction: FlexDirection.Row
733 }) : super(decoration), _direction = direction;
734
735 FlexDirection _direction;
736 FlexDirection get direction => _direction;
737 void set direction (FlexDirection value) {
738 _direction = value;
abarth-chromium 2015/05/22 06:26:23 Should early out when the newDirection and _direct
jackson 2015/05/22 20:06:54 Acknowledged.
739 relayout();
abarth-chromium 2015/05/22 06:26:23 Should markForLayout instead of calling relayout.
jackson 2015/05/22 20:06:55 Acknowledged.
740 }
741
742 void setParentData(RenderBox child) {
743 if (child.parentData is! FlexBoxParentData)
744 child.parentData = new FlexBoxParentData();
745 }
746
747 void layout(BoxConstraints constraints, { RenderNode relayoutSubtreeRoot }) {
748 width = clamp(min: constraints.minWidth, max: constraints.maxWidth);
749 height = clamp(min: constraints.minHeight, max: constraints.maxHeight);
750 relayout();
751 }
752
753 void relayout() {
754 internalLayout(this);
755 }
abarth-chromium 2015/05/22 06:26:22 layout and relayout don't quite seem right. You m
jackson 2015/05/22 20:06:54 Acknowledged.
756
757 int getFlex(RenderBox child) {
abarth-chromium 2015/05/22 06:26:22 s/getFlex/_getFlex/ to mark the function as privat
jackson 2015/05/22 20:06:54 Acknowledged.
758 assert(child.parentData is FlexBoxParentData);
759 return (child.parentData.flex != null ? child.parentData.flex : 0);
760 }
761
762 void internalLayout(RenderNode relayoutSubtreeRoot) {
763 // Based on http://www.w3.org/TR/css-flexbox-1/ Section 9.7 Resolving Flexib le Lengths
764 // Steps 1-3. Determine used flex factor, size inflexible items, calculate f ree space
765 int numFlexibleChildren = 0;
766 int totalFlex = 0;
767 double freeSpace = (_direction == FlexDirection.Row) ? width : height;
768 RenderBox child = _firstChild;
769 while (child != null) {
770 int flex = getFlex(child);
771 if (flex > 0) {
772 numFlexibleChildren++;
773 totalFlex += child.parentData.flex;
774 } else {
775 child.layout(new BoxConstraints(minWidth: width, maxWidth: width),
abarth-chromium 2015/05/22 06:26:23 Should the BoxConstraints depend on the flex direc
jackson 2015/05/22 20:06:54 Acknowledged.
776 relayoutSubtreeRoot: relayoutSubtreeRoot);
abarth-chromium 2015/05/22 06:26:23 I think you're supposed to call getIntrinsicDimens
jackson 2015/05/22 20:06:54 I talked to hixie, he said that it's ok to call la
777 freeSpace -= (_direction == FlexDirection.Row) ? child.width : child.hei ght;
778 }
779 child = child.parentData.nextSibling;
780 }
781
782 // Steps 4-5. Distribute remaining space to flexible children.
783 double spacePerFlex = freeSpace / totalFlex;
784 double usedSpace = 0.0;
785 child = _firstChild;
786 while (child != null) {
787 int flex = getFlex(child);
788 if (flex > 0) {
789 double spaceForChild = spacePerFlex * flex;
790 BoxConstraints constraints;
791 switch (_direction) {
792 case FlexDirection.Row:
ojan 2015/05/22 06:48:11 Not directly related to this patch, but I noticed
jackson 2015/05/22 20:06:55 Acknowledged.
793 constraints = new BoxConstraints(maxHeight: height, maxWidth: spaceF orChild);
abarth-chromium 2015/05/22 06:26:22 Do we want to set the minWidth to spaceForChild as
jackson 2015/05/22 20:06:54 Acknowledged.
794 break;
795 case FlexDirection.Column:
796 constraints = new BoxConstraints(maxHeight: spaceForChild, maxWidth: width);
abarth-chromium 2015/05/22 06:26:22 Same here for minHeight?
jackson 2015/05/22 20:06:55 Acknowledged.
797 break;
798 }
799 child.layout(constraints, relayoutSubtreeRoot: relayoutSubtreeRoot);
800 }
801
802 switch (_direction) {
803 // always center the item
804 case FlexDirection.Row:
805 child.parentData.x = usedSpace;
806 usedSpace += child.width;
807 child.parentData.y = height / 2 - child.height / 2;
808 break;
809 case FlexDirection.Column:
810 child.parentData.y = usedSpace;
811 usedSpace += child.height;
812 child.parentData.x = width / 2 - child.width / 2;
813 break;
814 }
815 child = child.parentData.nextSibling;
816 }
817 layoutDone();
818 }
819
820 void paint(RenderNodeDisplayList canvas) {
821 super.paint(canvas);
822 RenderBox child = _firstChild;
823 while (child != null) {
824 assert(child.parentData is FlexBoxParentData);
825 canvas.paintChild(child, child.parentData.x, child.parentData.y);
826 child = child.parentData.nextSibling;
827 }
828 }
829 }
726 830
727 // SCAFFOLD LAYOUT MANAGER 831 // SCAFFOLD LAYOUT MANAGER
728 832
729 // a sample special-purpose layout manager 833 // a sample special-purpose layout manager
730 834
731 class ScaffoldBox extends RenderBox { 835 class ScaffoldBox extends RenderBox {
732 836
733 ScaffoldBox(this.toolbar, this.body, this.statusbar, this.drawer) { 837 ScaffoldBox(this.toolbar, this.body, this.statusbar, this.drawer) {
734 assert(body != null); 838 assert(body != null);
735 } 839 }
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
791 canvas.paintChild(body, (body.parentData as BoxParentData).x, (body.parentDa ta as BoxParentData).y); 895 canvas.paintChild(body, (body.parentData as BoxParentData).x, (body.parentDa ta as BoxParentData).y);
792 if (statusbar != null) 896 if (statusbar != null)
793 canvas.paintChild(statusbar, (statusbar.parentData as BoxParentData).x, (s tatusbar.parentData as BoxParentData).y); 897 canvas.paintChild(statusbar, (statusbar.parentData as BoxParentData).x, (s tatusbar.parentData as BoxParentData).y);
794 if (toolbar != null) 898 if (toolbar != null)
795 canvas.paintChild(toolbar, (toolbar.parentData as BoxParentData).x, (toolb ar.parentData as BoxParentData).y); 899 canvas.paintChild(toolbar, (toolbar.parentData as BoxParentData).x, (toolb ar.parentData as BoxParentData).y);
796 if (drawer != null) 900 if (drawer != null)
797 canvas.paintChild(drawer, (drawer.parentData as BoxParentData).x, (drawer. parentData as BoxParentData).y); 901 canvas.paintChild(drawer, (drawer.parentData as BoxParentData).x, (drawer. parentData as BoxParentData).y);
798 } 902 }
799 903
800 } 904 }
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