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 |