import 'dart:async'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; class PlacarPage extends StatefulWidget { final String gameId; final String myTeam; final String opponentTeam; const PlacarPage({ super.key, required this.gameId, required this.myTeam, required this.opponentTeam, }); @override State createState() => _PlacarPageState(); } class _PlacarPageState extends State { int _myScore = 0; int _opponentScore = 0; Duration _duration = const Duration(minutes: 10); Timer? _timer; bool _isRunning = false; @override void initState() { super.initState(); // Força a tela na horizontal SystemChrome.setPreferredOrientations([ DeviceOrientation.landscapeRight, DeviceOrientation.landscapeLeft, ]); } void _toggleTimer() { if (_isRunning) { _timer?.cancel(); } else { _timer = Timer.periodic(const Duration(seconds: 1), (timer) { if (_duration.inSeconds > 0) { setState(() => _duration -= const Duration(seconds: 1)); } else { _timer?.cancel(); setState(() => _isRunning = false); } }); } setState(() => _isRunning = !_isRunning); } String _formatTime(Duration d) { return "${d.inMinutes.toString().padLeft(2, '0')}:${d.inSeconds.remainder(60).toString().padLeft(2, '0')}"; } @override void dispose() { _timer?.cancel(); // Restaura a vertical ao sair SystemChrome.setPreferredOrientations([ DeviceOrientation.portraitUp, DeviceOrientation.portraitDown, ]); super.dispose(); } @override Widget build(BuildContext context) { return Scaffold( body: Stack( children: [ // 1. FUNDO (O CAMPO DE BASQUETEBOL) Container( width: double.infinity, height: double.infinity, decoration: const BoxDecoration( color: Color(0xFFD2B48C), // Cor de madeira temporária // TODO: Descomenta a linha abaixo e usa a tua imagem do campo // image: DecorationImage(image: AssetImage('assets/court.png'), fit: BoxFit.cover), ), // Linhas do campo desenhadas por cima (Opcional se usares imagem real) child: const CustomPaint(painter: CourtPainterPlaceholder()), ), // 2. BARRA SUPERIOR (PLACARD) Positioned( top: 0, left: 0, right: 0, child: _buildTopScoreboard(), ), // 3. JOGADORES NO CAMPO (Posições manuais usando Positioned) // Exemplo de como posicionar os teus jogadores Positioned(top: 120, left: 100, child: _buildPlayerCard("6", "LeBron James")), Positioned(top: 250, left: 160, child: _buildPlayerCard("3", "Anthony Davis")), Positioned(top: 320, left: 280, child: _buildPlayerCard("28", "Rui Hachimura")), Positioned(top: 380, left: 160, child: _buildPlayerCard("1", "D'Angelo Russell")), Positioned(top: 500, left: 100, child: _buildPlayerCard("15", "Austin Reaves")), // 4. BOTÃO CENTRAL (PLAY/PAUSE) Center( child: GestureDetector( onTap: _toggleTimer, child: Container( decoration: BoxDecoration( shape: BoxShape.circle, color: const Color(0xFF2662D9).withOpacity(0.8), border: Border.all(color: Colors.blueAccent.withOpacity(0.5), width: 8), ), padding: const EdgeInsets.all(16), child: Icon( _isRunning ? Icons.pause : Icons.play_arrow, color: Colors.white, size: 40, ), ), ), ), // 5. PAINEL DE ACÇÕES EM BAIXO (Estatísticas: 1pt, 2pt, 3pt) Positioned( bottom: 20, left: 0, right: 0, child: _buildActionButtonsPanel(), ), // 6. BOTÃO DE FECHAR / GUARDAR NO CANTO Positioned( bottom: 20, right: 20, child: FloatingActionButton( backgroundColor: const Color(0xFF1E2A38), mini: true, onPressed: () => Navigator.pop(context), child: const Icon(Icons.close, color: Colors.white), ), ), ], ), ); } // --- WIDGETS AUXILIARES PARA LIMPAR O CÓDIGO --- Widget _buildTopScoreboard() { return Container( color: const Color(0xFF1E2A38), // Azul Escuro da barra padding: const EdgeInsets.symmetric(horizontal: 20, vertical: 10), child: SafeArea( bottom: false, child: Row( mainAxisAlignment: MainAxisAlignment.center, children: [ // Equipa Casa Text(widget.myTeam.toUpperCase(), style: const TextStyle(color: Colors.white, fontWeight: FontWeight.bold)), const SizedBox(width: 15), _scoreBox(_myScore, const Color(0xFF2662D9)), // Azul const SizedBox(width: 20), // Relógio Container( padding: const EdgeInsets.symmetric(horizontal: 20, vertical: 8), decoration: BoxDecoration(color: Colors.white.withOpacity(0.1), borderRadius: BorderRadius.circular(8)), child: Text( _formatTime(_duration), style: const TextStyle(color: Colors.white, fontSize: 24, fontWeight: FontWeight.bold, fontFamily: 'monospace'), ), ), const SizedBox(width: 20), // Equipa Visitante _scoreBox(_opponentScore, const Color(0xFFE74C3C)), // Vermelho const SizedBox(width: 15), Text(widget.opponentTeam.toUpperCase(), style: const TextStyle(color: Colors.white, fontWeight: FontWeight.bold)), ], ), ), ); } Widget _scoreBox(int score, Color color) { return Container( padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 8), decoration: BoxDecoration(color: color, borderRadius: BorderRadius.circular(8)), child: Text(score.toString(), style: const TextStyle(color: Colors.white, fontSize: 24, fontWeight: FontWeight.bold)), ); } Widget _buildPlayerCard(String number, String name) { return Container( decoration: BoxDecoration( color: const Color(0xFF1E2A38).withOpacity(0.9), borderRadius: BorderRadius.circular(8), ), padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 6), child: Row( mainAxisSize: MainAxisSize.min, children: [ CircleAvatar( backgroundColor: const Color(0xFF2662D9), radius: 12, child: Text(number, style: const TextStyle(color: Colors.white, fontSize: 10, fontWeight: FontWeight.bold)), ), const SizedBox(width: 8), Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text(name, style: const TextStyle(color: Colors.white, fontSize: 10, fontWeight: FontWeight.bold)), const Text("0 Pts | 0 Rbs | 0 Ast", style: TextStyle(color: Colors.grey, fontSize: 8)), ], ) ], ), ); } Widget _buildActionButtonsPanel() { return Row( mainAxisAlignment: MainAxisAlignment.center, children: [ // Podes adicionar onTap nestes botões para chamarem setState(() => _myScore += X) _actionBtn("1", Colors.orange), _actionBtn("2", Colors.orange), _actionBtn("3", Colors.orange), const SizedBox(width: 20), _actionBtn("M", Colors.blueGrey, icon: Icons.sports_basketball), _actionBtn("F", Colors.redAccent, icon: Icons.pan_tool), ], ); } Widget _actionBtn(String label, Color color, {IconData? icon}) { return Container( margin: const EdgeInsets.symmetric(horizontal: 4), decoration: BoxDecoration(color: color, shape: BoxShape.circle), padding: const EdgeInsets.all(12), child: icon != null ? Icon(icon, color: Colors.white, size: 20) : Text(label, style: const TextStyle(color: Colors.white, fontWeight: FontWeight.bold, fontSize: 16)), ); } } // Classe temporária para desenhar as marcações do campo caso não tenhas imagem class CourtPainterPlaceholder extends CustomPainter { const CourtPainterPlaceholder(); @override void paint(Canvas canvas, Size size) { final paint = Paint()..color = Colors.white.withOpacity(0.5)..style = PaintingStyle.stroke..strokeWidth = 2; canvas.drawRect(Rect.fromLTWH(0, 0, size.width, size.height), paint); canvas.drawLine(Offset(size.width / 2, 0), Offset(size.width / 2, size.height), paint); canvas.drawCircle(Offset(size.width / 2, size.height / 2), 60, paint); } @override bool shouldRepaint(covariant CustomPainter oldDelegate) => false; }