From 0f4d3765431a59cd157c8ae77596d26751128556 Mon Sep 17 00:00:00 2001 From: Adam Barth Date: Wed, 9 Sep 2015 10:16:04 -0700 Subject: [PATCH] Add dartdoc to RenderBlock and RenderFlex --- packages/flutter/lib/src/rendering/block.dart | 118 ++++++++++-------- packages/flutter/lib/src/rendering/box.dart | 3 - packages/flutter/lib/src/rendering/flex.dart | 57 +++++++-- packages/flutter/lib/src/rendering/image.dart | 27 ++-- .../flutter/lib/src/rendering/object.dart | 2 +- .../lib/src/widgets/homogeneous_viewport.dart | 12 +- .../lib/src/widgets/mixed_viewport.dart | 14 +-- 7 files changed, 149 insertions(+), 84 deletions(-) diff --git a/packages/flutter/lib/src/rendering/block.dart b/packages/flutter/lib/src/rendering/block.dart index 4c4ad2baaf0..91e49a9d19f 100644 --- a/packages/flutter/lib/src/rendering/block.dart +++ b/packages/flutter/lib/src/rendering/block.dart @@ -8,19 +8,32 @@ import 'package:sky/src/rendering/box.dart'; import 'package:sky/src/rendering/object.dart'; import 'package:vector_math/vector_math.dart'; +/// Parent data for use with [RenderBlockBase] class BlockParentData extends BoxParentData with ContainerParentDataMixin { } -enum BlockDirection { horizontal, vertical } +/// The direction in which the block should lay out +enum BlockDirection { + /// Children are arranged horizontally, from left to right + horizontal, + /// Children are arranged vertically, from top to bottom + vertical +} typedef double _ChildSizingFunction(RenderBox child, BoxConstraints constraints); typedef double _Constrainer(double value); +/// Implements the block layout algorithm +/// +/// In block layout, children are arranged linearly along the main axis (either +/// horizontally or vertically). In the cross axis, children are stretched to +/// match the block's cross-axis extent. In the main axis, children are given +/// unlimited space and the block expands its main axis to contain all its +/// children. Because blocks expand in the main axis, blocks must be given +/// unlimited space in the main axis, typically by being contained in a +/// viewport with a scrolling direction that matches the block's main axis. abstract class RenderBlockBase extends RenderBox with ContainerRenderObjectMixin, RenderBoxContainerDefaultsMixin { - // lays out RenderBox children in a vertical stack - // uses the maximum width provided by the parent - RenderBlockBase({ List children, BlockDirection direction: BlockDirection.vertical, @@ -35,8 +48,9 @@ abstract class RenderBlockBase extends RenderBox with ContainerRenderObjectMixin child.parentData = new BlockParentData(); } - BlockDirection _direction; + /// The direction to use as the main axis BlockDirection get direction => _direction; + BlockDirection _direction; void set direction (BlockDirection value) { if (_direction != value) { _direction = value; @@ -44,8 +58,9 @@ abstract class RenderBlockBase extends RenderBox with ContainerRenderObjectMixin } } - double _itemExtent; + /// If non-null, forces children to be exactly this large in the main axis double get itemExtent => _itemExtent; + double _itemExtent; void set itemExtent(double value) { if (value != _itemExtent) { _itemExtent = value; @@ -53,8 +68,9 @@ abstract class RenderBlockBase extends RenderBox with ContainerRenderObjectMixin } } - double _minExtent; + /// Forces the block to be at least this large in the main-axis double get minExtent => _minExtent; + double _minExtent; void set minExtent(double value) { if (value != _minExtent) { _minExtent = value; @@ -62,6 +78,7 @@ abstract class RenderBlockBase extends RenderBox with ContainerRenderObjectMixin } } + /// Whether the main axis is vertical bool get isVertical => _direction == BlockDirection.vertical; BoxConstraints _getInnerConstraints(BoxConstraints constraints) { @@ -102,6 +119,7 @@ abstract class RenderBlockBase extends RenderBox with ContainerRenderObjectMixin String debugDescribeSettings(String prefix) => '${super.debugDescribeSettings(prefix)}${prefix}direction: ${direction}\n'; } +/// A block layout with a concrete set of children class RenderBlock extends RenderBlockBase { RenderBlock({ @@ -194,21 +212,21 @@ class RenderBlock extends RenderBlockBase { } +/// A block layout whose children depend on its layout +/// +/// This class invokes a callbacks for layout and intrinsic dimensions. The main +/// [callback] (constructor argument and property) is expected to modify the +/// element's child list. The regular block layout algorithm is then applied to +/// the children. The intrinsic dimension callbacks are called to determine +/// intrinsic dimensions; if no value can be returned, they should not be set +/// or, if set, should return null. class RenderBlockViewport extends RenderBlockBase { - // This class invokes a callbacks for layout and intrinsic - // dimensions. The main callback (constructor argument and property - // called "callback") is expected to modify the element's child - // list. The regular block layout algorithm is then applied to the - // children. The intrinsic dimension callbacks are called to - // determine intrinsic dimensions; if no value can be returned, they - // should not be set or, if set, should return null. - RenderBlockViewport({ LayoutCallback callback, - DimensionCallback totalExtentCallback, - DimensionCallback maxCrossAxisDimensionCallback, - DimensionCallback minCrossAxisDimensionCallback, + ExtentCallback totalExtentCallback, + ExtentCallback maxCrossAxisDimensionCallback, + ExtentCallback minCrossAxisDimensionCallback, BlockDirection direction: BlockDirection.vertical, double itemExtent, double minExtent: 0.0, @@ -216,16 +234,19 @@ class RenderBlockViewport extends RenderBlockBase { List children }) : _callback = callback, _totalExtentCallback = totalExtentCallback, - _maxCrossAxisDimensionCallback = maxCrossAxisDimensionCallback, - _minCrossAxisDimensionCallback = minCrossAxisDimensionCallback, + _maxCrossAxisExtentCallback = maxCrossAxisDimensionCallback, + _minCrossAxisExtentCallback = minCrossAxisDimensionCallback, _startOffset = startOffset, super(children: children, direction: direction, itemExtent: itemExtent, minExtent: minExtent); bool _inCallback = false; - // Called during layout. Mutate the child list appropriately. - LayoutCallback _callback; + /// Called during [layout] to determine the blocks children + /// + /// Typically the callback will mutate the child list appropriately, for + /// example so the child list contains only visible children. LayoutCallback get callback => _callback; + LayoutCallback _callback; void set callback(LayoutCallback value) { assert(!_inCallback); if (value == _callback) @@ -234,11 +255,10 @@ class RenderBlockViewport extends RenderBlockBase { markNeedsLayout(); } - // Return the sum of the extent of all the children that could be included by the callback in one go. - // The extent is the dimension in the direction given by the 'direction' property. - DimensionCallback _totalExtentCallback; - DimensionCallback get totalExtentCallback => _totalExtentCallback; - void set totalExtentCallback(DimensionCallback value) { + /// Returns the total main-axis extent of all the children that could be included by [callback] in one go + ExtentCallback get totalExtentCallback => _totalExtentCallback; + ExtentCallback _totalExtentCallback; + void set totalExtentCallback(ExtentCallback value) { assert(!_inCallback); if (value == _totalExtentCallback) return; @@ -246,35 +266,33 @@ class RenderBlockViewport extends RenderBlockBase { markNeedsLayout(); } - // Return the minimum dimension across all the children that could - // be included in one go, in the direction orthogonal to that given - // by the 'direction' property. - DimensionCallback _minCrossAxisDimensionCallback; - DimensionCallback get minCrossAxisDimensionCallback => _minCrossAxisDimensionCallback; - void set minCrossAxisDimensionCallback(DimensionCallback value) { + /// Returns the minimum cross-axis extent across all the children that could be included by [callback] in one go + ExtentCallback get minCrossAxisExtentCallback => _minCrossAxisExtentCallback; + ExtentCallback _minCrossAxisExtentCallback; + void set minCrossAxisExtentCallback(ExtentCallback value) { assert(!_inCallback); - if (value == _minCrossAxisDimensionCallback) + if (value == _minCrossAxisExtentCallback) return; - _minCrossAxisDimensionCallback = value; + _minCrossAxisExtentCallback = value; markNeedsLayout(); } - // Return the maximum dimension across all the children that could - // be included in one go, in the direction orthogonal to that given - // by the 'direction' property. - DimensionCallback _maxCrossAxisDimensionCallback; - DimensionCallback get maxCrossAxisDimensionCallback => _maxCrossAxisDimensionCallback; - void set maxCrossAxisDimensionCallback(DimensionCallback value) { + /// Returns the maximum cross-axis extent across all the children that could be included by [callback] in one go + ExtentCallback get maxCrossAxisExtentCallback => _maxCrossAxisExtentCallback; + ExtentCallback _maxCrossAxisExtentCallback; + void set maxCrossAxisExtentCallback(ExtentCallback value) { assert(!_inCallback); - if (value == _maxCrossAxisDimensionCallback) + if (value == _maxCrossAxisExtentCallback) return; - _maxCrossAxisDimensionCallback = value; + _maxCrossAxisExtentCallback = value; markNeedsLayout(); } - // you can set this from within the callback if necessary - double _startOffset; + /// The offset at which to paint the first child + /// + /// Note: you can modify this property from within [callback], if necessary. double get startOffset => _startOffset; + double _startOffset; void set startOffset(double value) { if (value != _startOffset) { _startOffset = value; @@ -282,7 +300,7 @@ class RenderBlockViewport extends RenderBlockBase { } } - double _getIntrinsicDimension(BoxConstraints constraints, DimensionCallback intrinsicCallback, _Constrainer constrainer) { + double _getIntrinsicDimension(BoxConstraints constraints, ExtentCallback intrinsicCallback, _Constrainer constrainer) { assert(!_inCallback); double result; if (intrinsicCallback == null) { @@ -307,25 +325,25 @@ class RenderBlockViewport extends RenderBlockBase { double getMinIntrinsicWidth(BoxConstraints constraints) { if (isVertical) - return _getIntrinsicDimension(constraints, minCrossAxisDimensionCallback, constraints.constrainWidth); + return _getIntrinsicDimension(constraints, minCrossAxisExtentCallback, constraints.constrainWidth); return constraints.constrainWidth(minExtent); } double getMaxIntrinsicWidth(BoxConstraints constraints) { if (isVertical) - return _getIntrinsicDimension(constraints, maxCrossAxisDimensionCallback, constraints.constrainWidth); + return _getIntrinsicDimension(constraints, maxCrossAxisExtentCallback, constraints.constrainWidth); return _getIntrinsicDimension(constraints, totalExtentCallback, new BoxConstraints(minWidth: minExtent).enforce(constraints).constrainWidth); } double getMinIntrinsicHeight(BoxConstraints constraints) { if (!isVertical) - return _getIntrinsicDimension(constraints, minCrossAxisDimensionCallback, constraints.constrainHeight); + return _getIntrinsicDimension(constraints, minCrossAxisExtentCallback, constraints.constrainHeight); return constraints.constrainHeight(0.0); } double getMaxIntrinsicHeight(BoxConstraints constraints) { if (!isVertical) - return _getIntrinsicDimension(constraints, maxCrossAxisDimensionCallback, constraints.constrainHeight); + return _getIntrinsicDimension(constraints, maxCrossAxisExtentCallback, constraints.constrainHeight); return _getIntrinsicDimension(constraints, totalExtentCallback, new BoxConstraints(minHeight: minExtent).enforce(constraints).constrainHeight); } diff --git a/packages/flutter/lib/src/rendering/box.dart b/packages/flutter/lib/src/rendering/box.dart index ca7d6f86cc7..ed82ff85db4 100644 --- a/packages/flutter/lib/src/rendering/box.dart +++ b/packages/flutter/lib/src/rendering/box.dart @@ -12,9 +12,6 @@ import 'package:vector_math/vector_math.dart'; export 'package:sky/painting.dart' show TextBaseline; -// GENERIC BOX RENDERING -// Anything that has a concept of x, y, width, height is going to derive from this - // This class should only be used in debug builds class _DebugSize extends Size { _DebugSize(Size source, this._owner, this._canBeUsedByParent): super.copy(source); diff --git a/packages/flutter/lib/src/rendering/flex.dart b/packages/flutter/lib/src/rendering/flex.dart index 0c84c4c86cb..db106ee9ea1 100644 --- a/packages/flutter/lib/src/rendering/flex.dart +++ b/packages/flutter/lib/src/rendering/flex.dart @@ -9,7 +9,14 @@ import 'package:sky/src/rendering/object.dart'; export 'package:sky/src/rendering/object.dart' show EventDisposition; +/// Parent data for use with [RenderFlex] class FlexParentData extends BoxParentData with ContainerParentDataMixin { + /// The flex factor to use for this child + /// + /// If null, the child is inflexible and determines its own size. If non-null, + /// the child is flexible and its extent in the main axis is determined by + /// dividing the free space (after placing the inflexible children) + /// according to the flex factors of the flexible children. int flex; void merge(FlexParentData other) { @@ -21,29 +28,61 @@ class FlexParentData extends BoxParentData with ContainerParentDataMixin '${super.toString()}; flex=$flex'; } -enum FlexDirection { horizontal, vertical } +/// The direction in which the box should flex +enum FlexDirection { + /// Children are arranged horizontally, from left to right + horizontal, + /// Children are arranged vertically, from top to bottom + vertical +} +/// How the children should be placed along the main axis in a flex layout enum FlexJustifyContent { + /// Place the children as close to the start of the main axis as possible start, + /// Place the children as close to the end of the main axis as possible end, + /// Place the children as close to the middle of the main axis as possible center, + /// Place the free space evenly between the children spaceBetween, + /// Place the free space evenly between the children as well as before and after the first and last child spaceAround, } +/// How the children should be placed along the cross axis in a flex layout enum FlexAlignItems { + /// Place the children as close to the start of the cross axis as possible start, + /// Place the children as close to the end of the cross axis as possible end, + /// Place the children as close to the middle of the cross axis as possible center, + /// Require the children to fill the cross axis stretch, + /// Place the children along the cross axis such that their baselines match baseline, } typedef double _ChildSizingFunction(RenderBox child, BoxConstraints constraints); +/// Implements the flex layout algorithm +/// +/// In flex layout, children are arranged linearly along the main axis (either +/// horizontally or vertically). First, inflexible children (those with a null +/// flex factor) are allocated space along the main axis. If the flex is given +/// unlimited space in the main axis, the flex sizes its main axis to the total +/// size of the inflexible children along the main axis and forbids flexible +/// children. Otherwise, the flex expands to the maximum max-axis size and the +/// remaining space along is divided among the flexible children according to +/// their flex factors. Any remaining free space (i.e., if there aren't any +/// flexible children) is allocated according to the [justifyContent] property. +/// +/// In the cross axis, children determine their own size. The flex then sizes +/// its cross axis to fix the largest of its children. The children are then +/// positioned along the cross axis according to the [alignItems] property. class RenderFlex extends RenderBox with ContainerRenderObjectMixin, RenderBoxContainerDefaultsMixin { - // lays out RenderBox children using flexible layout RenderFlex({ List children, @@ -58,8 +97,9 @@ class RenderFlex extends RenderBox with ContainerRenderObjectMixin _direction; + FlexDirection _direction; void set direction (FlexDirection value) { if (_direction != value) { _direction = value; @@ -67,8 +107,9 @@ class RenderFlex extends RenderBox with ContainerRenderObjectMixin _justifyContent; + FlexJustifyContent _justifyContent; void set justifyContent (FlexJustifyContent value) { if (_justifyContent != value) { _justifyContent = value; @@ -76,8 +117,9 @@ class RenderFlex extends RenderBox with ContainerRenderObjectMixin _alignItems; + FlexAlignItems _alignItems; void set alignItems (FlexAlignItems value) { if (_alignItems != value) { _alignItems = value; @@ -85,8 +127,9 @@ class RenderFlex extends RenderBox with ContainerRenderObjectMixin _textBaseline; + TextBaseline _textBaseline; void set textBaseline (TextBaseline value) { if (_textBaseline != value) { _textBaseline = value; @@ -94,7 +137,7 @@ class RenderFlex extends RenderBox with ContainerRenderObjectMixin _image; void set image (sky.Image value) { if (value == _image) @@ -35,6 +40,7 @@ class RenderImage extends RenderBox { } double _width; + /// If non-null, requires the image to have this width double get width => _width; void set width (double value) { if (value == _width) @@ -44,6 +50,7 @@ class RenderImage extends RenderBox { } double _height; + /// If non-null, requires the image to have this height double get height => _height; void set height (double value) { if (value == _height) @@ -53,6 +60,7 @@ class RenderImage extends RenderBox { } sky.ColorFilter _colorFilter; + /// If non-null, apply this color filter to the image before painint. sky.ColorFilter get colorFilter => _colorFilter; void set colorFilter (sky.ColorFilter value) { if (value == _colorFilter) @@ -62,6 +70,7 @@ class RenderImage extends RenderBox { } ImageFit _fit; + /// How to inscribe the image into the place allocated during layout ImageFit get fit => _fit; void set fit (ImageFit value) { if (value == _fit) @@ -71,6 +80,7 @@ class RenderImage extends RenderBox { } ImageRepeat _repeat; + /// Not yet implemented ImageRepeat get repeat => _repeat; void set repeat (ImageRepeat value) { if (value == _repeat) @@ -79,6 +89,13 @@ class RenderImage extends RenderBox { markNeedsPaint(); } + /// Find a size for the render image within the given constraints + /// + /// - The dimensions of the RenderImage must fit within the constraints. + /// - The aspect ratio of the RenderImage matches the instrinsic aspect + /// ratio of the image. + /// - The RenderImage's dimension are maximal subject to being smaller than + /// the intrinsic size of the image. Size _sizeForConstraints(BoxConstraints constraints) { // Folds the given |width| and |height| into |cosntraints| so they can all // be treated uniformly. @@ -90,16 +107,6 @@ class RenderImage extends RenderBox { if (constraints.isTight || _image == null) return constraints.smallest; - // This algorithm attempts to find a size for the RenderImage that fits in - // the given constraints and preserves the image's intrinisc aspect ratio. - // Its goals as follow: - // - // - The dimensions of the RenderImage fit within the constraints. - // - The aspect ratio of the RenderImage matches the instrinsic aspect - // ratio of the image. - // - The RenderImage's dimension are maximal subject to being smaller than - // the intrinsic size of the image. - double width = _image.width.toDouble(); double height = _image.height.toDouble(); assert(width > 0.0); diff --git a/packages/flutter/lib/src/rendering/object.dart b/packages/flutter/lib/src/rendering/object.dart index 5d85ad6fb68..6fd819702fb 100644 --- a/packages/flutter/lib/src/rendering/object.dart +++ b/packages/flutter/lib/src/rendering/object.dart @@ -366,7 +366,7 @@ abstract class Constraints { typedef void RenderObjectVisitor(RenderObject child); typedef void LayoutCallback(Constraints constraints); -typedef double DimensionCallback(Constraints constraints); +typedef double ExtentCallback(Constraints constraints); /// An object in the render tree /// diff --git a/packages/flutter/lib/src/widgets/homogeneous_viewport.dart b/packages/flutter/lib/src/widgets/homogeneous_viewport.dart index c6c95e84a56..6695da2aff0 100644 --- a/packages/flutter/lib/src/widgets/homogeneous_viewport.dart +++ b/packages/flutter/lib/src/widgets/homogeneous_viewport.dart @@ -43,16 +43,16 @@ class HomogeneousViewport extends RenderObjectWrapper { RenderBlockViewport result = new RenderBlockViewport(); result.callback = layout; result.totalExtentCallback = getTotalExtent; - result.minCrossAxisDimensionCallback = getMinCrossAxisDimension; - result.maxCrossAxisDimensionCallback = getMaxCrossAxisDimension; + result.minCrossAxisExtentCallback = getMinCrossAxisExtent; + result.maxCrossAxisExtentCallback = getMaxCrossAxisExtent; return result; } void remove() { renderObject.callback = null; renderObject.totalExtentCallback = null; - renderObject.minCrossAxisDimensionCallback = null; - renderObject.maxCrossAxisDimensionCallback = null; + renderObject.minCrossAxisExtentCallback = null; + renderObject.maxCrossAxisExtentCallback = null; super.remove(); _children.clear(); _layoutDirty = true; @@ -172,11 +172,11 @@ class HomogeneousViewport extends RenderObjectWrapper { return itemCount != null ? itemCount * itemExtent : double.INFINITY; } - double getMinCrossAxisDimension(BoxConstraints constraints) { + double getMinCrossAxisExtent(BoxConstraints constraints) { return 0.0; } - double getMaxCrossAxisDimension(BoxConstraints constraints) { + double getMaxCrossAxisExtent(BoxConstraints constraints) { if (direction == ScrollDirection.vertical) return constraints.maxWidth; return constraints.maxHeight; diff --git a/packages/flutter/lib/src/widgets/mixed_viewport.dart b/packages/flutter/lib/src/widgets/mixed_viewport.dart index 2eab1222d3a..f855b6f27a2 100644 --- a/packages/flutter/lib/src/widgets/mixed_viewport.dart +++ b/packages/flutter/lib/src/widgets/mixed_viewport.dart @@ -98,17 +98,17 @@ class MixedViewport extends RenderObjectWrapper { // create it, because the render object is empty so it will not matter RenderBlockViewport result = new RenderBlockViewport(); result.callback = layout; - result.totalExtentCallback = _noIntrinsicDimensions; - result.maxCrossAxisDimensionCallback = _noIntrinsicDimensions; - result.minCrossAxisDimensionCallback = _noIntrinsicDimensions; + result.totalExtentCallback = _noIntrinsicExtent; + result.maxCrossAxisExtentCallback = _noIntrinsicExtent; + result.minCrossAxisExtentCallback = _noIntrinsicExtent; return result; } void remove() { renderObject.callback = null; renderObject.totalExtentCallback = null; - renderObject.maxCrossAxisDimensionCallback = null; - renderObject.minCrossAxisDimensionCallback = null; + renderObject.maxCrossAxisExtentCallback = null; + renderObject.minCrossAxisExtentCallback = null; super.remove(); _childrenByKey.clear(); layoutState._dirty = true; @@ -140,7 +140,7 @@ class MixedViewport extends RenderObjectWrapper { assert(renderObject == this.renderObject); // TODO(ianh): Remove this once the analyzer is cleverer } - double _noIntrinsicDimensions(BoxConstraints constraints) { + double _noIntrinsicExtent(BoxConstraints constraints) { assert(() { 'MixedViewport does not support returning intrinsic dimensions. ' + 'Calculating the intrinsic dimensions would require walking the entire child list, ' + @@ -330,7 +330,7 @@ class MixedViewport extends RenderObjectWrapper { 'all the children. You probably want to put the MixedViewport inside a Container with a fixed width.' is String); } final double endOffset = startOffset + extent; - + BoxConstraints innerConstraints; if (direction == ScrollDirection.vertical) { innerConstraints = new BoxConstraints.tightFor(width: constraints.constrainWidth());