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:math' as math; | 5 import 'dart:math' as math; |
6 | 6 |
7 import 'box.dart'; | 7 import 'box.dart'; |
8 import 'object.dart'; | 8 import 'object.dart'; |
9 | 9 |
10 class FlexBoxParentData extends BoxParentData with ContainerParentDataMixin<Rend
erBox> { | 10 class FlexBoxParentData extends BoxParentData with ContainerParentDataMixin<Rend
erBox> { |
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
103 RenderBox child = firstChild; | 103 RenderBox child = firstChild; |
104 while (child != null) { | 104 while (child != null) { |
105 int flex = _getFlex(child); | 105 int flex = _getFlex(child); |
106 totalFlex += flex; | 106 totalFlex += flex; |
107 if (flex > 0) { | 107 if (flex > 0) { |
108 double flexFraction = childSize(child, childConstraints) / _getFlex(ch
ild); | 108 double flexFraction = childSize(child, childConstraints) / _getFlex(ch
ild); |
109 maxFlexFractionSoFar = math.max(maxFlexFractionSoFar, flexFraction); | 109 maxFlexFractionSoFar = math.max(maxFlexFractionSoFar, flexFraction); |
110 } else { | 110 } else { |
111 inflexibleSpace += childSize(child, childConstraints); | 111 inflexibleSpace += childSize(child, childConstraints); |
112 } | 112 } |
| 113 assert(child.parentData is FlexBoxParentData); |
113 child = child.parentData.nextSibling; | 114 child = child.parentData.nextSibling; |
114 } | 115 } |
115 double mainSize = maxFlexFractionSoFar * totalFlex + inflexibleSpace; | 116 double mainSize = maxFlexFractionSoFar * totalFlex + inflexibleSpace; |
116 | 117 |
117 // Ensure that we don't violate the given constraints with our result | 118 // Ensure that we don't violate the given constraints with our result |
118 switch(_direction) { | 119 switch(_direction) { |
119 case FlexDirection.horizontal: | 120 case FlexDirection.horizontal: |
120 return constraints.constrainWidth(mainSize); | 121 return constraints.constrainWidth(mainSize); |
121 case FlexDirection.vertical: | 122 case FlexDirection.vertical: |
122 return constraints.constrainHeight(mainSize); | 123 return constraints.constrainHeight(mainSize); |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
165 case FlexDirection.vertical: | 166 case FlexDirection.vertical: |
166 mainSize = child.getMaxIntrinsicHeight(childConstraints); | 167 mainSize = child.getMaxIntrinsicHeight(childConstraints); |
167 BoxConstraints heightConstraints = | 168 BoxConstraints heightConstraints = |
168 new BoxConstraints(minWidth: mainSize, maxWidth: mainSize); | 169 new BoxConstraints(minWidth: mainSize, maxWidth: mainSize); |
169 crossSize = child.getMaxIntrinsicWidth(heightConstraints); | 170 crossSize = child.getMaxIntrinsicWidth(heightConstraints); |
170 break; | 171 break; |
171 } | 172 } |
172 inflexibleSpace += mainSize; | 173 inflexibleSpace += mainSize; |
173 maxCrossSize = math.max(maxCrossSize, crossSize); | 174 maxCrossSize = math.max(maxCrossSize, crossSize); |
174 } | 175 } |
| 176 assert(child.parentData is FlexBoxParentData); |
175 child = child.parentData.nextSibling; | 177 child = child.parentData.nextSibling; |
176 } | 178 } |
177 | 179 |
178 // Determine the spacePerFlex by allocating the remaining available space | 180 // Determine the spacePerFlex by allocating the remaining available space |
179 double spacePerFlex = (availableMainSpace - inflexibleSpace) / totalFlex; | 181 double spacePerFlex = (availableMainSpace - inflexibleSpace) / totalFlex; |
180 | 182 |
181 // Size remaining items, find the maximum cross size | 183 // Size remaining items, find the maximum cross size |
182 child = firstChild; | 184 child = firstChild; |
183 while (child != null) { | 185 while (child != null) { |
184 int flex = _getFlex(child); | 186 int flex = _getFlex(child); |
185 if (flex > 0) { | 187 if (flex > 0) { |
186 double childMainSize = spacePerFlex * flex; | 188 double childMainSize = spacePerFlex * flex; |
187 double crossSize; | 189 double crossSize; |
188 switch (_direction) { | 190 switch (_direction) { |
189 case FlexDirection.horizontal: | 191 case FlexDirection.horizontal: |
190 BoxConstraints childConstraints = | 192 BoxConstraints childConstraints = |
191 new BoxConstraints(minWidth: childMainSize, maxWidth: childMainS
ize); | 193 new BoxConstraints(minWidth: childMainSize, maxWidth: childMainS
ize); |
192 crossSize = child.getMaxIntrinsicHeight(childConstraints); | 194 crossSize = child.getMaxIntrinsicHeight(childConstraints); |
193 break; | 195 break; |
194 case FlexDirection.vertical: | 196 case FlexDirection.vertical: |
195 BoxConstraints childConstraints = | 197 BoxConstraints childConstraints = |
196 new BoxConstraints(minHeight: childMainSize, maxHeight: childMai
nSize); | 198 new BoxConstraints(minHeight: childMainSize, maxHeight: childMai
nSize); |
197 crossSize = child.getMaxIntrinsicWidth(childConstraints); | 199 crossSize = child.getMaxIntrinsicWidth(childConstraints); |
198 break; | 200 break; |
199 } | 201 } |
200 maxCrossSize = math.max(maxCrossSize, crossSize); | 202 maxCrossSize = math.max(maxCrossSize, crossSize); |
201 } | 203 } |
| 204 assert(child.parentData is FlexBoxParentData); |
202 child = child.parentData.nextSibling; | 205 child = child.parentData.nextSibling; |
203 } | 206 } |
204 | 207 |
205 // Ensure that we don't violate the given constraints with our result | 208 // Ensure that we don't violate the given constraints with our result |
206 switch(_direction) { | 209 switch(_direction) { |
207 case FlexDirection.horizontal: | 210 case FlexDirection.horizontal: |
208 return constraints.constrainHeight(maxCrossSize); | 211 return constraints.constrainHeight(maxCrossSize); |
209 case FlexDirection.vertical: | 212 case FlexDirection.vertical: |
210 return constraints.constrainWidth(maxCrossSize); | 213 return constraints.constrainWidth(maxCrossSize); |
211 } | 214 } |
(...skipping 24 matching lines...) Expand all Loading... |
236 ); | 239 ); |
237 } | 240 } |
238 | 241 |
239 double getMaxIntrinsicHeight(BoxConstraints constraints) { | 242 double getMaxIntrinsicHeight(BoxConstraints constraints) { |
240 return _getIntrinsicSize( | 243 return _getIntrinsicSize( |
241 constraints: constraints, | 244 constraints: constraints, |
242 sizingDirection: FlexDirection.vertical, | 245 sizingDirection: FlexDirection.vertical, |
243 childSize: (c, innerConstraints) => c.getMaxIntrinsicHeight(innerConstrain
ts)); | 246 childSize: (c, innerConstraints) => c.getMaxIntrinsicHeight(innerConstrain
ts)); |
244 } | 247 } |
245 | 248 |
| 249 double getDistanceToActualBaseline(TextBaseline baseline) { |
| 250 assert(!needsLayout); |
| 251 if (_direction == FlexDirection.horizontal) |
| 252 return defaultGetDistanceToHighestActualBaseline(baseline); |
| 253 return defaultGetDistanceToFirstActualBaseline(baseline); |
| 254 } |
| 255 |
246 int _getFlex(RenderBox child) { | 256 int _getFlex(RenderBox child) { |
247 assert(child.parentData is FlexBoxParentData); | 257 assert(child.parentData is FlexBoxParentData); |
248 return child.parentData.flex != null ? child.parentData.flex : 0; | 258 return child.parentData.flex != null ? child.parentData.flex : 0; |
249 } | 259 } |
250 | 260 |
251 double _getCrossSize(RenderBox child) { | 261 double _getCrossSize(RenderBox child) { |
252 return (_direction == FlexDirection.horizontal) ? child.size.height : child.
size.width; | 262 return (_direction == FlexDirection.horizontal) ? child.size.height : child.
size.width; |
253 } | 263 } |
254 | 264 |
255 double _getMainSize(RenderBox child) { | 265 double _getMainSize(RenderBox child) { |
256 return (_direction == FlexDirection.horizontal) ? child.size.width : child.s
ize.height; | 266 return (_direction == FlexDirection.horizontal) ? child.size.width : child.s
ize.height; |
257 } | 267 } |
258 | 268 |
259 void performLayout() { | 269 void performLayout() { |
260 // Based on http://www.w3.org/TR/css-flexbox-1/ Section 9.7 Resolving Flexib
le Lengths | 270 // Based on http://www.w3.org/TR/css-flexbox-1/ Section 9.7 Resolving Flexib
le Lengths |
261 // Steps 1-3. Determine used flex factor, size inflexible items, calculate f
ree space | 271 // Steps 1-3. Determine used flex factor, size inflexible items, calculate f
ree space |
262 int totalFlex = 0; | 272 int totalFlex = 0; |
263 int totalChildren = 0; | 273 int totalChildren = 0; |
264 assert(constraints != null); | 274 assert(constraints != null); |
265 final double mainSize = (_direction == FlexDirection.horizontal) ? constrain
ts.maxWidth : constraints.maxHeight; | 275 final double mainSize = (_direction == FlexDirection.horizontal) ? constrain
ts.maxWidth : constraints.maxHeight; |
266 double crossSize = 0.0; // This will be determined after laying out the chi
ldren | 276 double crossSize = 0.0; // This will be determined after laying out the chi
ldren |
267 double freeSpace = mainSize; | 277 double freeSpace = mainSize; |
268 RenderBox child = firstChild; | 278 RenderBox child = firstChild; |
269 while (child != null) { | 279 while (child != null) { |
| 280 assert(child.parentData is FlexBoxParentData); |
270 totalChildren++; | 281 totalChildren++; |
271 int flex = _getFlex(child); | 282 int flex = _getFlex(child); |
272 if (flex > 0) { | 283 if (flex > 0) { |
273 totalFlex += child.parentData.flex; | 284 totalFlex += child.parentData.flex; |
274 } else { | 285 } else { |
275 BoxConstraints innerConstraints = new BoxConstraints(maxHeight: constrai
nts.maxHeight, | 286 BoxConstraints innerConstraints = new BoxConstraints(maxHeight: constrai
nts.maxHeight, |
276 maxWidth: constrain
ts.maxWidth); | 287 maxWidth: constrain
ts.maxWidth); |
277 child.layout(innerConstraints, parentUsesSize: true); | 288 child.layout(innerConstraints, parentUsesSize: true); |
278 freeSpace -= _getMainSize(child); | 289 freeSpace -= _getMainSize(child); |
279 crossSize = math.max(crossSize, _getCrossSize(child)); | 290 crossSize = math.max(crossSize, _getCrossSize(child)); |
(...skipping 19 matching lines...) Expand all Loading... |
299 case FlexDirection.vertical: | 310 case FlexDirection.vertical: |
300 innerConstraints = new BoxConstraints(minHeight: spaceForChild, | 311 innerConstraints = new BoxConstraints(minHeight: spaceForChild, |
301 maxHeight: spaceForChild, | 312 maxHeight: spaceForChild, |
302 maxWidth: constraints.maxWidth
); | 313 maxWidth: constraints.maxWidth
); |
303 break; | 314 break; |
304 } | 315 } |
305 child.layout(innerConstraints, parentUsesSize: true); | 316 child.layout(innerConstraints, parentUsesSize: true); |
306 usedSpace += _getMainSize(child); | 317 usedSpace += _getMainSize(child); |
307 crossSize = math.max(crossSize, _getCrossSize(child)); | 318 crossSize = math.max(crossSize, _getCrossSize(child)); |
308 } | 319 } |
| 320 assert(child.parentData is FlexBoxParentData); |
309 child = child.parentData.nextSibling; | 321 child = child.parentData.nextSibling; |
310 } | 322 } |
311 | 323 |
312 // Section 8.2: Axis Alignment using the justify-content property | 324 // Section 8.2: Axis Alignment using the justify-content property |
313 double remainingSpace = math.max(0.0, freeSpace - usedSpace); | 325 double remainingSpace = math.max(0.0, freeSpace - usedSpace); |
314 double leadingSpace; | 326 double leadingSpace; |
315 double betweenSpace; | 327 double betweenSpace; |
316 child = firstChild; | 328 child = firstChild; |
317 switch (_justifyContent) { | 329 switch (_justifyContent) { |
318 case FlexJustifyContent.flexStart: | 330 case FlexJustifyContent.flexStart: |
(...skipping 26 matching lines...) Expand all Loading... |
345 case FlexDirection.vertical: | 357 case FlexDirection.vertical: |
346 size = constraints.constrain(new Size(crossSize, mainSize)); | 358 size = constraints.constrain(new Size(crossSize, mainSize)); |
347 crossSize = size.width; | 359 crossSize = size.width; |
348 break; | 360 break; |
349 } | 361 } |
350 | 362 |
351 // Position elements. For now, center the flex items in the cross direction | 363 // Position elements. For now, center the flex items in the cross direction |
352 double childMainPosition = leadingSpace; | 364 double childMainPosition = leadingSpace; |
353 child = firstChild; | 365 child = firstChild; |
354 while (child != null) { | 366 while (child != null) { |
| 367 assert(child.parentData is FlexBoxParentData); |
355 double childCrossPosition; | 368 double childCrossPosition; |
356 switch (_alignItems) { | 369 switch (_alignItems) { |
357 case FlexAlignItems.flexStart: | 370 case FlexAlignItems.flexStart: |
358 childCrossPosition = 0.0; | 371 childCrossPosition = 0.0; |
359 break; | 372 break; |
360 case FlexAlignItems.flexEnd: | 373 case FlexAlignItems.flexEnd: |
361 childCrossPosition = crossSize - _getCrossSize(child); | 374 childCrossPosition = crossSize - _getCrossSize(child); |
362 break; | 375 break; |
363 case FlexAlignItems.center: | 376 case FlexAlignItems.center: |
364 childCrossPosition = crossSize / 2.0 - _getCrossSize(child) / 2.0; | 377 childCrossPosition = crossSize / 2.0 - _getCrossSize(child) / 2.0; |
(...skipping 13 matching lines...) Expand all Loading... |
378 } | 391 } |
379 | 392 |
380 void hitTestChildren(HitTestResult result, { Point position }) { | 393 void hitTestChildren(HitTestResult result, { Point position }) { |
381 defaultHitTestChildren(result, position: position); | 394 defaultHitTestChildren(result, position: position); |
382 } | 395 } |
383 | 396 |
384 void paint(RenderCanvas canvas) { | 397 void paint(RenderCanvas canvas) { |
385 defaultPaint(canvas); | 398 defaultPaint(canvas); |
386 } | 399 } |
387 } | 400 } |
OLD | NEW |