calcPopupPosition method
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;
}