Commit d8283d1c authored by Ian Hickson's avatar Ian Hickson

RenderPadding's intrinsic should clamp child dims (#4329)

We used to rely on BoxConstraints.deflate's clamping, but now we have to
roll our own.
parent dd27a489
...@@ -206,6 +206,7 @@ class RenderImage extends RenderBox { ...@@ -206,6 +206,7 @@ class RenderImage extends RenderBox {
@override @override
double getMinIntrinsicWidth(double height) { double getMinIntrinsicWidth(double height) {
assert(height >= 0.0);
if (_width == null && _height == null) if (_width == null && _height == null)
return 0.0; return 0.0;
return _sizeForConstraints(new BoxConstraints.tightForFinite(height: height)).width; return _sizeForConstraints(new BoxConstraints.tightForFinite(height: height)).width;
...@@ -213,11 +214,13 @@ class RenderImage extends RenderBox { ...@@ -213,11 +214,13 @@ class RenderImage extends RenderBox {
@override @override
double getMaxIntrinsicWidth(double height) { double getMaxIntrinsicWidth(double height) {
assert(height >= 0.0);
return _sizeForConstraints(new BoxConstraints.tightForFinite(height: height)).width; return _sizeForConstraints(new BoxConstraints.tightForFinite(height: height)).width;
} }
@override @override
double getMinIntrinsicHeight(double width) { double getMinIntrinsicHeight(double width) {
assert(width >= 0.0);
if (_width == null && _height == null) if (_width == null && _height == null)
return 0.0; return 0.0;
return _sizeForConstraints(new BoxConstraints.tightForFinite(width: width)).height; return _sizeForConstraints(new BoxConstraints.tightForFinite(width: width)).height;
...@@ -225,6 +228,7 @@ class RenderImage extends RenderBox { ...@@ -225,6 +228,7 @@ class RenderImage extends RenderBox {
@override @override
double getMaxIntrinsicHeight(double width) { double getMaxIntrinsicHeight(double width) {
assert(width >= 0.0);
return _sizeForConstraints(new BoxConstraints.tightForFinite(width: width)).height; return _sizeForConstraints(new BoxConstraints.tightForFinite(width: width)).height;
} }
......
...@@ -115,7 +115,7 @@ class RenderPadding extends RenderShiftedBox { ...@@ -115,7 +115,7 @@ class RenderPadding extends RenderShiftedBox {
final double totalHorizontalPadding = padding.left + padding.right; final double totalHorizontalPadding = padding.left + padding.right;
final double totalVerticalPadding = padding.top + padding.bottom; final double totalVerticalPadding = padding.top + padding.bottom;
if (child != null) // next line relies on double.INFINITY absorption if (child != null) // next line relies on double.INFINITY absorption
return child.getMinIntrinsicWidth(height - totalVerticalPadding) + totalHorizontalPadding; return child.getMinIntrinsicWidth(math.max(0.0, height - totalVerticalPadding)) + totalHorizontalPadding;
return totalHorizontalPadding; return totalHorizontalPadding;
} }
...@@ -124,7 +124,7 @@ class RenderPadding extends RenderShiftedBox { ...@@ -124,7 +124,7 @@ class RenderPadding extends RenderShiftedBox {
final double totalHorizontalPadding = padding.left + padding.right; final double totalHorizontalPadding = padding.left + padding.right;
final double totalVerticalPadding = padding.top + padding.bottom; final double totalVerticalPadding = padding.top + padding.bottom;
if (child != null) // next line relies on double.INFINITY absorption if (child != null) // next line relies on double.INFINITY absorption
return child.getMaxIntrinsicWidth(height - totalVerticalPadding) + totalHorizontalPadding; return child.getMaxIntrinsicWidth(math.max(0.0, height - totalVerticalPadding)) + totalHorizontalPadding;
return totalHorizontalPadding; return totalHorizontalPadding;
} }
...@@ -133,7 +133,7 @@ class RenderPadding extends RenderShiftedBox { ...@@ -133,7 +133,7 @@ class RenderPadding extends RenderShiftedBox {
final double totalHorizontalPadding = padding.left + padding.right; final double totalHorizontalPadding = padding.left + padding.right;
final double totalVerticalPadding = padding.top + padding.bottom; final double totalVerticalPadding = padding.top + padding.bottom;
if (child != null) // next line relies on double.INFINITY absorption if (child != null) // next line relies on double.INFINITY absorption
return child.getMinIntrinsicHeight(width - totalHorizontalPadding) + totalVerticalPadding; return child.getMinIntrinsicHeight(math.max(0.0, width - totalHorizontalPadding)) + totalVerticalPadding;
return totalVerticalPadding; return totalVerticalPadding;
} }
...@@ -142,7 +142,7 @@ class RenderPadding extends RenderShiftedBox { ...@@ -142,7 +142,7 @@ class RenderPadding extends RenderShiftedBox {
final double totalHorizontalPadding = padding.left + padding.right; final double totalHorizontalPadding = padding.left + padding.right;
final double totalVerticalPadding = padding.top + padding.bottom; final double totalVerticalPadding = padding.top + padding.bottom;
if (child != null) // next line relies on double.INFINITY absorption if (child != null) // next line relies on double.INFINITY absorption
return child.getMaxIntrinsicHeight(width - totalHorizontalPadding) + totalVerticalPadding; return child.getMaxIntrinsicHeight(math.max(0.0, width - totalHorizontalPadding)) + totalVerticalPadding;
return totalVerticalPadding; return totalVerticalPadding;
} }
......
...@@ -28,25 +28,25 @@ void main() { ...@@ -28,25 +28,25 @@ void main() {
expect(parent.size, equals(new Size(100.0, 0.0))); expect(parent.size, equals(new Size(100.0, 0.0)));
parent.baseline = 25.0; parent.baseline = 25.0;
layout(root, phase: EnginePhase.layout); pumpFrame(phase: EnginePhase.layout);
expect(childParentData.offset.dx, equals(0.0)); expect(childParentData.offset.dx, equals(0.0));
expect(childParentData.offset.dy, equals(-75.0)); expect(childParentData.offset.dy, equals(-75.0));
expect(parent.size, equals(new Size(100.0, 25.0))); expect(parent.size, equals(new Size(100.0, 25.0)));
parent.baseline = 90.0; parent.baseline = 90.0;
layout(root, phase: EnginePhase.layout); pumpFrame(phase: EnginePhase.layout);
expect(childParentData.offset.dx, equals(0.0)); expect(childParentData.offset.dx, equals(0.0));
expect(childParentData.offset.dy, equals(-10.0)); expect(childParentData.offset.dy, equals(-10.0));
expect(parent.size, equals(new Size(100.0, 90.0))); expect(parent.size, equals(new Size(100.0, 90.0)));
parent.baseline = 100.0; parent.baseline = 100.0;
layout(root, phase: EnginePhase.layout); pumpFrame(phase: EnginePhase.layout);
expect(childParentData.offset.dx, equals(0.0)); expect(childParentData.offset.dx, equals(0.0));
expect(childParentData.offset.dy, equals(0.0)); expect(childParentData.offset.dy, equals(0.0));
expect(parent.size, equals(new Size(100.0, 100.0))); expect(parent.size, equals(new Size(100.0, 100.0)));
parent.baseline = 110.0; parent.baseline = 110.0;
layout(root, phase: EnginePhase.layout); pumpFrame(phase: EnginePhase.layout);
expect(childParentData.offset.dx, equals(0.0)); expect(childParentData.offset.dx, equals(0.0));
expect(childParentData.offset.dy, equals(10.0)); expect(childParentData.offset.dy, equals(10.0));
expect(parent.size, equals(new Size(100.0, 110.0))); expect(parent.size, equals(new Size(100.0, 110.0)));
......
...@@ -49,11 +49,13 @@ void main() { ...@@ -49,11 +49,13 @@ void main() {
RenderBox parent = new RenderIntrinsicWidth(child: child); RenderBox parent = new RenderIntrinsicWidth(child: child);
layout(parent, layout(parent,
constraints: new BoxConstraints( constraints: new BoxConstraints(
minWidth: 5.0, minWidth: 5.0,
minHeight: 8.0, minHeight: 8.0,
maxWidth: 500.0, maxWidth: 500.0,
maxHeight: 800.0)); maxHeight: 800.0
)
);
expect(parent.size.width, equals(100.0)); expect(parent.size.width, equals(100.0));
expect(parent.size.height, equals(110.0)); expect(parent.size.height, equals(110.0));
}); });
...@@ -63,12 +65,90 @@ void main() { ...@@ -63,12 +65,90 @@ void main() {
RenderBox parent = new RenderIntrinsicHeight(child: child); RenderBox parent = new RenderIntrinsicHeight(child: child);
layout(parent, layout(parent,
constraints: new BoxConstraints( constraints: new BoxConstraints(
minWidth: 5.0, minWidth: 5.0,
minHeight: 8.0, minHeight: 8.0,
maxWidth: 500.0, maxWidth: 500.0,
maxHeight: 800.0)); maxHeight: 800.0
)
);
expect(parent.size.width, equals(55.0)); expect(parent.size.width, equals(55.0));
expect(parent.size.height, equals(200.0)); expect(parent.size.height, equals(200.0));
}); });
test('Padding and boring intrinsics', () {
RenderBox box = new RenderPadding(
padding: new EdgeInsets.all(15.0),
child: new RenderSizedBox(const Size(20.0, 20.0))
);
expect(box.getMinIntrinsicWidth(0.0), 50.0);
expect(box.getMaxIntrinsicWidth(0.0), 50.0);
expect(box.getMinIntrinsicHeight(0.0), 50.0);
expect(box.getMaxIntrinsicHeight(0.0), 50.0);
expect(box.getMinIntrinsicWidth(10.0), 50.0);
expect(box.getMaxIntrinsicWidth(10.0), 50.0);
expect(box.getMinIntrinsicHeight(10.0), 50.0);
expect(box.getMaxIntrinsicHeight(10.0), 50.0);
expect(box.getMinIntrinsicWidth(80.0), 50.0);
expect(box.getMaxIntrinsicWidth(80.0), 50.0);
expect(box.getMinIntrinsicHeight(80.0), 50.0);
expect(box.getMaxIntrinsicHeight(80.0), 50.0);
expect(box.getMinIntrinsicWidth(double.INFINITY), 50.0);
expect(box.getMaxIntrinsicWidth(double.INFINITY), 50.0);
expect(box.getMinIntrinsicHeight(double.INFINITY), 50.0);
expect(box.getMaxIntrinsicHeight(double.INFINITY), 50.0);
// also a smoke test:
layout(
box,
constraints: new BoxConstraints(
minWidth: 10.0,
minHeight: 10.0,
maxWidth: 10.0,
maxHeight: 10.0
)
);
});
test('Padding and interesting intrinsics', () {
RenderBox box = new RenderPadding(
padding: new EdgeInsets.all(15.0),
child: new RenderAspectRatio(aspectRatio: 1.0)
);
expect(box.getMinIntrinsicWidth(0.0), 30.0);
expect(box.getMaxIntrinsicWidth(0.0), 30.0);
expect(box.getMinIntrinsicHeight(0.0), 30.0);
expect(box.getMaxIntrinsicHeight(0.0), 30.0);
expect(box.getMinIntrinsicWidth(10.0), 30.0);
expect(box.getMaxIntrinsicWidth(10.0), 30.0);
expect(box.getMinIntrinsicHeight(10.0), 30.0);
expect(box.getMaxIntrinsicHeight(10.0), 30.0);
expect(box.getMinIntrinsicWidth(80.0), 80.0);
expect(box.getMaxIntrinsicWidth(80.0), 80.0);
expect(box.getMinIntrinsicHeight(80.0), 80.0);
expect(box.getMaxIntrinsicHeight(80.0), 80.0);
expect(box.getMinIntrinsicWidth(double.INFINITY), 30.0);
expect(box.getMaxIntrinsicWidth(double.INFINITY), 30.0);
expect(box.getMinIntrinsicHeight(double.INFINITY), 30.0);
expect(box.getMaxIntrinsicHeight(double.INFINITY), 30.0);
// also a smoke test:
layout(
box,
constraints: new BoxConstraints(
minWidth: 10.0,
minHeight: 10.0,
maxWidth: 10.0,
maxHeight: 10.0
)
);
});
} }
...@@ -46,7 +46,8 @@ TestRenderingFlutterBinding _renderer; ...@@ -46,7 +46,8 @@ TestRenderingFlutterBinding _renderer;
TestRenderingFlutterBinding get renderer => _renderer; TestRenderingFlutterBinding get renderer => _renderer;
void layout(RenderBox box, { BoxConstraints constraints, EnginePhase phase: EnginePhase.layout }) { void layout(RenderBox box, { BoxConstraints constraints, EnginePhase phase: EnginePhase.layout }) {
assert(box != null); // if you want to just repump the last box, call pumpFrame(). assert(box != null); // If you want to just repump the last box, call pumpFrame().
assert(box.parent == null); // We stick the box in another, so you can't reuse it easily, sorry.
_renderer ??= new TestRenderingFlutterBinding(); _renderer ??= new TestRenderingFlutterBinding();
......
...@@ -25,13 +25,13 @@ void main() { ...@@ -25,13 +25,13 @@ void main() {
); );
layout(a, phase: EnginePhase.flushSemantics); layout(a, phase: EnginePhase.flushSemantics);
c.opacity = 0.9; c.opacity = 0.9;
layout(a, phase: EnginePhase.flushSemantics); pumpFrame(phase: EnginePhase.flushSemantics);
a.opacity = 0.8; a.opacity = 0.8;
c.opacity = 0.8; c.opacity = 0.8;
layout(a, phase: EnginePhase.flushSemantics); pumpFrame(phase: EnginePhase.flushSemantics);
a.opacity = 0.7; a.opacity = 0.7;
b.opacity = 0.7; b.opacity = 0.7;
c.opacity = 0.7; c.opacity = 0.7;
layout(a, phase: EnginePhase.flushSemantics); pumpFrame(phase: EnginePhase.flushSemantics);
}); });
} }
...@@ -84,10 +84,10 @@ void main() { ...@@ -84,10 +84,10 @@ void main() {
layout(table); layout(table);
table.setFlatChildren(3, <RenderBox>[new RenderPositionedBox(), child1, new RenderPositionedBox(), table.setFlatChildren(3, <RenderBox>[new RenderPositionedBox(), child1, new RenderPositionedBox(),
child2, new RenderPositionedBox(), child3]); child2, new RenderPositionedBox(), child3]);
layout(table); pumpFrame();
table.setFlatChildren(3, <RenderBox>[new RenderPositionedBox(), child1, new RenderPositionedBox(), table.setFlatChildren(3, <RenderBox>[new RenderPositionedBox(), child1, new RenderPositionedBox(),
child2, new RenderPositionedBox(), child3]); child2, new RenderPositionedBox(), child3]);
layout(table); pumpFrame();
expect(table.columns, equals(3)); expect(table.columns, equals(3));
expect(table.rows, equals(2)); expect(table.rows, equals(2));
}); });
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment