| OLD | NEW |
| (Empty) |
| 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 | |
| 3 // found in the LICENSE file. | |
| 4 | |
| 5 import 'dart:sky' as sky; | |
| 6 import 'render_box.dart'; | |
| 7 import 'render_node.dart'; | |
| 8 | |
| 9 class FlexBoxParentData extends BoxParentData with ContainerParentDataMixin<Rend
erBox> { | |
| 10 int flex; | |
| 11 void merge(FlexBoxParentData other) { | |
| 12 if (other.flex != null) | |
| 13 flex = other.flex; | |
| 14 super.merge(other); | |
| 15 } | |
| 16 } | |
| 17 | |
| 18 enum FlexDirection { Horizontal, Vertical } | |
| 19 | |
| 20 class RenderFlex extends RenderBox with ContainerRenderNodeMixin<RenderBox, Flex
BoxParentData>, | |
| 21 RenderBoxContainerDefaultsMixin<RenderBo
x, FlexBoxParentData> { | |
| 22 // lays out RenderBox children using flexible layout | |
| 23 | |
| 24 RenderFlex({ | |
| 25 FlexDirection direction: FlexDirection.Horizontal | |
| 26 }) : _direction = direction; | |
| 27 | |
| 28 FlexDirection _direction; | |
| 29 FlexDirection get direction => _direction; | |
| 30 void set direction (FlexDirection value) { | |
| 31 if (_direction != value) { | |
| 32 _direction = value; | |
| 33 markNeedsLayout(); | |
| 34 } | |
| 35 } | |
| 36 | |
| 37 void setParentData(RenderBox child) { | |
| 38 if (child.parentData is! FlexBoxParentData) | |
| 39 child.parentData = new FlexBoxParentData(); | |
| 40 } | |
| 41 | |
| 42 bool get sizedByParent => true; | |
| 43 void performResize() { | |
| 44 size = constraints.constrain(new sky.Size(constraints.maxWidth, constraints.
maxHeight)); | |
| 45 assert(size.height < double.INFINITY); | |
| 46 assert(size.width < double.INFINITY); | |
| 47 } | |
| 48 | |
| 49 int _getFlex(RenderBox child) { | |
| 50 assert(child.parentData is FlexBoxParentData); | |
| 51 return child.parentData.flex != null ? child.parentData.flex : 0; | |
| 52 } | |
| 53 | |
| 54 void performLayout() { | |
| 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 | |
| 57 int totalFlex = 0; | |
| 58 assert(constraints != null); | |
| 59 double freeSpace = (_direction == FlexDirection.Horizontal) ? constraints.ma
xWidth : constraints.maxHeight; | |
| 60 RenderBox child = firstChild; | |
| 61 while (child != null) { | |
| 62 int flex = _getFlex(child); | |
| 63 if (flex > 0) { | |
| 64 totalFlex += child.parentData.flex; | |
| 65 } else { | |
| 66 BoxConstraints innerConstraints = new BoxConstraints(maxHeight: constrai
nts.maxHeight, | |
| 67 maxWidth: constrain
ts.maxWidth); | |
| 68 child.layout(innerConstraints, parentUsesSize: true); | |
| 69 freeSpace -= (_direction == FlexDirection.Horizontal) ? child.size.width
: child.size.height; | |
| 70 } | |
| 71 child = child.parentData.nextSibling; | |
| 72 } | |
| 73 | |
| 74 // Steps 4-5. Distribute remaining space to flexible children. | |
| 75 double spacePerFlex = totalFlex > 0 ? (freeSpace / totalFlex) : 0.0; | |
| 76 double usedSpace = 0.0; | |
| 77 child = firstChild; | |
| 78 while (child != null) { | |
| 79 int flex = _getFlex(child); | |
| 80 if (flex > 0) { | |
| 81 double spaceForChild = spacePerFlex * flex; | |
| 82 BoxConstraints innerConstraints; | |
| 83 switch (_direction) { | |
| 84 case FlexDirection.Horizontal: | |
| 85 innerConstraints = new BoxConstraints(maxHeight: constraints.maxHeig
ht, | |
| 86 minWidth: spaceForChild, | |
| 87 maxWidth: spaceForChild); | |
| 88 break; | |
| 89 case FlexDirection.Vertical: | |
| 90 innerConstraints = new BoxConstraints(minHeight: spaceForChild, | |
| 91 maxHeight: spaceForChild, | |
| 92 maxWidth: constraints.maxWidth
); | |
| 93 break; | |
| 94 } | |
| 95 child.layout(innerConstraints, parentUsesSize: true); | |
| 96 } | |
| 97 | |
| 98 // For now, center the flex items in the cross direction | |
| 99 switch (_direction) { | |
| 100 case FlexDirection.Horizontal: | |
| 101 child.parentData.position = new sky.Point(usedSpace, size.height / 2.0
- child.size.height / 2.0); | |
| 102 usedSpace += child.size.width; | |
| 103 break; | |
| 104 case FlexDirection.Vertical: | |
| 105 child.parentData.position = new sky.Point(size.width / 2.0 - child.siz
e.width / 2.0, usedSpace); | |
| 106 usedSpace += child.size.height; | |
| 107 break; | |
| 108 } | |
| 109 child = child.parentData.nextSibling; | |
| 110 } | |
| 111 } | |
| 112 | |
| 113 void hitTestChildren(HitTestResult result, { sky.Point position }) { | |
| 114 defaultHitTestChildren(result, position: position); | |
| 115 } | |
| 116 | |
| 117 void paint(RenderNodeDisplayList canvas) { | |
| 118 defaultPaint(canvas); | |
| 119 } | |
| 120 } | |
| OLD | NEW |