| 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; |
| 6 |
| 5 import 'box.dart'; | 7 import 'box.dart'; |
| 6 import 'object.dart'; | 8 import 'object.dart'; |
| 7 | 9 |
| 8 class StackParentData extends BoxParentData with ContainerParentDataMixin<Render
Box> { | 10 class StackParentData extends BoxParentData with ContainerParentDataMixin<Render
Box> { |
| 9 double top; | 11 double top; |
| 10 double right; | 12 double right; |
| 11 double bottom; | 13 double bottom; |
| 12 double left; | 14 double left; |
| 13 | 15 |
| 14 void merge(StackParentData other) { | 16 void merge(StackParentData other) { |
| 15 if (other.top != null) | 17 if (other.top != null) |
| 16 top = other.top; | 18 top = other.top; |
| 17 if (other.right != null) | 19 if (other.right != null) |
| 18 right = other.right; | 20 right = other.right; |
| 19 if (other.bottom != null) | 21 if (other.bottom != null) |
| 20 bottom = other.bottom; | 22 bottom = other.bottom; |
| 21 if (other.left != null) | 23 if (other.left != null) |
| 22 left = other.left; | 24 left = other.left; |
| 23 super.merge(other); | 25 super.merge(other); |
| 24 } | 26 } |
| 25 | 27 |
| 28 bool get isPositioned => top != null || right != null || bottom != null || lef
t != null; |
| 29 |
| 26 String toString() => '${super.toString()}; top=$top; right=$right; bottom=$bot
tom, left=$left'; | 30 String toString() => '${super.toString()}; top=$top; right=$right; bottom=$bot
tom, left=$left'; |
| 27 } | 31 } |
| 28 | 32 |
| 29 class RenderStack extends RenderBox with ContainerRenderObjectMixin<RenderBox, S
tackParentData>, | 33 class RenderStack extends RenderBox with ContainerRenderObjectMixin<RenderBox, S
tackParentData>, |
| 30 RenderBoxContainerDefaultsMixin<RenderB
ox, StackParentData> { | 34 RenderBoxContainerDefaultsMixin<RenderB
ox, StackParentData> { |
| 31 RenderStack({ | 35 RenderStack({ |
| 32 List<RenderBox> children | 36 List<RenderBox> children |
| 33 }) { | 37 }) { |
| 34 if (children != null) | 38 if (children != null) |
| 35 children.forEach((child) { add(child); }); | 39 children.forEach((child) { add(child); }); |
| 36 } | 40 } |
| 37 | 41 |
| 38 void setParentData(RenderBox child) { | 42 void setParentData(RenderBox child) { |
| 39 if (child.parentData is! StackParentData) | 43 if (child.parentData is! StackParentData) |
| 40 child.parentData = new StackParentData(); | 44 child.parentData = new StackParentData(); |
| 41 } | 45 } |
| 42 | 46 |
| 47 |
| 43 double getMinIntrinsicWidth(BoxConstraints constraints) { | 48 double getMinIntrinsicWidth(BoxConstraints constraints) { |
| 44 return constraints.constrainWidth(double.INFINITY); | 49 double width = constraints.minWidth; |
| 50 RenderBox child = firstChild; |
| 51 while (child != null) { |
| 52 assert(child.parentData is StackParentData); |
| 53 if (!child.parentData.isPositioned) |
| 54 width = math.max(width, child.getMinIntrinsicWidth(constraints)); |
| 55 child = child.parentData.nextSibling; |
| 56 } |
| 57 assert(width == constraints.constrainWidth(width)); |
| 58 return width; |
| 45 } | 59 } |
| 46 | 60 |
| 47 double getMaxIntrinsicWidth(BoxConstraints constraints) { | 61 double getMaxIntrinsicWidth(BoxConstraints constraints) { |
| 48 return constraints.constrainWidth(double.INFINITY); | 62 bool hasNonPositionedChildren = false; |
| 63 double width = constraints.minWidth; |
| 64 RenderBox child = firstChild; |
| 65 while (child != null) { |
| 66 assert(child.parentData is StackParentData); |
| 67 if (!child.parentData.isPositioned) { |
| 68 hasNonPositionedChildren = true; |
| 69 width = math.max(width, child.getMaxIntrinsicWidth(constraints)); |
| 70 } |
| 71 child = child.parentData.nextSibling; |
| 72 } |
| 73 if (!hasNonPositionedChildren) |
| 74 return constraints.constrainWidth(double.INFINITY); |
| 75 assert(width == constraints.constrainWidth(width)); |
| 76 return width; |
| 49 } | 77 } |
| 50 | 78 |
| 51 double getMinIntrinsicHeight(BoxConstraints constraints) { | 79 double getMinIntrinsicHeight(BoxConstraints constraints) { |
| 52 return constraints.constrainHeight(double.INFINITY); | 80 double height = constraints.minHeight; |
| 81 RenderBox child = firstChild; |
| 82 while (child != null) { |
| 83 assert(child.parentData is StackParentData); |
| 84 if (!child.parentData.isPositioned) |
| 85 height = math.max(height, child.getMinIntrinsicHeight(constraints)); |
| 86 child = child.parentData.nextSibling; |
| 87 } |
| 88 assert(height == constraints.constrainHeight(height)); |
| 89 return height; |
| 53 } | 90 } |
| 54 | 91 |
| 55 double getMaxIntrinsicHeight(BoxConstraints constraints) { | 92 double getMaxIntrinsicHeight(BoxConstraints constraints) { |
| 56 return constraints.constrainHeight(double.INFINITY); | 93 bool hasNonPositionedChildren = false; |
| 94 double height = constraints.minHeight; |
| 95 RenderBox child = firstChild; |
| 96 while (child != null) { |
| 97 assert(child.parentData is StackParentData); |
| 98 if (!child.parentData.isPositioned) { |
| 99 hasNonPositionedChildren = true; |
| 100 height = math.max(height, child.getMaxIntrinsicHeight(constraints)); |
| 101 } |
| 102 child = child.parentData.nextSibling; |
| 103 } |
| 104 if (!hasNonPositionedChildren) |
| 105 return constraints.constrainHeight(double.INFINITY); |
| 106 assert(height == constraints.constrainHeight(height)); |
| 107 return height; |
| 57 } | 108 } |
| 58 | 109 |
| 59 void performLayout() { | 110 void performLayout() { |
| 60 size = constraints.constrain(Size.infinite); | 111 bool hasNonPositionedChildren = false; |
| 61 assert(size.width < double.INFINITY); | 112 |
| 62 assert(size.height < double.INFINITY); | 113 double width = 0.0; |
| 63 BoxConstraints innerConstraints = new BoxConstraints.loose(size); | 114 double height = 0.0; |
| 64 | 115 |
| 65 RenderBox child = firstChild; | 116 RenderBox child = firstChild; |
| 66 while (child != null) { | 117 while (child != null) { |
| 67 assert(child.parentData is StackParentData); | 118 assert(child.parentData is StackParentData); |
| 68 StackParentData parentData = child.parentData; | 119 final StackParentData parentData = child.parentData; |
| 69 | 120 |
| 70 BoxConstraints childConstraints = innerConstraints; | 121 if (!parentData.isPositioned) { |
| 122 hasNonPositionedChildren = true; |
| 71 | 123 |
| 72 if (parentData.left != null && parentData.right != null) | 124 child.layout(constraints, parentUsesSize: true); |
| 73 childConstraints = childConstraints.applyWidth(parentData.right - parent
Data.left); | 125 parentData.position = Point.origin; |
| 74 else if (parentData.left != null) | |
| 75 childConstraints = childConstraints.applyMaxWidth(size.width - parentDat
a.left); | |
| 76 else if (parentData.right != null) | |
| 77 childConstraints = childConstraints.applyMaxWidth(size.width - parentDat
a.right); | |
| 78 | 126 |
| 79 if (parentData.top != null && parentData.bottom != null) | 127 final Size childSize = child.size; |
| 80 childConstraints = childConstraints.applyHeight(parentData.bottom - pare
ntData.top); | 128 width = math.max(width, childSize.width); |
| 81 else if (parentData.top != null) | 129 height = math.max(height, childSize.height); |
| 82 childConstraints = childConstraints.applyMaxHeight(size.height - parentD
ata.top); | 130 } |
| 83 else if (parentData.bottom != null) | |
| 84 childConstraints = childConstraints.applyMaxHeight(size.width - parentDa
ta.bottom); | |
| 85 | 131 |
| 86 child.layout(childConstraints); | 132 child = parentData.nextSibling; |
| 133 } |
| 87 | 134 |
| 88 double x = 0.0; | 135 if (hasNonPositionedChildren) |
| 89 if (parentData.left != null) | 136 size = new Size(width, height); |
| 90 x = parentData.left; | 137 else |
| 91 else if (parentData.right != null) | 138 size = constraints.constrain(Size.infinite); |
| 92 x = size.width - parentData.right - child.size.width; | |
| 93 assert(x >= 0.0 && x + child.size.width <= size.width); | |
| 94 | 139 |
| 95 double y = 0.0; | 140 assert(size.width < double.INFINITY); |
| 96 if (parentData.top != null) | 141 assert(size.height < double.INFINITY); |
| 97 y = parentData.top; | |
| 98 else if (parentData.bottom != null) | |
| 99 y = size.height - parentData.bottom - child.size.height; | |
| 100 assert(y >= 0.0 && y + child.size.height <= size.height); | |
| 101 | 142 |
| 102 parentData.position = new Point(x, y); | 143 BoxConstraints innerConstraints = new BoxConstraints.loose(size); |
| 103 | 144 |
| 104 child = child.parentData.nextSibling; | 145 child = firstChild; |
| 146 while (child != null) { |
| 147 assert(child.parentData is StackParentData); |
| 148 final StackParentData parentData = child.parentData; |
| 149 |
| 150 if (parentData.isPositioned) { |
| 151 BoxConstraints childConstraints = innerConstraints; |
| 152 |
| 153 if (parentData.left != null && parentData.right != null) |
| 154 childConstraints = childConstraints.applyWidth(parentData.right - pare
ntData.left); |
| 155 else if (parentData.left != null) |
| 156 childConstraints = childConstraints.applyMaxWidth(size.width - parentD
ata.left); |
| 157 else if (parentData.right != null) |
| 158 childConstraints = childConstraints.applyMaxWidth(size.width - parentD
ata.right); |
| 159 |
| 160 if (parentData.top != null && parentData.bottom != null) |
| 161 childConstraints = childConstraints.applyHeight(parentData.bottom - pa
rentData.top); |
| 162 else if (parentData.top != null) |
| 163 childConstraints = childConstraints.applyMaxHeight(size.height - paren
tData.top); |
| 164 else if (parentData.bottom != null) |
| 165 childConstraints = childConstraints.applyMaxHeight(size.width - parent
Data.bottom); |
| 166 |
| 167 child.layout(childConstraints); |
| 168 |
| 169 double x = 0.0; |
| 170 if (parentData.left != null) |
| 171 x = parentData.left; |
| 172 else if (parentData.right != null) |
| 173 x = size.width - parentData.right - child.size.width; |
| 174 assert(x >= 0.0 && x + child.size.width <= size.width); |
| 175 |
| 176 double y = 0.0; |
| 177 if (parentData.top != null) |
| 178 y = parentData.top; |
| 179 else if (parentData.bottom != null) |
| 180 y = size.height - parentData.bottom - child.size.height; |
| 181 assert(y >= 0.0 && y + child.size.height <= size.height); |
| 182 |
| 183 parentData.position = new Point(x, y); |
| 184 } |
| 185 |
| 186 child = parentData.nextSibling; |
| 105 } | 187 } |
| 106 } | 188 } |
| 107 | 189 |
| 108 void hitTestChildren(HitTestResult result, { Point position }) { | 190 void hitTestChildren(HitTestResult result, { Point position }) { |
| 109 defaultHitTestChildren(result, position: position); | 191 defaultHitTestChildren(result, position: position); |
| 110 } | 192 } |
| 111 | 193 |
| 112 void paint(RenderObjectDisplayList canvas) { | 194 void paint(RenderObjectDisplayList canvas) { |
| 113 defaultPaint(canvas); | 195 defaultPaint(canvas); |
| 114 } | 196 } |
| 115 } | 197 } |
| OLD | NEW |