Simplify intrinsic dimension APIs (#4283)
This commit is contained in:
parent
52cf289101
commit
787fb3be7d
@ -454,38 +454,42 @@ class RenderBoxToRenderSectorAdapter extends RenderBox with RenderObjectWithChil
|
||||
}
|
||||
|
||||
@override
|
||||
double getMinIntrinsicWidth(BoxConstraints constraints) {
|
||||
double getMinIntrinsicWidth(double height) {
|
||||
if (child == null)
|
||||
return super.getMinIntrinsicWidth(constraints);
|
||||
return getIntrinsicDimensions(constraints).width;
|
||||
return 0.0;
|
||||
return getIntrinsicDimensions(height: height).width;
|
||||
}
|
||||
|
||||
@override
|
||||
double getMaxIntrinsicWidth(BoxConstraints constraints) {
|
||||
double getMaxIntrinsicWidth(double height) {
|
||||
if (child == null)
|
||||
return super.getMaxIntrinsicWidth(constraints);
|
||||
return getIntrinsicDimensions(constraints).width;
|
||||
return 0.0;
|
||||
return getIntrinsicDimensions(height: height).width;
|
||||
}
|
||||
|
||||
@override
|
||||
double getMinIntrinsicHeight(BoxConstraints constraints) {
|
||||
double getMinIntrinsicHeight(double width) {
|
||||
if (child == null)
|
||||
return super.getMinIntrinsicHeight(constraints);
|
||||
return getIntrinsicDimensions(constraints).height;
|
||||
return 0.0;
|
||||
return getIntrinsicDimensions(width: width).height;
|
||||
}
|
||||
|
||||
@override
|
||||
double getMaxIntrinsicHeight(BoxConstraints constraints) {
|
||||
double getMaxIntrinsicHeight(double width) {
|
||||
if (child == null)
|
||||
return super.getMaxIntrinsicHeight(constraints);
|
||||
return getIntrinsicDimensions(constraints).height;
|
||||
return 0.0;
|
||||
return getIntrinsicDimensions(width: width).height;
|
||||
}
|
||||
|
||||
Size getIntrinsicDimensions(BoxConstraints constraints) {
|
||||
Size getIntrinsicDimensions({
|
||||
double width: double.INFINITY,
|
||||
double height: double.INFINITY
|
||||
}) {
|
||||
assert(child is RenderSector);
|
||||
assert(child.parentData is SectorParentData);
|
||||
assert(constraints.maxWidth < double.INFINITY || constraints.maxHeight < double.INFINITY);
|
||||
double maxChildDeltaRadius = math.min(constraints.maxWidth, constraints.maxHeight) / 2.0 - innerRadius;
|
||||
assert(width != null);
|
||||
assert(height != null);
|
||||
double maxChildDeltaRadius = math.min(width, height) / 2.0 - innerRadius;
|
||||
SectorDimensions childDimensions = child.getIntrinsicDimensions(new SectorConstraints(maxDeltaRadius: maxChildDeltaRadius), innerRadius);
|
||||
double dimension = (innerRadius + childDimensions.deltaRadius) * 2.0;
|
||||
return constraints.constrain(new Size(dimension, dimension));
|
||||
|
@ -14,31 +14,23 @@ class RenderSolidColorBox extends RenderDecoratedBox {
|
||||
super(decoration: new BoxDecoration(backgroundColor: backgroundColor));
|
||||
|
||||
@override
|
||||
double getMinIntrinsicWidth(BoxConstraints constraints) {
|
||||
return constraints.constrainHeight(
|
||||
this.desiredSize == Size.infinite ? 0.0 : desiredSize.width
|
||||
);
|
||||
double getMinIntrinsicWidth(double height) {
|
||||
return desiredSize.width == double.INFINITY ? 0.0 : desiredSize.width;
|
||||
}
|
||||
|
||||
@override
|
||||
double getMaxIntrinsicWidth(BoxConstraints constraints) {
|
||||
return constraints.constrainWidth(
|
||||
this.desiredSize == Size.infinite ? 0.0 : desiredSize.width
|
||||
);
|
||||
double getMaxIntrinsicWidth(double height) {
|
||||
return desiredSize.width == double.INFINITY ? 0.0 : desiredSize.width;
|
||||
}
|
||||
|
||||
@override
|
||||
double getMinIntrinsicHeight(BoxConstraints constraints) {
|
||||
return constraints.constrainHeight(
|
||||
this.desiredSize == Size.infinite ? 0.0 : desiredSize.height
|
||||
);
|
||||
double getMinIntrinsicHeight(double width) {
|
||||
return desiredSize.height == double.INFINITY ? 0.0 : desiredSize.height;
|
||||
}
|
||||
|
||||
@override
|
||||
double getMaxIntrinsicHeight(BoxConstraints constraints) {
|
||||
return constraints.constrainHeight(
|
||||
this.desiredSize == Size.infinite ? 0.0 : desiredSize.height
|
||||
);
|
||||
double getMaxIntrinsicHeight(double width) {
|
||||
return desiredSize.height == double.INFINITY ? 0.0 : desiredSize.height;
|
||||
}
|
||||
|
||||
@override
|
||||
|
@ -100,47 +100,40 @@ class _RenderTabBar extends RenderBox with
|
||||
}
|
||||
|
||||
@override
|
||||
double getMinIntrinsicWidth(BoxConstraints constraints) {
|
||||
BoxConstraints widthConstraints =
|
||||
new BoxConstraints(maxWidth: constraints.maxWidth, maxHeight: constraints.maxHeight);
|
||||
|
||||
double getMinIntrinsicWidth(double height) {
|
||||
double maxWidth = 0.0;
|
||||
RenderBox child = firstChild;
|
||||
while (child != null) {
|
||||
maxWidth = math.max(maxWidth, child.getMinIntrinsicWidth(widthConstraints));
|
||||
maxWidth = math.max(maxWidth, child.getMinIntrinsicWidth(height));
|
||||
final _TabBarParentData childParentData = child.parentData;
|
||||
child = childParentData.nextSibling;
|
||||
}
|
||||
double width = isScrollable ? maxWidth : maxWidth * childCount;
|
||||
return constraints.constrainWidth(width);
|
||||
return isScrollable ? maxWidth : maxWidth * childCount;
|
||||
}
|
||||
|
||||
@override
|
||||
double getMaxIntrinsicWidth(BoxConstraints constraints) {
|
||||
BoxConstraints widthConstraints =
|
||||
new BoxConstraints(maxWidth: constraints.maxWidth, maxHeight: constraints.maxHeight);
|
||||
|
||||
double getMaxIntrinsicWidth(double height) {
|
||||
double maxWidth = 0.0;
|
||||
double totalWidth = 0.0;
|
||||
RenderBox child = firstChild;
|
||||
while (child != null) {
|
||||
maxWidth = math.max(maxWidth, child.getMaxIntrinsicWidth(widthConstraints));
|
||||
double childWidth = child.getMaxIntrinsicWidth(height);
|
||||
maxWidth = math.max(maxWidth, childWidth);
|
||||
totalWidth += childWidth;
|
||||
final _TabBarParentData childParentData = child.parentData;
|
||||
child = childParentData.nextSibling;
|
||||
}
|
||||
double width = isScrollable ? maxWidth : maxWidth * childCount;
|
||||
return constraints.constrainWidth(width);
|
||||
return isScrollable ? totalWidth : maxWidth * childCount;
|
||||
}
|
||||
|
||||
double get _tabHeight => textAndIcons ? _kTextAndIconTabHeight : _kTabHeight;
|
||||
double get _tabBarHeight => _tabHeight + _kTabIndicatorHeight;
|
||||
|
||||
double _getIntrinsicHeight(BoxConstraints constraints) => constraints.constrainHeight(_tabBarHeight);
|
||||
@override
|
||||
double getMinIntrinsicHeight(double width) => _tabBarHeight;
|
||||
|
||||
@override
|
||||
double getMinIntrinsicHeight(BoxConstraints constraints) => _getIntrinsicHeight(constraints);
|
||||
|
||||
@override
|
||||
double getMaxIntrinsicHeight(BoxConstraints constraints) => _getIntrinsicHeight(constraints);
|
||||
double getMaxIntrinsicHeight(double width) => _tabBarHeight;
|
||||
|
||||
void layoutFixedWidthTabs() {
|
||||
double tabWidth = size.width / childCount;
|
||||
|
@ -10,8 +10,7 @@ import 'object.dart';
|
||||
/// Parent data for use with [RenderBlockBase].
|
||||
class BlockParentData extends ContainerBoxParentDataMixin<RenderBox> { }
|
||||
|
||||
typedef double _ChildSizingFunction(RenderBox child, BoxConstraints constraints);
|
||||
typedef double _Constrainer(double value);
|
||||
typedef double _ChildSizingFunction(RenderBox child);
|
||||
|
||||
/// Implements the block layout algorithm.
|
||||
///
|
||||
@ -158,102 +157,65 @@ class RenderBlock extends RenderBox
|
||||
description.add('mainAxis: $mainAxis');
|
||||
}
|
||||
|
||||
double _getIntrinsicCrossAxis(BoxConstraints constraints, _ChildSizingFunction childSize, _Constrainer constrainer) {
|
||||
double _getIntrinsicCrossAxis(_ChildSizingFunction childSize) {
|
||||
double extent = 0.0;
|
||||
BoxConstraints innerConstraints;
|
||||
switch (mainAxis) {
|
||||
case Axis.horizontal:
|
||||
innerConstraints = constraints.heightConstraints();
|
||||
break;
|
||||
case Axis.vertical:
|
||||
innerConstraints = constraints.widthConstraints();
|
||||
break;
|
||||
}
|
||||
RenderBox child = firstChild;
|
||||
while (child != null) {
|
||||
extent = math.max(extent, childSize(child, innerConstraints));
|
||||
extent = math.max(extent, childSize(child));
|
||||
final BlockParentData childParentData = child.parentData;
|
||||
child = childParentData.nextSibling;
|
||||
}
|
||||
return constrainer(extent);
|
||||
return extent;
|
||||
}
|
||||
|
||||
double _getIntrinsicMainAxis(BoxConstraints constraints, _Constrainer constrainer) {
|
||||
double _getIntrinsicMainAxis(_ChildSizingFunction childSize) {
|
||||
double extent = 0.0;
|
||||
BoxConstraints innerConstraints = _getInnerConstraints(constraints);
|
||||
RenderBox child = firstChild;
|
||||
while (child != null) {
|
||||
switch (mainAxis) {
|
||||
case Axis.horizontal:
|
||||
extent += child.getMaxIntrinsicWidth(innerConstraints);
|
||||
break;
|
||||
case Axis.vertical:
|
||||
extent += child.getMinIntrinsicHeight(innerConstraints);
|
||||
break;
|
||||
}
|
||||
extent += childSize(child);
|
||||
final BlockParentData childParentData = child.parentData;
|
||||
child = childParentData.nextSibling;
|
||||
}
|
||||
return constrainer(extent);
|
||||
return extent;
|
||||
}
|
||||
|
||||
@override
|
||||
double getMinIntrinsicWidth(BoxConstraints constraints) {
|
||||
assert(constraints.debugAssertIsValid());
|
||||
double getMinIntrinsicWidth(double height) {
|
||||
switch (mainAxis) {
|
||||
case Axis.horizontal:
|
||||
return _getIntrinsicMainAxis(constraints, constraints.constrainWidth);
|
||||
return _getIntrinsicMainAxis((RenderBox child) => child.getMinIntrinsicWidth(height));
|
||||
case Axis.vertical:
|
||||
return _getIntrinsicCrossAxis(
|
||||
constraints,
|
||||
(RenderBox child, BoxConstraints innerConstraints) => child.getMinIntrinsicWidth(innerConstraints),
|
||||
constraints.constrainWidth
|
||||
);
|
||||
return _getIntrinsicCrossAxis((RenderBox child) => child.getMinIntrinsicWidth(height));
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
double getMaxIntrinsicWidth(BoxConstraints constraints) {
|
||||
assert(constraints.debugAssertIsValid());
|
||||
double getMaxIntrinsicWidth(double height) {
|
||||
switch (mainAxis) {
|
||||
case Axis.horizontal:
|
||||
return _getIntrinsicMainAxis(constraints, constraints.constrainWidth);
|
||||
return _getIntrinsicMainAxis((RenderBox child) => child.getMaxIntrinsicWidth(height));
|
||||
case Axis.vertical:
|
||||
return _getIntrinsicCrossAxis(
|
||||
constraints,
|
||||
(RenderBox child, BoxConstraints innerConstraints) => child.getMaxIntrinsicWidth(innerConstraints),
|
||||
constraints.constrainWidth
|
||||
);
|
||||
return _getIntrinsicCrossAxis((RenderBox child) => child.getMaxIntrinsicWidth(height));
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
double getMinIntrinsicHeight(BoxConstraints constraints) {
|
||||
assert(constraints.debugAssertIsValid());
|
||||
double getMinIntrinsicHeight(double width) {
|
||||
switch (mainAxis) {
|
||||
case Axis.horizontal:
|
||||
return _getIntrinsicCrossAxis(
|
||||
constraints,
|
||||
(RenderBox child, BoxConstraints innerConstraints) => child.getMinIntrinsicHeight(innerConstraints),
|
||||
constraints.constrainHeight
|
||||
);
|
||||
return _getIntrinsicMainAxis((RenderBox child) => child.getMinIntrinsicHeight(width));
|
||||
case Axis.vertical:
|
||||
return _getIntrinsicMainAxis(constraints, constraints.constrainHeight);
|
||||
return _getIntrinsicCrossAxis((RenderBox child) => child.getMinIntrinsicHeight(width));
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
double getMaxIntrinsicHeight(BoxConstraints constraints) {
|
||||
assert(constraints.debugAssertIsValid());
|
||||
double getMaxIntrinsicHeight(double width) {
|
||||
switch (mainAxis) {
|
||||
case Axis.horizontal:
|
||||
return _getIntrinsicCrossAxis(
|
||||
constraints,
|
||||
(RenderBox child, BoxConstraints innerConstraints) => child.getMaxIntrinsicHeight(innerConstraints),
|
||||
constraints.constrainHeight
|
||||
);
|
||||
return _getIntrinsicMainAxis((RenderBox child) => child.getMaxIntrinsicHeight(width));
|
||||
case Axis.vertical:
|
||||
return _getIntrinsicMainAxis(constraints, constraints.constrainHeight);
|
||||
return _getIntrinsicCrossAxis((RenderBox child) => child.getMaxIntrinsicHeight(width));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -83,6 +83,15 @@ class BoxConstraints extends Constraints {
|
||||
minHeight = height != null ? height : 0.0,
|
||||
maxHeight = height != null ? height : double.INFINITY;
|
||||
|
||||
/// Creates box constraints that require the given width or height, except if they are infinite.
|
||||
const BoxConstraints.tightForFinite({
|
||||
double width: double.INFINITY,
|
||||
double height: double.INFINITY
|
||||
}): minWidth = width != double.INFINITY ? width : 0.0,
|
||||
maxWidth = width != double.INFINITY ? width : double.INFINITY,
|
||||
minHeight = height != double.INFINITY ? height : 0.0,
|
||||
maxHeight = height != double.INFINITY ? height : double.INFINITY;
|
||||
|
||||
/// Creates box constraints that forbid sizes larger than the given size.
|
||||
BoxConstraints.loose(Size size)
|
||||
: minWidth = 0.0,
|
||||
@ -486,44 +495,164 @@ abstract class RenderBox extends RenderObject {
|
||||
child.parentData = new BoxParentData();
|
||||
}
|
||||
|
||||
/// Returns the minimum width that this box could be without failing to paint
|
||||
/// its contents within itself.
|
||||
/// Returns the minimum width that this box could be without failing to
|
||||
/// correctly paint its contents within itself, without clipping.
|
||||
///
|
||||
/// The height argument may give a specific height to assume. The given height
|
||||
/// can be infinite, meaning that the intrinsic width in an unconstrained
|
||||
/// environment is being requested. The given height should never be negative
|
||||
/// or null.
|
||||
///
|
||||
/// Override in subclasses that implement [performLayout].
|
||||
double getMinIntrinsicWidth(BoxConstraints constraints) {
|
||||
assert(constraints.debugAssertIsValid());
|
||||
return constraints.constrainWidth(0.0);
|
||||
///
|
||||
/// If the layout algorithm is independent of the context (e.g. it always
|
||||
/// tries to be a particular size), or if the layout algorithm is
|
||||
/// width-in-height-out, or if the layout algorithm uses both the incoming
|
||||
/// width and height constraints (e.g. it always sizes itself to
|
||||
/// [BoxConstraints.biggest]), then the `height` argument should be ignored.
|
||||
///
|
||||
/// If the layout algorithm is strictly height-in-width-out, or is
|
||||
/// height-in-width-out when the width is unconstrained, then the height
|
||||
/// argument is the height to use.
|
||||
///
|
||||
/// This function should never return a negative or infinite value.
|
||||
///
|
||||
/// ## Examples
|
||||
///
|
||||
/// ### Text
|
||||
///
|
||||
/// Text is the canonical example of a width-in-height-out algorithm. The
|
||||
/// `height` argument is therefore ignored.
|
||||
///
|
||||
/// Consider the string "Hello World" The _maximum_ intrinsic width (as
|
||||
/// returned from [getMaxIntrinsicWidth]) would be the width of the string
|
||||
/// with no line breaks.
|
||||
///
|
||||
/// The minimum intrinsic width would be the width of the widest word, "Hello"
|
||||
/// or "World". If the text is rendered in an even narrower width, however, it
|
||||
/// might still not overflow. For example, maybe the rendering would put a
|
||||
/// line-break half-way through the words, as in "Hel⁞lo⁞Wor⁞ld". However,
|
||||
/// this wouldn't be a _correct_ rendering, and [getMinIntrinsicWidth] is
|
||||
/// supposed to render the minimum width that the box could be without failing
|
||||
/// to _correctly_ paint the contents within itself.
|
||||
///
|
||||
/// The minimum intrinsic _height_ for a given width smaller than the minimum
|
||||
/// intrinsic width could therefore be greater than the minimum intrinsic
|
||||
/// height for the minimum intrinsic width.
|
||||
///
|
||||
/// ### Viewports (e.g. scrolling lists)
|
||||
///
|
||||
/// Some render boxes are intended to clip their children. For example, the
|
||||
/// render box for a scrolling list might always size itself to its parents'
|
||||
/// size (or rather, to the maximum incoming constraints), regardless of the
|
||||
/// children's sizes, and then clip the children and position them based on
|
||||
/// the current scroll offset.
|
||||
///
|
||||
/// The intrinsic dimensions in these cases still depend on the children, even
|
||||
/// though the layout algorithm sizes the box in a way independent of the
|
||||
/// children. It is the size that is needed to paint the box's contents (in
|
||||
/// this case, the children) _without clipping_ that matters.
|
||||
///
|
||||
/// In many cases, viewports do not have efficient access to all the children,
|
||||
/// and therefore cannot actually return a valid answer. In this case, when
|
||||
/// [RenderObject.debugCheckingIntrinsics] is false and asserts are enabled,
|
||||
/// the intrinsic functions should throw; in other cases, they should return
|
||||
/// 0.0. See [RenderVirtualViewport.debugThrowIfNotCheckingIntrinsics].
|
||||
///
|
||||
/// ### Aspect-ratio-driven boxes
|
||||
///
|
||||
/// Some boxes always return a fixed size based on the constraints. For these
|
||||
/// boxes, the intrinsic functions should return the appropriate size when the
|
||||
/// incoming `height` or `width` argument is finite, treating that as a tight
|
||||
/// constraint in the respective direction and treating the other direction's
|
||||
/// constraints as unbounded. This is because the definitions of
|
||||
/// [getMinIntrinsicWidth] and [getMinIntrinsicHeight] are in terms of what
|
||||
/// the dimensions _could be_, and such boxes can only be one size in such
|
||||
/// cases.
|
||||
///
|
||||
/// When the incoming argument is not finite, then they should return the
|
||||
/// actual intrinsic dimensions based on the contents, as any other box would.
|
||||
double getMinIntrinsicWidth(double height) {
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
/// Returns the smallest width beyond which increasing the width never
|
||||
/// decreases the preferred height.
|
||||
/// decreases the preferred height. The preferred height is the value that
|
||||
/// would be returned by [getMinIntrinsicHeight] for that width.
|
||||
///
|
||||
/// Override in subclasses that implement [performLayout].
|
||||
double getMaxIntrinsicWidth(BoxConstraints constraints) {
|
||||
assert(constraints.debugAssertIsValid());
|
||||
return constraints.constrainWidth(0.0);
|
||||
///
|
||||
/// If the layout algorithm is strictly height-in-width-out, or is
|
||||
/// height-in-width-out when the width is unconstrained, then this should
|
||||
/// return the same value as [getMinIntrinsicWidth] for the same height.
|
||||
///
|
||||
/// Otherwise, the height argument should be ignored, and the returned value
|
||||
/// should be equal to or bigger than the value returned by
|
||||
/// [getMinIntrinsicWidth].
|
||||
///
|
||||
/// The value returned by this method might not match the size that the object
|
||||
/// would actually take. For example, a [RenderBox] subclass that always
|
||||
/// exactly sizes itself using [BoxConstraints.biggest] might well size itself
|
||||
/// bigger than its max intrinsic size.
|
||||
///
|
||||
/// This function should never return a negative or infinite value.
|
||||
///
|
||||
/// See also examples in the definition of [getMinIntrinsicWidth].
|
||||
double getMaxIntrinsicWidth(double height) {
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
/// Return the minimum height that this box could be without failing to paint
|
||||
/// its contents within itself.
|
||||
/// Returns the minimum height that this box could be without failing to
|
||||
/// correctly paint its contents within itself, without clipping.
|
||||
///
|
||||
/// The width argument may give a specific width to assume. The given width
|
||||
/// can be infinite, meaning that the intrinsic height in an unconstrained
|
||||
/// environment is being requested. The given width should never be negative
|
||||
/// or null.
|
||||
///
|
||||
/// Override in subclasses that implement [performLayout].
|
||||
double getMinIntrinsicHeight(BoxConstraints constraints) {
|
||||
assert(constraints.debugAssertIsValid());
|
||||
return constraints.constrainHeight(0.0);
|
||||
///
|
||||
/// If the layout algorithm is independent of the context (e.g. it always
|
||||
/// tries to be a particular size), or if the layout algorithm is
|
||||
/// height-in-width-out, or if the layout algorithm uses both the incoming
|
||||
/// height and width constraints (e.g. it always sizes itself to
|
||||
/// [BoxConstraints.biggest]), then the `width` argument should be ignored.
|
||||
///
|
||||
/// If the layout algorithm is strictly width-in-height-out, or is
|
||||
/// width-in-height-out when the height is unconstrained, then the width
|
||||
/// argument is the width to use.
|
||||
///
|
||||
/// This function should never return a negative or infinite value.
|
||||
///
|
||||
/// See also examples in the definition of [getMinIntrinsicWidth].
|
||||
double getMinIntrinsicHeight(double width) {
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
/// Returns the smallest height beyond which increasing the height never
|
||||
/// decreases the preferred width.
|
||||
///
|
||||
/// If the layout algorithm used is width-in-height-out, i.e. the height
|
||||
/// depends on the width and not vice versa, then this will return the same
|
||||
/// as getMinIntrinsicHeight().
|
||||
/// decreases the preferred width. The preferred width is the value that
|
||||
/// would be returned by [getMinIntrinsicWidth] for that height.
|
||||
///
|
||||
/// Override in subclasses that implement [performLayout].
|
||||
double getMaxIntrinsicHeight(BoxConstraints constraints) {
|
||||
assert(constraints.debugAssertIsValid());
|
||||
return constraints.constrainHeight(0.0);
|
||||
///
|
||||
/// If the layout algorithm is strictly width-in-height-out, or is
|
||||
/// width-in-height-out when the height is unconstrained, then this should
|
||||
/// return the same value as [getMinIntrinsicHeight] for the same width.
|
||||
///
|
||||
/// Otherwise, the width argument should be ignored, and the returned value
|
||||
/// should be equal to or bigger than the value returned by
|
||||
/// [getMinIntrinsicHeight].
|
||||
///
|
||||
/// The value returned by this method might not match the size that the object
|
||||
/// would actually take. For example, a [RenderBox] subclass that always
|
||||
/// exactly sizes itself using [BoxConstraints.biggest] might well size itself
|
||||
/// bigger than its max intrinsic size.
|
||||
///
|
||||
/// This function should never return a negative or infinite value.
|
||||
///
|
||||
/// See also examples in the definition of [getMinIntrinsicWidth].
|
||||
double getMaxIntrinsicHeight(double width) {
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
/// Whether this render object has undergone layout and has a [size].
|
||||
@ -766,40 +895,47 @@ abstract class RenderBox extends RenderObject {
|
||||
);
|
||||
}
|
||||
if (_debugNeedsIntrinsicSizeCheck || debugCheckIntrinsicSizes) {
|
||||
// verify that the intrinsics are also within the constraints
|
||||
// verify that the intrinsics are sane
|
||||
assert(!RenderObject.debugCheckingIntrinsics);
|
||||
RenderObject.debugCheckingIntrinsics = true;
|
||||
double intrinsic;
|
||||
StringBuffer failures = new StringBuffer();
|
||||
int failureCount = 0;
|
||||
intrinsic = getMinIntrinsicWidth(constraints);
|
||||
if (intrinsic != constraints.constrainWidth(intrinsic)) {
|
||||
failures.writeln(' * getMinIntrinsicWidth() -- returned: w=$intrinsic');
|
||||
|
||||
double testIntrinsic(double function(double extent), String name, double constraint) {
|
||||
final double result = function(constraint);
|
||||
if (result < 0) {
|
||||
failures.writeln(' * $name($constraint) returned a negative value: $result');
|
||||
failureCount += 1;
|
||||
}
|
||||
if (!result.isFinite) {
|
||||
failures.writeln(' * $name($constraint) returned a non-finite value: $result');
|
||||
failureCount += 1;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
final double minIntrinsicWidth = testIntrinsic(getMinIntrinsicWidth, 'getMinIntrinsicWidth', constraints.maxWidth);
|
||||
final double maxIntrinsicWidth = testIntrinsic(getMaxIntrinsicWidth, 'getMaxIntrinsicWidth', constraints.maxWidth);
|
||||
if (minIntrinsicWidth > maxIntrinsicWidth) {
|
||||
failures.writeln(' * getMinIntrinsicWidth(${constraints.maxWidth}) returned a larger value ($minIntrinsicWidth) than getMaxIntrinsicWidth(${constraints.maxWidth}) ($maxIntrinsicWidth)');
|
||||
failureCount += 1;
|
||||
}
|
||||
intrinsic = getMaxIntrinsicWidth(constraints);
|
||||
if (intrinsic != constraints.constrainWidth(intrinsic)) {
|
||||
failures.writeln(' * getMaxIntrinsicWidth() -- returned: w=$intrinsic');
|
||||
failureCount += 1;
|
||||
}
|
||||
intrinsic = getMinIntrinsicHeight(constraints);
|
||||
if (intrinsic != constraints.constrainHeight(intrinsic)) {
|
||||
failures.writeln(' * getMinIntrinsicHeight() -- returned: h=$intrinsic');
|
||||
failureCount += 1;
|
||||
}
|
||||
intrinsic = getMaxIntrinsicHeight(constraints);
|
||||
if (intrinsic != constraints.constrainHeight(intrinsic)) {
|
||||
failures.writeln(' * getMaxIntrinsicHeight() -- returned: h=$intrinsic');
|
||||
final double minIntrinsicHeight = testIntrinsic(getMinIntrinsicHeight, 'getMinIntrinsicHeight', constraints.maxHeight);
|
||||
final double maxIntrinsicHeight = testIntrinsic(getMaxIntrinsicHeight, 'getMaxIntrinsicHeight', constraints.maxHeight);
|
||||
if (minIntrinsicHeight > maxIntrinsicHeight) {
|
||||
failures.writeln(' * getMinIntrinsicHeight(${constraints.maxHeight}) returned a larger value ($minIntrinsicHeight) than getMaxIntrinsicHeight(${constraints.maxHeight}) ($maxIntrinsicHeight)');
|
||||
failureCount += 1;
|
||||
}
|
||||
|
||||
// TODO(ianh): Test that values are internally consistent in more ways than the above.
|
||||
|
||||
RenderObject.debugCheckingIntrinsics = false;
|
||||
_debugNeedsIntrinsicSizeCheck = false;
|
||||
if (failures.isNotEmpty) {
|
||||
assert(failureCount > 0);
|
||||
throw new FlutterError(
|
||||
'The intrinsic dimension methods of the $runtimeType class returned values that violate the given constraints.\n'
|
||||
'The constraints were: $constraints\n'
|
||||
'The following method${failureCount > 1 ? "s" : ""} returned values outside of those constraints:\n'
|
||||
'The intrinsic dimension methods of the $runtimeType class returned values that violate the intrinsic protocol contract.\n'
|
||||
'The following ${failureCount > 1 ? "failures" : "failure"} was detected:\n'
|
||||
'$failures'
|
||||
'If you are not writing your own RenderBox subclass, then this is not\n'
|
||||
'your fault. Contact support: https://github.com/flutter/flutter/issues/new'
|
||||
|
@ -239,24 +239,40 @@ class RenderCustomMultiChildLayoutBox extends RenderBox
|
||||
return constraints.constrain(_delegate.getSize(constraints));
|
||||
}
|
||||
|
||||
// TODO(ianh): It's a bit dubious to be using the getSize function from the delegate to
|
||||
// figure out the intrinsic dimensions. We really should either not support intrinsics,
|
||||
// or we should expose intrinsic delegate callbacks and throw if they're not implemented.
|
||||
|
||||
@override
|
||||
double getMinIntrinsicWidth(BoxConstraints constraints) {
|
||||
return _getSize(constraints).width;
|
||||
double getMinIntrinsicWidth(double height) {
|
||||
final double width = _getSize(new BoxConstraints.tightForFinite(height: height)).width;
|
||||
if (width.isFinite)
|
||||
return width;
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
@override
|
||||
double getMaxIntrinsicWidth(BoxConstraints constraints) {
|
||||
return _getSize(constraints).width;
|
||||
double getMaxIntrinsicWidth(double height) {
|
||||
final double width = _getSize(new BoxConstraints.tightForFinite(height: height)).width;
|
||||
if (width.isFinite)
|
||||
return width;
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
@override
|
||||
double getMinIntrinsicHeight(BoxConstraints constraints) {
|
||||
return _getSize(constraints).height;
|
||||
double getMinIntrinsicHeight(double width) {
|
||||
final double height = _getSize(new BoxConstraints.tightForFinite(width: width)).height;
|
||||
if (height.isFinite)
|
||||
return height;
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
@override
|
||||
double getMaxIntrinsicHeight(BoxConstraints constraints) {
|
||||
return _getSize(constraints).height;
|
||||
double getMaxIntrinsicHeight(double width) {
|
||||
final double height = _getSize(new BoxConstraints.tightForFinite(width: width)).height;
|
||||
if (height.isFinite)
|
||||
return height;
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
@override
|
||||
|
@ -192,27 +192,13 @@ class RenderEditableLine extends RenderBox {
|
||||
}
|
||||
|
||||
@override
|
||||
double getMinIntrinsicWidth(BoxConstraints constraints) {
|
||||
assert(constraints.debugAssertIsValid());
|
||||
return constraints.constrainWidth(0.0);
|
||||
double getMinIntrinsicHeight(double width) {
|
||||
return _preferredHeight;
|
||||
}
|
||||
|
||||
@override
|
||||
double getMaxIntrinsicWidth(BoxConstraints constraints) {
|
||||
assert(constraints.debugAssertIsValid());
|
||||
return constraints.constrainWidth(0.0);
|
||||
}
|
||||
|
||||
@override
|
||||
double getMinIntrinsicHeight(BoxConstraints constraints) {
|
||||
assert(constraints.debugAssertIsValid());
|
||||
return constraints.constrainHeight(_preferredHeight);
|
||||
}
|
||||
|
||||
@override
|
||||
double getMaxIntrinsicHeight(BoxConstraints constraints) {
|
||||
assert(constraints.debugAssertIsValid());
|
||||
return constraints.constrainHeight(_preferredHeight);
|
||||
double getMaxIntrinsicHeight(double width) {
|
||||
return _preferredHeight;
|
||||
}
|
||||
|
||||
@override
|
||||
|
@ -54,23 +54,13 @@ class RenderErrorBox extends RenderBox {
|
||||
ui.Paragraph _paragraph;
|
||||
|
||||
@override
|
||||
double getMinIntrinsicWidth(BoxConstraints constraints) {
|
||||
return constraints.constrainWidth(0.0);
|
||||
double getMaxIntrinsicWidth(double height) {
|
||||
return _kMaxWidth;
|
||||
}
|
||||
|
||||
@override
|
||||
double getMaxIntrinsicWidth(BoxConstraints constraints) {
|
||||
return constraints.constrainWidth(_kMaxWidth);
|
||||
}
|
||||
|
||||
@override
|
||||
double getMinIntrinsicHeight(BoxConstraints constraints) {
|
||||
return constraints.constrainHeight(0.0);
|
||||
}
|
||||
|
||||
@override
|
||||
double getMaxIntrinsicHeight(BoxConstraints constraints) {
|
||||
return constraints.constrainHeight(_kMaxHeight);
|
||||
double getMaxIntrinsicHeight(double width) {
|
||||
return _kMaxHeight;
|
||||
}
|
||||
|
||||
@override
|
||||
|
@ -71,7 +71,7 @@ enum CrossAxisAlignment {
|
||||
baseline,
|
||||
}
|
||||
|
||||
typedef double _ChildSizingFunction(RenderBox child, BoxConstraints constraints);
|
||||
typedef double _ChildSizingFunction(RenderBox child, double extent);
|
||||
|
||||
/// Implements the flex layout algorithm
|
||||
///
|
||||
@ -156,25 +156,15 @@ class RenderFlex extends RenderBox with ContainerRenderObjectMixin<RenderBox, Fl
|
||||
child.parentData = new FlexParentData();
|
||||
}
|
||||
|
||||
double _getIntrinsicSize({ BoxConstraints constraints,
|
||||
FlexDirection sizingDirection,
|
||||
_ChildSizingFunction childSize }) {
|
||||
assert(constraints.debugAssertIsValid());
|
||||
// http://www.w3.org/TR/2015/WD-css-flexbox-1-20150514/#intrinsic-sizes
|
||||
double _getIntrinsicSize({
|
||||
FlexDirection sizingDirection,
|
||||
double extent, // the extent in the direction that isn't the sizing direction
|
||||
_ChildSizingFunction childSize // a method to find the size in the sizing direction
|
||||
}) {
|
||||
if (_direction == sizingDirection) {
|
||||
// INTRINSIC MAIN SIZE
|
||||
// Intrinsic main size is the smallest size the flex container can take
|
||||
// while maintaining the min/max-content contributions of its flex items.
|
||||
BoxConstraints childConstraints;
|
||||
switch(_direction) {
|
||||
case FlexDirection.horizontal:
|
||||
childConstraints = new BoxConstraints(maxHeight: constraints.maxHeight);
|
||||
break;
|
||||
case FlexDirection.vertical:
|
||||
childConstraints = new BoxConstraints(maxWidth: constraints.maxWidth);
|
||||
break;
|
||||
}
|
||||
|
||||
double totalFlex = 0.0;
|
||||
double inflexibleSpace = 0.0;
|
||||
double maxFlexFractionSoFar = 0.0;
|
||||
@ -183,47 +173,24 @@ class RenderFlex extends RenderBox with ContainerRenderObjectMixin<RenderBox, Fl
|
||||
int flex = _getFlex(child);
|
||||
totalFlex += flex;
|
||||
if (flex > 0) {
|
||||
double flexFraction = childSize(child, childConstraints) / _getFlex(child);
|
||||
double flexFraction = childSize(child, extent) / _getFlex(child);
|
||||
maxFlexFractionSoFar = math.max(maxFlexFractionSoFar, flexFraction);
|
||||
} else {
|
||||
inflexibleSpace += childSize(child, childConstraints);
|
||||
inflexibleSpace += childSize(child, extent);
|
||||
}
|
||||
final FlexParentData childParentData = child.parentData;
|
||||
child = childParentData.nextSibling;
|
||||
}
|
||||
double mainSize = maxFlexFractionSoFar * totalFlex + inflexibleSpace;
|
||||
|
||||
// Ensure that we don't violate the given constraints with our result
|
||||
switch(_direction) {
|
||||
case FlexDirection.horizontal:
|
||||
return constraints.constrainWidth(mainSize);
|
||||
case FlexDirection.vertical:
|
||||
return constraints.constrainHeight(mainSize);
|
||||
}
|
||||
return maxFlexFractionSoFar * totalFlex + inflexibleSpace;
|
||||
} else {
|
||||
// INTRINSIC CROSS SIZE
|
||||
// The spec wants us to perform layout into the given available main-axis
|
||||
// space and return the cross size. That's too expensive, so instead we
|
||||
// size inflexible children according to their max intrinsic size in the
|
||||
// main direction and use those constraints to determine their max
|
||||
// intrinsic size in the cross direction. We don't care if the caller
|
||||
// asked for max or min -- the answer is always computed using the
|
||||
// max size in the main direction.
|
||||
// Intrinsic cross size is the max of the intrinsic cross sizes of the
|
||||
// children, after the flexible children are fit into the available space,
|
||||
// with the children sized using their max intrinsic dimensions.
|
||||
// TODO(ianh): Support baseline alignment.
|
||||
|
||||
double availableMainSpace;
|
||||
BoxConstraints childConstraints;
|
||||
switch(_direction) {
|
||||
case FlexDirection.horizontal:
|
||||
childConstraints = new BoxConstraints(maxHeight: constraints.maxHeight);
|
||||
availableMainSpace = constraints.maxWidth;
|
||||
break;
|
||||
case FlexDirection.vertical:
|
||||
childConstraints = new BoxConstraints(maxWidth: constraints.maxWidth);
|
||||
availableMainSpace = constraints.maxHeight;
|
||||
break;
|
||||
}
|
||||
|
||||
// Get inflexible space using the max in the main direction
|
||||
// Get inflexible space using the max intrinsic dimensions of fixed children in the main direction.
|
||||
double availableMainSpace = extent;
|
||||
int totalFlex = 0;
|
||||
double inflexibleSpace = 0.0;
|
||||
double maxCrossSize = 0.0;
|
||||
@ -236,16 +203,12 @@ class RenderFlex extends RenderBox with ContainerRenderObjectMixin<RenderBox, Fl
|
||||
if (flex == 0) {
|
||||
switch (_direction) {
|
||||
case FlexDirection.horizontal:
|
||||
mainSize = child.getMaxIntrinsicWidth(childConstraints);
|
||||
BoxConstraints widthConstraints =
|
||||
new BoxConstraints(minWidth: mainSize, maxWidth: mainSize);
|
||||
crossSize = child.getMaxIntrinsicHeight(widthConstraints);
|
||||
mainSize = child.getMaxIntrinsicWidth(double.INFINITY);
|
||||
crossSize = childSize(child, mainSize);
|
||||
break;
|
||||
case FlexDirection.vertical:
|
||||
mainSize = child.getMaxIntrinsicHeight(childConstraints);
|
||||
BoxConstraints heightConstraints =
|
||||
new BoxConstraints(minWidth: mainSize, maxWidth: mainSize);
|
||||
crossSize = child.getMaxIntrinsicWidth(heightConstraints);
|
||||
mainSize = child.getMaxIntrinsicHeight(double.INFINITY);
|
||||
crossSize = childSize(child, mainSize);
|
||||
break;
|
||||
}
|
||||
inflexibleSpace += mainSize;
|
||||
@ -255,79 +218,59 @@ class RenderFlex extends RenderBox with ContainerRenderObjectMixin<RenderBox, Fl
|
||||
child = childParentData.nextSibling;
|
||||
}
|
||||
|
||||
// Determine the spacePerFlex by allocating the remaining available space
|
||||
// Determine the spacePerFlex by allocating the remaining available space.
|
||||
// When you're overconstrained spacePerFlex can be negative.
|
||||
double spacePerFlex = math.max(0.0,
|
||||
(availableMainSpace - inflexibleSpace) / totalFlex);
|
||||
|
||||
// Size remaining items, find the maximum cross size
|
||||
// Size remaining (flexible) items, find the maximum cross size.
|
||||
child = firstChild;
|
||||
while (child != null) {
|
||||
int flex = _getFlex(child);
|
||||
if (flex > 0) {
|
||||
double childMainSize = spacePerFlex * flex;
|
||||
double crossSize;
|
||||
switch (_direction) {
|
||||
case FlexDirection.horizontal:
|
||||
BoxConstraints childConstraints =
|
||||
new BoxConstraints(minWidth: childMainSize, maxWidth: childMainSize);
|
||||
crossSize = child.getMaxIntrinsicHeight(childConstraints);
|
||||
break;
|
||||
case FlexDirection.vertical:
|
||||
BoxConstraints childConstraints =
|
||||
new BoxConstraints(minHeight: childMainSize, maxHeight: childMainSize);
|
||||
crossSize = child.getMaxIntrinsicWidth(childConstraints);
|
||||
break;
|
||||
}
|
||||
maxCrossSize = math.max(maxCrossSize, crossSize);
|
||||
}
|
||||
if (flex > 0)
|
||||
maxCrossSize = math.max(maxCrossSize, childSize(child, spacePerFlex * flex));
|
||||
final FlexParentData childParentData = child.parentData;
|
||||
child = childParentData.nextSibling;
|
||||
}
|
||||
|
||||
// Ensure that we don't violate the given constraints with our result
|
||||
switch(_direction) {
|
||||
case FlexDirection.horizontal:
|
||||
return constraints.constrainHeight(maxCrossSize);
|
||||
case FlexDirection.vertical:
|
||||
return constraints.constrainWidth(maxCrossSize);
|
||||
}
|
||||
return maxCrossSize;
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
double getMinIntrinsicWidth(BoxConstraints constraints) {
|
||||
double getMinIntrinsicWidth(double height) {
|
||||
return _getIntrinsicSize(
|
||||
constraints: constraints,
|
||||
sizingDirection: FlexDirection.horizontal,
|
||||
childSize: (RenderBox child, BoxConstraints innerConstraints) => child.getMinIntrinsicWidth(innerConstraints)
|
||||
extent: height,
|
||||
childSize: (RenderBox child, double extent) => child.getMinIntrinsicWidth(extent)
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
double getMaxIntrinsicWidth(BoxConstraints constraints) {
|
||||
double getMaxIntrinsicWidth(double height) {
|
||||
return _getIntrinsicSize(
|
||||
constraints: constraints,
|
||||
sizingDirection: FlexDirection.horizontal,
|
||||
childSize: (RenderBox child, BoxConstraints innerConstraints) => child.getMaxIntrinsicWidth(innerConstraints)
|
||||
extent: height,
|
||||
childSize: (RenderBox child, double extent) => child.getMaxIntrinsicWidth(extent)
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
double getMinIntrinsicHeight(BoxConstraints constraints) {
|
||||
double getMinIntrinsicHeight(double width) {
|
||||
return _getIntrinsicSize(
|
||||
constraints: constraints,
|
||||
sizingDirection: FlexDirection.vertical,
|
||||
childSize: (RenderBox child, BoxConstraints innerConstraints) => child.getMinIntrinsicHeight(innerConstraints)
|
||||
extent: width,
|
||||
childSize: (RenderBox child, double extent) => child.getMinIntrinsicHeight(extent)
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
double getMaxIntrinsicHeight(BoxConstraints constraints) {
|
||||
double getMaxIntrinsicHeight(double width) {
|
||||
return _getIntrinsicSize(
|
||||
constraints: constraints,
|
||||
sizingDirection: FlexDirection.vertical,
|
||||
childSize: (RenderBox child, BoxConstraints innerConstraints) => child.getMaxIntrinsicHeight(innerConstraints));
|
||||
extent: width,
|
||||
childSize: (RenderBox child, double extent) => child.getMaxIntrinsicHeight(extent)
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
@ -352,8 +295,6 @@ class RenderFlex extends RenderBox with ContainerRenderObjectMixin<RenderBox, Fl
|
||||
|
||||
@override
|
||||
void performLayout() {
|
||||
// Originally based on http://www.w3.org/TR/css-flexbox-1/ Section 9.7 Resolving Flexible Lengths
|
||||
|
||||
// Determine used flex factor, size inflexible items, calculate free space.
|
||||
int totalFlex = 0;
|
||||
int totalChildren = 0;
|
||||
|
@ -240,24 +240,40 @@ class RenderFlow extends RenderBox
|
||||
@override
|
||||
bool get isRepaintBoundary => true;
|
||||
|
||||
// TODO(ianh): It's a bit dubious to be using the getSize function from the delegate to
|
||||
// figure out the intrinsic dimensions. We really should either not support intrinsics,
|
||||
// or we should expose intrinsic delegate callbacks and throw if they're not implemented.
|
||||
|
||||
@override
|
||||
double getMinIntrinsicWidth(BoxConstraints constraints) {
|
||||
return _getSize(constraints).width;
|
||||
double getMinIntrinsicWidth(double height) {
|
||||
final double width = _getSize(new BoxConstraints.tightForFinite(height: height)).width;
|
||||
if (width.isFinite)
|
||||
return width;
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
@override
|
||||
double getMaxIntrinsicWidth(BoxConstraints constraints) {
|
||||
return _getSize(constraints).width;
|
||||
double getMaxIntrinsicWidth(double height) {
|
||||
final double width = _getSize(new BoxConstraints.tightForFinite(height: height)).width;
|
||||
if (width.isFinite)
|
||||
return width;
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
@override
|
||||
double getMinIntrinsicHeight(BoxConstraints constraints) {
|
||||
return _getSize(constraints).height;
|
||||
double getMinIntrinsicHeight(double width) {
|
||||
final double height = _getSize(new BoxConstraints.tightForFinite(width: width)).height;
|
||||
if (height.isFinite)
|
||||
return height;
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
@override
|
||||
double getMaxIntrinsicHeight(BoxConstraints constraints) {
|
||||
return _getSize(constraints).height;
|
||||
double getMaxIntrinsicHeight(double width) {
|
||||
final double height = _getSize(new BoxConstraints.tightForFinite(width: width)).height;
|
||||
if (height.isFinite)
|
||||
return height;
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
@override
|
||||
|
@ -181,26 +181,34 @@ abstract class GridDelegate {
|
||||
|
||||
/// Returns the minimum width that this grid could be without failing to paint
|
||||
/// its contents within itself.
|
||||
double getMinIntrinsicWidth(BoxConstraints constraints, int childCount) {
|
||||
return constraints.constrainWidth(_getGridSize(constraints, childCount).width);
|
||||
///
|
||||
/// For more details, see [RenderBox.getMinIntrinsicWidth].
|
||||
double getMinIntrinsicWidth(double height, int childCount) {
|
||||
return _getGridSize(new BoxConstraints.tightForFinite(height: height), childCount).width;
|
||||
}
|
||||
|
||||
/// Returns the smallest width beyond which increasing the width never
|
||||
/// decreases the preferred height.
|
||||
double getMaxIntrinsicWidth(BoxConstraints constraints, int childCount) {
|
||||
return constraints.constrainWidth(_getGridSize(constraints, childCount).width);
|
||||
///
|
||||
/// For more details, see [RenderBox.getMaxIntrinsicWidth].
|
||||
double getMaxIntrinsicWidth(double height, int childCount) {
|
||||
return _getGridSize(new BoxConstraints.tightForFinite(height: height), childCount).width;
|
||||
}
|
||||
|
||||
/// Return the minimum height that this grid could be without failing to paint
|
||||
/// its contents within itself.
|
||||
double getMinIntrinsicHeight(BoxConstraints constraints, int childCount) {
|
||||
return constraints.constrainHeight(_getGridSize(constraints, childCount).height);
|
||||
///
|
||||
/// For more details, see [RenderBox.getMinIntrinsicHeight].
|
||||
double getMinIntrinsicHeight(double width, int childCount) {
|
||||
return _getGridSize(new BoxConstraints.tightForFinite(width: width), childCount).height;
|
||||
}
|
||||
|
||||
/// Returns the smallest height beyond which increasing the height never
|
||||
/// decreases the preferred width.
|
||||
double getMaxIntrinsicHeight(BoxConstraints constraints, int childCount) {
|
||||
return constraints.constrainHeight(_getGridSize(constraints, childCount).height);
|
||||
///
|
||||
/// For more details, see [RenderBox.getMaxIntrinsicHeight].
|
||||
double getMaxIntrinsicHeight(double width, int childCount) {
|
||||
return _getGridSize(new BoxConstraints.tightForFinite(width: width), childCount).height;
|
||||
}
|
||||
}
|
||||
|
||||
@ -293,13 +301,13 @@ class FixedColumnCountGridDelegate extends GridDelegateWithInOrderChildPlacement
|
||||
}
|
||||
|
||||
@override
|
||||
double getMinIntrinsicWidth(BoxConstraints constraints, int childCount) {
|
||||
return constraints.constrainWidth(0.0);
|
||||
double getMinIntrinsicWidth(double height, int childCount) {
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
@override
|
||||
double getMaxIntrinsicWidth(BoxConstraints constraints, int childCount) {
|
||||
return constraints.constrainWidth(0.0);
|
||||
double getMaxIntrinsicWidth(double height, int childCount) {
|
||||
return 0.0;
|
||||
}
|
||||
}
|
||||
|
||||
@ -359,13 +367,13 @@ class MaxTileWidthGridDelegate extends GridDelegateWithInOrderChildPlacement {
|
||||
}
|
||||
|
||||
@override
|
||||
double getMinIntrinsicWidth(BoxConstraints constraints, int childCount) {
|
||||
return constraints.constrainWidth(0.0);
|
||||
double getMinIntrinsicWidth(double height, int childCount) {
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
@override
|
||||
double getMaxIntrinsicWidth(BoxConstraints constraints, int childCount) {
|
||||
return constraints.constrainWidth(maxTileWidth * childCount);
|
||||
double getMaxIntrinsicWidth(double height, int childCount) {
|
||||
return maxTileWidth * childCount;
|
||||
}
|
||||
}
|
||||
|
||||
@ -470,27 +478,23 @@ class RenderGrid extends RenderVirtualViewport<GridParentData> {
|
||||
}
|
||||
|
||||
@override
|
||||
double getMinIntrinsicWidth(BoxConstraints constraints) {
|
||||
assert(constraints.debugAssertIsValid());
|
||||
return _delegate.getMinIntrinsicWidth(constraints, virtualChildCount);
|
||||
double getMinIntrinsicWidth(double height) {
|
||||
return _delegate.getMinIntrinsicWidth(height, virtualChildCount);
|
||||
}
|
||||
|
||||
@override
|
||||
double getMaxIntrinsicWidth(BoxConstraints constraints) {
|
||||
assert(constraints.debugAssertIsValid());
|
||||
return _delegate.getMaxIntrinsicWidth(constraints, virtualChildCount);
|
||||
double getMaxIntrinsicWidth(double height) {
|
||||
return _delegate.getMaxIntrinsicWidth(height, virtualChildCount);
|
||||
}
|
||||
|
||||
@override
|
||||
double getMinIntrinsicHeight(BoxConstraints constraints) {
|
||||
assert(constraints.debugAssertIsValid());
|
||||
return _delegate.getMinIntrinsicHeight(constraints, virtualChildCount);
|
||||
double getMinIntrinsicHeight(double width) {
|
||||
return _delegate.getMinIntrinsicHeight(width, virtualChildCount);
|
||||
}
|
||||
|
||||
@override
|
||||
double getMaxIntrinsicHeight(BoxConstraints constraints) {
|
||||
assert(constraints.debugAssertIsValid());
|
||||
return _delegate.getMaxIntrinsicHeight(constraints, virtualChildCount);
|
||||
double getMaxIntrinsicHeight(double width) {
|
||||
return _delegate.getMaxIntrinsicHeight(width, virtualChildCount);
|
||||
}
|
||||
|
||||
@override
|
||||
|
@ -205,31 +205,27 @@ class RenderImage extends RenderBox {
|
||||
}
|
||||
|
||||
@override
|
||||
double getMinIntrinsicWidth(BoxConstraints constraints) {
|
||||
assert(constraints.debugAssertIsValid());
|
||||
double getMinIntrinsicWidth(double height) {
|
||||
if (_width == null && _height == null)
|
||||
return constraints.constrainWidth(0.0);
|
||||
return _sizeForConstraints(constraints).width;
|
||||
return 0.0;
|
||||
return _sizeForConstraints(new BoxConstraints.tightForFinite(height: height)).width;
|
||||
}
|
||||
|
||||
@override
|
||||
double getMaxIntrinsicWidth(BoxConstraints constraints) {
|
||||
assert(constraints.debugAssertIsValid());
|
||||
return _sizeForConstraints(constraints).width;
|
||||
double getMaxIntrinsicWidth(double height) {
|
||||
return _sizeForConstraints(new BoxConstraints.tightForFinite(height: height)).width;
|
||||
}
|
||||
|
||||
@override
|
||||
double getMinIntrinsicHeight(BoxConstraints constraints) {
|
||||
assert(constraints.debugAssertIsValid());
|
||||
double getMinIntrinsicHeight(double width) {
|
||||
if (_width == null && _height == null)
|
||||
return constraints.constrainHeight(0.0);
|
||||
return _sizeForConstraints(constraints).height;
|
||||
return 0.0;
|
||||
return _sizeForConstraints(new BoxConstraints.tightForFinite(width: width)).height;
|
||||
}
|
||||
|
||||
@override
|
||||
double getMaxIntrinsicHeight(BoxConstraints constraints) {
|
||||
assert(constraints.debugAssertIsValid());
|
||||
return _sizeForConstraints(constraints).height;
|
||||
double getMaxIntrinsicHeight(double width) {
|
||||
return _sizeForConstraints(new BoxConstraints.tightForFinite(width: width)).height;
|
||||
}
|
||||
|
||||
@override
|
||||
|
@ -87,7 +87,7 @@ class RenderList extends RenderVirtualViewport<ListParentData> {
|
||||
double get _preferredExtent {
|
||||
if (itemExtent == null)
|
||||
return double.INFINITY;
|
||||
int count = virtualChildCount;
|
||||
final int count = virtualChildCount;
|
||||
if (count == null)
|
||||
return double.INFINITY;
|
||||
double extent = itemExtent * count;
|
||||
@ -96,44 +96,52 @@ class RenderList extends RenderVirtualViewport<ListParentData> {
|
||||
return extent;
|
||||
}
|
||||
|
||||
double _getIntrinsicWidth(BoxConstraints constraints) {
|
||||
assert(constraints.debugAssertIsValid());
|
||||
double _getIntrinsicWidth() {
|
||||
switch (mainAxis) {
|
||||
case Axis.vertical:
|
||||
return constraints.constrainWidth(0.0);
|
||||
assert(debugThrowIfNotCheckingIntrinsics());
|
||||
return 0.0;
|
||||
case Axis.horizontal:
|
||||
return constraints.constrainWidth(_preferredExtent);
|
||||
final double width = _preferredExtent;
|
||||
if (width.isFinite)
|
||||
return width;
|
||||
assert(debugThrowIfNotCheckingIntrinsics());
|
||||
return 0.0;
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
double getMinIntrinsicWidth(BoxConstraints constraints) {
|
||||
return _getIntrinsicWidth(constraints);
|
||||
double getMinIntrinsicWidth(double height) {
|
||||
return _getIntrinsicWidth();
|
||||
}
|
||||
|
||||
@override
|
||||
double getMaxIntrinsicWidth(BoxConstraints constraints) {
|
||||
return _getIntrinsicWidth(constraints);
|
||||
double getMaxIntrinsicWidth(double height) {
|
||||
return _getIntrinsicWidth();
|
||||
}
|
||||
|
||||
double _getIntrinsicHeight(BoxConstraints constraints) {
|
||||
assert(constraints.debugAssertIsValid());
|
||||
double _getIntrinsicHeight() {
|
||||
switch (mainAxis) {
|
||||
case Axis.vertical:
|
||||
return constraints.constrainHeight(_preferredExtent);
|
||||
final double height = _preferredExtent;
|
||||
if (height.isFinite)
|
||||
return height;
|
||||
assert(debugThrowIfNotCheckingIntrinsics());
|
||||
return 0.0;
|
||||
case Axis.horizontal:
|
||||
return constraints.constrainHeight(0.0);
|
||||
assert(debugThrowIfNotCheckingIntrinsics());
|
||||
return 0.0;
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
double getMinIntrinsicHeight(BoxConstraints constraints) {
|
||||
return _getIntrinsicHeight(constraints);
|
||||
double getMinIntrinsicHeight(double width) {
|
||||
return _getIntrinsicHeight();
|
||||
}
|
||||
|
||||
@override
|
||||
double getMaxIntrinsicHeight(BoxConstraints constraints) {
|
||||
return _getIntrinsicHeight(constraints);
|
||||
double getMaxIntrinsicHeight(double width) {
|
||||
return _getIntrinsicHeight();
|
||||
}
|
||||
|
||||
@override
|
||||
|
@ -14,18 +14,6 @@ class RenderOffStage extends RenderBox with RenderObjectWithChildMixin<RenderBox
|
||||
this.child = child;
|
||||
}
|
||||
|
||||
@override
|
||||
double getMinIntrinsicWidth(BoxConstraints constraints) => constraints.minWidth;
|
||||
|
||||
@override
|
||||
double getMaxIntrinsicWidth(BoxConstraints constraints) => constraints.minWidth;
|
||||
|
||||
@override
|
||||
double getMinIntrinsicHeight(BoxConstraints constraints) => constraints.minHeight;
|
||||
|
||||
@override
|
||||
double getMaxIntrinsicHeight(BoxConstraints constraints) => constraints.minHeight;
|
||||
|
||||
@override
|
||||
bool get sizedByParent => true;
|
||||
|
||||
|
@ -87,45 +87,43 @@ class RenderParagraph extends RenderBox {
|
||||
markNeedsPaint();
|
||||
}
|
||||
|
||||
void _layoutText(BoxConstraints constraints) {
|
||||
assert(constraints != null);
|
||||
assert(constraints.debugAssertIsValid());
|
||||
_textPainter.layout(minWidth: constraints.minWidth, maxWidth: _softWrap ? constraints.maxWidth : double.INFINITY);
|
||||
void _layoutText({ double minWidth: 0.0, double maxWidth: double.INFINITY }) {
|
||||
_textPainter.layout(minWidth: minWidth, maxWidth: _softWrap ? maxWidth : double.INFINITY);
|
||||
}
|
||||
|
||||
@override
|
||||
double getMinIntrinsicWidth(BoxConstraints constraints) {
|
||||
_layoutText(constraints);
|
||||
return constraints.constrainWidth(_textPainter.minIntrinsicWidth);
|
||||
double getMinIntrinsicWidth(double height) {
|
||||
_layoutText();
|
||||
return _textPainter.minIntrinsicWidth;
|
||||
}
|
||||
|
||||
@override
|
||||
double getMaxIntrinsicWidth(BoxConstraints constraints) {
|
||||
_layoutText(constraints);
|
||||
return constraints.constrainWidth(_textPainter.maxIntrinsicWidth);
|
||||
double getMaxIntrinsicWidth(double height) {
|
||||
_layoutText();
|
||||
return _textPainter.maxIntrinsicWidth;
|
||||
}
|
||||
|
||||
double _getIntrinsicHeight(BoxConstraints constraints) {
|
||||
_layoutText(constraints);
|
||||
return constraints.constrainHeight(_textPainter.height);
|
||||
double _getIntrinsicHeight(double width) {
|
||||
_layoutText(minWidth: width, maxWidth: width);
|
||||
return _textPainter.height;
|
||||
}
|
||||
|
||||
@override
|
||||
double getMinIntrinsicHeight(BoxConstraints constraints) {
|
||||
assert(constraints.debugAssertIsValid());
|
||||
return _getIntrinsicHeight(constraints);
|
||||
double getMinIntrinsicHeight(double width) {
|
||||
return _getIntrinsicHeight(width);
|
||||
}
|
||||
|
||||
@override
|
||||
double getMaxIntrinsicHeight(BoxConstraints constraints) {
|
||||
assert(constraints.debugAssertIsValid());
|
||||
return _getIntrinsicHeight(constraints);
|
||||
double getMaxIntrinsicHeight(double width) {
|
||||
return _getIntrinsicHeight(width);
|
||||
}
|
||||
|
||||
@override
|
||||
double computeDistanceToActualBaseline(TextBaseline baseline) {
|
||||
assert(!needsLayout);
|
||||
_layoutText(constraints);
|
||||
assert(constraints != null);
|
||||
assert(constraints.debugAssertIsValid());
|
||||
_layoutText(minWidth: constraints.minWidth, maxWidth: constraints.maxWidth);
|
||||
return _textPainter.computeDistanceToActualBaseline(baseline);
|
||||
}
|
||||
|
||||
@ -136,7 +134,7 @@ class RenderParagraph extends RenderBox {
|
||||
void handleEvent(PointerEvent event, BoxHitTestEntry entry) {
|
||||
if (event is! PointerDownEvent)
|
||||
return;
|
||||
_layoutText(constraints);
|
||||
_layoutText(minWidth: constraints.minWidth, maxWidth: constraints.maxWidth);
|
||||
Offset offset = entry.localPosition.toOffset();
|
||||
TextPosition position = _textPainter.getPositionForOffset(offset);
|
||||
TextSpan span = _textPainter.text.getSpanForPosition(position);
|
||||
@ -149,7 +147,7 @@ class RenderParagraph extends RenderBox {
|
||||
|
||||
@override
|
||||
void performLayout() {
|
||||
_layoutText(constraints);
|
||||
_layoutText(minWidth: constraints.minWidth, maxWidth: constraints.maxWidth);
|
||||
size = constraints.constrain(_textPainter.size);
|
||||
|
||||
final bool didOverflowWidth = size.width < _textPainter.width;
|
||||
@ -200,7 +198,7 @@ class RenderParagraph extends RenderBox {
|
||||
//
|
||||
// If you remove this call, make sure that changing the textAlign still
|
||||
// works properly.
|
||||
_layoutText(constraints);
|
||||
_layoutText(minWidth: constraints.minWidth, maxWidth: constraints.maxWidth);
|
||||
final Canvas canvas = context.canvas;
|
||||
if (_hasVisualOverflow) {
|
||||
final Rect bounds = offset & size;
|
||||
|
@ -97,13 +97,13 @@ class RenderPerformanceOverlay extends RenderBox {
|
||||
bool get alwaysNeedsCompositing => true;
|
||||
|
||||
@override
|
||||
double getMinIntrinsicWidth(BoxConstraints constraints) {
|
||||
return constraints.constrainWidth(0.0);
|
||||
double getMinIntrinsicWidth(double height) {
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
@override
|
||||
double getMaxIntrinsicWidth(BoxConstraints constraints) {
|
||||
return constraints.constrainWidth(0.0);
|
||||
double getMaxIntrinsicWidth(double height) {
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
double get _intrinsicHeight {
|
||||
@ -119,13 +119,13 @@ class RenderPerformanceOverlay extends RenderBox {
|
||||
}
|
||||
|
||||
@override
|
||||
double getMinIntrinsicHeight(BoxConstraints constraints) {
|
||||
return constraints.constrainHeight(_intrinsicHeight);
|
||||
double getMinIntrinsicHeight(double width) {
|
||||
return _intrinsicHeight;
|
||||
}
|
||||
|
||||
@override
|
||||
double getMaxIntrinsicHeight(BoxConstraints constraints) {
|
||||
return constraints.constrainHeight(_intrinsicHeight);
|
||||
double getMaxIntrinsicHeight(double width) {
|
||||
return _intrinsicHeight;
|
||||
}
|
||||
|
||||
@override
|
||||
|
@ -42,35 +42,31 @@ class RenderProxyBox extends RenderBox with RenderObjectWithChildMixin<RenderBox
|
||||
}
|
||||
|
||||
@override
|
||||
double getMinIntrinsicWidth(BoxConstraints constraints) {
|
||||
assert(constraints.debugAssertIsValid());
|
||||
double getMinIntrinsicWidth(double height) {
|
||||
if (child != null)
|
||||
return child.getMinIntrinsicWidth(constraints);
|
||||
return super.getMinIntrinsicWidth(constraints);
|
||||
return child.getMinIntrinsicWidth(height);
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
@override
|
||||
double getMaxIntrinsicWidth(BoxConstraints constraints) {
|
||||
assert(constraints.debugAssertIsValid());
|
||||
double getMaxIntrinsicWidth(double height) {
|
||||
if (child != null)
|
||||
return child.getMaxIntrinsicWidth(constraints);
|
||||
return super.getMaxIntrinsicWidth(constraints);
|
||||
return child.getMaxIntrinsicWidth(height);
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
@override
|
||||
double getMinIntrinsicHeight(BoxConstraints constraints) {
|
||||
assert(constraints.debugAssertIsValid());
|
||||
double getMinIntrinsicHeight(double width) {
|
||||
if (child != null)
|
||||
return child.getMinIntrinsicHeight(constraints);
|
||||
return super.getMinIntrinsicHeight(constraints);
|
||||
return child.getMinIntrinsicHeight(width);
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
@override
|
||||
double getMaxIntrinsicHeight(BoxConstraints constraints) {
|
||||
assert(constraints.debugAssertIsValid());
|
||||
double getMaxIntrinsicHeight(double width) {
|
||||
if (child != null)
|
||||
return child.getMaxIntrinsicHeight(constraints);
|
||||
return super.getMaxIntrinsicHeight(constraints);
|
||||
return child.getMaxIntrinsicHeight(width);
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
@override
|
||||
@ -199,35 +195,35 @@ class RenderConstrainedBox extends RenderProxyBox {
|
||||
}
|
||||
|
||||
@override
|
||||
double getMinIntrinsicWidth(BoxConstraints constraints) {
|
||||
assert(constraints.debugAssertIsValid());
|
||||
if (child != null)
|
||||
return child.getMinIntrinsicWidth(_additionalConstraints.enforce(constraints));
|
||||
return _additionalConstraints.enforce(constraints).constrainWidth(0.0);
|
||||
double getMinIntrinsicWidth(double height) {
|
||||
final double width = super.getMinIntrinsicWidth(height);
|
||||
if (_additionalConstraints.hasBoundedWidth)
|
||||
return _additionalConstraints.constrainWidth(width);
|
||||
return width;
|
||||
}
|
||||
|
||||
@override
|
||||
double getMaxIntrinsicWidth(BoxConstraints constraints) {
|
||||
assert(constraints.debugAssertIsValid());
|
||||
if (child != null)
|
||||
return child.getMaxIntrinsicWidth(_additionalConstraints.enforce(constraints));
|
||||
return _additionalConstraints.enforce(constraints).constrainWidth(0.0);
|
||||
double getMaxIntrinsicWidth(double height) {
|
||||
final double width = super.getMaxIntrinsicWidth(height);
|
||||
if (_additionalConstraints.hasBoundedWidth)
|
||||
return _additionalConstraints.constrainWidth(width);
|
||||
return width;
|
||||
}
|
||||
|
||||
@override
|
||||
double getMinIntrinsicHeight(BoxConstraints constraints) {
|
||||
assert(constraints.debugAssertIsValid());
|
||||
if (child != null)
|
||||
return child.getMinIntrinsicHeight(_additionalConstraints.enforce(constraints));
|
||||
return _additionalConstraints.enforce(constraints).constrainHeight(0.0);
|
||||
double getMinIntrinsicHeight(double width) {
|
||||
final double height = super.getMinIntrinsicHeight(width);
|
||||
if (_additionalConstraints.hasBoundedHeight)
|
||||
return _additionalConstraints.constrainHeight(height);
|
||||
return height;
|
||||
}
|
||||
|
||||
@override
|
||||
double getMaxIntrinsicHeight(BoxConstraints constraints) {
|
||||
assert(constraints.debugAssertIsValid());
|
||||
if (child != null)
|
||||
return child.getMaxIntrinsicHeight(_additionalConstraints.enforce(constraints));
|
||||
return _additionalConstraints.enforce(constraints).constrainHeight(0.0);
|
||||
double getMaxIntrinsicHeight(double width) {
|
||||
final double height = super.getMaxIntrinsicHeight(width);
|
||||
if (_additionalConstraints.hasBoundedHeight)
|
||||
return _additionalConstraints.constrainHeight(height);
|
||||
return height;
|
||||
}
|
||||
|
||||
@override
|
||||
@ -309,38 +305,6 @@ class RenderLimitedBox extends RenderProxyBox {
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
double getMinIntrinsicWidth(BoxConstraints constraints) {
|
||||
assert(constraints.debugAssertIsValid());
|
||||
if (child != null)
|
||||
return child.getMinIntrinsicWidth(_limitConstraints(constraints));
|
||||
return _limitConstraints(constraints).constrainWidth(0.0);
|
||||
}
|
||||
|
||||
@override
|
||||
double getMaxIntrinsicWidth(BoxConstraints constraints) {
|
||||
assert(constraints.debugAssertIsValid());
|
||||
if (child != null)
|
||||
return child.getMaxIntrinsicWidth(_limitConstraints(constraints));
|
||||
return _limitConstraints(constraints).constrainWidth(0.0);
|
||||
}
|
||||
|
||||
@override
|
||||
double getMinIntrinsicHeight(BoxConstraints constraints) {
|
||||
assert(constraints.debugAssertIsValid());
|
||||
if (child != null)
|
||||
return child.getMinIntrinsicHeight(_limitConstraints(constraints));
|
||||
return _limitConstraints(constraints).constrainHeight(0.0);
|
||||
}
|
||||
|
||||
@override
|
||||
double getMaxIntrinsicHeight(BoxConstraints constraints) {
|
||||
assert(constraints.debugAssertIsValid());
|
||||
if (child != null)
|
||||
return child.getMaxIntrinsicHeight(_limitConstraints(constraints));
|
||||
return _limitConstraints(constraints).constrainHeight(0.0);
|
||||
}
|
||||
|
||||
@override
|
||||
void performLayout() {
|
||||
if (child != null) {
|
||||
@ -417,27 +381,39 @@ class RenderAspectRatio extends RenderProxyBox {
|
||||
}
|
||||
|
||||
@override
|
||||
double getMinIntrinsicWidth(BoxConstraints constraints) {
|
||||
assert(constraints.debugAssertIsValid());
|
||||
return constraints.minWidth;
|
||||
double getMinIntrinsicWidth(double height) {
|
||||
if (height.isFinite)
|
||||
return height * _aspectRatio;
|
||||
if (child != null)
|
||||
return child.getMinIntrinsicWidth(height);
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
@override
|
||||
double getMaxIntrinsicWidth(BoxConstraints constraints) {
|
||||
assert(constraints.debugAssertIsValid());
|
||||
return constraints.constrainWidth(constraints.maxHeight * aspectRatio);
|
||||
double getMaxIntrinsicWidth(double height) {
|
||||
if (height.isFinite)
|
||||
return height * _aspectRatio;
|
||||
if (child != null)
|
||||
return child.getMaxIntrinsicWidth(height);
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
@override
|
||||
double getMinIntrinsicHeight(BoxConstraints constraints) {
|
||||
assert(constraints.debugAssertIsValid());
|
||||
return constraints.minHeight;
|
||||
double getMinIntrinsicHeight(double width) {
|
||||
if (width.isFinite)
|
||||
return width / _aspectRatio;
|
||||
if (child != null)
|
||||
return child.getMinIntrinsicHeight(width);
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
@override
|
||||
double getMaxIntrinsicHeight(BoxConstraints constraints) {
|
||||
assert(constraints.debugAssertIsValid());
|
||||
return constraints.constrainHeight(constraints.maxWidth / aspectRatio);
|
||||
double getMaxIntrinsicHeight(double width) {
|
||||
if (width.isFinite)
|
||||
return width / _aspectRatio;
|
||||
if (child != null)
|
||||
return child.getMaxIntrinsicHeight(width);
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
Size _applyAspectRatio(BoxConstraints constraints) {
|
||||
@ -563,53 +539,50 @@ class RenderIntrinsicWidth extends RenderProxyBox {
|
||||
assert(child != null);
|
||||
if (constraints.hasTightWidth)
|
||||
return constraints;
|
||||
double width = child.getMaxIntrinsicWidth(constraints);
|
||||
final double width = child.getMaxIntrinsicWidth(constraints.maxHeight);
|
||||
assert(width == constraints.constrainWidth(width));
|
||||
return constraints.tighten(width: _applyStep(width, _stepWidth));
|
||||
}
|
||||
|
||||
@override
|
||||
double getMinIntrinsicWidth(BoxConstraints constraints) {
|
||||
assert(constraints.debugAssertIsValid());
|
||||
return getMaxIntrinsicWidth(constraints);
|
||||
double getMinIntrinsicWidth(double height) {
|
||||
return getMaxIntrinsicWidth(height);
|
||||
}
|
||||
|
||||
@override
|
||||
double getMaxIntrinsicWidth(BoxConstraints constraints) {
|
||||
assert(constraints.debugAssertIsValid());
|
||||
double getMaxIntrinsicWidth(double height) {
|
||||
if (child == null)
|
||||
return constraints.constrainWidth(0.0);
|
||||
double childResult = child.getMaxIntrinsicWidth(constraints);
|
||||
return 0.0;
|
||||
double childResult = child.getMaxIntrinsicWidth(height);
|
||||
assert(!childResult.isInfinite);
|
||||
return constraints.constrainWidth(_applyStep(childResult, _stepWidth));
|
||||
return _applyStep(childResult, _stepWidth);
|
||||
}
|
||||
|
||||
@override
|
||||
double getMinIntrinsicHeight(BoxConstraints constraints) {
|
||||
assert(constraints.debugAssertIsValid());
|
||||
double getMinIntrinsicHeight(double width) {
|
||||
if (child == null)
|
||||
return constraints.constrainHeight(0.0);
|
||||
double childResult = child.getMinIntrinsicHeight(_getInnerConstraints(constraints));
|
||||
assert(!childResult.isInfinite);
|
||||
return constraints.constrainHeight(_applyStep(childResult, _stepHeight));
|
||||
return 0.0;
|
||||
double childResult = child.getMinIntrinsicHeight(_getInnerConstraints(new BoxConstraints.tightForFinite(width: width)).maxWidth);
|
||||
assert(childResult.isFinite);
|
||||
return _applyStep(childResult, _stepHeight);
|
||||
}
|
||||
|
||||
@override
|
||||
double getMaxIntrinsicHeight(BoxConstraints constraints) {
|
||||
assert(constraints.debugAssertIsValid());
|
||||
double getMaxIntrinsicHeight(double width) {
|
||||
if (child == null)
|
||||
return constraints.constrainHeight(0.0);
|
||||
double childResult = child.getMaxIntrinsicHeight(_getInnerConstraints(constraints));
|
||||
assert(!childResult.isInfinite);
|
||||
return constraints.constrainHeight(_applyStep(childResult, _stepHeight));
|
||||
return 0.0;
|
||||
double childResult = child.getMaxIntrinsicHeight(_getInnerConstraints(new BoxConstraints.tightForFinite(width: width)).maxWidth);
|
||||
assert(childResult.isFinite);
|
||||
return _applyStep(childResult, _stepHeight);
|
||||
}
|
||||
|
||||
@override
|
||||
void performLayout() {
|
||||
if (child != null) {
|
||||
BoxConstraints childConstraints = _getInnerConstraints(constraints);
|
||||
assert(childConstraints.hasTightWidth);
|
||||
if (_stepHeight != null)
|
||||
childConstraints.tighten(height: getMaxIntrinsicHeight(childConstraints));
|
||||
childConstraints.tighten(height: getMaxIntrinsicHeight(childConstraints.maxWidth));
|
||||
child.layout(childConstraints, parentUsesSize: true);
|
||||
size = child.size;
|
||||
} else {
|
||||
@ -642,39 +615,28 @@ class RenderIntrinsicHeight extends RenderProxyBox {
|
||||
assert(child != null);
|
||||
if (constraints.hasTightHeight)
|
||||
return constraints;
|
||||
double height = child.getMaxIntrinsicHeight(constraints);
|
||||
final double height = child.getMaxIntrinsicHeight(constraints.maxWidth);
|
||||
assert(height == constraints.constrainHeight(height));
|
||||
return constraints.tighten(height: height);
|
||||
}
|
||||
|
||||
@override
|
||||
double getMinIntrinsicWidth(BoxConstraints constraints) {
|
||||
assert(constraints.debugAssertIsValid());
|
||||
double getMinIntrinsicWidth(double height) {
|
||||
if (child == null)
|
||||
return constraints.constrainWidth(0.0);
|
||||
return child.getMinIntrinsicWidth(_getInnerConstraints(constraints));
|
||||
return 0.0;
|
||||
return child.getMinIntrinsicWidth(_getInnerConstraints(new BoxConstraints.tightForFinite(height: height)).maxHeight);
|
||||
}
|
||||
|
||||
@override
|
||||
double getMaxIntrinsicWidth(BoxConstraints constraints) {
|
||||
assert(constraints.debugAssertIsValid());
|
||||
double getMaxIntrinsicWidth(double height) {
|
||||
if (child == null)
|
||||
return constraints.constrainWidth(0.0);
|
||||
return child.getMaxIntrinsicWidth(_getInnerConstraints(constraints));
|
||||
return 0.0;
|
||||
return child.getMaxIntrinsicWidth(_getInnerConstraints(new BoxConstraints.tightForFinite(height: height)).maxHeight);
|
||||
}
|
||||
|
||||
@override
|
||||
double getMinIntrinsicHeight(BoxConstraints constraints) {
|
||||
assert(constraints.debugAssertIsValid());
|
||||
return getMaxIntrinsicHeight(constraints);
|
||||
}
|
||||
|
||||
@override
|
||||
double getMaxIntrinsicHeight(BoxConstraints constraints) {
|
||||
assert(constraints.debugAssertIsValid());
|
||||
if (child == null)
|
||||
return constraints.constrainHeight(0.0);
|
||||
return child.getMaxIntrinsicHeight(constraints);
|
||||
double getMinIntrinsicHeight(double width) {
|
||||
return getMaxIntrinsicHeight(width);
|
||||
}
|
||||
|
||||
@override
|
||||
|
@ -43,35 +43,31 @@ class RenderRotatedBox extends RenderBox with RenderObjectWithChildMixin<RenderB
|
||||
bool get _isVertical => quarterTurns % 2 == 1;
|
||||
|
||||
@override
|
||||
double getMinIntrinsicWidth(BoxConstraints constraints) {
|
||||
assert(constraints.debugAssertIsValid());
|
||||
if (child != null)
|
||||
return _isVertical ? child.getMinIntrinsicHeight(constraints.flipped) : child.getMinIntrinsicWidth(constraints);
|
||||
return super.getMinIntrinsicWidth(constraints);
|
||||
double getMinIntrinsicWidth(double height) {
|
||||
if (child == null)
|
||||
return 0.0;
|
||||
return _isVertical ? child.getMinIntrinsicHeight(height) : child.getMinIntrinsicWidth(height);
|
||||
}
|
||||
|
||||
@override
|
||||
double getMaxIntrinsicWidth(BoxConstraints constraints) {
|
||||
assert(constraints.debugAssertIsValid());
|
||||
if (child != null)
|
||||
return _isVertical ? child.getMaxIntrinsicHeight(constraints.flipped) : child.getMaxIntrinsicWidth(constraints);
|
||||
return super.getMaxIntrinsicWidth(constraints);
|
||||
double getMaxIntrinsicWidth(double height) {
|
||||
if (child == null)
|
||||
return 0.0;
|
||||
return _isVertical ? child.getMaxIntrinsicHeight(height) : child.getMaxIntrinsicWidth(height);
|
||||
}
|
||||
|
||||
@override
|
||||
double getMinIntrinsicHeight(BoxConstraints constraints) {
|
||||
assert(constraints.debugAssertIsValid());
|
||||
if (child != null)
|
||||
return _isVertical ? child.getMinIntrinsicWidth(constraints.flipped) : child.getMinIntrinsicHeight(constraints);
|
||||
return super.getMinIntrinsicHeight(constraints);
|
||||
double getMinIntrinsicHeight(double width) {
|
||||
if (child == null)
|
||||
return 0.0;
|
||||
return _isVertical ? child.getMinIntrinsicWidth(width) : child.getMinIntrinsicHeight(width);
|
||||
}
|
||||
|
||||
@override
|
||||
double getMaxIntrinsicHeight(BoxConstraints constraints) {
|
||||
assert(constraints.debugAssertIsValid());
|
||||
if (child != null)
|
||||
return _isVertical ? child.getMaxIntrinsicWidth(constraints.flipped) : child.getMaxIntrinsicHeight(constraints);
|
||||
return super.getMaxIntrinsicHeight(constraints);
|
||||
double getMaxIntrinsicHeight(double width) {
|
||||
if (child == null)
|
||||
return 0.0;
|
||||
return _isVertical ? child.getMaxIntrinsicWidth(width) : child.getMaxIntrinsicHeight(width);
|
||||
}
|
||||
|
||||
Matrix4 _paintTransform;
|
||||
|
@ -17,35 +17,31 @@ abstract class RenderShiftedBox extends RenderBox with RenderObjectWithChildMixi
|
||||
}
|
||||
|
||||
@override
|
||||
double getMinIntrinsicWidth(BoxConstraints constraints) {
|
||||
assert(constraints.debugAssertIsValid());
|
||||
double getMinIntrinsicWidth(double height) {
|
||||
if (child != null)
|
||||
return child.getMinIntrinsicWidth(constraints);
|
||||
return super.getMinIntrinsicWidth(constraints);
|
||||
return child.getMinIntrinsicWidth(height);
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
@override
|
||||
double getMaxIntrinsicWidth(BoxConstraints constraints) {
|
||||
assert(constraints.debugAssertIsValid());
|
||||
double getMaxIntrinsicWidth(double height) {
|
||||
if (child != null)
|
||||
return child.getMaxIntrinsicWidth(constraints);
|
||||
return super.getMaxIntrinsicWidth(constraints);
|
||||
return child.getMaxIntrinsicWidth(height);
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
@override
|
||||
double getMinIntrinsicHeight(BoxConstraints constraints) {
|
||||
assert(constraints.debugAssertIsValid());
|
||||
double getMinIntrinsicHeight(double width) {
|
||||
if (child != null)
|
||||
return child.getMinIntrinsicHeight(constraints);
|
||||
return super.getMinIntrinsicHeight(constraints);
|
||||
return child.getMinIntrinsicHeight(width);
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
@override
|
||||
double getMaxIntrinsicHeight(BoxConstraints constraints) {
|
||||
assert(constraints.debugAssertIsValid());
|
||||
double getMaxIntrinsicHeight(double width) {
|
||||
if (child != null)
|
||||
return child.getMaxIntrinsicHeight(constraints);
|
||||
return super.getMaxIntrinsicHeight(constraints);
|
||||
return child.getMaxIntrinsicHeight(width);
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
@override
|
||||
@ -115,39 +111,39 @@ class RenderPadding extends RenderShiftedBox {
|
||||
}
|
||||
|
||||
@override
|
||||
double getMinIntrinsicWidth(BoxConstraints constraints) {
|
||||
assert(constraints.debugAssertIsValid());
|
||||
double totalPadding = padding.left + padding.right;
|
||||
if (child != null)
|
||||
return constraints.constrainWidth(child.getMinIntrinsicWidth(constraints.deflate(padding)) + totalPadding);
|
||||
return constraints.constrainWidth(totalPadding);
|
||||
double getMinIntrinsicWidth(double height) {
|
||||
final double totalHorizontalPadding = padding.left + padding.right;
|
||||
final double totalVerticalPadding = padding.top + padding.bottom;
|
||||
if (child != null) // next line relies on double.INFINITY absorption
|
||||
return child.getMinIntrinsicWidth(height - totalVerticalPadding) + totalHorizontalPadding;
|
||||
return totalHorizontalPadding;
|
||||
}
|
||||
|
||||
@override
|
||||
double getMaxIntrinsicWidth(BoxConstraints constraints) {
|
||||
assert(constraints.debugAssertIsValid());
|
||||
double totalPadding = padding.left + padding.right;
|
||||
if (child != null)
|
||||
return constraints.constrainWidth(child.getMaxIntrinsicWidth(constraints.deflate(padding)) + totalPadding);
|
||||
return constraints.constrainWidth(totalPadding);
|
||||
double getMaxIntrinsicWidth(double height) {
|
||||
final double totalHorizontalPadding = padding.left + padding.right;
|
||||
final double totalVerticalPadding = padding.top + padding.bottom;
|
||||
if (child != null) // next line relies on double.INFINITY absorption
|
||||
return child.getMaxIntrinsicWidth(height - totalVerticalPadding) + totalHorizontalPadding;
|
||||
return totalHorizontalPadding;
|
||||
}
|
||||
|
||||
@override
|
||||
double getMinIntrinsicHeight(BoxConstraints constraints) {
|
||||
assert(constraints.debugAssertIsValid());
|
||||
double totalPadding = padding.top + padding.bottom;
|
||||
if (child != null)
|
||||
return constraints.constrainHeight(child.getMinIntrinsicHeight(constraints.deflate(padding)) + totalPadding);
|
||||
return constraints.constrainHeight(totalPadding);
|
||||
double getMinIntrinsicHeight(double width) {
|
||||
final double totalHorizontalPadding = padding.left + padding.right;
|
||||
final double totalVerticalPadding = padding.top + padding.bottom;
|
||||
if (child != null) // next line relies on double.INFINITY absorption
|
||||
return child.getMinIntrinsicHeight(width - totalHorizontalPadding) + totalVerticalPadding;
|
||||
return totalVerticalPadding;
|
||||
}
|
||||
|
||||
@override
|
||||
double getMaxIntrinsicHeight(BoxConstraints constraints) {
|
||||
assert(constraints.debugAssertIsValid());
|
||||
double totalPadding = padding.top + padding.bottom;
|
||||
if (child != null)
|
||||
return constraints.constrainHeight(child.getMaxIntrinsicHeight(constraints.deflate(padding)) + totalPadding);
|
||||
return constraints.constrainHeight(totalPadding);
|
||||
double getMaxIntrinsicHeight(double width) {
|
||||
final double totalHorizontalPadding = padding.left + padding.right;
|
||||
final double totalVerticalPadding = padding.top + padding.bottom;
|
||||
if (child != null) // next line relies on double.INFINITY absorption
|
||||
return child.getMaxIntrinsicHeight(width - totalHorizontalPadding) + totalVerticalPadding;
|
||||
return totalVerticalPadding;
|
||||
}
|
||||
|
||||
@override
|
||||
@ -502,30 +498,6 @@ class RenderConstrainedOverflowBox extends RenderAligningShiftedBox {
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
double getMinIntrinsicWidth(BoxConstraints constraints) {
|
||||
assert(constraints.debugAssertIsValid());
|
||||
return constraints.minWidth;
|
||||
}
|
||||
|
||||
@override
|
||||
double getMaxIntrinsicWidth(BoxConstraints constraints) {
|
||||
assert(constraints.debugAssertIsValid());
|
||||
return constraints.minWidth;
|
||||
}
|
||||
|
||||
@override
|
||||
double getMinIntrinsicHeight(BoxConstraints constraints) {
|
||||
assert(constraints.debugAssertIsValid());
|
||||
return constraints.minHeight;
|
||||
}
|
||||
|
||||
@override
|
||||
double getMaxIntrinsicHeight(BoxConstraints constraints) {
|
||||
assert(constraints.debugAssertIsValid());
|
||||
return constraints.minHeight;
|
||||
}
|
||||
|
||||
@override
|
||||
bool get sizedByParent => true;
|
||||
|
||||
@ -579,27 +551,23 @@ class RenderSizedOverflowBox extends RenderAligningShiftedBox {
|
||||
}
|
||||
|
||||
@override
|
||||
double getMinIntrinsicWidth(BoxConstraints constraints) {
|
||||
assert(constraints.debugAssertIsValid());
|
||||
return constraints.constrainWidth(_requestedSize.width);
|
||||
double getMinIntrinsicWidth(double height) {
|
||||
return _requestedSize.width;
|
||||
}
|
||||
|
||||
@override
|
||||
double getMaxIntrinsicWidth(BoxConstraints constraints) {
|
||||
assert(constraints.debugAssertIsValid());
|
||||
return constraints.constrainWidth(_requestedSize.width);
|
||||
double getMaxIntrinsicWidth(double height) {
|
||||
return _requestedSize.width;
|
||||
}
|
||||
|
||||
@override
|
||||
double getMinIntrinsicHeight(BoxConstraints constraints) {
|
||||
assert(constraints.debugAssertIsValid());
|
||||
return constraints.constrainHeight(_requestedSize.height);
|
||||
double getMinIntrinsicHeight(double width) {
|
||||
return _requestedSize.height;
|
||||
}
|
||||
|
||||
@override
|
||||
double getMaxIntrinsicHeight(BoxConstraints constraints) {
|
||||
assert(constraints.debugAssertIsValid());
|
||||
return constraints.constrainHeight(_requestedSize.height);
|
||||
double getMaxIntrinsicHeight(double width) {
|
||||
return _requestedSize.height;
|
||||
}
|
||||
|
||||
@override
|
||||
@ -699,35 +667,51 @@ class RenderFractionallySizedOverflowBox extends RenderAligningShiftedBox {
|
||||
}
|
||||
|
||||
@override
|
||||
double getMinIntrinsicWidth(BoxConstraints constraints) {
|
||||
assert(constraints.debugAssertIsValid());
|
||||
if (child != null)
|
||||
return constraints.constrainWidth(child.getMinIntrinsicWidth(_getInnerConstraints(constraints)));
|
||||
return constraints.constrainWidth(_getInnerConstraints(constraints).constrainWidth(0.0));
|
||||
double getMinIntrinsicWidth(double height) {
|
||||
double result;
|
||||
if (child == null) {
|
||||
result = super.getMinIntrinsicWidth(height);
|
||||
} else { // the following line relies on double.INFINITY absorption
|
||||
result = child.getMinIntrinsicWidth(height * (_heightFactor ?? 1.0));
|
||||
}
|
||||
assert(result.isFinite);
|
||||
return result / (_widthFactor ?? 1.0);
|
||||
}
|
||||
|
||||
@override
|
||||
double getMaxIntrinsicWidth(BoxConstraints constraints) {
|
||||
assert(constraints.debugAssertIsValid());
|
||||
if (child != null)
|
||||
return constraints.constrainWidth(child.getMaxIntrinsicWidth(_getInnerConstraints(constraints)));
|
||||
return constraints.constrainWidth(_getInnerConstraints(constraints).constrainWidth(0.0));
|
||||
double getMaxIntrinsicWidth(double height) {
|
||||
double result;
|
||||
if (child == null) {
|
||||
result = super.getMaxIntrinsicWidth(height);
|
||||
} else { // the following line relies on double.INFINITY absorption
|
||||
result = child.getMaxIntrinsicWidth(height * (_heightFactor ?? 1.0));
|
||||
}
|
||||
assert(result.isFinite);
|
||||
return result / (_widthFactor ?? 1.0);
|
||||
}
|
||||
|
||||
@override
|
||||
double getMinIntrinsicHeight(BoxConstraints constraints) {
|
||||
assert(constraints.debugAssertIsValid());
|
||||
if (child != null)
|
||||
return constraints.constrainHeight(child.getMinIntrinsicHeight(_getInnerConstraints(constraints)));
|
||||
return constraints.constrainHeight(_getInnerConstraints(constraints).constrainHeight(0.0));
|
||||
double getMinIntrinsicHeight(double width) {
|
||||
double result;
|
||||
if (child == null) {
|
||||
result = super.getMinIntrinsicHeight(width);
|
||||
} else { // the following line relies on double.INFINITY absorption
|
||||
result = child.getMinIntrinsicHeight(width * (_widthFactor ?? 1.0));
|
||||
}
|
||||
assert(result.isFinite);
|
||||
return result / (_heightFactor ?? 1.0);
|
||||
}
|
||||
|
||||
@override
|
||||
double getMaxIntrinsicHeight(BoxConstraints constraints) {
|
||||
assert(constraints.debugAssertIsValid());
|
||||
if (child != null)
|
||||
return constraints.constrainHeight(child.getMaxIntrinsicHeight(_getInnerConstraints(constraints)));
|
||||
return constraints.constrainHeight(_getInnerConstraints(constraints).constrainHeight(0.0));
|
||||
double getMaxIntrinsicHeight(double width) {
|
||||
double result;
|
||||
if (child == null) {
|
||||
result = super.getMaxIntrinsicHeight(width);
|
||||
} else { // the following line relies on double.INFINITY absorption
|
||||
result = child.getMaxIntrinsicHeight(width * (_widthFactor ?? 1.0));
|
||||
}
|
||||
assert(result.isFinite);
|
||||
return result / (_heightFactor ?? 1.0);
|
||||
}
|
||||
|
||||
@override
|
||||
@ -797,28 +781,40 @@ class RenderCustomSingleChildLayoutBox extends RenderShiftedBox {
|
||||
return constraints.constrain(_delegate.getSize(constraints));
|
||||
}
|
||||
|
||||
// TODO(ianh): It's a bit dubious to be using the getSize function from the delegate to
|
||||
// figure out the intrinsic dimensions. We really should either not support intrinsics,
|
||||
// or we should expose intrinsic delegate callbacks and throw if they're not implemented.
|
||||
|
||||
@override
|
||||
double getMinIntrinsicWidth(BoxConstraints constraints) {
|
||||
assert(constraints.debugAssertIsValid());
|
||||
return _getSize(constraints).width;
|
||||
double getMinIntrinsicWidth(double height) {
|
||||
final double width = _getSize(new BoxConstraints.tightForFinite(height: height)).width;
|
||||
if (width.isFinite)
|
||||
return width;
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
@override
|
||||
double getMaxIntrinsicWidth(BoxConstraints constraints) {
|
||||
assert(constraints.debugAssertIsValid());
|
||||
return _getSize(constraints).width;
|
||||
double getMaxIntrinsicWidth(double height) {
|
||||
final double width = _getSize(new BoxConstraints.tightForFinite(height: height)).width;
|
||||
if (width.isFinite)
|
||||
return width;
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
@override
|
||||
double getMinIntrinsicHeight(BoxConstraints constraints) {
|
||||
assert(constraints.debugAssertIsValid());
|
||||
return _getSize(constraints).height;
|
||||
double getMinIntrinsicHeight(double width) {
|
||||
final double height = _getSize(new BoxConstraints.tightForFinite(width: width)).height;
|
||||
if (height.isFinite)
|
||||
return height;
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
@override
|
||||
double getMaxIntrinsicHeight(BoxConstraints constraints) {
|
||||
assert(constraints.debugAssertIsValid());
|
||||
return _getSize(constraints).height;
|
||||
double getMaxIntrinsicHeight(double width) {
|
||||
final double height = _getSize(new BoxConstraints.tightForFinite(width: width)).height;
|
||||
if (height.isFinite)
|
||||
return height;
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
@override
|
||||
|
@ -224,78 +224,37 @@ abstract class RenderStackBase extends RenderBox
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
double getMinIntrinsicWidth(BoxConstraints constraints) {
|
||||
assert(constraints.debugAssertIsValid());
|
||||
double width = constraints.minWidth;
|
||||
double _getIntrinsicDimension(double mainChildSizeGetter(RenderBox child)) {
|
||||
double extent = 0.0;
|
||||
RenderBox child = firstChild;
|
||||
while (child != null) {
|
||||
final StackParentData childParentData = child.parentData;
|
||||
if (!childParentData.isPositioned)
|
||||
width = math.max(width, child.getMinIntrinsicWidth(constraints));
|
||||
extent = math.max(extent, mainChildSizeGetter(child));
|
||||
assert(child.parentData == childParentData);
|
||||
child = childParentData.nextSibling;
|
||||
}
|
||||
assert(width == constraints.constrainWidth(width));
|
||||
return width;
|
||||
return extent;
|
||||
}
|
||||
|
||||
@override
|
||||
double getMaxIntrinsicWidth(BoxConstraints constraints) {
|
||||
assert(constraints.debugAssertIsValid());
|
||||
bool hasNonPositionedChildren = false;
|
||||
double width = constraints.minWidth;
|
||||
RenderBox child = firstChild;
|
||||
while (child != null) {
|
||||
final StackParentData childParentData = child.parentData;
|
||||
if (!childParentData.isPositioned) {
|
||||
hasNonPositionedChildren = true;
|
||||
width = math.max(width, child.getMaxIntrinsicWidth(constraints));
|
||||
}
|
||||
assert(child.parentData == childParentData);
|
||||
child = childParentData.nextSibling;
|
||||
}
|
||||
if (!hasNonPositionedChildren)
|
||||
return constraints.constrainWidth();
|
||||
assert(width == constraints.constrainWidth(width));
|
||||
return width;
|
||||
double getMinIntrinsicWidth(double height) {
|
||||
return _getIntrinsicDimension((RenderBox child) => child.getMinIntrinsicWidth(height));
|
||||
}
|
||||
|
||||
@override
|
||||
double getMinIntrinsicHeight(BoxConstraints constraints) {
|
||||
assert(constraints.debugAssertIsValid());
|
||||
double height = constraints.minHeight;
|
||||
RenderBox child = firstChild;
|
||||
while (child != null) {
|
||||
final StackParentData childParentData = child.parentData;
|
||||
if (!childParentData.isPositioned)
|
||||
height = math.max(height, child.getMinIntrinsicHeight(constraints));
|
||||
assert(child.parentData == childParentData);
|
||||
child = childParentData.nextSibling;
|
||||
}
|
||||
assert(height == constraints.constrainHeight(height));
|
||||
return height;
|
||||
double getMaxIntrinsicWidth(double height) {
|
||||
return _getIntrinsicDimension((RenderBox child) => child.getMaxIntrinsicWidth(height));
|
||||
}
|
||||
|
||||
@override
|
||||
double getMaxIntrinsicHeight(BoxConstraints constraints) {
|
||||
assert(constraints.debugAssertIsValid());
|
||||
bool hasNonPositionedChildren = false;
|
||||
double height = constraints.minHeight;
|
||||
RenderBox child = firstChild;
|
||||
while (child != null) {
|
||||
final StackParentData childParentData = child.parentData;
|
||||
if (!childParentData.isPositioned) {
|
||||
hasNonPositionedChildren = true;
|
||||
height = math.max(height, child.getMaxIntrinsicHeight(constraints));
|
||||
}
|
||||
assert(child.parentData == childParentData);
|
||||
child = childParentData.nextSibling;
|
||||
}
|
||||
if (!hasNonPositionedChildren)
|
||||
return constraints.constrainHeight();
|
||||
assert(height == constraints.constrainHeight(height));
|
||||
return height;
|
||||
double getMinIntrinsicHeight(double width) {
|
||||
return _getIntrinsicDimension((RenderBox child) => child.getMinIntrinsicHeight(width));
|
||||
}
|
||||
|
||||
@override
|
||||
double getMaxIntrinsicHeight(double width) {
|
||||
return _getIntrinsicDimension((RenderBox child) => child.getMaxIntrinsicHeight(width));
|
||||
}
|
||||
|
||||
@override
|
||||
|
@ -82,7 +82,7 @@ class IntrinsicColumnWidth extends TableColumnWidth {
|
||||
double minIntrinsicWidth(Iterable<RenderBox> cells, double containerWidth) {
|
||||
double result = 0.0;
|
||||
for (RenderBox cell in cells)
|
||||
result = math.max(result, cell.getMinIntrinsicWidth(const BoxConstraints()));
|
||||
result = math.max(result, cell.getMinIntrinsicWidth(double.INFINITY));
|
||||
return result;
|
||||
}
|
||||
|
||||
@ -90,7 +90,7 @@ class IntrinsicColumnWidth extends TableColumnWidth {
|
||||
double maxIntrinsicWidth(Iterable<RenderBox> cells, double containerWidth) {
|
||||
double result = 0.0;
|
||||
for (RenderBox cell in cells)
|
||||
result = math.max(result, cell.getMaxIntrinsicWidth(const BoxConstraints()));
|
||||
result = math.max(result, cell.getMaxIntrinsicWidth(double.INFINITY));
|
||||
return result;
|
||||
}
|
||||
|
||||
@ -689,36 +689,33 @@ class RenderTable extends RenderBox {
|
||||
}
|
||||
|
||||
@override
|
||||
double getMinIntrinsicWidth(BoxConstraints constraints) {
|
||||
assert(constraints.debugAssertIsValid());
|
||||
double getMinIntrinsicWidth(double height) {
|
||||
assert(_children.length == rows * columns);
|
||||
double totalMinWidth = 0.0;
|
||||
for (int x = 0; x < columns; x += 1) {
|
||||
TableColumnWidth columnWidth = _columnWidths[x] ?? defaultColumnWidth;
|
||||
Iterable<RenderBox> columnCells = column(x);
|
||||
totalMinWidth += columnWidth.minIntrinsicWidth(columnCells, constraints.maxWidth);
|
||||
totalMinWidth += columnWidth.minIntrinsicWidth(columnCells, double.INFINITY);
|
||||
}
|
||||
return constraints.constrainWidth(totalMinWidth);
|
||||
return totalMinWidth;
|
||||
}
|
||||
|
||||
@override
|
||||
double getMaxIntrinsicWidth(BoxConstraints constraints) {
|
||||
assert(constraints.debugAssertIsValid());
|
||||
double getMaxIntrinsicWidth(double height) {
|
||||
assert(_children.length == rows * columns);
|
||||
double totalMaxWidth = 0.0;
|
||||
for (int x = 0; x < columns; x += 1) {
|
||||
TableColumnWidth columnWidth = _columnWidths[x] ?? defaultColumnWidth;
|
||||
Iterable<RenderBox> columnCells = column(x);
|
||||
totalMaxWidth += columnWidth.maxIntrinsicWidth(columnCells, constraints.maxWidth);
|
||||
totalMaxWidth += columnWidth.maxIntrinsicWidth(columnCells, double.INFINITY);
|
||||
}
|
||||
return constraints.constrainWidth(totalMaxWidth);
|
||||
return totalMaxWidth;
|
||||
}
|
||||
|
||||
@override
|
||||
double getMinIntrinsicHeight(BoxConstraints constraints) {
|
||||
double getMinIntrinsicHeight(double width) {
|
||||
// winner of the 2016 world's most expensive intrinsic dimension function award
|
||||
// honorable mention, most likely to improve if taught about memoization award
|
||||
assert(constraints.debugAssertIsValid());
|
||||
assert(_children.length == rows * columns);
|
||||
final List<double> widths = _computeColumnWidths(constraints);
|
||||
double rowTop = 0.0;
|
||||
@ -728,16 +725,16 @@ class RenderTable extends RenderBox {
|
||||
final int xy = x + y * columns;
|
||||
RenderBox child = _children[xy];
|
||||
if (child != null)
|
||||
rowHeight = math.max(rowHeight, child.getMaxIntrinsicHeight(new BoxConstraints.tightFor(width: widths[x])));
|
||||
rowHeight = math.max(rowHeight, child.getMaxIntrinsicHeight(widths[x]));
|
||||
}
|
||||
rowTop += rowHeight;
|
||||
}
|
||||
return constraints.constrainHeight(rowTop);
|
||||
return rowTop;
|
||||
}
|
||||
|
||||
@override
|
||||
double getMaxIntrinsicHeight(BoxConstraints constraints) {
|
||||
return getMinIntrinsicHeight(constraints);
|
||||
double getMaxIntrinsicHeight(double width) {
|
||||
return getMinIntrinsicHeight(width);
|
||||
}
|
||||
|
||||
double _baselineDistance;
|
||||
|
@ -218,35 +218,31 @@ class RenderViewport extends RenderViewportBase with RenderObjectWithChildMixin<
|
||||
}
|
||||
|
||||
@override
|
||||
double getMinIntrinsicWidth(BoxConstraints constraints) {
|
||||
assert(constraints.debugAssertIsValid());
|
||||
double getMinIntrinsicWidth(double height) {
|
||||
if (child != null)
|
||||
return constraints.constrainWidth(child.getMinIntrinsicWidth(_getInnerConstraints(constraints)));
|
||||
return super.getMinIntrinsicWidth(constraints);
|
||||
return child.getMinIntrinsicWidth(height);
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
@override
|
||||
double getMaxIntrinsicWidth(BoxConstraints constraints) {
|
||||
assert(constraints.debugAssertIsValid());
|
||||
double getMaxIntrinsicWidth(double height) {
|
||||
if (child != null)
|
||||
return constraints.constrainWidth(child.getMaxIntrinsicWidth(_getInnerConstraints(constraints)));
|
||||
return super.getMaxIntrinsicWidth(constraints);
|
||||
return child.getMaxIntrinsicWidth(height);
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
@override
|
||||
double getMinIntrinsicHeight(BoxConstraints constraints) {
|
||||
assert(constraints.debugAssertIsValid());
|
||||
double getMinIntrinsicHeight(double width) {
|
||||
if (child != null)
|
||||
return constraints.constrainHeight(child.getMinIntrinsicHeight(_getInnerConstraints(constraints)));
|
||||
return super.getMinIntrinsicHeight(constraints);
|
||||
return child.getMinIntrinsicHeight(width);
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
@override
|
||||
double getMaxIntrinsicHeight(BoxConstraints constraints) {
|
||||
assert(constraints.debugAssertIsValid());
|
||||
double getMaxIntrinsicHeight(double width) {
|
||||
if (child != null)
|
||||
return constraints.constrainHeight(child.getMaxIntrinsicHeight(_getInnerConstraints(constraints)));
|
||||
return super.getMaxIntrinsicHeight(constraints);
|
||||
return child.getMaxIntrinsicHeight(width);
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
// We don't override computeDistanceToActualBaseline(), because we
|
||||
@ -353,6 +349,51 @@ abstract class RenderVirtualViewport<T extends ContainerBoxParentDataMixin<Rende
|
||||
markNeedsLayout();
|
||||
}
|
||||
|
||||
/// Throws an exception if asserts are enabled, unless the
|
||||
/// [RenderObject.debugCheckingIntrinsics] flag is set.
|
||||
///
|
||||
/// This is a convenience function for subclasses to call from their
|
||||
/// intrinsic-sizing functions if they don't have a good way to generate the
|
||||
/// numbers.
|
||||
bool debugThrowIfNotCheckingIntrinsics() {
|
||||
assert(() {
|
||||
if (!RenderObject.debugCheckingIntrinsics) {
|
||||
throw new FlutterError(
|
||||
'RenderVirtualViewport does not support returning intrinsic dimensions.\n'
|
||||
'Calculating the intrinsic dimensions would require walking the entire '
|
||||
'child list, which cannot reliably and efficiently be done for render '
|
||||
'objects that potentially generate their child list during layout.'
|
||||
);
|
||||
}
|
||||
return true;
|
||||
});
|
||||
return true;
|
||||
}
|
||||
|
||||
@override
|
||||
double getMinIntrinsicWidth(double height) {
|
||||
assert(debugThrowIfNotCheckingIntrinsics);
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
@override
|
||||
double getMaxIntrinsicWidth(double height) {
|
||||
assert(debugThrowIfNotCheckingIntrinsics);
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
@override
|
||||
double getMinIntrinsicHeight(double width) {
|
||||
assert(debugThrowIfNotCheckingIntrinsics);
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
@override
|
||||
double getMaxIntrinsicHeight(double width) {
|
||||
assert(debugThrowIfNotCheckingIntrinsics);
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
@override
|
||||
bool hitTestChildren(HitTestResult result, { Point position }) {
|
||||
return defaultHitTestChildren(result, position: position + -_effectivePaintOffset);
|
||||
|
@ -44,32 +44,42 @@ class _RenderLayoutBuilder extends RenderBox with RenderObjectWithChildMixin<Ren
|
||||
markNeedsLayout();
|
||||
}
|
||||
|
||||
double getIntrinsicWidth(BoxConstraints constraints) => constraints.constrainWidth();
|
||||
|
||||
double getIntrinsicHeight(BoxConstraints constraints) => constraints.constrainHeight();
|
||||
|
||||
@override
|
||||
double getMinIntrinsicWidth(BoxConstraints constraints) {
|
||||
assert(constraints.debugAssertIsValid());
|
||||
return getIntrinsicWidth(constraints);
|
||||
bool _debugThrowIfNotCheckingIntrinsics() {
|
||||
assert(() {
|
||||
if (!RenderObject.debugCheckingIntrinsics) {
|
||||
throw new FlutterError(
|
||||
'LayoutBuilder does not support returning intrinsic dimensions.\n'
|
||||
'Calculating the intrinsic dimensions would require running the layout callback speculatively, '
|
||||
'which might mutate the live render object tree.'
|
||||
);
|
||||
}
|
||||
return true;
|
||||
});
|
||||
return true;
|
||||
}
|
||||
|
||||
@override
|
||||
double getMaxIntrinsicWidth(BoxConstraints constraints) {
|
||||
assert(constraints.debugAssertIsValid());
|
||||
return getIntrinsicWidth(constraints);
|
||||
double getMinIntrinsicWidth(double height) {
|
||||
assert(_debugThrowIfNotCheckingIntrinsics());
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
@override
|
||||
double getMinIntrinsicHeight(BoxConstraints constraints) {
|
||||
assert(constraints.debugAssertIsValid());
|
||||
return getIntrinsicHeight(constraints);
|
||||
double getMaxIntrinsicWidth(double height) {
|
||||
assert(_debugThrowIfNotCheckingIntrinsics());
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
@override
|
||||
double getMaxIntrinsicHeight(BoxConstraints constraints) {
|
||||
assert(constraints.debugAssertIsValid());
|
||||
return getIntrinsicHeight(constraints);
|
||||
double getMinIntrinsicHeight(double width) {
|
||||
assert(_debugThrowIfNotCheckingIntrinsics());
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
@override
|
||||
double getMaxIntrinsicHeight(double width) {
|
||||
assert(_debugThrowIfNotCheckingIntrinsics());
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
@override
|
||||
@ -85,7 +95,7 @@ class _RenderLayoutBuilder extends RenderBox with RenderObjectWithChildMixin<Ren
|
||||
if (callback != null)
|
||||
invokeLayoutCallback(callback);
|
||||
if (child != null)
|
||||
child.layout(constraints.loosen(), parentUsesSize: false);
|
||||
child.layout(constraints.loosen());
|
||||
}
|
||||
|
||||
@override
|
||||
|
@ -368,48 +368,28 @@ class _RenderLazyBlock extends RenderVirtualViewport<_LazyBlockParentData> {
|
||||
return true;
|
||||
}
|
||||
|
||||
double getIntrinsicWidth(BoxConstraints constraints) {
|
||||
switch (mainAxis) {
|
||||
case Axis.horizontal:
|
||||
return constraints.constrainWidth(0.0);
|
||||
case Axis.vertical:
|
||||
assert(_debugThrowIfNotCheckingIntrinsics());
|
||||
return constraints.constrainWidth(0.0);
|
||||
}
|
||||
@override
|
||||
double getMinIntrinsicWidth(double height) {
|
||||
assert(_debugThrowIfNotCheckingIntrinsics());
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
@override
|
||||
double getMinIntrinsicWidth(BoxConstraints constraints) {
|
||||
assert(constraints.debugAssertIsValid());
|
||||
return getIntrinsicWidth(constraints);
|
||||
double getMaxIntrinsicWidth(double height) {
|
||||
assert(_debugThrowIfNotCheckingIntrinsics());
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
@override
|
||||
double getMaxIntrinsicWidth(BoxConstraints constraints) {
|
||||
assert(constraints.debugAssertIsValid());
|
||||
return getIntrinsicWidth(constraints);
|
||||
}
|
||||
|
||||
double getIntrinsicHeight(BoxConstraints constraints) {
|
||||
switch (mainAxis) {
|
||||
case Axis.horizontal:
|
||||
return constraints.constrainHeight(0.0);
|
||||
case Axis.vertical:
|
||||
assert(_debugThrowIfNotCheckingIntrinsics());
|
||||
return constraints.constrainHeight(0.0);
|
||||
}
|
||||
double getMinIntrinsicHeight(double width) {
|
||||
assert(_debugThrowIfNotCheckingIntrinsics());
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
@override
|
||||
double getMinIntrinsicHeight(BoxConstraints constraints) {
|
||||
assert(constraints.debugAssertIsValid());
|
||||
return getIntrinsicHeight(constraints);
|
||||
}
|
||||
|
||||
@override
|
||||
double getMaxIntrinsicHeight(BoxConstraints constraints) {
|
||||
assert(constraints.debugAssertIsValid());
|
||||
return getIntrinsicHeight(constraints);
|
||||
double getMaxIntrinsicHeight(double width) {
|
||||
assert(_debugThrowIfNotCheckingIntrinsics());
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
@override
|
||||
|
@ -4,21 +4,96 @@
|
||||
|
||||
import 'package:flutter/rendering.dart';
|
||||
import 'package:test/test.dart';
|
||||
import 'rendering_tester.dart';
|
||||
|
||||
void main() {
|
||||
test('Intrinsic sizing', () {
|
||||
test('Intrinsic sizing 2.0', () {
|
||||
RenderAspectRatio box = new RenderAspectRatio(aspectRatio: 2.0);
|
||||
|
||||
BoxConstraints constraints = new BoxConstraints.loose(new Size(200.0, 200.0));
|
||||
expect(box.getMinIntrinsicWidth(constraints), equals(0.0));
|
||||
expect(box.getMaxIntrinsicWidth(constraints), equals(200.0));
|
||||
expect(box.getMinIntrinsicHeight(constraints), equals(0.0));
|
||||
expect(box.getMaxIntrinsicHeight(constraints), equals(100.0));
|
||||
expect(box.getMinIntrinsicWidth(200.0), 400.0);
|
||||
expect(box.getMinIntrinsicWidth(400.0), 800.0);
|
||||
|
||||
constraints = new BoxConstraints(maxHeight: 400.0);
|
||||
expect(box.getMinIntrinsicWidth(constraints), equals(0.0));
|
||||
expect(box.getMaxIntrinsicWidth(constraints), equals(800.0));
|
||||
expect(box.getMinIntrinsicHeight(constraints), equals(0.0));
|
||||
expect(box.getMaxIntrinsicHeight(constraints), equals(400.0));
|
||||
expect(box.getMaxIntrinsicWidth(200.0), 400.0);
|
||||
expect(box.getMaxIntrinsicWidth(400.0), 800.0);
|
||||
|
||||
expect(box.getMinIntrinsicHeight(200.0), 100.0);
|
||||
expect(box.getMinIntrinsicHeight(400.0), 200.0);
|
||||
|
||||
expect(box.getMaxIntrinsicHeight(200.0), 100.0);
|
||||
expect(box.getMaxIntrinsicHeight(400.0), 200.0);
|
||||
|
||||
expect(box.getMinIntrinsicWidth(double.INFINITY), 0.0);
|
||||
expect(box.getMaxIntrinsicWidth(double.INFINITY), 0.0);
|
||||
expect(box.getMinIntrinsicHeight(double.INFINITY), 0.0);
|
||||
expect(box.getMaxIntrinsicHeight(double.INFINITY), 0.0);
|
||||
});
|
||||
|
||||
test('Intrinsic sizing 0.5', () {
|
||||
RenderAspectRatio box = new RenderAspectRatio(aspectRatio: 0.5);
|
||||
|
||||
expect(box.getMinIntrinsicWidth(200.0), 100.0);
|
||||
expect(box.getMinIntrinsicWidth(400.0), 200.0);
|
||||
|
||||
expect(box.getMaxIntrinsicWidth(200.0), 100.0);
|
||||
expect(box.getMaxIntrinsicWidth(400.0), 200.0);
|
||||
|
||||
expect(box.getMinIntrinsicHeight(200.0), 400.0);
|
||||
expect(box.getMinIntrinsicHeight(400.0), 800.0);
|
||||
|
||||
expect(box.getMaxIntrinsicHeight(200.0), 400.0);
|
||||
expect(box.getMaxIntrinsicHeight(400.0), 800.0);
|
||||
|
||||
expect(box.getMinIntrinsicWidth(double.INFINITY), 0.0);
|
||||
expect(box.getMaxIntrinsicWidth(double.INFINITY), 0.0);
|
||||
expect(box.getMinIntrinsicHeight(double.INFINITY), 0.0);
|
||||
expect(box.getMaxIntrinsicHeight(double.INFINITY), 0.0);
|
||||
});
|
||||
|
||||
test('Intrinsic sizing 2.0', () {
|
||||
RenderAspectRatio box = new RenderAspectRatio(
|
||||
aspectRatio: 2.0,
|
||||
child: new RenderSizedBox(const Size(90.0, 70.0))
|
||||
);
|
||||
|
||||
expect(box.getMinIntrinsicWidth(200.0), 400.0);
|
||||
expect(box.getMinIntrinsicWidth(400.0), 800.0);
|
||||
|
||||
expect(box.getMaxIntrinsicWidth(200.0), 400.0);
|
||||
expect(box.getMaxIntrinsicWidth(400.0), 800.0);
|
||||
|
||||
expect(box.getMinIntrinsicHeight(200.0), 100.0);
|
||||
expect(box.getMinIntrinsicHeight(400.0), 200.0);
|
||||
|
||||
expect(box.getMaxIntrinsicHeight(200.0), 100.0);
|
||||
expect(box.getMaxIntrinsicHeight(400.0), 200.0);
|
||||
|
||||
expect(box.getMinIntrinsicWidth(double.INFINITY), 90.0);
|
||||
expect(box.getMaxIntrinsicWidth(double.INFINITY), 90.0);
|
||||
expect(box.getMinIntrinsicHeight(double.INFINITY), 70.0);
|
||||
expect(box.getMaxIntrinsicHeight(double.INFINITY), 70.0);
|
||||
});
|
||||
|
||||
test('Intrinsic sizing 0.5', () {
|
||||
RenderAspectRatio box = new RenderAspectRatio(
|
||||
aspectRatio: 0.5,
|
||||
child: new RenderSizedBox(const Size(90.0, 70.0))
|
||||
);
|
||||
|
||||
expect(box.getMinIntrinsicWidth(200.0), 100.0);
|
||||
expect(box.getMinIntrinsicWidth(400.0), 200.0);
|
||||
|
||||
expect(box.getMaxIntrinsicWidth(200.0), 100.0);
|
||||
expect(box.getMaxIntrinsicWidth(400.0), 200.0);
|
||||
|
||||
expect(box.getMinIntrinsicHeight(200.0), 400.0);
|
||||
expect(box.getMinIntrinsicHeight(400.0), 800.0);
|
||||
|
||||
expect(box.getMaxIntrinsicHeight(200.0), 400.0);
|
||||
expect(box.getMaxIntrinsicHeight(400.0), 800.0);
|
||||
|
||||
expect(box.getMinIntrinsicWidth(double.INFINITY), 90.0);
|
||||
expect(box.getMaxIntrinsicWidth(double.INFINITY), 90.0);
|
||||
expect(box.getMinIntrinsicHeight(double.INFINITY), 70.0);
|
||||
expect(box.getMaxIntrinsicHeight(double.INFINITY), 70.0);
|
||||
});
|
||||
}
|
||||
|
@ -1,70 +0,0 @@
|
||||
// Copyright 2015 The Chromium Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
import 'package:flutter/rendering.dart';
|
||||
import 'package:test/test.dart';
|
||||
|
||||
void main() {
|
||||
test('block intrinsics', () {
|
||||
RenderParagraph paragraph = new RenderParagraph(
|
||||
new TextSpan(
|
||||
style: new TextStyle(height: 1.0),
|
||||
text: 'Hello World'
|
||||
)
|
||||
);
|
||||
const BoxConstraints unconstrained = const BoxConstraints();
|
||||
double textWidth = paragraph.getMaxIntrinsicWidth(unconstrained);
|
||||
double oneLineTextHeight = paragraph.getMinIntrinsicHeight(unconstrained);
|
||||
final BoxConstraints constrained = new BoxConstraints(maxWidth: textWidth * 0.9);
|
||||
double wrappedTextWidth = paragraph.getMinIntrinsicWidth(unconstrained);
|
||||
double twoLinesTextHeight = paragraph.getMinIntrinsicHeight(constrained);
|
||||
|
||||
// controls
|
||||
expect(wrappedTextWidth, lessThan(textWidth));
|
||||
expect(paragraph.getMinIntrinsicWidth(unconstrained), equals(wrappedTextWidth));
|
||||
expect(paragraph.getMaxIntrinsicWidth(constrained), equals(constrained.maxWidth));
|
||||
|
||||
expect(oneLineTextHeight, lessThan(twoLinesTextHeight));
|
||||
expect(twoLinesTextHeight, lessThan(oneLineTextHeight * 3.0));
|
||||
expect(paragraph.getMaxIntrinsicHeight(unconstrained), equals(oneLineTextHeight));
|
||||
expect(paragraph.getMaxIntrinsicHeight(constrained), equals(twoLinesTextHeight));
|
||||
|
||||
// test setup
|
||||
RenderBlock testBlock = new RenderBlock(
|
||||
children: <RenderBox>[
|
||||
paragraph,
|
||||
]
|
||||
);
|
||||
final BoxConstraints empty = new BoxConstraints.tight(Size.zero);
|
||||
|
||||
// vertical block
|
||||
expect(testBlock.getMinIntrinsicWidth(unconstrained), equals(wrappedTextWidth));
|
||||
expect(testBlock.getMinIntrinsicWidth(constrained), equals(wrappedTextWidth));
|
||||
expect(testBlock.getMaxIntrinsicWidth(unconstrained), equals(textWidth));
|
||||
expect(testBlock.getMaxIntrinsicWidth(constrained), equals(constrained.maxWidth));
|
||||
expect(testBlock.getMinIntrinsicHeight(unconstrained), equals(oneLineTextHeight));
|
||||
expect(testBlock.getMinIntrinsicHeight(constrained), equals(twoLinesTextHeight));
|
||||
expect(testBlock.getMaxIntrinsicHeight(unconstrained), equals(oneLineTextHeight));
|
||||
expect(testBlock.getMaxIntrinsicHeight(constrained), equals(twoLinesTextHeight));
|
||||
expect(testBlock.getMinIntrinsicWidth(empty), equals(0.0));
|
||||
expect(testBlock.getMaxIntrinsicWidth(empty), equals(0.0));
|
||||
expect(testBlock.getMinIntrinsicHeight(empty), equals(0.0));
|
||||
expect(testBlock.getMaxIntrinsicHeight(empty), equals(0.0));
|
||||
|
||||
// horizontal block
|
||||
testBlock.mainAxis = Axis.horizontal;
|
||||
expect(testBlock.getMinIntrinsicWidth(unconstrained), equals(textWidth));
|
||||
expect(testBlock.getMinIntrinsicWidth(constrained), equals(constrained.maxWidth));
|
||||
expect(testBlock.getMaxIntrinsicWidth(unconstrained), equals(textWidth));
|
||||
expect(testBlock.getMaxIntrinsicWidth(constrained), equals(constrained.maxWidth));
|
||||
expect(testBlock.getMinIntrinsicHeight(unconstrained), equals(oneLineTextHeight));
|
||||
expect(testBlock.getMinIntrinsicHeight(constrained), equals(oneLineTextHeight));
|
||||
expect(testBlock.getMaxIntrinsicHeight(unconstrained), equals(oneLineTextHeight));
|
||||
expect(testBlock.getMaxIntrinsicHeight(constrained), equals(oneLineTextHeight));
|
||||
expect(testBlock.getMinIntrinsicWidth(empty), equals(0.0));
|
||||
expect(testBlock.getMaxIntrinsicWidth(empty), equals(0.0));
|
||||
expect(testBlock.getMinIntrinsicHeight(empty), equals(0.0));
|
||||
expect(testBlock.getMaxIntrinsicHeight(empty), equals(0.0));
|
||||
});
|
||||
}
|
@ -35,10 +35,10 @@ void main() {
|
||||
BoxConstraints viewport = new BoxConstraints(maxHeight: 100.0, maxWidth: 100.0);
|
||||
layout(flex, constraints: viewport);
|
||||
expect(flexible.size.height, equals(0.0));
|
||||
expect(flex.getMinIntrinsicHeight(viewport), equals(100.0));
|
||||
expect(flex.getMaxIntrinsicHeight(viewport), equals(100.0));
|
||||
expect(flex.getMinIntrinsicWidth(viewport), equals(100.0));
|
||||
expect(flex.getMaxIntrinsicWidth(viewport), equals(100.0));
|
||||
expect(flex.getMinIntrinsicHeight(100.0), equals(200.0));
|
||||
expect(flex.getMaxIntrinsicHeight(100.0), equals(200.0));
|
||||
expect(flex.getMinIntrinsicWidth(100.0), equals(0.0));
|
||||
expect(flex.getMaxIntrinsicWidth(100.0), equals(0.0));
|
||||
});
|
||||
|
||||
test('Horizontal Overflow', () {
|
||||
@ -57,10 +57,10 @@ void main() {
|
||||
BoxConstraints viewport = new BoxConstraints(maxHeight: 100.0, maxWidth: 100.0);
|
||||
layout(flex, constraints: viewport);
|
||||
expect(flexible.size.width, equals(0.0));
|
||||
expect(flex.getMinIntrinsicHeight(viewport), equals(100.0));
|
||||
expect(flex.getMaxIntrinsicHeight(viewport), equals(100.0));
|
||||
expect(flex.getMinIntrinsicWidth(viewport), equals(100.0));
|
||||
expect(flex.getMaxIntrinsicWidth(viewport), equals(100.0));
|
||||
expect(flex.getMinIntrinsicHeight(100.0), equals(0.0));
|
||||
expect(flex.getMaxIntrinsicHeight(100.0), equals(0.0));
|
||||
expect(flex.getMinIntrinsicWidth(100.0), equals(200.0));
|
||||
expect(flex.getMaxIntrinsicWidth(100.0), equals(200.0));
|
||||
});
|
||||
|
||||
test('Vertical Flipped Constraints', () {
|
||||
@ -72,7 +72,7 @@ void main() {
|
||||
);
|
||||
BoxConstraints viewport = new BoxConstraints(maxHeight: 200.0, maxWidth: 1000.0);
|
||||
layout(flex, constraints: viewport);
|
||||
expect(flex.getMaxIntrinsicWidth(viewport) , equals(1000.0));
|
||||
expect(flex.getMaxIntrinsicWidth(200.0), equals(0.0));
|
||||
});
|
||||
|
||||
// We can't right a horizontal version of the above test due to
|
||||
|
@ -7,29 +7,30 @@ import 'package:test/test.dart';
|
||||
|
||||
import 'rendering_tester.dart';
|
||||
|
||||
// before using this, consider using RenderSizedBox from rendering_tester.dart
|
||||
class RenderTestBox extends RenderBox {
|
||||
RenderTestBox(this._intrinsicDimensions);
|
||||
|
||||
final BoxConstraints _intrinsicDimensions;
|
||||
|
||||
@override
|
||||
double getMinIntrinsicWidth(BoxConstraints constraints) {
|
||||
return constraints.constrainWidth(_intrinsicDimensions.minWidth);
|
||||
double getMinIntrinsicWidth(double height) {
|
||||
return _intrinsicDimensions.minWidth;
|
||||
}
|
||||
|
||||
@override
|
||||
double getMaxIntrinsicWidth(BoxConstraints constraints) {
|
||||
return constraints.constrainWidth(_intrinsicDimensions.maxWidth);
|
||||
double getMaxIntrinsicWidth(double height) {
|
||||
return _intrinsicDimensions.maxWidth;
|
||||
}
|
||||
|
||||
@override
|
||||
double getMinIntrinsicHeight(BoxConstraints constraints) {
|
||||
return constraints.constrainHeight(_intrinsicDimensions.minHeight);
|
||||
double getMinIntrinsicHeight(double width) {
|
||||
return _intrinsicDimensions.minHeight;
|
||||
}
|
||||
|
||||
@override
|
||||
double getMaxIntrinsicHeight(BoxConstraints constraints) {
|
||||
return constraints.constrainHeight(_intrinsicDimensions.maxHeight);
|
||||
double getMaxIntrinsicHeight(double width) {
|
||||
return _intrinsicDimensions.maxHeight;
|
||||
}
|
||||
|
||||
@override
|
||||
|
@ -0,0 +1,68 @@
|
||||
// Copyright 2015 The Chromium Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
import 'package:flutter/rendering.dart';
|
||||
import 'package:test/test.dart';
|
||||
|
||||
void main() {
|
||||
test('block and paragraph intrinsics', () {
|
||||
final RenderParagraph paragraph = new RenderParagraph(
|
||||
new TextSpan(
|
||||
style: new TextStyle(height: 1.0),
|
||||
text: 'Hello World'
|
||||
)
|
||||
);
|
||||
final RenderBlock testBlock = new RenderBlock(
|
||||
children: <RenderBox>[
|
||||
paragraph,
|
||||
]
|
||||
);
|
||||
|
||||
final double textWidth = paragraph.getMaxIntrinsicWidth(double.INFINITY);
|
||||
final double oneLineTextHeight = paragraph.getMinIntrinsicHeight(double.INFINITY);
|
||||
final double constrainedWidth = textWidth * 0.9;
|
||||
final double wrappedTextWidth = paragraph.getMinIntrinsicWidth(double.INFINITY);
|
||||
final double twoLinesTextHeight = paragraph.getMinIntrinsicHeight(constrainedWidth);
|
||||
final double manyLinesTextHeight = paragraph.getMinIntrinsicHeight(0.0);
|
||||
|
||||
// paragraph
|
||||
expect(wrappedTextWidth, greaterThan(0.0));
|
||||
expect(wrappedTextWidth, lessThan(textWidth));
|
||||
expect(oneLineTextHeight, lessThan(twoLinesTextHeight));
|
||||
expect(twoLinesTextHeight, lessThan(oneLineTextHeight * 3.0));
|
||||
expect(manyLinesTextHeight, greaterThan(twoLinesTextHeight));
|
||||
expect(paragraph.getMaxIntrinsicHeight(double.INFINITY), equals(oneLineTextHeight));
|
||||
expect(paragraph.getMaxIntrinsicHeight(constrainedWidth), equals(twoLinesTextHeight));
|
||||
expect(paragraph.getMaxIntrinsicHeight(0.0), equals(manyLinesTextHeight));
|
||||
|
||||
// vertical block (same expectations)
|
||||
expect(testBlock.getMinIntrinsicWidth(double.INFINITY), equals(wrappedTextWidth));
|
||||
expect(testBlock.getMaxIntrinsicWidth(double.INFINITY), equals(textWidth));
|
||||
expect(testBlock.getMinIntrinsicHeight(double.INFINITY), equals(oneLineTextHeight));
|
||||
expect(testBlock.getMinIntrinsicHeight(constrainedWidth), equals(twoLinesTextHeight));
|
||||
expect(testBlock.getMaxIntrinsicHeight(double.INFINITY), equals(oneLineTextHeight));
|
||||
expect(testBlock.getMaxIntrinsicHeight(constrainedWidth), equals(twoLinesTextHeight));
|
||||
expect(testBlock.getMinIntrinsicWidth(0.0), equals(wrappedTextWidth));
|
||||
expect(testBlock.getMaxIntrinsicWidth(0.0), equals(textWidth));
|
||||
expect(testBlock.getMinIntrinsicHeight(wrappedTextWidth), equals(twoLinesTextHeight));
|
||||
expect(testBlock.getMaxIntrinsicHeight(wrappedTextWidth), equals(twoLinesTextHeight));
|
||||
expect(testBlock.getMinIntrinsicHeight(0.0), equals(manyLinesTextHeight));
|
||||
expect(testBlock.getMaxIntrinsicHeight(0.0), equals(manyLinesTextHeight));
|
||||
|
||||
// horizontal block (same expectations again)
|
||||
testBlock.mainAxis = Axis.horizontal;
|
||||
expect(testBlock.getMinIntrinsicWidth(double.INFINITY), equals(wrappedTextWidth));
|
||||
expect(testBlock.getMaxIntrinsicWidth(double.INFINITY), equals(textWidth));
|
||||
expect(testBlock.getMinIntrinsicHeight(double.INFINITY), equals(oneLineTextHeight));
|
||||
expect(testBlock.getMinIntrinsicHeight(constrainedWidth), equals(twoLinesTextHeight));
|
||||
expect(testBlock.getMaxIntrinsicHeight(double.INFINITY), equals(oneLineTextHeight));
|
||||
expect(testBlock.getMaxIntrinsicHeight(constrainedWidth), equals(twoLinesTextHeight));
|
||||
expect(testBlock.getMinIntrinsicWidth(0.0), equals(wrappedTextWidth));
|
||||
expect(testBlock.getMaxIntrinsicWidth(0.0), equals(textWidth));
|
||||
expect(testBlock.getMinIntrinsicHeight(wrappedTextWidth), equals(twoLinesTextHeight));
|
||||
expect(testBlock.getMaxIntrinsicHeight(wrappedTextWidth), equals(twoLinesTextHeight));
|
||||
expect(testBlock.getMinIntrinsicHeight(0.0), equals(manyLinesTextHeight));
|
||||
expect(testBlock.getMaxIntrinsicHeight(0.0), equals(manyLinesTextHeight));
|
||||
});
|
||||
}
|
@ -91,7 +91,33 @@ class RenderSizedBox extends RenderBox {
|
||||
final Size _size;
|
||||
|
||||
@override
|
||||
void performLayout() {
|
||||
double getMinIntrinsicWidth(double height) {
|
||||
return _size.width;
|
||||
}
|
||||
|
||||
@override
|
||||
double getMaxIntrinsicWidth(double height) {
|
||||
return _size.width;
|
||||
}
|
||||
|
||||
@override
|
||||
double getMinIntrinsicHeight(double width) {
|
||||
return _size.height;
|
||||
}
|
||||
|
||||
@override
|
||||
double getMaxIntrinsicHeight(double width) {
|
||||
return _size.height;
|
||||
}
|
||||
|
||||
@override
|
||||
bool get sizedByParent => true;
|
||||
|
||||
@override
|
||||
void performResize() {
|
||||
size = constraints.constrain(_size);
|
||||
}
|
||||
|
||||
@override
|
||||
void performLayout() { }
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user