Merge pull request #863 from Hixie/mixed-viewport-changes
Make RenderBlockViewport shrink-wrap its children in the main axis direction
This commit is contained in:
commit
bdc77e868c
@ -49,6 +49,16 @@ abstract class RenderBlockBase extends RenderBox with ContainerRenderObjectMixin
|
|||||||
return new BoxConstraints.tightFor(height: constraints.constrainHeight(constraints.maxHeight));
|
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() {
|
void performLayout() {
|
||||||
BoxConstraints innerConstraints = _getInnerConstraints(constraints);
|
BoxConstraints innerConstraints = _getInnerConstraints(constraints);
|
||||||
double position = 0.0;
|
double position = 0.0;
|
||||||
@ -60,6 +70,10 @@ abstract class RenderBlockBase extends RenderBox with ContainerRenderObjectMixin
|
|||||||
position += _isVertical ? child.size.height : child.size.width;
|
position += _isVertical ? child.size.height : child.size.width;
|
||||||
child = child.parentData.nextSibling;
|
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);
|
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() {
|
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();
|
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) {
|
void paint(PaintingContext context, Offset offset) {
|
||||||
@ -168,9 +170,6 @@ class RenderBlock extends RenderBlockBase {
|
|||||||
|
|
||||||
class RenderBlockViewport extends RenderBlockBase {
|
class RenderBlockViewport extends RenderBlockBase {
|
||||||
|
|
||||||
// sizes itself to the given constraints
|
|
||||||
// at the start of layout, calls callback
|
|
||||||
|
|
||||||
RenderBlockViewport({
|
RenderBlockViewport({
|
||||||
LayoutCallback callback,
|
LayoutCallback callback,
|
||||||
List<RenderBox> children,
|
List<RenderBox> children,
|
||||||
@ -200,20 +199,30 @@ class RenderBlockViewport extends RenderBlockBase {
|
|||||||
markNeedsPaint();
|
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) {
|
double getMinIntrinsicWidth(BoxConstraints constraints) {
|
||||||
return constraints.constrainWidth();
|
return _noIntrinsicDimensions();
|
||||||
}
|
}
|
||||||
|
|
||||||
double getMaxIntrinsicWidth(BoxConstraints constraints) {
|
double getMaxIntrinsicWidth(BoxConstraints constraints) {
|
||||||
return constraints.constrainWidth();
|
return _noIntrinsicDimensions();
|
||||||
}
|
}
|
||||||
|
|
||||||
double getMinIntrinsicHeight(BoxConstraints constraints) {
|
double getMinIntrinsicHeight(BoxConstraints constraints) {
|
||||||
return constraints.constrainHeight();
|
return _noIntrinsicDimensions();
|
||||||
}
|
}
|
||||||
|
|
||||||
double getMaxIntrinsicHeight(BoxConstraints constraints) {
|
double getMaxIntrinsicHeight(BoxConstraints constraints) {
|
||||||
return constraints.constrainHeight();
|
return _noIntrinsicDimensions();
|
||||||
}
|
}
|
||||||
|
|
||||||
// We don't override computeDistanceToActualBaseline(), because we
|
// 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
|
// scroll the RenderBlockViewport, it would shift in its parent if
|
||||||
// the parent was baseline-aligned, which makes no sense.
|
// 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;
|
bool get debugDoesLayoutWithCallback => true;
|
||||||
void performLayout() {
|
void performLayout() {
|
||||||
assert(constraints.maxHeight < double.INFINITY);
|
|
||||||
if (_callback != null) {
|
if (_callback != null) {
|
||||||
try {
|
try {
|
||||||
_inCallback = true;
|
_inCallback = true;
|
||||||
|
@ -78,7 +78,7 @@ class MixedViewportLayoutState {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class MixedViewport extends RenderObjectWrapper {
|
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) {
|
: super(key: key) {
|
||||||
assert(this.layoutState != null);
|
assert(this.layoutState != null);
|
||||||
}
|
}
|
||||||
@ -258,7 +258,11 @@ class MixedViewport extends RenderObjectWrapper {
|
|||||||
|
|
||||||
final List<double> offsets = layoutState._childOffsets;
|
final List<double> offsets = layoutState._childOffsets;
|
||||||
final Map<_Key, Widget> childrenByKey = layoutState._childrenByKey;
|
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;
|
final double endOffset = startOffset + height;
|
||||||
BoxConstraints innerConstraints = new BoxConstraints.tightFor(width: constraints.constrainWidth());
|
BoxConstraints innerConstraints = new BoxConstraints.tightFor(width: constraints.constrainWidth());
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user