positionMongolDependentBox function

Offset positionMongolDependentBox({
  1. required Size size,
  2. required Size childSize,
  3. required Offset target,
  4. required bool preferRight,
  5. double horizontalOffset = 0.0,
  6. double margin = 10.0,
})

Position a child box within a container box, either left or right of a target point.

The container's size is described by size.

The target point is specified by target, as an offset from the top left of the container.

The child box's size is given by childSize.

The return value is the suggested distance from the top left of the container box to the top left of the child box.

The suggested position will be to the left of the target point if preferRight is false, and to the right of the target point if it is true, unless it wouldn't fit on the preferred side but would fit on the other side.

The suggested position will place the nearest side of the child to the target point horizontalOffset from the target point (even if it cannot fit given that constraint).

The suggested position will be at least margin away from the edge of the container. If possible, the child will be positioned so that its center is aligned with the target point. If the child cannot fit vertically within the container given the margin, then the child will be centered in the container.

Used by MongolTooltip to position a tooltip relative to its parent.

The arguments must not be null.

Implementation

Offset positionMongolDependentBox({
  required Size size,
  required Size childSize,
  required Offset target,
  required bool preferRight,
  double horizontalOffset = 0.0,
  double margin = 10.0,
}) {
  // HORIZONTAL DIRECTION
  final bool fitsRight =
      target.dx + horizontalOffset + childSize.width <= size.width - margin;
  final bool fitsLeft =
      target.dx - horizontalOffset - childSize.width >= margin;
  final bool tooltipRight =
      preferRight ? fitsRight || !fitsLeft : !(fitsLeft || !fitsRight);
  double x;
  if (tooltipRight) {
    x = math.min(target.dx + horizontalOffset, size.width - margin);
  } else {
    x = math.max(target.dx - horizontalOffset - childSize.width, margin);
  }
  // VERTICAL DIRECTION
  double y;
  if (size.height - margin * 2.0 < childSize.height) {
    y = (size.height - childSize.height) / 2.0;
  } else {
    final double normalizedTargetY =
        target.dy.clamp(margin, size.height - margin);
    final double edge = margin + childSize.height / 2.0;
    if (normalizedTargetY < edge) {
      y = margin;
    } else if (normalizedTargetY > size.height - edge) {
      y = size.height - margin - childSize.height;
    } else {
      y = normalizedTargetY - childSize.height / 2.0;
    }
  }
  return Offset(x, y);
}