import 'package:flutter/material.dart'; import 'dart:math' as math; class ZoneMapDialog extends StatelessWidget { final String playerName; final bool isMake; final bool is3PointAction; // 👇 AGORA O POP-UP SABE O QUE ARRASTASTE! final Function(String zone, int points, double relativeX, double relativeY) onZoneSelected; const ZoneMapDialog({ super.key, required this.playerName, required this.isMake, required this.is3PointAction, required this.onZoneSelected, }); @override Widget build(BuildContext context) { final Color headerColor = const Color(0xFFE88F15); final Color yellowBackground = const Color(0xFFDFAB00); final double screenHeight = MediaQuery.of(context).size.height; final double dialogHeight = screenHeight * 0.95; final double dialogWidth = dialogHeight * 1.0; return Dialog( backgroundColor: yellowBackground, shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(12)), clipBehavior: Clip.antiAlias, insetPadding: const EdgeInsets.all(10), child: SizedBox( height: dialogHeight, width: dialogWidth, child: Column( children: [ Container( height: 40, color: headerColor, width: double.infinity, child: Stack( alignment: Alignment.center, children: [ Text( isMake ? "Lançamento de $playerName (Marcou)" : "Lançamento de $playerName (Falhou)", style: const TextStyle(color: Colors.white, fontSize: 14, fontWeight: FontWeight.bold), ), Positioned( right: 8, child: InkWell( onTap: () => Navigator.pop(context), child: Container( padding: const EdgeInsets.all(4), decoration: const BoxDecoration(color: Colors.white, shape: BoxShape.circle), child: Icon(Icons.close, color: headerColor, size: 16), ), ), ) ], ), ), Expanded( child: LayoutBuilder( builder: (context, constraints) { return GestureDetector( onTapUp: (details) => _calculateAndReturnZone(context, details.localPosition, constraints.biggest), child: CustomPaint( size: Size(constraints.maxWidth, constraints.maxHeight), painter: DebugPainter(is3PointAction: is3PointAction), // 👇 Passa a info para o desenhador ), ); }, ), ), ], ), ), ); } void _calculateAndReturnZone(BuildContext context, Offset tap, Size size) { final double w = size.width; final double h = size.height; final double x = tap.dx; final double y = tap.dy; final double basketX = w / 2; final double margin = w * 0.10; final double length = h * 0.35; final double larguraDoArco = (w / 2) - margin; final double alturaDoArco = larguraDoArco * 0.30; final double totalArcoHeight = alturaDoArco * 4; String zone = ""; int pts = 2; // 1. SABER SE CLICOU NA ZONA DE 3 OU DE 2 bool is3 = false; if (y < length) { if (x < margin || x > w - margin) is3 = true; } else { double dx = x - basketX; double dy = y - length; double ellipse = (dx * dx) / (larguraDoArco * larguraDoArco) + (dy * dy) / (math.pow(totalArcoHeight / 2, 2)); if (ellipse > 1.0) is3 = true; } // 👇 MAGIA AQUI: BLOQUEIA O CLIQUE NA ZONA ESCURA! 👇 if (is3PointAction && !is3) return; // Arrastou 3pts mas clicou na de 2pts -> IGNORA if (!is3PointAction && is3) return; // Arrastou 2pts mas clicou na de 3pts -> IGNORA double angle = math.atan2(y - length, x - basketX); if (is3) { pts = 3; if (y < length) { zone = (x < w / 2) ? "Canto Esquerdo (3pt)" : "Canto Direito (3pt)"; } else if (angle > 2.35) { zone = "Ala Esquerda (3pt)"; } else if (angle < 0.78) { zone = "Ala Direita (3pt)"; } else { zone = "Topo (3pt)"; } } else { pts = 2; final double pW = w * 0.28; final double pH = h * 0.38; if (x > basketX - pW / 2 && x < basketX + pW / 2 && y < pH) { zone = "Garrafão"; } else { if (y < length) { zone = (x < w / 2) ? "Meia Distância (Canto Esq)" : "Meia Distância (Canto Dir)"; } else if (angle > 2.35) { zone = "Meia Distância (Esq)"; } else if (angle < 0.78) { zone = "Meia Distância (Dir)"; } else { zone = "Meia Distância (Centro)"; } } } // 👇 A MUDANÇA ESTÁ AQUI! Passamos os dados e deixamos quem chamou decidir como fechar! onZoneSelected(zone, pts, x / w, y / h); } } class DebugPainter extends CustomPainter { final bool is3PointAction; DebugPainter({required this.is3PointAction}); @override void paint(Canvas canvas, Size size) { final double w = size.width; final double h = size.height; final double basketX = w / 2; final Paint whiteStroke = Paint()..color = Colors.white..style = PaintingStyle.stroke..strokeWidth = 2.0; final Paint blackStroke = Paint()..color = Colors.black87..style = PaintingStyle.stroke..strokeWidth = 2.0; final double margin = w * 0.10; final double length = h * 0.35; final double larguraDoArco = (w / 2) - margin; final double alturaDoArco = larguraDoArco * 0.30; final double totalArcoHeight = alturaDoArco * 4; // DESENHA O CAMPO canvas.drawLine(Offset(margin, 0), Offset(margin, length), whiteStroke); canvas.drawLine(Offset(w - margin, 0), Offset(w - margin, length), whiteStroke); canvas.drawLine(Offset(0, length), Offset(margin, length), whiteStroke); canvas.drawLine(Offset(w - margin, length), Offset(w, length), whiteStroke); canvas.drawArc(Rect.fromCenter(center: Offset(basketX, length), width: larguraDoArco * 2, height: totalArcoHeight), 0, math.pi, false, whiteStroke); double sXL = basketX + (larguraDoArco * math.cos(math.pi * 0.75)); double sYL = length + ((totalArcoHeight / 2) * math.sin(math.pi * 0.75)); double sXR = basketX + (larguraDoArco * math.cos(math.pi * 0.25)); double sYR = length + ((totalArcoHeight / 2) * math.sin(math.pi * 0.25)); canvas.drawLine(Offset(sXL, sYL), Offset(0, h * 0.85), whiteStroke); canvas.drawLine(Offset(sXR, sYR), Offset(w, h * 0.85), whiteStroke); final double pW = w * 0.28; final double pH = h * 0.38; canvas.drawRect(Rect.fromLTWH(basketX - pW / 2, 0, pW, pH), blackStroke); final double ftR = pW / 2; canvas.drawArc(Rect.fromCircle(center: Offset(basketX, pH), radius: ftR), 0, math.pi, false, blackStroke); for (int i = 0; i < 10; i++) { canvas.drawArc(Rect.fromCircle(center: Offset(basketX, pH), radius: ftR), math.pi + (i * 2 * (math.pi / 20)), math.pi / 20, false, blackStroke); } canvas.drawLine(Offset(basketX - pW / 2, pH), Offset(sXL, sYL), blackStroke); canvas.drawLine(Offset(basketX + pW / 2, pH), Offset(sXR, sYR), blackStroke); canvas.drawArc(Rect.fromCircle(center: Offset(basketX, h), radius: w * 0.12), math.pi, math.pi, false, blackStroke); canvas.drawCircle(Offset(basketX, h * 0.12), w * 0.02, blackStroke); canvas.drawLine(Offset(basketX - w * 0.08, h * 0.12 - 5), Offset(basketX + w * 0.08, h * 0.12 - 5), blackStroke); // ========================================== // 👇 EFEITO DE ESCURECIMENTO (SHADOW) 👇 // ========================================== final Paint shadowPaint = Paint()..color = Colors.black.withOpacity(0.75); // 75% escuro! // Cria o molde da área de 2 pontos Path path2pt = Path(); path2pt.moveTo(margin, 0); path2pt.lineTo(margin, length); // Faz o arco curvo da linha de 3 pontos path2pt.arcTo(Rect.fromCenter(center: Offset(basketX, length), width: larguraDoArco * 2, height: totalArcoHeight), math.pi, -math.pi, false); path2pt.lineTo(w - margin, 0); path2pt.close(); if (is3PointAction) { // Arrastou 3 Pontos -> Escurece a Zona de 2! canvas.drawPath(path2pt, shadowPaint); } else { // Arrastou 2 Pontos -> Escurece a Zona de 3! Path fullScreen = Path()..addRect(Rect.fromLTWH(0, 0, w, h)); Path path3pt = Path.combine(PathOperation.difference, fullScreen, path2pt); canvas.drawPath(path3pt, shadowPaint); } } @override bool shouldRepaint(covariant CustomPainter oldDelegate) => true; }