import 'package:flutter/material.dart'; import '../../game/models/piece.dart'; import '../theme/palette.dart'; /// Draws a piece as rounded tiles at a given cell size; reused by the tray, /// the drag overlay, and ghost previews. void paintPiece( Canvas canvas, Piece piece, { required double cellSize, Offset origin = Offset.zero, Color? overrideColor, }) { final paint = Paint() ..color = overrideColor ?? GamePalette.tile(piece.colorId); final inset = cellSize * 0.05; final radius = Radius.circular(cellSize * 0.18); for (final (dx, dy) in piece.offsets) { final rect = Rect.fromLTWH( origin.dx + dx * cellSize + inset, origin.dy + dy * cellSize + inset, cellSize - inset * 2, cellSize - inset * 2, ); canvas.drawRRect(RRect.fromRectAndRadius(rect, radius), paint); if (overrideColor == null) { // Subtle top highlight for depth. final highlight = Paint()..color = Colors.white.withValues(alpha: 0.18); canvas.drawRRect( RRect.fromRectAndRadius( Rect.fromLTWH(rect.left, rect.top, rect.width, rect.height * 0.32), radius, ), highlight, ); } } } /// Bounding size of a piece in cells. (int, int) pieceCellBounds(Piece piece) { var w = 0; var h = 0; for (final (dx, dy) in piece.offsets) { if (dx + 1 > w) w = dx + 1; if (dy + 1 > h) h = dy + 1; } return (w, h); } class PieceWidget extends StatelessWidget { const PieceWidget({super.key, required this.piece, required this.cellSize}); final Piece piece; final double cellSize; @override Widget build(BuildContext context) { final (w, h) = pieceCellBounds(piece); return CustomPaint( size: Size(w * cellSize, h * cellSize), painter: _PiecePainter(piece, cellSize), ); } } class _PiecePainter extends CustomPainter { const _PiecePainter(this.piece, this.cellSize); final Piece piece; final double cellSize; @override void paint(Canvas canvas, Size size) { paintPiece(canvas, piece, cellSize: cellSize); } @override bool shouldRepaint(_PiecePainter old) => old.piece != piece || old.cellSize != cellSize; }