calcPopupPosition method

Offset calcPopupPosition(
  1. BuildContext context
)

Calculate the position of the menu. Finds dropdown button size, window size, and popup menu size. Then finds location of the dropdown button. Finally, depending on the SDropdownMenuPosition, this function will calculate the location of the menu (from its top left corner) relative to the screen's (0, 0) coordinate. Also adjusts the positon of the menu will be out of screen bounds (thus making it clip off screen)

Implementation

Offset calcPopupPosition(BuildContext context) {
  // Get the render box for finding size
  RenderBox renderBox = context.findRenderObject() as RenderBox;
  // Get button size
  Size buttonSize = renderBox.size;
  // Get user provided offset
  Offset styleOffset = widget.style.offset ?? Offset.zero;
  // Get window size
  Size windowSize = MediaQuery.of(context).size;
  // Get popup menu size
  Size popupSize = Size(widget.width, widget.height);
  // Get location of the widget
  Offset offset = renderBox.localToGlobal(Offset.zero);

  // The returned location of the menu's top left corner
  Offset answer;

  // Calculate menu position
  switch (widget.position) {
    case SDropdownMenuPosition.topLeft:
      answer = topLeftPositionCalculation(buttonSize, popupSize, offset);
      break;
    case SDropdownMenuPosition.topCenter:
      answer = topCenterPositionCalculation(buttonSize, popupSize, offset);
      break;
    case SDropdownMenuPosition.topRight:
      answer = topRightPositionCalculation(buttonSize, popupSize, offset);
      break;
    case SDropdownMenuPosition.centerLeft:
      answer = centerLeftPositionCalculation(buttonSize, popupSize, offset);
      break;
    case SDropdownMenuPosition.center:
      answer = centerPositionCalculation(buttonSize, popupSize, offset);
      break;
    case SDropdownMenuPosition.centerRight:
      answer = centerRightPositionCalculation(buttonSize, popupSize, offset);
      break;
    case SDropdownMenuPosition.bottomLeft:
      answer = bottomLeftPositionCalculation(buttonSize, popupSize, offset);
      break;
    case SDropdownMenuPosition.bottomRight:
      answer = bottomRightPositionCalculation(buttonSize, popupSize, offset);
      break;
    case SDropdownMenuPosition.bottomCenter:
    default:
      // default is bottom center
      answer = bottomCenterPositionCalculation(buttonSize, popupSize, offset);
      break;
  }

  // Add given offset
  answer = Offset(answer.dx + styleOffset.dx, answer.dy + styleOffset.dy);

  // Bounds checking
  // Exceeds bounds on the right
  if (answer.dx > (windowSize.width - popupSize.width)) {
    answer = Offset(windowSize.width - popupSize.width, answer.dy);
  }
  // Exceeds bounds on the left
  if (answer.dx < 0) {
    answer = Offset(0, answer.dy);
  }
  // Exceeds bounds on the top
  if (answer.dy < 0) {
    answer = Offset(answer.dx, 0);
  }
  // Exceeds bounds on the bottom
  if (answer.dy > (windowSize.height - popupSize.height)) {
    answer = Offset(answer.dx, windowSize.height - popupSize.height);
  }

  // Return calculated position
  return answer;
}