positionMongolDependentBox function
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);
}