import 'package:flutter/material.dart'; import '../../game/models/piece.dart'; import '../theme/palette.dart'; import 'tile_painter.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 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, ); if (overrideColor != null) { canvas.drawRRect( RRect.fromRectAndRadius(rect, radius), Paint()..color = overrideColor, ); } else { paintGlossyTile(canvas, rect, GamePalette.tile(piece.colorId)); } } } /// 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; }