| 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:sky' as sky; | 5 import 'dart:sky' as sky; |
| 6 import 'box.dart'; | 6 import 'box.dart'; |
| 7 import 'object.dart'; | 7 import 'object.dart'; |
| 8 | 8 |
| 9 class FlexBoxParentData extends BoxParentData with ContainerParentDataMixin<Rend
erBox> { | 9 class FlexBoxParentData extends BoxParentData with ContainerParentDataMixin<Rend
erBox> { |
| 10 int flex; | 10 int flex; |
| 11 void merge(FlexBoxParentData other) { | 11 void merge(FlexBoxParentData other) { |
| 12 if (other.flex != null) | 12 if (other.flex != null) |
| 13 flex = other.flex; | 13 flex = other.flex; |
| 14 super.merge(other); | 14 super.merge(other); |
| 15 } | 15 } |
| 16 } | 16 } |
| 17 | 17 |
| 18 enum FlexDirection { Horizontal, Vertical } | 18 enum FlexDirection { horizontal, vertical } |
| 19 | 19 |
| 20 class RenderFlex extends RenderBox with ContainerRenderObjectMixin<RenderBox, Fl
exBoxParentData>, | 20 class RenderFlex extends RenderBox with ContainerRenderObjectMixin<RenderBox, Fl
exBoxParentData>, |
| 21 RenderBoxContainerDefaultsMixin<RenderBo
x, FlexBoxParentData> { | 21 RenderBoxContainerDefaultsMixin<RenderBo
x, FlexBoxParentData> { |
| 22 // lays out RenderBox children using flexible layout | 22 // lays out RenderBox children using flexible layout |
| 23 | 23 |
| 24 RenderFlex({ | 24 RenderFlex({ |
| 25 FlexDirection direction: FlexDirection.Horizontal | 25 FlexDirection direction: FlexDirection.horizontal |
| 26 }) : _direction = direction; | 26 }) : _direction = direction; |
| 27 | 27 |
| 28 FlexDirection _direction; | 28 FlexDirection _direction; |
| 29 FlexDirection get direction => _direction; | 29 FlexDirection get direction => _direction; |
| 30 void set direction (FlexDirection value) { | 30 void set direction (FlexDirection value) { |
| 31 if (_direction != value) { | 31 if (_direction != value) { |
| 32 _direction = value; | 32 _direction = value; |
| 33 markNeedsLayout(); | 33 markNeedsLayout(); |
| 34 } | 34 } |
| 35 } | 35 } |
| (...skipping 13 matching lines...) Expand all Loading... |
| 49 int _getFlex(RenderBox child) { | 49 int _getFlex(RenderBox child) { |
| 50 assert(child.parentData is FlexBoxParentData); | 50 assert(child.parentData is FlexBoxParentData); |
| 51 return child.parentData.flex != null ? child.parentData.flex : 0; | 51 return child.parentData.flex != null ? child.parentData.flex : 0; |
| 52 } | 52 } |
| 53 | 53 |
| 54 void performLayout() { | 54 void performLayout() { |
| 55 // Based on http://www.w3.org/TR/css-flexbox-1/ Section 9.7 Resolving Flexib
le Lengths | 55 // Based on http://www.w3.org/TR/css-flexbox-1/ Section 9.7 Resolving Flexib
le Lengths |
| 56 // Steps 1-3. Determine used flex factor, size inflexible items, calculate f
ree space | 56 // Steps 1-3. Determine used flex factor, size inflexible items, calculate f
ree space |
| 57 int totalFlex = 0; | 57 int totalFlex = 0; |
| 58 assert(constraints != null); | 58 assert(constraints != null); |
| 59 double freeSpace = (_direction == FlexDirection.Horizontal) ? constraints.ma
xWidth : constraints.maxHeight; | 59 double freeSpace = (_direction == FlexDirection.horizontal) ? constraints.ma
xWidth : constraints.maxHeight; |
| 60 RenderBox child = firstChild; | 60 RenderBox child = firstChild; |
| 61 while (child != null) { | 61 while (child != null) { |
| 62 int flex = _getFlex(child); | 62 int flex = _getFlex(child); |
| 63 if (flex > 0) { | 63 if (flex > 0) { |
| 64 totalFlex += child.parentData.flex; | 64 totalFlex += child.parentData.flex; |
| 65 } else { | 65 } else { |
| 66 BoxConstraints innerConstraints = new BoxConstraints(maxHeight: constrai
nts.maxHeight, | 66 BoxConstraints innerConstraints = new BoxConstraints(maxHeight: constrai
nts.maxHeight, |
| 67 maxWidth: constrain
ts.maxWidth); | 67 maxWidth: constrain
ts.maxWidth); |
| 68 child.layout(innerConstraints, parentUsesSize: true); | 68 child.layout(innerConstraints, parentUsesSize: true); |
| 69 freeSpace -= (_direction == FlexDirection.Horizontal) ? child.size.width
: child.size.height; | 69 freeSpace -= (_direction == FlexDirection.horizontal) ? child.size.width
: child.size.height; |
| 70 } | 70 } |
| 71 child = child.parentData.nextSibling; | 71 child = child.parentData.nextSibling; |
| 72 } | 72 } |
| 73 | 73 |
| 74 // Steps 4-5. Distribute remaining space to flexible children. | 74 // Steps 4-5. Distribute remaining space to flexible children. |
| 75 double spacePerFlex = totalFlex > 0 ? (freeSpace / totalFlex) : 0.0; | 75 double spacePerFlex = totalFlex > 0 ? (freeSpace / totalFlex) : 0.0; |
| 76 double usedSpace = 0.0; | 76 double usedSpace = 0.0; |
| 77 child = firstChild; | 77 child = firstChild; |
| 78 while (child != null) { | 78 while (child != null) { |
| 79 int flex = _getFlex(child); | 79 int flex = _getFlex(child); |
| 80 if (flex > 0) { | 80 if (flex > 0) { |
| 81 double spaceForChild = spacePerFlex * flex; | 81 double spaceForChild = spacePerFlex * flex; |
| 82 BoxConstraints innerConstraints; | 82 BoxConstraints innerConstraints; |
| 83 switch (_direction) { | 83 switch (_direction) { |
| 84 case FlexDirection.Horizontal: | 84 case FlexDirection.horizontal: |
| 85 innerConstraints = new BoxConstraints(maxHeight: constraints.maxHeig
ht, | 85 innerConstraints = new BoxConstraints(maxHeight: constraints.maxHeig
ht, |
| 86 minWidth: spaceForChild, | 86 minWidth: spaceForChild, |
| 87 maxWidth: spaceForChild); | 87 maxWidth: spaceForChild); |
| 88 break; | 88 break; |
| 89 case FlexDirection.Vertical: | 89 case FlexDirection.vertical: |
| 90 innerConstraints = new BoxConstraints(minHeight: spaceForChild, | 90 innerConstraints = new BoxConstraints(minHeight: spaceForChild, |
| 91 maxHeight: spaceForChild, | 91 maxHeight: spaceForChild, |
| 92 maxWidth: constraints.maxWidth
); | 92 maxWidth: constraints.maxWidth
); |
| 93 break; | 93 break; |
| 94 } | 94 } |
| 95 child.layout(innerConstraints, parentUsesSize: true); | 95 child.layout(innerConstraints, parentUsesSize: true); |
| 96 } | 96 } |
| 97 | 97 |
| 98 // For now, center the flex items in the cross direction | 98 // For now, center the flex items in the cross direction |
| 99 switch (_direction) { | 99 switch (_direction) { |
| 100 case FlexDirection.Horizontal: | 100 case FlexDirection.horizontal: |
| 101 child.parentData.position = new sky.Point(usedSpace, size.height / 2.0
- child.size.height / 2.0); | 101 child.parentData.position = new sky.Point(usedSpace, size.height / 2.0
- child.size.height / 2.0); |
| 102 usedSpace += child.size.width; | 102 usedSpace += child.size.width; |
| 103 break; | 103 break; |
| 104 case FlexDirection.Vertical: | 104 case FlexDirection.vertical: |
| 105 child.parentData.position = new sky.Point(size.width / 2.0 - child.siz
e.width / 2.0, usedSpace); | 105 child.parentData.position = new sky.Point(size.width / 2.0 - child.siz
e.width / 2.0, usedSpace); |
| 106 usedSpace += child.size.height; | 106 usedSpace += child.size.height; |
| 107 break; | 107 break; |
| 108 } | 108 } |
| 109 child = child.parentData.nextSibling; | 109 child = child.parentData.nextSibling; |
| 110 } | 110 } |
| 111 } | 111 } |
| 112 | 112 |
| 113 void hitTestChildren(HitTestResult result, { sky.Point position }) { | 113 void hitTestChildren(HitTestResult result, { sky.Point position }) { |
| 114 defaultHitTestChildren(result, position: position); | 114 defaultHitTestChildren(result, position: position); |
| 115 } | 115 } |
| 116 | 116 |
| 117 void paint(RenderObjectDisplayList canvas) { | 117 void paint(RenderObjectDisplayList canvas) { |
| 118 defaultPaint(canvas); | 118 defaultPaint(canvas); |
| 119 } | 119 } |
| 120 } | 120 } |
| OLD | NEW |