Beispiel #1
0
        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
                                             ));
        }
Beispiel #2
0
        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));
        }
Beispiel #5
0
        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));
            }
        }
Beispiel #6
0
        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);
        }
Beispiel #8
0
        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;
            }
        }
Beispiel #9
0
        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;
            }
        }
Beispiel #10
0
 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();
     }
 }
Beispiel #11
0
 Size _getSize(BoxConstraints constraints)
 {
     return(constraints.constrain(this._delegate.getSize(constraints)));
 }
Beispiel #12
0
        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;
            }
        }
Beispiel #13
0
        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)));
 }
Beispiel #15
0
        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));
        }
Beispiel #16
0
        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);
        }
Beispiel #17
0
        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);
        }