| 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 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; |
| (...skipping 212 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 223 constraints: constraints, | 223 constraints: constraints, |
| 224 sizingDirection: FlexDirection.vertical, | 224 sizingDirection: FlexDirection.vertical, |
| 225 childSize: (c, innerConstraints) => c.getMaxIntrinsicHeight(innerConstrain
ts)); | 225 childSize: (c, innerConstraints) => c.getMaxIntrinsicHeight(innerConstrain
ts)); |
| 226 } | 226 } |
| 227 | 227 |
| 228 int _getFlex(RenderBox child) { | 228 int _getFlex(RenderBox child) { |
| 229 assert(child.parentData is FlexBoxParentData); | 229 assert(child.parentData is FlexBoxParentData); |
| 230 return child.parentData.flex != null ? child.parentData.flex : 0; | 230 return child.parentData.flex != null ? child.parentData.flex : 0; |
| 231 } | 231 } |
| 232 | 232 |
| 233 double _getCrossSize(RenderBox child) { |
| 234 return (_direction == FlexDirection.horizontal) ? child.size.height : child.
size.width; |
| 235 } |
| 236 |
| 237 double _getMainSize(RenderBox child) { |
| 238 return (_direction == FlexDirection.horizontal) ? child.size.width : child.s
ize.height; |
| 239 } |
| 240 |
| 233 void performLayout() { | 241 void performLayout() { |
| 234 // Based on http://www.w3.org/TR/css-flexbox-1/ Section 9.7 Resolving Flexib
le Lengths | 242 // Based on http://www.w3.org/TR/css-flexbox-1/ Section 9.7 Resolving Flexib
le Lengths |
| 235 // Steps 1-3. Determine used flex factor, size inflexible items, calculate f
ree space | 243 // Steps 1-3. Determine used flex factor, size inflexible items, calculate f
ree space |
| 236 int totalFlex = 0; | 244 int totalFlex = 0; |
| 237 int totalChildren = 0; | 245 int totalChildren = 0; |
| 238 assert(constraints != null); | 246 assert(constraints != null); |
| 239 final double mainSize = (_direction == FlexDirection.horizontal) ? constrain
ts.maxWidth : constraints.maxHeight; | 247 final double mainSize = (_direction == FlexDirection.horizontal) ? constrain
ts.maxWidth : constraints.maxHeight; |
| 240 double crossSize = 0.0; // This will be determined after laying out the chi
ldren | 248 double crossSize = 0.0; // This will be determined after laying out the chi
ldren |
| 241 double freeSpace = mainSize; | 249 double freeSpace = mainSize; |
| 242 RenderBox child = firstChild; | 250 RenderBox child = firstChild; |
| 243 while (child != null) { | 251 while (child != null) { |
| 244 totalChildren++; | 252 totalChildren++; |
| 245 int flex = _getFlex(child); | 253 int flex = _getFlex(child); |
| 246 if (flex > 0) { | 254 if (flex > 0) { |
| 247 totalFlex += child.parentData.flex; | 255 totalFlex += child.parentData.flex; |
| 248 } else { | 256 } else { |
| 249 BoxConstraints innerConstraints = new BoxConstraints(maxHeight: constrai
nts.maxHeight, | 257 BoxConstraints innerConstraints = new BoxConstraints(maxHeight: constrai
nts.maxHeight, |
| 250 maxWidth: constrain
ts.maxWidth); | 258 maxWidth: constrain
ts.maxWidth); |
| 251 child.layout(innerConstraints, parentUsesSize: true); | 259 child.layout(innerConstraints, parentUsesSize: true); |
| 252 freeSpace -= (_direction == FlexDirection.horizontal) ? child.size.width
: child.size.height; | 260 freeSpace -= _getMainSize(child); |
| 261 crossSize = math.max(crossSize, _getCrossSize(child)); |
| 253 } | 262 } |
| 254 child = child.parentData.nextSibling; | 263 child = child.parentData.nextSibling; |
| 255 } | 264 } |
| 256 | 265 |
| 257 // Steps 4-5. Distribute remaining space to flexible children. | 266 // Steps 4-5. Distribute remaining space to flexible children. |
| 258 double spacePerFlex = totalFlex > 0 ? (freeSpace / totalFlex) : 0.0; | 267 double spacePerFlex = totalFlex > 0 ? (freeSpace / totalFlex) : 0.0; |
| 259 double usedSpace = 0.0; | 268 double usedSpace = 0.0; |
| 260 child = firstChild; | 269 child = firstChild; |
| 261 while (child != null) { | 270 while (child != null) { |
| 262 int flex = _getFlex(child); | 271 int flex = _getFlex(child); |
| 263 if (flex > 0) { | 272 if (flex > 0) { |
| 264 double spaceForChild = spacePerFlex * flex; | 273 double spaceForChild = spacePerFlex * flex; |
| 265 BoxConstraints innerConstraints; | 274 BoxConstraints innerConstraints; |
| 266 switch (_direction) { | 275 switch (_direction) { |
| 267 case FlexDirection.horizontal: | 276 case FlexDirection.horizontal: |
| 268 innerConstraints = new BoxConstraints(maxHeight: constraints.maxHeig
ht, | 277 innerConstraints = new BoxConstraints(maxHeight: constraints.maxHeig
ht, |
| 269 minWidth: spaceForChild, | 278 minWidth: spaceForChild, |
| 270 maxWidth: spaceForChild); | 279 maxWidth: spaceForChild); |
| 271 child.layout(innerConstraints, parentUsesSize: true); | |
| 272 usedSpace += child.size.width; | |
| 273 crossSize = math.max(crossSize, child.size.height); | |
| 274 break; | 280 break; |
| 275 case FlexDirection.vertical: | 281 case FlexDirection.vertical: |
| 276 innerConstraints = new BoxConstraints(minHeight: spaceForChild, | 282 innerConstraints = new BoxConstraints(minHeight: spaceForChild, |
| 277 maxHeight: spaceForChild, | 283 maxHeight: spaceForChild, |
| 278 maxWidth: constraints.maxWidth
); | 284 maxWidth: constraints.maxWidth
); |
| 279 child.layout(innerConstraints, parentUsesSize: true); | |
| 280 usedSpace += child.size.height; | |
| 281 crossSize = math.max(crossSize, child.size.width); | |
| 282 break; | 285 break; |
| 283 } | 286 } |
| 287 child.layout(innerConstraints, parentUsesSize: true); |
| 288 usedSpace += _getMainSize(child); |
| 289 crossSize = math.max(crossSize, _getCrossSize(child)); |
| 284 } | 290 } |
| 285 child = child.parentData.nextSibling; | 291 child = child.parentData.nextSibling; |
| 286 } | 292 } |
| 287 | 293 |
| 288 // Section 8.2: Axis Alignment using the justify-content property | 294 // Section 8.2: Axis Alignment using the justify-content property |
| 289 double remainingSpace = math.max(0.0, freeSpace - usedSpace); | 295 double remainingSpace = math.max(0.0, freeSpace - usedSpace); |
| 290 double leadingSpace; | 296 double leadingSpace; |
| 291 double betweenSpace; | 297 double betweenSpace; |
| 292 child = firstChild; | 298 child = firstChild; |
| 293 switch (_justifyContent) { | 299 switch (_justifyContent) { |
| (...skipping 15 matching lines...) Expand all Loading... |
| 309 break; | 315 break; |
| 310 case FlexJustifyContent.spaceAround: | 316 case FlexJustifyContent.spaceAround: |
| 311 betweenSpace = totalChildren > 0 ? remainingSpace / totalChildren : 0.0; | 317 betweenSpace = totalChildren > 0 ? remainingSpace / totalChildren : 0.0; |
| 312 leadingSpace = betweenSpace / 2.0; | 318 leadingSpace = betweenSpace / 2.0; |
| 313 break; | 319 break; |
| 314 } | 320 } |
| 315 | 321 |
| 316 switch (_direction) { | 322 switch (_direction) { |
| 317 case FlexDirection.horizontal: | 323 case FlexDirection.horizontal: |
| 318 size = constraints.constrain(new Size(mainSize, crossSize)); | 324 size = constraints.constrain(new Size(mainSize, crossSize)); |
| 325 crossSize = size.height; |
| 319 break; | 326 break; |
| 320 case FlexDirection.vertical: | 327 case FlexDirection.vertical: |
| 321 size = constraints.constrain(new Size(crossSize, mainSize)); | 328 size = constraints.constrain(new Size(crossSize, mainSize)); |
| 329 crossSize = size.width; |
| 322 break; | 330 break; |
| 323 } | 331 } |
| 324 | 332 |
| 325 // Position elements. For now, center the flex items in the cross direction | 333 // Position elements. For now, center the flex items in the cross direction |
| 326 double mainDimPosition = leadingSpace; | 334 double childMainPosition = leadingSpace; |
| 327 child = firstChild; | 335 child = firstChild; |
| 328 while (child != null) { | 336 while (child != null) { |
| 337 double childCrossPosition = crossSize / 2.0 - _getCrossSize(child) / 2.0; |
| 329 switch (_direction) { | 338 switch (_direction) { |
| 330 case FlexDirection.horizontal: | 339 case FlexDirection.horizontal: |
| 331 child.parentData.position = new Point(mainDimPosition, size.height / 2
.0 - child.size.height / 2.0); | 340 child.parentData.position = new Point(childMainPosition, childCrossPos
ition); |
| 332 mainDimPosition += child.size.width; | |
| 333 break; | 341 break; |
| 334 case FlexDirection.vertical: | 342 case FlexDirection.vertical: |
| 335 child.parentData.position = new Point(size.width / 2.0 - child.size.wi
dth / 2.0, mainDimPosition); | 343 child.parentData.position = new Point(childCrossPosition, childMainPos
ition); |
| 336 mainDimPosition += child.size.height; | |
| 337 break; | 344 break; |
| 338 } | 345 } |
| 339 mainDimPosition += betweenSpace; | 346 childMainPosition += _getMainSize(child) + betweenSpace; |
| 340 child = child.parentData.nextSibling; | 347 child = child.parentData.nextSibling; |
| 341 } | 348 } |
| 342 } | 349 } |
| 343 | 350 |
| 344 void hitTestChildren(HitTestResult result, { Point position }) { | 351 void hitTestChildren(HitTestResult result, { Point position }) { |
| 345 defaultHitTestChildren(result, position: position); | 352 defaultHitTestChildren(result, position: position); |
| 346 } | 353 } |
| 347 | 354 |
| 348 void paint(RenderObjectDisplayList canvas) { | 355 void paint(RenderObjectDisplayList canvas) { |
| 349 defaultPaint(canvas); | 356 defaultPaint(canvas); |
| 350 } | 357 } |
| 351 } | 358 } |
| OLD | NEW |