applyPositionedChildOffset static method

void applyPositionedChildOffset(
  1. RenderBoxModel parent,
  2. RenderBoxModel child
)

Implementation

static void applyPositionedChildOffset(
  RenderBoxModel parent,
  RenderBoxModel child,
) {
  final RenderLayoutParentData childParentData = child.parentData as RenderLayoutParentData;
  Size? parentSize = parent.boxSize;

  if (parent.isScrollingContentBox) {
    RenderLayoutBox overflowContainerBox = parent.parent as RenderLayoutBox;

    if(overflowContainerBox.widthSizeType == BoxSizeType.specified && overflowContainerBox.heightSizeType == BoxSizeType.specified) {
      parentSize = Size(
          overflowContainerBox.renderStyle.width.computedValue,
          overflowContainerBox.renderStyle.height.computedValue
      );
    } else {
      parentSize = parent.boxSize;
    }
  } else {
    parentSize = parent.boxSize;
  }

  // Calc x,y by parentData.
  double? x, y;

  double? childMarginTop = 0;
  double? childMarginBottom = 0;
  double? childMarginLeft = 0;
  double? childMarginRight = 0;

  RenderStyle childRenderStyle = child.renderStyle;
  childMarginTop = childRenderStyle.marginTop.computedValue;
  childMarginBottom = childRenderStyle.marginBottom.computedValue;
  childMarginLeft = childRenderStyle.marginLeft.computedValue;
  childMarginRight = childRenderStyle.marginRight.computedValue;

  // Offset to global coordinate system of base.
  if (childParentData.isPositioned) {
    EdgeInsets borderEdge = parent.renderStyle.border;
    double borderLeft = borderEdge.left;
    double borderRight = borderEdge.right;
    double borderTop = borderEdge.top;
    double borderBottom = borderEdge.bottom;
    RenderStyle childRenderStyle = child.renderStyle;
    Offset? placeholderOffset;

    // ScrollTop and scrollLeft will be added to offset of renderBox in the paint stage
    // for positioned fixed element.
    if (child.renderStyle.position == CSSPositionType.fixed) {
      Element rootElement = parent.renderStyle.target;
      child.scrollingOffsetX = rootElement.scrollLeft;
      child.scrollingOffsetY = rootElement.scrollTop;
    }

    double top;
    if (childRenderStyle.top.isNotAuto) {
      top = childRenderStyle.top.computedValue + borderTop + childMarginTop;

      if (parent.isScrollingContentBox) {
        RenderLayoutBox overflowContainingBox = parent.parent as RenderLayoutBox;
        top -= overflowContainingBox.renderStyle.paddingTop.computedValue;
      }
    } else if (childRenderStyle.bottom.isNotAuto) {
      top = parentSize!.height - child.boxSize!.height - borderBottom - childMarginBottom - childRenderStyle.bottom.computedValue;

      if (parent.isScrollingContentBox) {
        RenderLayoutBox overflowContainingBox = parent.parent as RenderLayoutBox;
        top -= (overflowContainingBox.renderStyle.effectiveBorderTopWidth.computedValue + overflowContainingBox.renderStyle.effectiveBorderBottomWidth.computedValue
            + overflowContainingBox.renderStyle.paddingTop.computedValue);
      }
    } else {
      placeholderOffset = _getPlaceholderToParentOffset(child.renderPositionPlaceholder!, parent);
      // Use original offset in normal flow if no top and bottom is set.
      top = placeholderOffset.dy;
    }

    double left;
    if (childRenderStyle.left.isNotAuto) {
      left = childRenderStyle.left.computedValue + borderLeft + childMarginLeft;

      if (parent.isScrollingContentBox) {
        RenderLayoutBox overflowContainingBox = parent.parent as RenderLayoutBox;
        left -= overflowContainingBox.renderStyle.paddingLeft.computedValue;
      }
    } else if (childRenderStyle.right.isNotAuto) {
      left = parentSize!.width - child.boxSize!.width - borderRight - childMarginRight - childRenderStyle.right.computedValue;

      if (parent.isScrollingContentBox) {
        RenderLayoutBox overflowContainingBox = parent.parent as RenderLayoutBox;
        left -= (overflowContainingBox.renderStyle.effectiveBorderLeftWidth.computedValue + overflowContainingBox.renderStyle.effectiveBorderRightWidth.computedValue
          + overflowContainingBox.renderStyle.paddingLeft.computedValue);
      }
    } else {
      placeholderOffset ??= _getPlaceholderToParentOffset(child.renderPositionPlaceholder!, parent);
      // Use original offset in normal flow if no left and right is set.
      left = placeholderOffset.dx;
    }

    x = left;
    y = top;
  }

  Offset offset = _getAutoMarginPositionedElementOffset(x, y, child, parentSize!);
  childParentData.offset = offset;
}