Commit 007d0a2f authored by Ian Hickson's avatar Ian Hickson

Cache intrinsic dimensions (#4446)

Also, make sure that the parent is notified when they change.

Fixes #2298
parent 6c896dcc
......@@ -454,28 +454,28 @@ class RenderBoxToRenderSectorAdapter extends RenderBox with RenderObjectWithChil
}
@override
double getMinIntrinsicWidth(double height) {
double computeMinIntrinsicWidth(double height) {
if (child == null)
return 0.0;
return getIntrinsicDimensions(height: height).width;
}
@override
double getMaxIntrinsicWidth(double height) {
double computeMaxIntrinsicWidth(double height) {
if (child == null)
return 0.0;
return getIntrinsicDimensions(height: height).width;
}
@override
double getMinIntrinsicHeight(double width) {
double computeMinIntrinsicHeight(double width) {
if (child == null)
return 0.0;
return getIntrinsicDimensions(width: width).height;
}
@override
double getMaxIntrinsicHeight(double width) {
double computeMaxIntrinsicHeight(double width) {
if (child == null)
return 0.0;
return getIntrinsicDimensions(width: width).height;
......
......@@ -14,22 +14,22 @@ class RenderSolidColorBox extends RenderDecoratedBox {
super(decoration: new BoxDecoration(backgroundColor: backgroundColor));
@override
double getMinIntrinsicWidth(double height) {
double computeMinIntrinsicWidth(double height) {
return desiredSize.width == double.INFINITY ? 0.0 : desiredSize.width;
}
@override
double getMaxIntrinsicWidth(double height) {
double computeMaxIntrinsicWidth(double height) {
return desiredSize.width == double.INFINITY ? 0.0 : desiredSize.width;
}
@override
double getMinIntrinsicHeight(double width) {
double computeMinIntrinsicHeight(double width) {
return desiredSize.height == double.INFINITY ? 0.0 : desiredSize.height;
}
@override
double getMaxIntrinsicHeight(double width) {
double computeMaxIntrinsicHeight(double width) {
return desiredSize.height == double.INFINITY ? 0.0 : desiredSize.height;
}
......
......@@ -100,7 +100,7 @@ class _RenderTabBar extends RenderBox with
}
@override
double getMinIntrinsicWidth(double height) {
double computeMinIntrinsicWidth(double height) {
double maxWidth = 0.0;
RenderBox child = firstChild;
while (child != null) {
......@@ -112,7 +112,7 @@ class _RenderTabBar extends RenderBox with
}
@override
double getMaxIntrinsicWidth(double height) {
double computeMaxIntrinsicWidth(double height) {
double maxWidth = 0.0;
double totalWidth = 0.0;
RenderBox child = firstChild;
......@@ -130,10 +130,10 @@ class _RenderTabBar extends RenderBox with
double get _tabBarHeight => _tabHeight + _kTabIndicatorHeight;
@override
double getMinIntrinsicHeight(double width) => _tabBarHeight;
double computeMinIntrinsicHeight(double width) => _tabBarHeight;
@override
double getMaxIntrinsicHeight(double width) => _tabBarHeight;
double computeMaxIntrinsicHeight(double width) => _tabBarHeight;
void layoutFixedWidthTabs() {
double tabWidth = size.width / childCount;
......
......@@ -180,7 +180,7 @@ class RenderBlock extends RenderBox
}
@override
double getMinIntrinsicWidth(double height) {
double computeMinIntrinsicWidth(double height) {
switch (mainAxis) {
case Axis.horizontal:
return _getIntrinsicMainAxis((RenderBox child) => child.getMinIntrinsicWidth(height));
......@@ -190,7 +190,7 @@ class RenderBlock extends RenderBox
}
@override
double getMaxIntrinsicWidth(double height) {
double computeMaxIntrinsicWidth(double height) {
switch (mainAxis) {
case Axis.horizontal:
return _getIntrinsicMainAxis((RenderBox child) => child.getMaxIntrinsicWidth(height));
......@@ -200,7 +200,7 @@ class RenderBlock extends RenderBox
}
@override
double getMinIntrinsicHeight(double width) {
double computeMinIntrinsicHeight(double width) {
switch (mainAxis) {
case Axis.horizontal:
return _getIntrinsicMainAxis((RenderBox child) => child.getMinIntrinsicHeight(width));
......@@ -210,7 +210,7 @@ class RenderBlock extends RenderBox
}
@override
double getMaxIntrinsicHeight(double width) {
double computeMaxIntrinsicHeight(double width) {
switch (mainAxis) {
case Axis.horizontal:
return _getIntrinsicMainAxis((RenderBox child) => child.getMaxIntrinsicHeight(width));
......
This diff is collapsed.
......@@ -244,7 +244,7 @@ class RenderCustomMultiChildLayoutBox extends RenderBox
// or we should expose intrinsic delegate callbacks and throw if they're not implemented.
@override
double getMinIntrinsicWidth(double height) {
double computeMinIntrinsicWidth(double height) {
final double width = _getSize(new BoxConstraints.tightForFinite(height: height)).width;
if (width.isFinite)
return width;
......@@ -252,7 +252,7 @@ class RenderCustomMultiChildLayoutBox extends RenderBox
}
@override
double getMaxIntrinsicWidth(double height) {
double computeMaxIntrinsicWidth(double height) {
final double width = _getSize(new BoxConstraints.tightForFinite(height: height)).width;
if (width.isFinite)
return width;
......@@ -260,7 +260,7 @@ class RenderCustomMultiChildLayoutBox extends RenderBox
}
@override
double getMinIntrinsicHeight(double width) {
double computeMinIntrinsicHeight(double width) {
final double height = _getSize(new BoxConstraints.tightForFinite(width: width)).height;
if (height.isFinite)
return height;
......@@ -268,7 +268,7 @@ class RenderCustomMultiChildLayoutBox extends RenderBox
}
@override
double getMaxIntrinsicHeight(double width) {
double computeMaxIntrinsicHeight(double width) {
final double height = _getSize(new BoxConstraints.tightForFinite(width: width)).height;
if (height.isFinite)
return height;
......
......@@ -61,6 +61,11 @@ double debugRepaintRainbowHueIncrement = 2.0;
bool debugPrintMarkNeedsPaintStacks = false;
/// Log the call stacks that mark render objects as needing layout.
///
/// For sanity, this only logs the stack traces of cases where an object is
/// added to the list of nodes needing layout. This avoids printing multiple
/// redundant stack traces as a single [RenderObject.markNeedsLayout] call walks
/// up the tree.
bool debugPrintMarkNeedsLayoutStacks = false;
/// Check the intrinsic sizes of each [RenderBox] during layout.
......
......@@ -192,12 +192,12 @@ class RenderEditableLine extends RenderBox {
}
@override
double getMinIntrinsicHeight(double width) {
double computeMinIntrinsicHeight(double width) {
return _preferredHeight;
}
@override
double getMaxIntrinsicHeight(double width) {
double computeMaxIntrinsicHeight(double width) {
return _preferredHeight;
}
......
......@@ -54,12 +54,12 @@ class RenderErrorBox extends RenderBox {
ui.Paragraph _paragraph;
@override
double getMaxIntrinsicWidth(double height) {
double computeMaxIntrinsicWidth(double height) {
return _kMaxWidth;
}
@override
double getMaxIntrinsicHeight(double width) {
double computeMaxIntrinsicHeight(double width) {
return _kMaxHeight;
}
......
......@@ -238,7 +238,7 @@ class RenderFlex extends RenderBox with ContainerRenderObjectMixin<RenderBox, Fl
}
@override
double getMinIntrinsicWidth(double height) {
double computeMinIntrinsicWidth(double height) {
return _getIntrinsicSize(
sizingDirection: FlexDirection.horizontal,
extent: height,
......@@ -247,7 +247,7 @@ class RenderFlex extends RenderBox with ContainerRenderObjectMixin<RenderBox, Fl
}
@override
double getMaxIntrinsicWidth(double height) {
double computeMaxIntrinsicWidth(double height) {
return _getIntrinsicSize(
sizingDirection: FlexDirection.horizontal,
extent: height,
......@@ -256,7 +256,7 @@ class RenderFlex extends RenderBox with ContainerRenderObjectMixin<RenderBox, Fl
}
@override
double getMinIntrinsicHeight(double width) {
double computeMinIntrinsicHeight(double width) {
return _getIntrinsicSize(
sizingDirection: FlexDirection.vertical,
extent: width,
......@@ -265,7 +265,7 @@ class RenderFlex extends RenderBox with ContainerRenderObjectMixin<RenderBox, Fl
}
@override
double getMaxIntrinsicHeight(double width) {
double computeMaxIntrinsicHeight(double width) {
return _getIntrinsicSize(
sizingDirection: FlexDirection.vertical,
extent: width,
......
......@@ -245,7 +245,7 @@ class RenderFlow extends RenderBox
// or we should expose intrinsic delegate callbacks and throw if they're not implemented.
@override
double getMinIntrinsicWidth(double height) {
double computeMinIntrinsicWidth(double height) {
final double width = _getSize(new BoxConstraints.tightForFinite(height: height)).width;
if (width.isFinite)
return width;
......@@ -253,7 +253,7 @@ class RenderFlow extends RenderBox
}
@override
double getMaxIntrinsicWidth(double height) {
double computeMaxIntrinsicWidth(double height) {
final double width = _getSize(new BoxConstraints.tightForFinite(height: height)).width;
if (width.isFinite)
return width;
......@@ -261,7 +261,7 @@ class RenderFlow extends RenderBox
}
@override
double getMinIntrinsicHeight(double width) {
double computeMinIntrinsicHeight(double width) {
final double height = _getSize(new BoxConstraints.tightForFinite(width: width)).height;
if (height.isFinite)
return height;
......@@ -269,7 +269,7 @@ class RenderFlow extends RenderBox
}
@override
double getMaxIntrinsicHeight(double width) {
double computeMaxIntrinsicHeight(double width) {
final double height = _getSize(new BoxConstraints.tightForFinite(width: width)).height;
if (height.isFinite)
return height;
......
......@@ -212,11 +212,12 @@ abstract class GridDelegate {
/// Returns the minimum width that this grid could be without failing to paint
/// its contents within itself.
///
/// Override this to provide a more efficient solution. The default
/// implementation actually instantiates a grid specification and measures the
/// grid at the given height and child count.
/// Override this to provide a more efficient or more correct solution. The
/// default implementation actually instantiates a grid specification and
/// measures the grid at the given height and child count.
///
/// For more details, see [RenderBox.getMinIntrinsicWidth].
/// For more details on implementing this method, see
/// [RenderBox.computeMinIntrinsicWidth].
double getMinIntrinsicWidth(double height, int childCount) {
final double width = _getGridSize(new BoxConstraints.tightForFinite(height: height), childCount).width;
if (width.isFinite)
......@@ -227,11 +228,12 @@ abstract class GridDelegate {
/// Returns the smallest width beyond which increasing the width never
/// decreases the preferred height.
///
/// Override this to provide a more efficient solution. The default
/// implementation actually instantiates a grid specification and measures the
/// grid at the given height and child count.
/// Override this to provide a more efficient or more correct solution. The
/// default implementation actually instantiates a grid specification and
/// measures the grid at the given height and child count.
///
/// For more details, see [RenderBox.getMaxIntrinsicWidth].
/// For more details on implementing this method, see
/// [RenderBox.computeMaxIntrinsicWidth].
double getMaxIntrinsicWidth(double height, int childCount) {
final double width = _getGridSize(new BoxConstraints.tightForFinite(height: height), childCount).width;
if (width.isFinite)
......@@ -242,11 +244,12 @@ abstract class GridDelegate {
/// Return the minimum height that this grid could be without failing to paint
/// its contents within itself.
///
/// Override this to provide a more efficient solution. The default
/// implementation actually instantiates a grid specification and measures the
/// grid at the given width and child count.
/// Override this to provide a more efficient or more correct solution. The
/// default implementation actually instantiates a grid specification and
/// measures the grid at the given height and child count.
///
/// For more details, see [RenderBox.getMinIntrinsicHeight].
/// For more details on implementing this method, see
/// [RenderBox.computeMinIntrinsicHeight].
double getMinIntrinsicHeight(double width, int childCount) {
final double height = _getGridSize(new BoxConstraints.tightForFinite(width: width), childCount).height;
if (height.isFinite)
......@@ -257,11 +260,12 @@ abstract class GridDelegate {
/// Returns the smallest height beyond which increasing the height never
/// decreases the preferred width.
///
/// Override this to provide a more efficient solution. The default
/// implementation actually instantiates a grid specification and measures the
/// grid at the given width and child count.
/// Override this to provide a more efficient or more correct solution. The
/// default implementation actually instantiates a grid specification and
/// measures the grid at the given height and child count.
///
/// For more details, see [RenderBox.getMaxIntrinsicHeight].
/// For more details on implementing this method, see
/// [RenderBox.computeMaxIntrinsicHeight].
double getMaxIntrinsicHeight(double width, int childCount) {
final double height = _getGridSize(new BoxConstraints.tightForFinite(width: width), childCount).height;
if (height.isFinite)
......@@ -581,22 +585,22 @@ class RenderGrid extends RenderVirtualViewport<GridParentData> {
}
@override
double getMinIntrinsicWidth(double height) {
double computeMinIntrinsicWidth(double height) {
return _delegate.getMinIntrinsicWidth(height, virtualChildCount);
}
@override
double getMaxIntrinsicWidth(double height) {
double computeMaxIntrinsicWidth(double height) {
return _delegate.getMaxIntrinsicWidth(height, virtualChildCount);
}
@override
double getMinIntrinsicHeight(double width) {
double computeMinIntrinsicHeight(double width) {
return _delegate.getMinIntrinsicHeight(width, virtualChildCount);
}
@override
double getMaxIntrinsicHeight(double width) {
double computeMaxIntrinsicHeight(double width) {
return _delegate.getMaxIntrinsicHeight(width, virtualChildCount);
}
......
......@@ -205,7 +205,7 @@ class RenderImage extends RenderBox {
}
@override
double getMinIntrinsicWidth(double height) {
double computeMinIntrinsicWidth(double height) {
assert(height >= 0.0);
if (_width == null && _height == null)
return 0.0;
......@@ -213,13 +213,13 @@ class RenderImage extends RenderBox {
}
@override
double getMaxIntrinsicWidth(double height) {
double computeMaxIntrinsicWidth(double height) {
assert(height >= 0.0);
return _sizeForConstraints(new BoxConstraints.tightForFinite(height: height)).width;
}
@override
double getMinIntrinsicHeight(double width) {
double computeMinIntrinsicHeight(double width) {
assert(width >= 0.0);
if (_width == null && _height == null)
return 0.0;
......@@ -227,7 +227,7 @@ class RenderImage extends RenderBox {
}
@override
double getMaxIntrinsicHeight(double width) {
double computeMaxIntrinsicHeight(double width) {
assert(width >= 0.0);
return _sizeForConstraints(new BoxConstraints.tightForFinite(width: width)).height;
}
......
......@@ -96,7 +96,7 @@ class RenderList extends RenderVirtualViewport<ListParentData> {
return extent;
}
double _getIntrinsicWidth() {
double _computeIntrinsicWidth() {
switch (mainAxis) {
case Axis.vertical:
assert(debugThrowIfNotCheckingIntrinsics());
......@@ -111,16 +111,16 @@ class RenderList extends RenderVirtualViewport<ListParentData> {
}
@override
double getMinIntrinsicWidth(double height) {
return _getIntrinsicWidth();
double computeMinIntrinsicWidth(double height) {
return _computeIntrinsicWidth();
}
@override
double getMaxIntrinsicWidth(double height) {
return _getIntrinsicWidth();
double computeMaxIntrinsicWidth(double height) {
return _computeIntrinsicWidth();
}
double _getIntrinsicHeight() {
double _computeIntrinsicHeight() {
switch (mainAxis) {
case Axis.vertical:
final double height = _preferredExtent;
......@@ -135,13 +135,13 @@ class RenderList extends RenderVirtualViewport<ListParentData> {
}
@override
double getMinIntrinsicHeight(double width) {
return _getIntrinsicHeight();
double computeMinIntrinsicHeight(double width) {
return _computeIntrinsicHeight();
}
@override
double getMaxIntrinsicHeight(double width) {
return _getIntrinsicHeight();
double computeMaxIntrinsicHeight(double width) {
return _computeIntrinsicHeight();
}
@override
......
......@@ -1199,7 +1199,7 @@ abstract class RenderObject extends AbstractNode implements HitTestTarget {
/// debugAssertDoesMeetConstraints(), and should not be checked in
/// release mode (where it will always be false).
static bool debugCheckingIntrinsics = false;
bool _debugAncestorsAlreadyMarkedNeedsLayout() {
bool _debugSubtreeRelayoutRootAlreadyMarkedNeedsLayout() {
if (_relayoutSubtreeRoot == null)
return true; // we haven't yet done layout even once, so there's nothing for us to do
RenderObject node = this;
......@@ -1214,49 +1214,83 @@ abstract class RenderObject extends AbstractNode implements HitTestTarget {
return true;
}
/// Mark this render object's layout information as dirty.
/// Mark this render object's layout information as dirty, and either register
/// this object with its [PipelineOwner], or defer to the parent, depending on
/// whether this object is a relayout boundary or not respectively.
///
/// ## Background
///
/// Rather than eagerly updating layout information in response to writes into
/// this render object, we instead mark the layout information as dirty, which
/// a render object, we instead mark the layout information as dirty, which
/// schedules a visual update. As part of the visual update, the rendering
/// pipeline will update this render object's layout information.
/// pipeline updates the render object's layout information.
///
/// This mechanism batches the layout work so that multiple sequential writes
/// are coalesced, removing redundant computation.
///
/// Causes [needsLayout] to return true for this render object. If the parent
/// render object indicated that it uses the size of this render object in
/// computing its layout information, this function will also mark the parent
/// as needing layout.
/// If a render object's parent indicates that it uses the size of one of its
/// render object children when computing its layout information, this
/// function, when called for the child, will also mark the parent as needing
/// layout. In that case, since both the parent and the child need to have
/// their layout recomputed, the pipeline owner is only notified about the
/// parent; when the parent is laid out, it will call the child's [layout]
/// method and thus the child will be laid out as well.
///
/// Once [markNeedsLayout] has been called on a render object, [needsLayout]
/// returns true for that render object until just after the pipeline owner
/// has called [layout] on the render object.
///
/// ## Special cases
///
/// Some subclasses of [RenderObject], notably [RenderBox], have other
/// situations in which the parent needs to be notified if the child is
/// dirtied. Such subclasses override markNeedsLayout and either call
/// `super.markNeedsLayout()`, in the normal case, or call
/// [markParentNeedsLayout], in the case where the parent neds to be laid out
/// as well as the child.
void markNeedsLayout() {
assert(_debugCanPerformMutations);
if (_needsLayout) {
assert(_debugAncestorsAlreadyMarkedNeedsLayout());
assert(_debugSubtreeRelayoutRootAlreadyMarkedNeedsLayout());
return;
}
_needsLayout = true;
assert(_relayoutSubtreeRoot != null);
if (_relayoutSubtreeRoot != this) {
final RenderObject parent = this.parent;
if (!_doingThisLayoutWithCallback) {
parent.markNeedsLayout();
} else {
assert(parent._debugDoingThisLayout);
}
assert(parent == this.parent);
markParentNeedsLayout();
} else {
assert(() {
if (debugPrintMarkNeedsLayoutStacks)
debugPrintStack();
return true;
});
_needsLayout = true;
if (owner != null) {
assert(() {
if (debugPrintMarkNeedsLayoutStacks)
debugPrintStack();
return true;
});
owner._nodesNeedingLayout.add(this);
owner.requestVisualUpdate();
}
}
}
/// Mark this render object's layout information as dirty, and then defer to
/// the parent.
///
/// This function should only be called from [markNeedsLayout] implementations
/// of subclasses that introduce more reasons for deferring the handling of
/// dirty layout to the parent. See [markNeedsLayout] for details.
///
/// Only call this if [parent] is not null.
@protected
void markParentNeedsLayout() {
_needsLayout = true;
final RenderObject parent = this.parent;
if (!_doingThisLayoutWithCallback) {
parent.markNeedsLayout();
} else {
assert(parent._debugDoingThisLayout);
}
assert(parent == this.parent);
}
void _cleanRelayoutSubtreeRoot() {
if (_relayoutSubtreeRoot != this) {
_relayoutSubtreeRoot = null;
......
......@@ -92,30 +92,30 @@ class RenderParagraph extends RenderBox {
}
@override
double getMinIntrinsicWidth(double height) {
double computeMinIntrinsicWidth(double height) {
_layoutText();
return _textPainter.minIntrinsicWidth;
}
@override
double getMaxIntrinsicWidth(double height) {
double computeMaxIntrinsicWidth(double height) {
_layoutText();
return _textPainter.maxIntrinsicWidth;
}
double _getIntrinsicHeight(double width) {
double _computeIntrinsicHeight(double width) {
_layoutText(minWidth: width, maxWidth: width);
return _textPainter.height;
}
@override
double getMinIntrinsicHeight(double width) {
return _getIntrinsicHeight(width);
double computeMinIntrinsicHeight(double width) {
return _computeIntrinsicHeight(width);
}
@override
double getMaxIntrinsicHeight(double width) {
return _getIntrinsicHeight(width);
double computeMaxIntrinsicHeight(double width) {
return _computeIntrinsicHeight(width);
}
@override
......
......@@ -97,12 +97,12 @@ class RenderPerformanceOverlay extends RenderBox {
bool get alwaysNeedsCompositing => true;
@override
double getMinIntrinsicWidth(double height) {
double computeMinIntrinsicWidth(double height) {
return 0.0;
}
@override
double getMaxIntrinsicWidth(double height) {
double computeMaxIntrinsicWidth(double height) {
return 0.0;
}
......@@ -119,12 +119,12 @@ class RenderPerformanceOverlay extends RenderBox {
}
@override
double getMinIntrinsicHeight(double width) {
double computeMinIntrinsicHeight(double width) {
return _intrinsicHeight;
}
@override
double getMaxIntrinsicHeight(double width) {
double computeMaxIntrinsicHeight(double width) {
return _intrinsicHeight;
}
......
......@@ -42,28 +42,28 @@ class RenderProxyBox extends RenderBox with RenderObjectWithChildMixin<RenderBox
}
@override
double getMinIntrinsicWidth(double height) {
double computeMinIntrinsicWidth(double height) {
if (child != null)
return child.getMinIntrinsicWidth(height);
return 0.0;
}
@override
double getMaxIntrinsicWidth(double height) {
double computeMaxIntrinsicWidth(double height) {
if (child != null)
return child.getMaxIntrinsicWidth(height);
return 0.0;
}
@override
double getMinIntrinsicHeight(double width) {
double computeMinIntrinsicHeight(double width) {
if (child != null)
return child.getMinIntrinsicHeight(width);
return 0.0;
}
@override
double getMaxIntrinsicHeight(double width) {
double computeMaxIntrinsicHeight(double width) {
if (child != null)
return child.getMaxIntrinsicHeight(width);
return 0.0;
......@@ -195,32 +195,32 @@ class RenderConstrainedBox extends RenderProxyBox {
}
@override
double getMinIntrinsicWidth(double height) {
final double width = super.getMinIntrinsicWidth(height);
double computeMinIntrinsicWidth(double height) {
final double width = super.computeMinIntrinsicWidth(height);
if (_additionalConstraints.hasBoundedWidth)
return _additionalConstraints.constrainWidth(width);
return width;
}
@override
double getMaxIntrinsicWidth(double height) {
final double width = super.getMaxIntrinsicWidth(height);
double computeMaxIntrinsicWidth(double height) {
final double width = super.computeMaxIntrinsicWidth(height);
if (_additionalConstraints.hasBoundedWidth)
return _additionalConstraints.constrainWidth(width);
return width;
}
@override
double getMinIntrinsicHeight(double width) {
final double height = super.getMinIntrinsicHeight(width);
double computeMinIntrinsicHeight(double width) {
final double height = super.computeMinIntrinsicHeight(width);
if (_additionalConstraints.hasBoundedHeight)
return _additionalConstraints.constrainHeight(height);
return height;
}
@override
double getMaxIntrinsicHeight(double width) {
final double height = super.getMaxIntrinsicHeight(width);
double computeMaxIntrinsicHeight(double width) {
final double height = super.computeMaxIntrinsicHeight(width);
if (_additionalConstraints.hasBoundedHeight)
return _additionalConstraints.constrainHeight(height);
return height;
......@@ -381,7 +381,7 @@ class RenderAspectRatio extends RenderProxyBox {
}
@override
double getMinIntrinsicWidth(double height) {
double computeMinIntrinsicWidth(double height) {
if (height.isFinite)
return height * _aspectRatio;
if (child != null)
......@@ -390,7 +390,7 @@ class RenderAspectRatio extends RenderProxyBox {
}
@override
double getMaxIntrinsicWidth(double height) {
double computeMaxIntrinsicWidth(double height) {
if (height.isFinite)
return height * _aspectRatio;
if (child != null)
......@@ -399,7 +399,7 @@ class RenderAspectRatio extends RenderProxyBox {
}
@override
double getMinIntrinsicHeight(double width) {
double computeMinIntrinsicHeight(double width) {
if (width.isFinite)
return width / _aspectRatio;
if (child != null)
......@@ -408,7 +408,7 @@ class RenderAspectRatio extends RenderProxyBox {
}
@override
double getMaxIntrinsicHeight(double width) {
double computeMaxIntrinsicHeight(double width) {
if (width.isFinite)
return width / _aspectRatio;
if (child != null)
......@@ -537,12 +537,12 @@ class RenderIntrinsicWidth extends RenderProxyBox {
}
@override
double getMinIntrinsicWidth(double height) {
return getMaxIntrinsicWidth(height);
double computeMinIntrinsicWidth(double height) {
return computeMaxIntrinsicWidth(height);
}
@override
double getMaxIntrinsicWidth(double height) {
double computeMaxIntrinsicWidth(double height) {
if (child == null)
return 0.0;
final double width = child.getMaxIntrinsicWidth(height);
......@@ -550,22 +550,22 @@ class RenderIntrinsicWidth extends RenderProxyBox {
}
@override
double getMinIntrinsicHeight(double width) {
double computeMinIntrinsicHeight(double width) {
if (child == null)
return 0.0;
if (!width.isFinite)
width = getMaxIntrinsicWidth(double.INFINITY);
width = computeMaxIntrinsicWidth(double.INFINITY);
assert(width.isFinite);
final double height = child.getMinIntrinsicHeight(width);
return _applyStep(height, _stepHeight);
}
@override
double getMaxIntrinsicHeight(double width) {
double computeMaxIntrinsicHeight(double width) {
if (child == null)
return 0.0;
if (!width.isFinite)
width = getMaxIntrinsicWidth(double.INFINITY);
width = computeMaxIntrinsicWidth(double.INFINITY);
assert(width.isFinite);
final double height = child.getMaxIntrinsicHeight(width);
return _applyStep(height, _stepHeight);
......@@ -614,7 +614,7 @@ class RenderIntrinsicHeight extends RenderProxyBox {
}) : super(child);
@override
double getMinIntrinsicWidth(double height) {
double computeMinIntrinsicWidth(double height) {
if (child == null)
return 0.0;
if (!height.isFinite)
......@@ -624,7 +624,7 @@ class RenderIntrinsicHeight extends RenderProxyBox {
}
@override
double getMaxIntrinsicWidth(double height) {
double computeMaxIntrinsicWidth(double height) {
if (child == null)
return 0.0;
if (!height.isFinite)
......@@ -634,8 +634,8 @@ class RenderIntrinsicHeight extends RenderProxyBox {
}
@override
double getMinIntrinsicHeight(double width) {
return getMaxIntrinsicHeight(width);
double computeMinIntrinsicHeight(double width) {
return computeMaxIntrinsicHeight(width);
}
@override
......
......@@ -43,28 +43,28 @@ class RenderRotatedBox extends RenderBox with RenderObjectWithChildMixin<RenderB
bool get _isVertical => quarterTurns % 2 == 1;
@override
double getMinIntrinsicWidth(double height) {
double computeMinIntrinsicWidth(double height) {
if (child == null)
return 0.0;
return _isVertical ? child.getMinIntrinsicHeight(height) : child.getMinIntrinsicWidth(height);
}
@override
double getMaxIntrinsicWidth(double height) {
double computeMaxIntrinsicWidth(double height) {
if (child == null)
return 0.0;
return _isVertical ? child.getMaxIntrinsicHeight(height) : child.getMaxIntrinsicWidth(height);
}
@override
double getMinIntrinsicHeight(double width) {
double computeMinIntrinsicHeight(double width) {
if (child == null)
return 0.0;
return _isVertical ? child.getMinIntrinsicWidth(width) : child.getMinIntrinsicHeight(width);
}
@override
double getMaxIntrinsicHeight(double width) {
double computeMaxIntrinsicHeight(double width) {
if (child == null)
return 0.0;
return _isVertical ? child.getMaxIntrinsicWidth(width) : child.getMaxIntrinsicHeight(width);
......
......@@ -17,28 +17,28 @@ abstract class RenderShiftedBox extends RenderBox with RenderObjectWithChildMixi
}
@override
double getMinIntrinsicWidth(double height) {
double computeMinIntrinsicWidth(double height) {
if (child != null)
return child.getMinIntrinsicWidth(height);
return 0.0;
}
@override
double getMaxIntrinsicWidth(double height) {
double computeMaxIntrinsicWidth(double height) {
if (child != null)
return child.getMaxIntrinsicWidth(height);
return 0.0;
}
@override
double getMinIntrinsicHeight(double width) {
double computeMinIntrinsicHeight(double width) {
if (child != null)
return child.getMinIntrinsicHeight(width);
return 0.0;
}
@override
double getMaxIntrinsicHeight(double width) {
double computeMaxIntrinsicHeight(double width) {
if (child != null)
return child.getMaxIntrinsicHeight(width);
return 0.0;
......@@ -111,7 +111,7 @@ class RenderPadding extends RenderShiftedBox {
}
@override
double getMinIntrinsicWidth(double height) {
double computeMinIntrinsicWidth(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
......@@ -120,7 +120,7 @@ class RenderPadding extends RenderShiftedBox {
}
@override
double getMaxIntrinsicWidth(double height) {
double computeMaxIntrinsicWidth(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
......@@ -129,7 +129,7 @@ class RenderPadding extends RenderShiftedBox {
}
@override
double getMinIntrinsicHeight(double width) {
double computeMinIntrinsicHeight(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
......@@ -138,7 +138,7 @@ class RenderPadding extends RenderShiftedBox {
}
@override
double getMaxIntrinsicHeight(double width) {
double computeMaxIntrinsicHeight(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
......@@ -551,22 +551,22 @@ class RenderSizedOverflowBox extends RenderAligningShiftedBox {
}
@override
double getMinIntrinsicWidth(double height) {
double computeMinIntrinsicWidth(double height) {
return _requestedSize.width;
}
@override
double getMaxIntrinsicWidth(double height) {
double computeMaxIntrinsicWidth(double height) {
return _requestedSize.width;
}
@override
double getMinIntrinsicHeight(double width) {
double computeMinIntrinsicHeight(double width) {
return _requestedSize.height;
}
@override
double getMaxIntrinsicHeight(double width) {
double computeMaxIntrinsicHeight(double width) {
return _requestedSize.height;
}
......@@ -667,10 +667,10 @@ class RenderFractionallySizedOverflowBox extends RenderAligningShiftedBox {
}
@override
double getMinIntrinsicWidth(double height) {
double computeMinIntrinsicWidth(double height) {
double result;
if (child == null) {
result = super.getMinIntrinsicWidth(height);
result = super.computeMinIntrinsicWidth(height);
} else { // the following line relies on double.INFINITY absorption
result = child.getMinIntrinsicWidth(height * (_heightFactor ?? 1.0));
}
......@@ -679,10 +679,10 @@ class RenderFractionallySizedOverflowBox extends RenderAligningShiftedBox {
}
@override
double getMaxIntrinsicWidth(double height) {
double computeMaxIntrinsicWidth(double height) {
double result;
if (child == null) {
result = super.getMaxIntrinsicWidth(height);
result = super.computeMaxIntrinsicWidth(height);
} else { // the following line relies on double.INFINITY absorption
result = child.getMaxIntrinsicWidth(height * (_heightFactor ?? 1.0));
}
......@@ -691,10 +691,10 @@ class RenderFractionallySizedOverflowBox extends RenderAligningShiftedBox {
}
@override
double getMinIntrinsicHeight(double width) {
double computeMinIntrinsicHeight(double width) {
double result;
if (child == null) {
result = super.getMinIntrinsicHeight(width);
result = super.computeMinIntrinsicHeight(width);
} else { // the following line relies on double.INFINITY absorption
result = child.getMinIntrinsicHeight(width * (_widthFactor ?? 1.0));
}
......@@ -703,10 +703,10 @@ class RenderFractionallySizedOverflowBox extends RenderAligningShiftedBox {
}
@override
double getMaxIntrinsicHeight(double width) {
double computeMaxIntrinsicHeight(double width) {
double result;
if (child == null) {
result = super.getMaxIntrinsicHeight(width);
result = super.computeMaxIntrinsicHeight(width);
} else { // the following line relies on double.INFINITY absorption
result = child.getMaxIntrinsicHeight(width * (_widthFactor ?? 1.0));
}
......@@ -786,7 +786,7 @@ class RenderCustomSingleChildLayoutBox extends RenderShiftedBox {
// or we should expose intrinsic delegate callbacks and throw if they're not implemented.
@override
double getMinIntrinsicWidth(double height) {
double computeMinIntrinsicWidth(double height) {
final double width = _getSize(new BoxConstraints.tightForFinite(height: height)).width;
if (width.isFinite)
return width;
......@@ -794,7 +794,7 @@ class RenderCustomSingleChildLayoutBox extends RenderShiftedBox {
}
@override
double getMaxIntrinsicWidth(double height) {
double computeMaxIntrinsicWidth(double height) {
final double width = _getSize(new BoxConstraints.tightForFinite(height: height)).width;
if (width.isFinite)
return width;
......@@ -802,7 +802,7 @@ class RenderCustomSingleChildLayoutBox extends RenderShiftedBox {
}
@override
double getMinIntrinsicHeight(double width) {
double computeMinIntrinsicHeight(double width) {
final double height = _getSize(new BoxConstraints.tightForFinite(width: width)).height;
if (height.isFinite)
return height;
......@@ -810,7 +810,7 @@ class RenderCustomSingleChildLayoutBox extends RenderShiftedBox {
}
@override
double getMaxIntrinsicHeight(double width) {
double computeMaxIntrinsicHeight(double width) {
final double height = _getSize(new BoxConstraints.tightForFinite(width: width)).height;
if (height.isFinite)
return height;
......
......@@ -286,22 +286,22 @@ class RenderStack extends RenderBox
}
@override
double getMinIntrinsicWidth(double height) {
double computeMinIntrinsicWidth(double height) {
return _getIntrinsicDimension((RenderBox child) => child.getMinIntrinsicWidth(height));
}
@override
double getMaxIntrinsicWidth(double height) {
double computeMaxIntrinsicWidth(double height) {
return _getIntrinsicDimension((RenderBox child) => child.getMaxIntrinsicWidth(height));
}
@override
double getMinIntrinsicHeight(double width) {
double computeMinIntrinsicHeight(double width) {
return _getIntrinsicDimension((RenderBox child) => child.getMinIntrinsicHeight(width));
}
@override
double getMaxIntrinsicHeight(double width) {
double computeMaxIntrinsicHeight(double width) {
return _getIntrinsicDimension((RenderBox child) => child.getMaxIntrinsicHeight(width));
}
......
......@@ -819,7 +819,7 @@ class RenderTable extends RenderBox {
}
@override
double getMinIntrinsicWidth(double height) {
double computeMinIntrinsicWidth(double height) {
assert(_children.length == rows * columns);
double totalMinWidth = 0.0;
for (int x = 0; x < columns; x += 1) {
......@@ -831,7 +831,7 @@ class RenderTable extends RenderBox {
}
@override
double getMaxIntrinsicWidth(double height) {
double computeMaxIntrinsicWidth(double height) {
assert(_children.length == rows * columns);
double totalMaxWidth = 0.0;
for (int x = 0; x < columns; x += 1) {
......@@ -843,7 +843,7 @@ class RenderTable extends RenderBox {
}
@override
double getMinIntrinsicHeight(double width) {
double computeMinIntrinsicHeight(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(_children.length == rows * columns);
......@@ -863,8 +863,8 @@ class RenderTable extends RenderBox {
}
@override
double getMaxIntrinsicHeight(double width) {
return getMinIntrinsicHeight(width);
double computeMaxIntrinsicHeight(double width) {
return computeMinIntrinsicHeight(width);
}
double _baselineDistance;
......
......@@ -236,28 +236,28 @@ class RenderViewport extends RenderViewportBase with RenderObjectWithChildMixin<
}
@override
double getMinIntrinsicWidth(double height) {
double computeMinIntrinsicWidth(double height) {
if (child != null)
return child.getMinIntrinsicWidth(height);
return 0.0;
}
@override
double getMaxIntrinsicWidth(double height) {
double computeMaxIntrinsicWidth(double height) {
if (child != null)
return child.getMaxIntrinsicWidth(height);
return 0.0;
}
@override
double getMinIntrinsicHeight(double width) {
double computeMinIntrinsicHeight(double width) {
if (child != null)
return child.getMinIntrinsicHeight(width);
return 0.0;
}
@override
double getMaxIntrinsicHeight(double width) {
double computeMaxIntrinsicHeight(double width) {
if (child != null)
return child.getMaxIntrinsicHeight(width);
return 0.0;
......@@ -408,25 +408,25 @@ abstract class RenderVirtualViewport<T extends ContainerBoxParentDataMixin<Rende
}
@override
double getMinIntrinsicWidth(double height) {
double computeMinIntrinsicWidth(double height) {
assert(debugThrowIfNotCheckingIntrinsics());
return 0.0;
}
@override
double getMaxIntrinsicWidth(double height) {
double computeMaxIntrinsicWidth(double height) {
assert(debugThrowIfNotCheckingIntrinsics());
return 0.0;
}
@override
double getMinIntrinsicHeight(double width) {
double computeMinIntrinsicHeight(double width) {
assert(debugThrowIfNotCheckingIntrinsics());
return 0.0;
}
@override
double getMaxIntrinsicHeight(double width) {
double computeMaxIntrinsicHeight(double width) {
assert(debugThrowIfNotCheckingIntrinsics());
return 0.0;
}
......
......@@ -66,25 +66,25 @@ class _RenderLayoutBuilder extends RenderBox with RenderObjectWithChildMixin<Ren
}
@override
double getMinIntrinsicWidth(double height) {
double computeMinIntrinsicWidth(double height) {
assert(_debugThrowIfNotCheckingIntrinsics());
return 0.0;
}
@override
double getMaxIntrinsicWidth(double height) {
double computeMaxIntrinsicWidth(double height) {
assert(_debugThrowIfNotCheckingIntrinsics());
return 0.0;
}
@override
double getMinIntrinsicHeight(double width) {
double computeMinIntrinsicHeight(double width) {
assert(_debugThrowIfNotCheckingIntrinsics());
return 0.0;
}
@override
double getMaxIntrinsicHeight(double width) {
double computeMaxIntrinsicHeight(double width) {
assert(_debugThrowIfNotCheckingIntrinsics());
return 0.0;
}
......
......@@ -368,25 +368,25 @@ class _RenderLazyBlock extends RenderVirtualViewport<_LazyBlockParentData> {
}
@override
double getMinIntrinsicWidth(double height) {
double computeMinIntrinsicWidth(double height) {
assert(_debugThrowIfNotCheckingIntrinsics());
return 0.0;
}
@override
double getMaxIntrinsicWidth(double height) {
double computeMaxIntrinsicWidth(double height) {
assert(_debugThrowIfNotCheckingIntrinsics());
return 0.0;
}
@override
double getMinIntrinsicHeight(double width) {
double computeMinIntrinsicHeight(double width) {
assert(_debugThrowIfNotCheckingIntrinsics());
return 0.0;
}
@override
double getMaxIntrinsicHeight(double width) {
double computeMaxIntrinsicHeight(double width) {
assert(_debugThrowIfNotCheckingIntrinsics());
return 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';
class RenderTestBox extends RenderBox {
double value = 0.0;
double next() { value += 1.0; return value; }
@override double computeMinIntrinsicWidth(double height) => next();
@override double computeMaxIntrinsicWidth(double height) => next();
@override double computeMinIntrinsicHeight(double width) => next();
@override double computeMaxIntrinsicHeight(double width) => next();
}
void main() {
test('Intrinsics cache', () {
RenderBox test = new RenderTestBox();
expect(test.getMinIntrinsicWidth(0.0), equals(1.0));
expect(test.getMinIntrinsicWidth(100.0), equals(2.0));
expect(test.getMinIntrinsicWidth(200.0), equals(3.0));
expect(test.getMinIntrinsicWidth(0.0), equals(1.0));
expect(test.getMinIntrinsicWidth(100.0), equals(2.0));
expect(test.getMinIntrinsicWidth(200.0), equals(3.0));
expect(test.getMaxIntrinsicWidth(0.0), equals(4.0));
expect(test.getMaxIntrinsicWidth(100.0), equals(5.0));
expect(test.getMaxIntrinsicWidth(200.0), equals(6.0));
expect(test.getMaxIntrinsicWidth(0.0), equals(4.0));
expect(test.getMaxIntrinsicWidth(100.0), equals(5.0));
expect(test.getMaxIntrinsicWidth(200.0), equals(6.0));
expect(test.getMinIntrinsicHeight(0.0), equals(7.0));
expect(test.getMinIntrinsicHeight(100.0), equals(8.0));
expect(test.getMinIntrinsicHeight(200.0), equals(9.0));
expect(test.getMinIntrinsicHeight(0.0), equals(7.0));
expect(test.getMinIntrinsicHeight(100.0), equals(8.0));
expect(test.getMinIntrinsicHeight(200.0), equals(9.0));
expect(test.getMaxIntrinsicHeight(0.0), equals(10.0));
expect(test.getMaxIntrinsicHeight(100.0), equals(11.0));
expect(test.getMaxIntrinsicHeight(200.0), equals(12.0));
expect(test.getMaxIntrinsicHeight(0.0), equals(10.0));
expect(test.getMaxIntrinsicHeight(100.0), equals(11.0));
expect(test.getMaxIntrinsicHeight(200.0), equals(12.0));
// now read them all again backwards
expect(test.getMaxIntrinsicHeight(200.0), equals(12.0));
expect(test.getMaxIntrinsicHeight(100.0), equals(11.0));
expect(test.getMaxIntrinsicHeight(0.0), equals(10.0));
expect(test.getMinIntrinsicHeight(200.0), equals(9.0));
expect(test.getMinIntrinsicHeight(100.0), equals(8.0));
expect(test.getMinIntrinsicHeight(0.0), equals(7.0));
expect(test.getMaxIntrinsicWidth(200.0), equals(6.0));
expect(test.getMaxIntrinsicWidth(100.0), equals(5.0));
expect(test.getMaxIntrinsicWidth(0.0), equals(4.0));
expect(test.getMinIntrinsicWidth(200.0), equals(3.0));
expect(test.getMinIntrinsicWidth(100.0), equals(2.0));
expect(test.getMinIntrinsicWidth(0.0), equals(1.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';
import 'rendering_tester.dart';
class RenderFixedSize extends RenderBox {
double dimension = 100.0;
void grow() {
dimension *= 2.0;
markNeedsLayout();
}
@override double computeMinIntrinsicWidth(double height) => dimension;
@override double computeMaxIntrinsicWidth(double height) => dimension;
@override double computeMinIntrinsicHeight(double width) => dimension;
@override double computeMaxIntrinsicHeight(double width) => dimension;
@override
void performLayout() {
size = new Size.square(dimension);
}
}
class RenderParentSize extends RenderProxyBox {
RenderParentSize({ RenderBox child }) : super(child);
@override
bool get sizedByParent => true;
@override
void performResize() {
size = constraints.biggest;
}
@override
void performLayout() {
child.layout(constraints);
}
}
class RenderIntrinsicSize extends RenderProxyBox {
RenderIntrinsicSize({ RenderBox child }) : super(child);
@override
void performLayout() {
child.layout(constraints);
size = new Size(
child.getMinIntrinsicWidth(double.INFINITY),
child.getMinIntrinsicHeight(double.INFINITY)
);
}
}
void main() {
test('Whether using intrinsics means you get hooked into layout', () {
RenderBox root;
RenderFixedSize inner;
layout(
root = new RenderIntrinsicSize(
child: new RenderParentSize(
child: inner = new RenderFixedSize()
)
),
constraints: new BoxConstraints(
minWidth: 0.0,
minHeight: 0.0,
maxWidth: 1000.0,
maxHeight: 1000.0
)
);
expect(root.size, equals(inner.size));
inner.grow();
pumpFrame();
expect(root.size, equals(inner.size));
});
}
......@@ -14,22 +14,22 @@ class RenderTestBox extends RenderBox {
final BoxConstraints _intrinsicDimensions;
@override
double getMinIntrinsicWidth(double height) {
double computeMinIntrinsicWidth(double height) {
return _intrinsicDimensions.minWidth;
}
@override
double getMaxIntrinsicWidth(double height) {
double computeMaxIntrinsicWidth(double height) {
return _intrinsicDimensions.maxWidth;
}
@override
double getMinIntrinsicHeight(double width) {
double computeMinIntrinsicHeight(double width) {
return _intrinsicDimensions.minHeight;
}
@override
double getMaxIntrinsicHeight(double width) {
double computeMaxIntrinsicHeight(double width) {
return _intrinsicDimensions.maxHeight;
}
......
......@@ -92,22 +92,22 @@ class RenderSizedBox extends RenderBox {
final Size _size;
@override
double getMinIntrinsicWidth(double height) {
double computeMinIntrinsicWidth(double height) {
return _size.width;
}
@override
double getMaxIntrinsicWidth(double height) {
double computeMaxIntrinsicWidth(double height) {
return _size.width;
}
@override
double getMinIntrinsicHeight(double width) {
double computeMinIntrinsicHeight(double width) {
return _size.height;
}
@override
double getMaxIntrinsicHeight(double width) {
double computeMaxIntrinsicHeight(double width) {
return _size.height;
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment