Files
BlockSeasons/lib/ui/widgets/tray_widget.dart
T
airkjw 3138fc4b08 Add playable core UI: board painter, drag-and-drop, HUD, result overlay
CustomPainter board with gems/ghost/clear-flash, finger-lifted drag
with snap preview, combo text effect, HUD chips, phase overlays with
rescue stubs, demo stage. E2E widget test drives a real drag gesture.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-06-11 13:19:34 +09:00

60 lines
1.6 KiB
Dart

import 'package:flutter/material.dart';
import '../../game/models/piece.dart';
import 'piece_painter.dart';
/// The 3-slot piece tray. Reports raw pan gestures up; the game screen owns
/// drag state so the lifted piece can float over the board.
class TrayWidget extends StatelessWidget {
const TrayWidget({
super.key,
required this.tray,
required this.draggingIndex,
required this.onDragStart,
required this.onDragUpdate,
required this.onDragEnd,
});
final List<Piece> tray;
final int? draggingIndex;
final void Function(int index, Offset globalPosition) onDragStart;
final void Function(Offset globalPosition) onDragUpdate;
final void Function() onDragEnd;
static const double slotCellSize = 16;
@override
Widget build(BuildContext context) {
return SizedBox(
height: 96,
child: Row(
children: [
for (var i = 0; i < 3; i++)
Expanded(
child: i < tray.length
? _slot(context, i, tray[i])
: const SizedBox.shrink(),
),
],
),
);
}
Widget _slot(BuildContext context, int index, Piece piece) {
final hidden = index == draggingIndex;
return GestureDetector(
behavior: HitTestBehavior.opaque,
onPanStart: (d) => onDragStart(index, d.globalPosition),
onPanUpdate: (d) => onDragUpdate(d.globalPosition),
onPanEnd: (_) => onDragEnd(),
onPanCancel: onDragEnd,
child: Center(
child: Opacity(
opacity: hidden ? 0.0 : 1.0,
child: PieceWidget(piece: piece, cellSize: slotCellSize),
),
),
);
}
}