import 'package:flutter/material.dart'; import 'game_pallete.dart'; enum PlateState { normal, marked, selected, } typedef PlateMarkCallback = void Function(String plateName); class ColorPlate extends StatefulWidget { final String plateName; final double size; final PlateMarkCallback? onSelected; const ColorPlate( {super.key, required this.plateName, required this.size, this.onSelected}); @override State createState() => _ColorPlateState(); } class _ColorPlateState extends State { var _tapPosition = Offset.zero; var state = PlateState.normal; Color get borderColor { switch (state) { case PlateState.normal: return Colors.black; case PlateState.marked: return Colors.amber; case PlateState.selected: return Colors.greenAccent; } } void _getTapPosition(TapDownDetails details) { final RenderBox referenceBox = context.findRenderObject() as RenderBox; _tapPosition = referenceBox.globalToLocal(details.globalPosition); _tapPosition = details.globalPosition; } void _showContextMenu(BuildContext context) async { final oldState = state; setState(() { state = PlateState.marked; }); final overlay = Overlay.of(context).context.findRenderObject(); final result = await showMenu( context: context, position: RelativeRect.fromRect( Rect.fromLTWH(_tapPosition.dx, _tapPosition.dy, 30, 30), Rect.fromLTWH(0, 0, overlay!.paintBounds.size.width, overlay.paintBounds.size.height), ), items: [ PopupMenuItem( enabled: false, child: Text("Plate ${widget.plateName}"), ), PopupMenuItem( enabled: oldState != PlateState.marked, value: "mark", child: Text("Mark"), ), const PopupMenuItem( value: "cancel", child: Text("Cancel"), ) ], ); setState(() { if (result == "mark" || oldState == PlateState.selected) { state = PlateState.selected; if (oldState != PlateState.selected) { widget.onSelected?.call(widget.plateName); } } else { state = PlateState.normal; } }); } @override Widget build(BuildContext context) { return GestureDetector( onTapDown: (details) => _getTapPosition(details), onTap: () => _showContextMenu(context), child: Container( width: widget.size, height: widget.size, decoration: BoxDecoration( color: pallete[widget.plateName], border: Border.all( color: borderColor, width: 4, ), borderRadius: BorderRadius.circular(10), ), ), ); } }