calculateTooltipPosition function

Offset calculateTooltipPosition({
  1. required Offset anchorPosition,
  2. required Size anchorSize,
  3. required Size tooltipSize,
  4. required Size screenSize,
  5. required UITooltipPlacement placement,
  6. double offset = 16.0,
  7. double margin = 16.0,
})

Implementation

Offset calculateTooltipPosition({
  required Offset anchorPosition,
  required Size anchorSize,
  required Size tooltipSize,
  required Size screenSize,
  required UITooltipPlacement placement,
  double offset = 16.0,
  double margin = 16.0,
}) {
  // Initial position variables
  double left = 0.0;
  double top = 0.0;

  // Calculate position based on requested placement
  switch (placement) {
    // TOP placements (tooltip above anchor)
    case UITooltipPlacement.TOP_CENTER:
      left = anchorPosition.dx + (anchorSize.width - tooltipSize.width) / 2;
      top = anchorPosition.dy - tooltipSize.height - offset;
      break;
    case UITooltipPlacement.TOP_START:
      left = anchorPosition.dx;
      top = anchorPosition.dy - tooltipSize.height - offset;
      break;
    case UITooltipPlacement.TOP_END:
      left = anchorPosition.dx + anchorSize.width - tooltipSize.width;
      top = anchorPosition.dy - tooltipSize.height - offset;
      break;

    // BOTTOM placements (tooltip below anchor)
    case UITooltipPlacement.BOTTOM_CENTER:
      left = anchorPosition.dx + (anchorSize.width - tooltipSize.width) / 2;
      top = anchorPosition.dy + anchorSize.height + offset;
      break;
    case UITooltipPlacement.BOTTOM_START:
      left = anchorPosition.dx;
      top = anchorPosition.dy + anchorSize.height + offset;
      break;
    case UITooltipPlacement.BOTTOM_END:
      left = anchorPosition.dx + anchorSize.width - tooltipSize.width;
      top = anchorPosition.dy + anchorSize.height + offset;
      break;

    // LEFT placements (tooltip to the left of anchor)
    case UITooltipPlacement.LEFT_CENTER:
      left = anchorPosition.dx - tooltipSize.width - offset;
      top = anchorPosition.dy + (anchorSize.height - tooltipSize.height) / 2;
      break;
    case UITooltipPlacement.LEFT_START:
      left = anchorPosition.dx - tooltipSize.width - offset;
      top = anchorPosition.dy;
      break;
    case UITooltipPlacement.LEFT_END:
      left = anchorPosition.dx - tooltipSize.width - offset;
      top = anchorPosition.dy + anchorSize.height - tooltipSize.height;
      break;

    // RIGHT placements (tooltip to the right of anchor)
    case UITooltipPlacement.RIGHT_CENTER:
      left = anchorPosition.dx + anchorSize.width + offset;
      top = anchorPosition.dy + (anchorSize.height - tooltipSize.height) / 2;
      break;
    case UITooltipPlacement.RIGHT_START:
      left = anchorPosition.dx + anchorSize.width + offset;
      top = anchorPosition.dy;
      break;
    case UITooltipPlacement.RIGHT_END:
      left = anchorPosition.dx + anchorSize.width + offset;
      top = anchorPosition.dy + anchorSize.height - tooltipSize.height;
      break;

    case UITooltipPlacement.UNKNOWN:
      // Default to BOTTOM_CENTER if unknown
      left = anchorPosition.dx + (anchorSize.width - tooltipSize.width) / 2;
      top = anchorPosition.dy + anchorSize.height + offset;
      break;
  }

  // Check if tooltip would be offscreen and adjust accordingly

  // Off left edge
  if (left < margin) {
    // If we're using LEFT placement, switch to RIGHT
    if (placement == UITooltipPlacement.LEFT_CENTER ||
        placement == UITooltipPlacement.LEFT_START ||
        placement == UITooltipPlacement.LEFT_END) {
      // Recalculate using RIGHT placement
      left = anchorPosition.dx + anchorSize.width + offset;
    } else {
      left = margin;
    }
  }

  // Off right edge
  if (left + tooltipSize.width > screenSize.width - margin) {
    // If we're using RIGHT placement, switch to LEFT
    if (placement == UITooltipPlacement.RIGHT_CENTER ||
        placement == UITooltipPlacement.RIGHT_START ||
        placement == UITooltipPlacement.RIGHT_END) {
      // Recalculate using LEFT placement
      left = anchorPosition.dx - tooltipSize.width - offset;
    } else {
      left = screenSize.width - tooltipSize.width - margin;
    }
  }

  // Off top edge
  if (top < margin) {
    // If we're using TOP placement, switch to BOTTOM
    if (placement == UITooltipPlacement.TOP_CENTER ||
        placement == UITooltipPlacement.TOP_START ||
        placement == UITooltipPlacement.TOP_END) {
      // Recalculate using BOTTOM placement
      top = anchorPosition.dy + anchorSize.height + offset;
    } else {
      top = margin;
    }
  }

  // Off bottom edge
  if (top + tooltipSize.height > screenSize.height - margin) {
    // If we're using BOTTOM placement, switch to TOP
    if (placement == UITooltipPlacement.BOTTOM_CENTER ||
        placement == UITooltipPlacement.BOTTOM_START ||
        placement == UITooltipPlacement.BOTTOM_END) {
      // Recalculate using TOP placement
      top = anchorPosition.dy - tooltipSize.height - offset;
    } else {
      top = screenSize.height - tooltipSize.height - margin;
    }
  }

  return Offset(left, top);
}