| 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 |