Commit 301d0d37 authored by Hixie's avatar Hixie

Make RenderBlockViewport shrink-wrap its children in the main axis direction.

parent 65289031
......@@ -49,6 +49,16 @@ abstract class RenderBlockBase extends RenderBox with ContainerRenderObjectMixin
return new BoxConstraints.tightFor(height: constraints.constrainHeight(constraints.maxHeight));
}
double get _mainAxisExtent {
RenderBox child = lastChild;
if (child == null)
return 0.0;
BoxParentData parentData = child.parentData;
return _isVertical ?
parentData.position.y + child.size.height :
parentData.position.x + child.size.width;
}
void performLayout() {
BoxConstraints innerConstraints = _getInnerConstraints(constraints);
double position = 0.0;
......@@ -60,6 +70,10 @@ abstract class RenderBlockBase extends RenderBox with ContainerRenderObjectMixin
position += _isVertical ? child.size.height : child.size.width;
child = child.parentData.nextSibling;
}
size = _isVertical ?
constraints.constrain(new Size(constraints.maxWidth, _mainAxisExtent)) :
constraints.constrain(new Size(_mainAxisExtent, constraints.maxHeight));
assert(!size.isInfinite);
}
}
......@@ -137,23 +151,11 @@ class RenderBlock extends RenderBlockBase {
return defaultComputeDistanceToFirstActualBaseline(baseline);
}
double get _mainAxisExtent {
RenderBox child = lastChild;
if (child == null)
return 0.0;
BoxParentData parentData = child.parentData;
return _isVertical ?
parentData.position.y + child.size.height :
parentData.position.x + child.size.width;
}
void performLayout() {
assert(_isVertical ? constraints.maxHeight >= double.INFINITY : constraints.maxWidth >= double.INFINITY);
assert((_isVertical ? constraints.maxHeight >= double.INFINITY : constraints.maxWidth >= double.INFINITY) &&
'RenderBlock does not clip or resize its children, so it must be placed in a parent that does not constrain ' +
'the block\'s main direction. You probably want to put the RenderBlock inside a RenderViewport.' is String);
super.performLayout();
size = _isVertical ?
constraints.constrain(new Size(constraints.maxWidth, _mainAxisExtent)) :
constraints.constrain(new Size(_mainAxisExtent, constraints.maxHeight));
assert(!size.isInfinite);
}
void paint(PaintingContext context, Offset offset) {
......@@ -168,9 +170,6 @@ class RenderBlock extends RenderBlockBase {
class RenderBlockViewport extends RenderBlockBase {
// sizes itself to the given constraints
// at the start of layout, calls callback
RenderBlockViewport({
LayoutCallback callback,
List<RenderBox> children,
......@@ -200,20 +199,30 @@ class RenderBlockViewport extends RenderBlockBase {
markNeedsPaint();
}
double _noIntrinsicDimensions() {
assert(() {
'RenderBlockViewport does not support returning intrinsic dimensions. ' +
'Calculating the intrinsic dimensions would require walking the entire child list, ' +
'which defeats the entire point of having a lazily-built list of children.';
return false;
});
return 0.0;
}
double getMinIntrinsicWidth(BoxConstraints constraints) {
return constraints.constrainWidth();
return _noIntrinsicDimensions();
}
double getMaxIntrinsicWidth(BoxConstraints constraints) {
return constraints.constrainWidth();
return _noIntrinsicDimensions();
}
double getMinIntrinsicHeight(BoxConstraints constraints) {
return constraints.constrainHeight();
return _noIntrinsicDimensions();
}
double getMaxIntrinsicHeight(BoxConstraints constraints) {
return constraints.constrainHeight();
return _noIntrinsicDimensions();
}
// We don't override computeDistanceToActualBaseline(), because we
......@@ -221,16 +230,8 @@ class RenderBlockViewport extends RenderBlockBase {
// scroll the RenderBlockViewport, it would shift in its parent if
// the parent was baseline-aligned, which makes no sense.
bool get sizedByParent => true;
void performResize() {
size = constraints.biggest;
assert(!size.isInfinite);
}
bool get debugDoesLayoutWithCallback => true;
void performLayout() {
assert(constraints.maxHeight < double.INFINITY);
if (_callback != null) {
try {
_inCallback = true;
......
......@@ -78,7 +78,7 @@ class MixedViewportLayoutState {
}
class MixedViewport extends RenderObjectWrapper {
MixedViewport({ this.builder, this.startOffset, this.token, this.layoutState, Key key })
MixedViewport({ Key key, this.builder, this.startOffset, this.token, this.layoutState })
: super(key: key) {
assert(this.layoutState != null);
}
......@@ -258,7 +258,11 @@ class MixedViewport extends RenderObjectWrapper {
final List<double> offsets = layoutState._childOffsets;
final Map<_Key, Widget> childrenByKey = layoutState._childrenByKey;
final double height = renderObject.size.height;
final double height = constraints.maxHeight;
assert(height < double.INFINITY &&
'There is no point putting a lazily-built MixedViewport inside a box with infinite internal height ' +
'(e.g. inside something that scrolls), because it would then just eagerly build all the children. ' +
'You probably want to put the MixedViewport inside a container with a fixed height.' is String);
final double endOffset = startOffset + height;
BoxConstraints innerConstraints = new BoxConstraints.tightFor(width: constraints.constrainWidth());
......
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