showContextMenu function
OverlayEntry
showContextMenu({
- required BuildContext context,
- required PreferredSizeWidget child,
- required Color backgroundColor,
- bool opaque = false,
- double spacing = 16,
- double arrowSize = 12,
- Duration duration = const Duration(milliseconds: 200),
Implementation
OverlayEntry showContextMenu({
required BuildContext context,
required PreferredSizeWidget child,
required Color backgroundColor,
bool opaque = false,
double spacing = 16,
double arrowSize = 12,
Duration duration = const Duration(milliseconds: 200),
}) {
final renderBox = context.findRenderObject() as RenderBox?;
if (renderBox == null) {
throw Exception('RenderBox not found');
}
final size = renderBox.size;
final offset = renderBox.localToGlobal(Offset.zero);
final screenWidth = MediaQuery.of(context).size.width;
final overflowsTop = offset.dy - child.preferredSize.height < 0;
final topInset = overflowsTop
? offset.dy + size.height
: offset.dy - child.preferredSize.height - spacing;
final overflowsRight = offset.dx + child.preferredSize.width > screenWidth;
final leftInset = overflowsRight
? screenWidth - child.preferredSize.width - spacing
: offset.dx;
final arrowLeft = offset.dx + size.width / 2;
late final OverlayEntry _entry;
_entry = OverlayEntry(
opaque: opaque,
builder: (context) => GestureDetector(
onTap: () {
_entry.remove();
},
child: ColoredBox(
color: Colors.transparent,
child: Stack(
children: [
Positioned(
top: topInset,
left: leftInset,
child: FadeIn(
duration: duration,
child: child,
),
),
Positioned(
top: offset.dy - arrowSize - (spacing - arrowSize),
left: arrowLeft - arrowSize / 2,
child: FadeIn(
duration: duration,
child: CustomPaint(
painter: TrianglePainter(
strokeColor: backgroundColor,
),
size: Size(arrowSize, arrowSize),
),
),
),
],
),
),
),
);
Overlay.of(context, rootOverlay: true).insert(_entry);
return _entry;
}