protected override void performLayout() { BoxConstraints constraints = this.constraints; _resolve(); D.assert(_resolvedPadding != null); if (child == null) { size = constraints.constrain(new Size( _resolvedPadding.left + _resolvedPadding.right, _resolvedPadding.top + _resolvedPadding.bottom )); return; } BoxConstraints innerConstraints = constraints.deflate(_resolvedPadding); child.layout(innerConstraints, parentUsesSize: true); BoxParentData childParentData = child.parentData as BoxParentData; childParentData.offset = new Offset(_resolvedPadding.left, _resolvedPadding.top); size = constraints.constrain(new Size( _resolvedPadding.left + child.size.width + _resolvedPadding.right, _resolvedPadding.top + child.size.height + _resolvedPadding.bottom )); }
protected override void performLayout() { BoxConstraints constraints = this.constraints; float maxHeight = CupertinoSegmentedControlsUtils._kMinSegmentedControlHeight; float childWidth = constraints.minWidth / childCount; foreach (RenderBox child in getChildrenAsList()) { childWidth = Mathf.Max(childWidth, child.getMaxIntrinsicWidth(float.PositiveInfinity)); } childWidth = Mathf.Min(childWidth, constraints.maxWidth / childCount); RenderBox child1 = firstChild; while (child1 != null) { float boxHeight = child1.getMaxIntrinsicHeight(childWidth); maxHeight = Mathf.Max(maxHeight, boxHeight); child1 = childAfter(child1); } constraints.constrainHeight(maxHeight); BoxConstraints childConstraints = BoxConstraints.tightFor( width: childWidth, height: maxHeight ); child1 = firstChild; while (child1 != null) { child1.layout(childConstraints, parentUsesSize: true); child1 = childAfter(child1); } switch (textDirection) { case TextDirection.rtl: _layoutRects( childBefore, lastChild, firstChild ); break; case TextDirection.ltr: _layoutRects( childAfter, firstChild, lastChild ); break; } size = constraints.constrain(new Size(childWidth * childCount, maxHeight)); }
protected override void performLayout() { BoxConstraints constraints = this.constraints; BoxConstraints innerConstraints = constraints.copyWith(maxHeight: float.PositiveInfinity); child.layout(innerConstraints, parentUsesSize: true); size = constraints.constrain(child.size); alignChild(); }
protected override void performLayout() { BoxConstraints constraints = this.constraints; float childWidth = (constraints.minWidth - totalSeparatorWidth) / childCount; float maxHeight = CupertinoSlidingSegmentedControlsUtils._kMinSegmentedControlHeight; foreach (RenderBox child1 in getChildrenAsList()) { childWidth = Mathf.Max(childWidth, child1.getMaxIntrinsicWidth(float.PositiveInfinity) + 2 * CupertinoSlidingSegmentedControlsUtils._kSegmentMinPadding); } childWidth = Mathf.Min( childWidth, (constraints.maxWidth - totalSeparatorWidth) / childCount ); RenderBox child = firstChild; while (child != null) { float boxHeight = child.getMaxIntrinsicHeight(childWidth); maxHeight = Mathf.Max(maxHeight, boxHeight); child = childAfter(child); } constraints.constrainHeight(maxHeight); BoxConstraints childConstraints = BoxConstraints.tightFor( width: childWidth, height: maxHeight ); // Layout children. child = firstChild; while (child != null) { child.layout(childConstraints, parentUsesSize: true); child = childAfter(child); } float start = 0; child = firstChild; while (child != null) { _SlidingSegmentedControlContainerBoxParentData childParentData = child.parentData as _SlidingSegmentedControlContainerBoxParentData; Offset childOffset = new Offset(start, 0); childParentData.offset = childOffset; start += child.size.width + CupertinoSlidingSegmentedControlsUtils._kSeparatorWidth + CupertinoSlidingSegmentedControlsUtils._kSeparatorInset.horizontal; child = childAfter(child); } size = constraints.constrain(new Size(childWidth * childCount + totalSeparatorWidth, maxHeight)); }
protected override void performLayout() { BoxConstraints constraints = this.constraints; bool shrinkWrapWidth = _widthFactor != null || float.IsPositiveInfinity(constraints.maxWidth); bool shrinkWrapHeight = _heightFactor != null || float.IsPositiveInfinity(constraints.maxHeight); if (child != null) { child.layout(constraints.loosen(), parentUsesSize: true); size = constraints.constrain(new Size( shrinkWrapWidth ? child.size.width * (_widthFactor ?? 1.0f) : float.PositiveInfinity, shrinkWrapHeight ? child.size.height * (_heightFactor ?? 1.0f) : float.PositiveInfinity)); alignChild(); } else { size = constraints.constrain(new Size( shrinkWrapWidth ? 0.0f : float.PositiveInfinity, shrinkWrapHeight ? 0.0f : float.PositiveInfinity)); } }
protected override void performLayout() { BoxConstraints constraints = this.constraints; if (child != null) { BoxConstraints childConstraints = null; if (constrainedAxis != null) { switch (constrainedAxis) { case Axis.horizontal: childConstraints = new BoxConstraints( maxWidth: constraints.maxWidth, minWidth: constraints.minWidth); break; case Axis.vertical: childConstraints = new BoxConstraints( maxHeight: constraints.maxHeight, minHeight: constraints.minHeight); break; } } else { childConstraints = new BoxConstraints(); } child.layout(childConstraints, parentUsesSize: true); size = constraints.constrain(child.size); alignChild(); var childParentData = (BoxParentData)child.parentData; _overflowContainerRect = Offset.zero & size; _overflowChildRect = childParentData.offset & child.size; } else { size = constraints.smallest; _overflowContainerRect = Rect.zero; _overflowChildRect = Rect.zero; } _isOverflowing = RelativeRect.fromRect( _overflowContainerRect, _overflowChildRect).hasInsets; }
protected override void performLayout() { BoxConstraints constraints = this.constraints; if (child == null) { size = constraints.smallest; } else { child.layout(_getInnerConstraints(constraints), parentUsesSize: true); size = constraints.constrain(child.size); } offset.applyViewportDimension(_viewportExtent); offset.applyContentDimensions(_minScrollExtent, _maxScrollExtent); }
protected override void performLayout() { _lastValue = _controller.value; _hasVisualOverflow = false; BoxConstraints constraints = this.constraints; if (child == null || constraints.isTight) { _controller.stop(); size = _sizeTween.begin = _sizeTween.end = constraints.smallest; _state = RenderAnimatedSizeState.start; child?.layout(constraints); return; } child.layout(constraints, parentUsesSize: true); switch (_state) { case RenderAnimatedSizeState.start: _layoutStart(); break; case RenderAnimatedSizeState.stable: _layoutStable(); break; case RenderAnimatedSizeState.changed: _layoutChanged(); break; case RenderAnimatedSizeState.unstable: _layoutUnstable(); break; } size = constraints.constrain(_animatedSize); alignChild(); if (size.width < _sizeTween.end.width || size.height < _sizeTween.end.height) { _hasVisualOverflow = true; } }
protected override void performLayout() { BoxConstraints constraints = this.constraints; if (child != null) { child.layout(constraints, parentUsesSize: true); float height = Mathf.Max(child.size.width, minSize.width); float width = Mathf.Max(child.size.height, minSize.height); size = constraints.constrain(new Size(height, width)); BoxParentData childParentData = child.parentData as BoxParentData; childParentData.offset = Alignment.center.alongOffset(size - child.size as Offset); } else { size = Size.zero; } }
protected override void performLayout() { if (child != null) { BoxConstraints constraints = this.constraints; child.layout(constraints.loosen(), parentUsesSize: true); float?childBaseline = child.getDistanceToBaseline(baselineType); float actualBaseline = baseline; float top = actualBaseline - (childBaseline ?? 0.0f); var childParentData = (BoxParentData)child.parentData; childParentData.offset = new Offset(0.0f, top); Size childSize = child.size; size = constraints.constrain(new Size(childSize.width, top + childSize.height)); } else { performResize(); } }
Size _getSize(BoxConstraints constraints) { return(constraints.constrain(this._delegate.getSize(constraints))); }
protected override void performLayout() { D.assert(_debugHasNecessaryDirections); BoxConstraints constraints = this.constraints; int totalFlex = 0; int totalChildren = 0; D.assert(constraints != null); float maxMainSize = _direction == Axis.horizontal ? constraints.maxWidth : constraints.maxHeight; bool canFlex = maxMainSize < float.PositiveInfinity; float crossSize = 0.0f; float allocatedSize = 0.0f; RenderBox child = firstChild; RenderBox lastFlexChild = null; while (child != null) { var childParentData = (FlexParentData)child.parentData; totalChildren++; int flex = _getFlex(child); if (flex > 0) { totalFlex += childParentData.flex; lastFlexChild = child; } else { BoxConstraints innerConstraints = null; if (crossAxisAlignment == CrossAxisAlignment.stretch) { switch (_direction) { case Axis.horizontal: innerConstraints = new BoxConstraints( minHeight: constraints.maxHeight, maxHeight: constraints.maxHeight); break; case Axis.vertical: innerConstraints = new BoxConstraints( minWidth: constraints.maxWidth, maxWidth: constraints.maxWidth); break; } } else { switch (_direction) { case Axis.horizontal: innerConstraints = new BoxConstraints( maxHeight: constraints.maxHeight); break; case Axis.vertical: innerConstraints = new BoxConstraints( maxWidth: constraints.maxWidth); break; } } child.layout(innerConstraints, parentUsesSize: true); allocatedSize += _getMainSize(child); crossSize = Mathf.Max(crossSize, _getCrossSize(child)); } D.assert(child.parentData == childParentData); child = childParentData.nextSibling; } float freeSpace = Mathf.Max(0.0f, (canFlex ? maxMainSize : 0.0f) - allocatedSize); float allocatedFlexSpace = 0.0f; float maxBaselineDistance = 0.0f; if (totalFlex > 0 || crossAxisAlignment == CrossAxisAlignment.baseline) { float spacePerFlex = canFlex && totalFlex > 0 ? (freeSpace / totalFlex) : float.NaN; child = firstChild; float maxSizeAboveBaseline = 0; float maxSizeBelowBaseline = 0; while (child != null) { int flex = _getFlex(child); if (flex > 0) { float maxChildExtent = canFlex ? (child == lastFlexChild ? (freeSpace - allocatedFlexSpace) : spacePerFlex * flex) : float.PositiveInfinity; float minChildExtent = 0.0f; switch (_getFit(child)) { case FlexFit.tight: minChildExtent = maxChildExtent; break; case FlexFit.loose: minChildExtent = 0.0f; break; } BoxConstraints innerConstraints = null; if (crossAxisAlignment == CrossAxisAlignment.stretch) { switch (_direction) { case Axis.horizontal: innerConstraints = new BoxConstraints( minWidth: minChildExtent, maxWidth: maxChildExtent, minHeight: constraints.maxHeight, maxHeight: constraints.maxHeight); break; case Axis.vertical: innerConstraints = new BoxConstraints( minWidth: constraints.maxWidth, maxWidth: constraints.maxWidth, minHeight: minChildExtent, maxHeight: maxChildExtent); break; } } else { switch (_direction) { case Axis.horizontal: innerConstraints = new BoxConstraints( minWidth: minChildExtent, maxWidth: maxChildExtent, maxHeight: constraints.maxHeight); break; case Axis.vertical: innerConstraints = new BoxConstraints( maxWidth: constraints.maxWidth, minHeight: minChildExtent, maxHeight: maxChildExtent); break; } } child.layout(innerConstraints, parentUsesSize: true); float childSize = _getMainSize(child); allocatedSize += childSize; allocatedFlexSpace += maxChildExtent; crossSize = Mathf.Max(crossSize, _getCrossSize(child)); } if (crossAxisAlignment == CrossAxisAlignment.baseline) { float?distance = child.getDistanceToBaseline(textBaseline, onlyReal: true); if (distance != null) { maxBaselineDistance = Mathf.Max(maxBaselineDistance, distance.Value); maxSizeAboveBaseline = Mathf.Max(distance.Value, maxSizeAboveBaseline); maxSizeBelowBaseline = Mathf.Max(child.size.height - distance.Value, maxSizeBelowBaseline); crossSize = maxSizeAboveBaseline + maxSizeBelowBaseline; } } var childParentData = (FlexParentData)child.parentData; child = childParentData.nextSibling; } } float idealSize = canFlex && mainAxisSize == MainAxisSize.max ? maxMainSize : allocatedSize; float actualSize = 0.0f; float actualSizeDelta = 0.0f; switch (_direction) { case Axis.horizontal: size = constraints.constrain(new Size(idealSize, crossSize)); actualSize = size.width; crossSize = size.height; break; case Axis.vertical: size = constraints.constrain(new Size(crossSize, idealSize)); actualSize = size.height; crossSize = size.width; break; } actualSizeDelta = actualSize - allocatedSize; _overflow = Mathf.Max(0.0f, -actualSizeDelta); float remainingSpace = Mathf.Max(0.0f, actualSizeDelta); float leadingSpace = 0.0f; float betweenSpace = 0.0f; bool flipMainAxis = !_startIsTopLeft(direction, textDirection, verticalDirection); switch (_mainAxisAlignment) { case MainAxisAlignment.start: leadingSpace = 0.0f; betweenSpace = 0.0f; break; case MainAxisAlignment.end: leadingSpace = remainingSpace; betweenSpace = 0.0f; break; case MainAxisAlignment.center: leadingSpace = remainingSpace / 2.0f; betweenSpace = 0.0f; break; case MainAxisAlignment.spaceBetween: leadingSpace = 0.0f; betweenSpace = totalChildren > 1 ? remainingSpace / (totalChildren - 1) : 0.0f; break; case MainAxisAlignment.spaceAround: betweenSpace = totalChildren > 0 ? remainingSpace / totalChildren : 0.0f; leadingSpace = betweenSpace / 2.0f; break; case MainAxisAlignment.spaceEvenly: betweenSpace = totalChildren > 0 ? remainingSpace / (totalChildren + 1) : 0.0f; leadingSpace = betweenSpace; break; } // Position elements float childMainPosition = flipMainAxis ? actualSize - leadingSpace : leadingSpace; child = firstChild; while (child != null) { var childParentData = (FlexParentData)child.parentData; float childCrossPosition = 0.0f; switch (_crossAxisAlignment) { case CrossAxisAlignment.start: case CrossAxisAlignment.end: childCrossPosition = _startIsTopLeft( AxisUtils.flipAxis(direction), textDirection, verticalDirection) == (_crossAxisAlignment == CrossAxisAlignment.start) ? 0.0f : crossSize - _getCrossSize(child); break; case CrossAxisAlignment.center: childCrossPosition = crossSize / 2.0f - _getCrossSize(child) / 2.0f; break; case CrossAxisAlignment.stretch: childCrossPosition = 0.0f; break; case CrossAxisAlignment.baseline: childCrossPosition = 0.0f; if (_direction == Axis.horizontal) { float?distance = child.getDistanceToBaseline(textBaseline, onlyReal: true); if (distance != null) { childCrossPosition = maxBaselineDistance - distance.Value; } } break; } if (flipMainAxis) { childMainPosition -= _getMainSize(child); } switch (_direction) { case Axis.horizontal: childParentData.offset = new Offset(childMainPosition, childCrossPosition); break; case Axis.vertical: childParentData.offset = new Offset(childCrossPosition, childMainPosition); break; } if (flipMainAxis) { childMainPosition -= betweenSpace; } else { childMainPosition += _getMainSize(child) + betweenSpace; } child = childParentData.nextSibling; } }
protected override void performLayout() { BoxConstraints constraints = this.constraints; _layoutChildren(constraints); _layoutTextWithConstraints(constraints); _setParentData(); var textSize = _textPainter.size; var textDidExceedMaxLines = _textPainter.didExceedMaxLines; size = constraints.constrain(textSize); var didOverflowHeight = size.height < textSize.height || textDidExceedMaxLines; var didOverflowWidth = size.width < textSize.width; var hasVisualOverflow = didOverflowWidth || didOverflowHeight; if (hasVisualOverflow) { switch (_overflow) { case TextOverflow.visible: _needsClipping = false; _overflowShader = null; break; case TextOverflow.clip: case TextOverflow.ellipsis: _needsClipping = true; _overflowShader = null; break; case TextOverflow.fade: D.assert(textDirection != null); _needsClipping = true; TextPainter fadeSizePainter = new TextPainter( text: new TextSpan(style: _textPainter.text.style, text: "\u2026"), textDirection: textDirection.Value, textScaleFactor: textScaleFactor, locale: locale ); fadeSizePainter.layout(); if (didOverflowWidth) { float fadeEnd = 0, fadeStart = 0; switch (textDirection) { case TextDirection.rtl: fadeEnd = 0.0f; fadeStart = fadeSizePainter.width; break; case TextDirection.ltr: fadeEnd = size.width; fadeStart = fadeEnd - fadeSizePainter.width; break; } _overflowShader = ui.Gradient.linear( new Offset(fadeStart, 0.0f), new Offset(fadeEnd, 0.0f), new List <Color> { new Color(0xFFFFFFFF), new Color(0x00FFFFFF) } ); } else { float fadeEnd = size.height; float fadeStart = fadeEnd - fadeSizePainter.height / 2.0f; _overflowShader = ui.Gradient.linear( new Offset(0.0f, fadeStart), new Offset(0.0f, fadeEnd), new List <Color> { new Color(0xFFFFFFFF), new Color(0x00FFFFFF) } ); } break; } } else { _needsClipping = false; _overflowShader = null; } }
Size _getSize(BoxConstraints constraints) { D.assert(constraints.debugAssertIsValid()); return(constraints.constrain(this._delegate.getSize(constraints))); }
protected override void performLayout() { BoxConstraints constraints = this.constraints; bool hasLeading = leading != null; bool hasSubtitle = subtitle != null; bool hasTrailing = trailing != null; bool isTwoLine = !isThreeLine && hasSubtitle; bool isOneLine = !isThreeLine && !hasSubtitle; BoxConstraints maxIconHeightConstrains = new BoxConstraints( maxHeight: isDense ? 48.0f : 56.0f ); BoxConstraints looseConstraints = constraints.loosen(); BoxConstraints iconConstraints = looseConstraints.enforce(maxIconHeightConstrains); float tileWidth = looseConstraints.maxWidth; Size leadingSize = _layoutBox(leading, iconConstraints); Size trailingSize = _layoutBox(trailing, iconConstraints); D.assert( tileWidth != leadingSize.width, () => "Leading widget consumes entire width. Please use a sized widget." ); D.assert( tileWidth != trailingSize.width, () => "Trailing widget consumes entire width. Please use a sized widget." ); float titleStart = hasLeading ? Mathf.Max(_minLeadingWidth, leadingSize.width) + _horizontalTitleGap : 0.0f; BoxConstraints textConstraints = looseConstraints.tighten( width: tileWidth - titleStart - (hasTrailing ? trailingSize.width + _horizontalTitleGap : 0.0f)); Size titleSize = _layoutBox(title, textConstraints); Size subtitleSize = _layoutBox(subtitle, textConstraints); float titleBaseline = 0.0f; float subtitleBaseline = 0.0f; if (isTwoLine) { titleBaseline = isDense ? 28.0f : 32.0f; subtitleBaseline = isDense ? 48.0f : 52.0f; } else if (isThreeLine) { titleBaseline = isDense ? 22.0f : 28.0f; subtitleBaseline = isDense ? 42.0f : 48.0f; } else { D.assert(isOneLine); } float defaultTileHeight = _defaultTileHeight; float tileHeight = 0.0f; float titleY = 0.0f; float subtitleY = 0.0f; if (!hasSubtitle) { tileHeight = Mathf.Max(defaultTileHeight, titleSize.height + 2.0f * _minVerticalPadding); titleY = (tileHeight - titleSize.height) / 2.0f; } else { D.assert(subtitleBaselineType != null); titleY = titleBaseline - _boxBaseline(title, titleBaselineType); subtitleY = subtitleBaseline - _boxBaseline(subtitle, subtitleBaselineType ?? TextBaseline.alphabetic); tileHeight = defaultTileHeight; float titleOverlap = titleY + titleSize.height - subtitleY; if (titleOverlap > 0.0f) { titleY -= titleOverlap / 2.0f; subtitleY += titleOverlap / 2.0f; } if (titleY < _minVerticalPadding || (subtitleY + subtitleSize.height + _minVerticalPadding) > tileHeight) { tileHeight = titleSize.height + subtitleSize.height + 2.0f * _minVerticalPadding; titleY = _minVerticalPadding; subtitleY = titleSize.height + _minVerticalPadding; } } float leadingY; float trailingY; if (tileHeight > 72.0f) { leadingY = 16.0f; trailingY = 16.0f; } else { leadingY = Mathf.Min((tileHeight - leadingSize.height) / 2.0f, 16.0f); trailingY = (tileHeight - trailingSize.height) / 2.0f; } if (hasLeading) { _positionBox(leading, new Offset(0.0f, leadingY)); } _positionBox(title, new Offset(titleStart, titleY)); if (hasSubtitle) { _positionBox(subtitle, new Offset(titleStart, subtitleY)); } if (hasTrailing) { _positionBox(trailing, new Offset(tileWidth - trailingSize.width, trailingY)); } size = constraints.constrain(new Size(tileWidth, tileHeight)); D.assert(size.width == constraints.constrainWidth(tileWidth)); D.assert(size.height == constraints.constrainHeight(tileHeight)); }
protected override void performLayout() { BoxConstraints constraints = this.constraints; D.assert(() => { switch (mainAxis) { case Axis.horizontal: if (!constraints.hasBoundedWidth) { return(true); } break; case Axis.vertical: if (!constraints.hasBoundedHeight) { return(true); } break; } throw new UIWidgetsError(new List <DiagnosticsNode> { new ErrorSummary("RenderListBody must have unlimited space along its main axis."), new ErrorDescription( "RenderListBody does not clip or resize its children, so it must be " + "placed in a parent that does not constrain the main axis." ), new ErrorHint( "You probably want to put the RenderListBody inside a " + "RenderViewport with a matching main axis." ) }); }); D.assert(() => { switch (mainAxis) { case Axis.horizontal: if (constraints.hasBoundedHeight) { return(true); } break; case Axis.vertical: if (constraints.hasBoundedWidth) { return(true); } break; } throw new UIWidgetsError(new List <DiagnosticsNode> { new ErrorSummary("RenderListBody must have a bounded constraint for its cross axis."), new ErrorDescription( "RenderListBody forces its children to expand to fit the RenderListBody's container, " + "so it must be placed in a parent that constrains the cross " + "axis to a finite dimension." ), // TODO(jacobr): this hint is a great candidate to promote to being an // automated quick fix in the future. new ErrorHint( "If you are attempting to nest a RenderListBody with " + "one direction inside one of another direction, you will want to " + "wrap the inner one inside a box that fixes the dimension in that direction, " + "for example, a RenderIntrinsicWidth or RenderIntrinsicHeight object. " + "This is relatively expensive, however." // (that's why we don't do it automatically) ) }); }); float mainAxisExtent = 0.0f; RenderBox child = firstChild; BoxConstraints innerConstraints; float position; switch (axisDirection) { case AxisDirection.right: innerConstraints = BoxConstraints.tightFor(height: constraints.maxHeight); while (child != null) { child.layout(innerConstraints, parentUsesSize: true); ListBodyParentData childParentData = (ListBodyParentData)child.parentData; childParentData.offset = new Offset(mainAxisExtent, 0.0f); mainAxisExtent += child.size.width; D.assert(child.parentData == childParentData); child = childParentData.nextSibling; } size = constraints.constrain(new Size(mainAxisExtent, constraints.maxHeight)); break; case AxisDirection.left: innerConstraints = BoxConstraints.tightFor(height: constraints.maxHeight); while (child != null) { child.layout(innerConstraints, parentUsesSize: true); ListBodyParentData childParentData = (ListBodyParentData)child.parentData; mainAxisExtent += child.size.width; D.assert(child.parentData == childParentData); child = childParentData.nextSibling; } position = 0.0f; child = firstChild; while (child != null) { ListBodyParentData childParentData = (ListBodyParentData)child.parentData; position += child.size.width; childParentData.offset = new Offset((mainAxisExtent - position), 0.0f); D.assert(child.parentData == childParentData); child = childParentData.nextSibling; } size = constraints.constrain(new Size(mainAxisExtent, constraints.maxHeight)); break; case AxisDirection.down: innerConstraints = BoxConstraints.tightFor(width: constraints.maxWidth); while (child != null) { child.layout(innerConstraints, parentUsesSize: true); ListBodyParentData childParentData = (ListBodyParentData)child.parentData; childParentData.offset = new Offset(0.0f, mainAxisExtent); mainAxisExtent += child.size.height; D.assert(child.parentData == childParentData); child = childParentData.nextSibling; } size = constraints.constrain(new Size(constraints.maxWidth, mainAxisExtent)); break; case AxisDirection.up: innerConstraints = BoxConstraints.tightFor(width: constraints.maxWidth); while (child != null) { child.layout(innerConstraints, parentUsesSize: true); ListBodyParentData childParentData = (ListBodyParentData)child.parentData; mainAxisExtent += child.size.height; D.assert(child.parentData == childParentData); child = childParentData.nextSibling; } position = 0.0f; child = firstChild; while (child != null) { ListBodyParentData childParentData = (ListBodyParentData)child.parentData; position += child.size.height; childParentData.offset = new Offset(0.0f, mainAxisExtent - position); D.assert(child.parentData == childParentData); child = childParentData.nextSibling; } size = constraints.constrain(new Size(constraints.maxWidth, mainAxisExtent)); break; } D.assert(size.isFinite); }
protected override void performLayout() { BoxConstraints constraints = this.constraints; int rows = this.rows; int columns = this.columns; D.assert(_children.Count == rows * columns); if (rows * columns == 0) { size = constraints.constrain(new Size(0.0f, 0.0f)); return; } List <float> widths = _computeColumnWidths(constraints); List <float> positions = new List <float>(); for (int i = 0; i < columns; i++) { positions.Add(0.0f); } float tableWidth = 0.0f; switch (textDirection) { case TextDirection.rtl: positions[columns - 1] = 0.0f; for (int x = columns - 2; x >= 0; x -= 1) { positions[x] = positions[x + 1] + widths[x + 1]; } _columnLefts = positions; tableWidth = positions[0] + widths[0]; break; case TextDirection.ltr: positions[0] = 0.0f; for (int x = 1; x < columns; x += 1) { positions[x] = positions[x - 1] + widths[x - 1]; } _columnLefts = positions; tableWidth = positions[columns - 1] + widths[columns - 1]; break; } _rowTops.Clear(); _baselineDistance = null; float rowTop = 0.0f; for (int y = 0; y < rows; y++) { _rowTops.Add(rowTop); float rowHeight = 0.0f; bool haveBaseline = false; float beforeBaselineDistance = 0.0f; float afterBaselineDistance = 0.0f; List <float?> baselines = new List <float?>(); for (int i = 0; i < columns; i++) { baselines.Add(null); } for (int x = 0; x < columns; x++) { int xy = x + y * columns; RenderBox child = _children[xy]; if (child != null) { TableCellParentData childParentData = (TableCellParentData)child.parentData; D.assert(childParentData != null); childParentData.x = x; childParentData.y = y; switch (childParentData.verticalAlignment ?? defaultVerticalAlignment) { case TableCellVerticalAlignment.baseline: { D.assert(textBaseline != null); child.layout(BoxConstraints.tightFor(width: widths[x]), parentUsesSize: true); float?childBaseline = child.getDistanceToBaseline(textBaseline.Value, onlyReal: true); if (childBaseline != null) { beforeBaselineDistance = Mathf.Max(beforeBaselineDistance, childBaseline.Value); afterBaselineDistance = Mathf.Max(afterBaselineDistance, child.size.height - childBaseline.Value); baselines[x] = childBaseline.Value; haveBaseline = true; } else { rowHeight = Mathf.Max(rowHeight, child.size.height); childParentData.offset = new Offset(positions[x], rowTop); } break; } case TableCellVerticalAlignment.top: case TableCellVerticalAlignment.middle: case TableCellVerticalAlignment.bottom: { child.layout(BoxConstraints.tightFor(width: widths[x]), parentUsesSize: true); rowHeight = Mathf.Max(rowHeight, child.size.height); break; } case TableCellVerticalAlignment.fill: { break; } } } } if (haveBaseline) { if (y == 0) { _baselineDistance = beforeBaselineDistance; } rowHeight = Mathf.Max(rowHeight, beforeBaselineDistance + afterBaselineDistance); } for (int x = 0; x < columns; x++) { int xy = x + y * columns; RenderBox child = _children[xy]; if (child != null) { TableCellParentData childParentData = (TableCellParentData)child.parentData; switch (childParentData.verticalAlignment ?? defaultVerticalAlignment) { case TableCellVerticalAlignment.baseline: { if (baselines[x] != null) { childParentData.offset = new Offset(positions[x], rowTop + beforeBaselineDistance - baselines[x].Value); } break; } case TableCellVerticalAlignment.top: { childParentData.offset = new Offset(positions[x], rowTop); break; } case TableCellVerticalAlignment.middle: { childParentData.offset = new Offset(positions[x], rowTop + (rowHeight - child.size.height) / 2.0f); break; } case TableCellVerticalAlignment.bottom: { childParentData.offset = new Offset(positions[x], rowTop + rowHeight - child.size.height); break; } case TableCellVerticalAlignment.fill: { child.layout(BoxConstraints.tightFor(width: widths[x], height: rowHeight)); childParentData.offset = new Offset(positions[x], rowTop); break; } } } } rowTop += rowHeight; } _rowTops.Add(rowTop); size = constraints.constrain(new Size(tableWidth, rowTop)); D.assert(_rowTops.Count == rows + 1); }