| 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> { |
| 11 int flex; | 11 int flex; |
| 12 | 12 |
| 13 @override |
| 13 void merge(FlexBoxParentData other) { | 14 void merge(FlexBoxParentData other) { |
| 14 if (other.flex != null) | 15 if (other.flex != null) |
| 15 flex = other.flex; | 16 flex = other.flex; |
| 16 super.merge(other); | 17 super.merge(other); |
| 17 } | 18 } |
| 18 | 19 |
| 20 @override |
| 19 String toString() => '${super.toString()}; flex=$flex'; | 21 String toString() => '${super.toString()}; flex=$flex'; |
| 20 } | 22 } |
| 21 | 23 |
| 22 enum FlexDirection { horizontal, vertical } | 24 enum FlexDirection { horizontal, vertical } |
| 23 | 25 |
| 24 enum FlexJustifyContent { | 26 enum FlexJustifyContent { |
| 25 flexStart, | 27 flexStart, |
| 26 flexEnd, | 28 flexEnd, |
| 27 center, | 29 center, |
| 28 spaceBetween, | 30 spaceBetween, |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 67 | 69 |
| 68 FlexAlignItems _alignItems; | 70 FlexAlignItems _alignItems; |
| 69 FlexAlignItems get alignItems => _alignItems; | 71 FlexAlignItems get alignItems => _alignItems; |
| 70 void set alignItems (FlexAlignItems value) { | 72 void set alignItems (FlexAlignItems value) { |
| 71 if (_alignItems != value) { | 73 if (_alignItems != value) { |
| 72 _alignItems = value; | 74 _alignItems = value; |
| 73 markNeedsLayout(); | 75 markNeedsLayout(); |
| 74 } | 76 } |
| 75 } | 77 } |
| 76 | 78 |
| 79 @override |
| 77 void setupParentData(RenderBox child) { | 80 void setupParentData(RenderBox child) { |
| 78 if (child.parentData is! FlexBoxParentData) | 81 if (child.parentData is! FlexBoxParentData) |
| 79 child.parentData = new FlexBoxParentData(); | 82 child.parentData = new FlexBoxParentData(); |
| 80 } | 83 } |
| 81 | 84 |
| 82 double _getIntrinsicSize({ BoxConstraints constraints, | 85 double _getIntrinsicSize({ BoxConstraints constraints, |
| 83 FlexDirection sizingDirection, | 86 FlexDirection sizingDirection, |
| 84 _ChildSizingFunction childSize }) { | 87 _ChildSizingFunction childSize }) { |
| 85 // http://www.w3.org/TR/2015/WD-css-flexbox-1-20150514/#intrinsic-sizes | 88 // http://www.w3.org/TR/2015/WD-css-flexbox-1-20150514/#intrinsic-sizes |
| 86 if (_direction == sizingDirection) { | 89 if (_direction == sizingDirection) { |
| (...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 152 RenderBox child = firstChild; | 155 RenderBox child = firstChild; |
| 153 while (child != null) { | 156 while (child != null) { |
| 154 int flex = _getFlex(child); | 157 int flex = _getFlex(child); |
| 155 totalFlex += flex; | 158 totalFlex += flex; |
| 156 double mainSize; | 159 double mainSize; |
| 157 double crossSize; | 160 double crossSize; |
| 158 if (flex == 0) { | 161 if (flex == 0) { |
| 159 switch (_direction) { | 162 switch (_direction) { |
| 160 case FlexDirection.horizontal: | 163 case FlexDirection.horizontal: |
| 161 mainSize = child.getMaxIntrinsicWidth(childConstraints); | 164 mainSize = child.getMaxIntrinsicWidth(childConstraints); |
| 162 BoxConstraints widthConstraints = | 165 BoxConstraints widthConstraints = |
| 163 new BoxConstraints(minWidth: mainSize, maxWidth: mainSize); | 166 new BoxConstraints(minWidth: mainSize, maxWidth: mainSize); |
| 164 crossSize = child.getMaxIntrinsicHeight(widthConstraints); | 167 crossSize = child.getMaxIntrinsicHeight(widthConstraints); |
| 165 break; | 168 break; |
| 166 case FlexDirection.vertical: | 169 case FlexDirection.vertical: |
| 167 mainSize = child.getMaxIntrinsicHeight(childConstraints); | 170 mainSize = child.getMaxIntrinsicHeight(childConstraints); |
| 168 BoxConstraints heightConstraints = | 171 BoxConstraints heightConstraints = |
| 169 new BoxConstraints(minWidth: mainSize, maxWidth: mainSize); | 172 new BoxConstraints(minWidth: mainSize, maxWidth: mainSize); |
| 170 crossSize = child.getMaxIntrinsicWidth(heightConstraints); | 173 crossSize = child.getMaxIntrinsicWidth(heightConstraints); |
| 171 break; | 174 break; |
| 172 } | 175 } |
| 173 inflexibleSpace += mainSize; | 176 inflexibleSpace += mainSize; |
| 174 maxCrossSize = math.max(maxCrossSize, crossSize); | 177 maxCrossSize = math.max(maxCrossSize, crossSize); |
| 175 } | 178 } |
| 176 assert(child.parentData is FlexBoxParentData); | 179 assert(child.parentData is FlexBoxParentData); |
| 177 child = child.parentData.nextSibling; | 180 child = child.parentData.nextSibling; |
| 178 } | 181 } |
| 179 | 182 |
| 180 // Determine the spacePerFlex by allocating the remaining available space | 183 // Determine the spacePerFlex by allocating the remaining available space |
| 181 double spacePerFlex = (availableMainSpace - inflexibleSpace) / totalFlex; | 184 double spacePerFlex = (availableMainSpace - inflexibleSpace) / totalFlex; |
| 182 | 185 |
| 183 // Size remaining items, find the maximum cross size | 186 // Size remaining items, find the maximum cross size |
| 184 child = firstChild; | 187 child = firstChild; |
| 185 while (child != null) { | 188 while (child != null) { |
| 186 int flex = _getFlex(child); | 189 int flex = _getFlex(child); |
| 187 if (flex > 0) { | 190 if (flex > 0) { |
| 188 double childMainSize = spacePerFlex * flex; | 191 double childMainSize = spacePerFlex * flex; |
| 189 double crossSize; | 192 double crossSize; |
| 190 switch (_direction) { | 193 switch (_direction) { |
| 191 case FlexDirection.horizontal: | 194 case FlexDirection.horizontal: |
| 192 BoxConstraints childConstraints = | 195 BoxConstraints childConstraints = |
| 193 new BoxConstraints(minWidth: childMainSize, maxWidth: childMainS
ize); | 196 new BoxConstraints(minWidth: childMainSize, maxWidth: childMainS
ize); |
| 194 crossSize = child.getMaxIntrinsicHeight(childConstraints); | 197 crossSize = child.getMaxIntrinsicHeight(childConstraints); |
| 195 break; | 198 break; |
| 196 case FlexDirection.vertical: | 199 case FlexDirection.vertical: |
| 197 BoxConstraints childConstraints = | 200 BoxConstraints childConstraints = |
| 198 new BoxConstraints(minHeight: childMainSize, maxHeight: childMai
nSize); | 201 new BoxConstraints(minHeight: childMainSize, maxHeight: childMai
nSize); |
| 199 crossSize = child.getMaxIntrinsicWidth(childConstraints); | 202 crossSize = child.getMaxIntrinsicWidth(childConstraints); |
| 200 break; | 203 break; |
| 201 } | 204 } |
| 202 maxCrossSize = math.max(maxCrossSize, crossSize); | 205 maxCrossSize = math.max(maxCrossSize, crossSize); |
| 203 } | 206 } |
| 204 assert(child.parentData is FlexBoxParentData); | 207 assert(child.parentData is FlexBoxParentData); |
| 205 child = child.parentData.nextSibling; | 208 child = child.parentData.nextSibling; |
| 206 } | 209 } |
| 207 | 210 |
| 208 // Ensure that we don't violate the given constraints with our result | 211 // Ensure that we don't violate the given constraints with our result |
| 209 switch(_direction) { | 212 switch(_direction) { |
| 210 case FlexDirection.horizontal: | 213 case FlexDirection.horizontal: |
| 211 return constraints.constrainHeight(maxCrossSize); | 214 return constraints.constrainHeight(maxCrossSize); |
| 212 case FlexDirection.vertical: | 215 case FlexDirection.vertical: |
| 213 return constraints.constrainWidth(maxCrossSize); | 216 return constraints.constrainWidth(maxCrossSize); |
| 214 } | 217 } |
| 215 } | 218 } |
| 216 } | 219 } |
| 217 | 220 |
| 221 @override |
| 218 double getMinIntrinsicWidth(BoxConstraints constraints) { | 222 double getMinIntrinsicWidth(BoxConstraints constraints) { |
| 219 return _getIntrinsicSize( | 223 return _getIntrinsicSize( |
| 220 constraints: constraints, | 224 constraints: constraints, |
| 221 sizingDirection: FlexDirection.horizontal, | 225 sizingDirection: FlexDirection.horizontal, |
| 222 childSize: (c, innerConstraints) => c.getMinIntrinsicWidth(innerConstraint
s) | 226 childSize: (c, innerConstraints) => c.getMinIntrinsicWidth(innerConstraint
s) |
| 223 ); | 227 ); |
| 224 } | 228 } |
| 225 | 229 |
| 230 @override |
| 226 double getMaxIntrinsicWidth(BoxConstraints constraints) { | 231 double getMaxIntrinsicWidth(BoxConstraints constraints) { |
| 227 return _getIntrinsicSize( | 232 return _getIntrinsicSize( |
| 228 constraints: constraints, | 233 constraints: constraints, |
| 229 sizingDirection: FlexDirection.horizontal, | 234 sizingDirection: FlexDirection.horizontal, |
| 230 childSize: (c, innerConstraints) => c.getMaxIntrinsicWidth(innerConstraint
s) | 235 childSize: (c, innerConstraints) => c.getMaxIntrinsicWidth(innerConstraint
s) |
| 231 ); | 236 ); |
| 232 } | 237 } |
| 233 | 238 |
| 239 @override |
| 234 double getMinIntrinsicHeight(BoxConstraints constraints) { | 240 double getMinIntrinsicHeight(BoxConstraints constraints) { |
| 235 return _getIntrinsicSize( | 241 return _getIntrinsicSize( |
| 236 constraints: constraints, | 242 constraints: constraints, |
| 237 sizingDirection: FlexDirection.vertical, | 243 sizingDirection: FlexDirection.vertical, |
| 238 childSize: (c, innerConstraints) => c.getMinIntrinsicHeight(innerConstrain
ts) | 244 childSize: (c, innerConstraints) => c.getMinIntrinsicHeight(innerConstrain
ts) |
| 239 ); | 245 ); |
| 240 } | 246 } |
| 241 | 247 |
| 248 @override |
| 242 double getMaxIntrinsicHeight(BoxConstraints constraints) { | 249 double getMaxIntrinsicHeight(BoxConstraints constraints) { |
| 243 return _getIntrinsicSize( | 250 return _getIntrinsicSize( |
| 244 constraints: constraints, | 251 constraints: constraints, |
| 245 sizingDirection: FlexDirection.vertical, | 252 sizingDirection: FlexDirection.vertical, |
| 246 childSize: (c, innerConstraints) => c.getMaxIntrinsicHeight(innerConstrain
ts)); | 253 childSize: (c, innerConstraints) => c.getMaxIntrinsicHeight(innerConstrain
ts)); |
| 247 } | 254 } |
| 248 | 255 |
| 256 @override |
| 249 double computeDistanceToActualBaseline(TextBaseline baseline) { | 257 double computeDistanceToActualBaseline(TextBaseline baseline) { |
| 250 if (_direction == FlexDirection.horizontal) | 258 if (_direction == FlexDirection.horizontal) |
| 251 return defaultComputeDistanceToHighestActualBaseline(baseline); | 259 return defaultComputeDistanceToHighestActualBaseline(baseline); |
| 252 return defaultComputeDistanceToFirstActualBaseline(baseline); | 260 return defaultComputeDistanceToFirstActualBaseline(baseline); |
| 253 } | 261 } |
| 254 | 262 |
| 255 int _getFlex(RenderBox child) { | 263 int _getFlex(RenderBox child) { |
| 256 assert(child.parentData is FlexBoxParentData); | 264 assert(child.parentData is FlexBoxParentData); |
| 257 return child.parentData.flex != null ? child.parentData.flex : 0; | 265 return child.parentData.flex != null ? child.parentData.flex : 0; |
| 258 } | 266 } |
| 259 | 267 |
| 260 double _getCrossSize(RenderBox child) { | 268 double _getCrossSize(RenderBox child) { |
| 261 return (_direction == FlexDirection.horizontal) ? child.size.height : child.
size.width; | 269 return (_direction == FlexDirection.horizontal) ? child.size.height : child.
size.width; |
| 262 } | 270 } |
| 263 | 271 |
| 264 double _getMainSize(RenderBox child) { | 272 double _getMainSize(RenderBox child) { |
| 265 return (_direction == FlexDirection.horizontal) ? child.size.width : child.s
ize.height; | 273 return (_direction == FlexDirection.horizontal) ? child.size.width : child.s
ize.height; |
| 266 } | 274 } |
| 267 | 275 |
| 276 @override |
| 268 void performLayout() { | 277 void performLayout() { |
| 269 // Based on http://www.w3.org/TR/css-flexbox-1/ Section 9.7 Resolving Flexib
le Lengths | 278 // Based on http://www.w3.org/TR/css-flexbox-1/ Section 9.7 Resolving Flexib
le Lengths |
| 270 // Steps 1-3. Determine used flex factor, size inflexible items, calculate f
ree space | 279 // Steps 1-3. Determine used flex factor, size inflexible items, calculate f
ree space |
| 271 int totalFlex = 0; | 280 int totalFlex = 0; |
| 272 int totalChildren = 0; | 281 int totalChildren = 0; |
| 273 assert(constraints != null); | 282 assert(constraints != null); |
| 274 final double mainSize = (_direction == FlexDirection.horizontal) ? constrain
ts.maxWidth : constraints.maxHeight; | 283 final double mainSize = (_direction == FlexDirection.horizontal) ? constrain
ts.maxWidth : constraints.maxHeight; |
| 275 double crossSize = 0.0; // This will be determined after laying out the chi
ldren | 284 double crossSize = 0.0; // This will be determined after laying out the chi
ldren |
| 276 double freeSpace = mainSize; | 285 double freeSpace = mainSize; |
| 277 RenderBox child = firstChild; | 286 RenderBox child = firstChild; |
| (...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 382 break; | 391 break; |
| 383 case FlexDirection.vertical: | 392 case FlexDirection.vertical: |
| 384 child.parentData.position = new Point(childCrossPosition, childMainPos
ition); | 393 child.parentData.position = new Point(childCrossPosition, childMainPos
ition); |
| 385 break; | 394 break; |
| 386 } | 395 } |
| 387 childMainPosition += _getMainSize(child) + betweenSpace; | 396 childMainPosition += _getMainSize(child) + betweenSpace; |
| 388 child = child.parentData.nextSibling; | 397 child = child.parentData.nextSibling; |
| 389 } | 398 } |
| 390 } | 399 } |
| 391 | 400 |
| 401 @override |
| 392 void hitTestChildren(HitTestResult result, { Point position }) { | 402 void hitTestChildren(HitTestResult result, { Point position }) { |
| 393 defaultHitTestChildren(result, position: position); | 403 defaultHitTestChildren(result, position: position); |
| 394 } | 404 } |
| 395 | 405 |
| 406 @override |
| 396 void paint(PaintingCanvas canvas, Offset offset) { | 407 void paint(PaintingCanvas canvas, Offset offset) { |
| 397 defaultPaint(canvas, offset); | 408 defaultPaint(canvas, offset); |
| 398 } | 409 } |
| 399 } | 410 } |
| OLD | NEW |