From c3a90f28166baecbf807e1a64a3d5305b6508b3f Mon Sep 17 00:00:00 2001 From: 230404 <230404@epvc.pt> Date: Mon, 4 May 2026 15:00:09 +0100 Subject: [PATCH] ok --- lib/controllers/placar_controller.dart | 41 ++++++++++++++++++++++++-- lib/icons.dart/resaltosicon.dart | 22 +++++++------- 2 files changed, 51 insertions(+), 12 deletions(-) diff --git a/lib/controllers/placar_controller.dart b/lib/controllers/placar_controller.dart index ca2bf75..a3e07fc 100644 --- a/lib/controllers/placar_controller.dart +++ b/lib/controllers/placar_controller.dart @@ -377,6 +377,42 @@ class PlacarController extends ChangeNotifier { notifyListeners(); } + // ── TROCAR JOGADORES NO CAMPO ────────────────────────────────────────────── + void swapCourtPlayers(String draggedPlayerData, String targetPlayerData) { + // Verifica se são da mesma equipa (Minha Equipa) + if (draggedPlayerData.startsWith("player_my_") && targetPlayerData.startsWith("player_my_")) { + String id1 = draggedPlayerData.replaceAll("player_my_", ""); + String id2 = targetPlayerData.replaceAll("player_my_", ""); + + int idx1 = myCourt.indexOf(id1); + int idx2 = myCourt.indexOf(id2); + + if (idx1 != -1 && idx2 != -1) { + myCourt[idx1] = id2; + myCourt[idx2] = id1; + } + } + // Verifica se são da mesma equipa (Adversário) + else if (draggedPlayerData.startsWith("player_opp_") && targetPlayerData.startsWith("player_opp_")) { + String id1 = draggedPlayerData.replaceAll("player_opp_", ""); + String id2 = targetPlayerData.replaceAll("player_opp_", ""); + + int idx1 = oppCourt.indexOf(id1); + int idx2 = oppCourt.indexOf(id2); + + if (idx1 != -1 && idx2 != -1) { + oppCourt[idx1] = id2; + oppCourt[idx2] = id1; + } + } else { + // Se forem de equipas diferentes ou dados inválidos, ignora. + return; + } + + _scheduleAutoSave(); + notifyListeners(); + } + void registerShotFromPopup(BuildContext context, String action, String targetPlayer, String zone, int points, double relativeX, double relativeY) { String playerId = targetPlayer.replaceAll("player_my_", "").replaceAll("player_opp_", ""); bool isMake = action.startsWith("add_"); @@ -672,7 +708,8 @@ class PlacarController extends ChangeNotifier { _autoSaveTimer?.cancel(); super.dispose(); } -Future saveGameStats(BuildContext context) async { + + Future saveGameStats(BuildContext context) async { final supabase = Supabase.instance.client; isSaving = true; notifyListeners(); @@ -784,7 +821,7 @@ Future saveGameStats(BuildContext context) async { } }); - // 3. Preparar os Locais dos Lançamentos (MAPA DE CALOR) - O QUE FALTAVA + // 3. Preparar os Locais dos Lançamentos (MAPA DE CALOR) List> batchShots = []; for (var shot in matchShots) { if (!shot.playerId.startsWith("fake_")) { diff --git a/lib/icons.dart/resaltosicon.dart b/lib/icons.dart/resaltosicon.dart index f45865f..d25ce00 100644 --- a/lib/icons.dart/resaltosicon.dart +++ b/lib/icons.dart/resaltosicon.dart @@ -2,9 +2,6 @@ import 'package:flutter/material.dart'; import 'package:playmaker/classe/theme.dart'; import 'package:playmaker/controllers/placar_controller.dart'; -// ============================================================================ -// 4. PAINEL DE BOTÕES DE ACÇÃO (DRAG & DROP) -// ============================================================================ class ActionButtonsPanel extends StatelessWidget { final PlacarController controller; final double sf; @@ -24,23 +21,29 @@ class ActionButtonsPanel extends StatelessWidget { crossAxisAlignment: CrossAxisAlignment.end, children: [ _columnBtn([ - _dragAndTargetBtn("-1", AppTheme.actionMiss, "miss_1", baseSize, feedSize, sf, badge: ""), + // 🔴 1ª Linha: Agora "sub_pts_1" (Anular pontos) + _dragAndTargetBtn("-1", AppTheme.actionMiss, "sub_pts_1", baseSize, feedSize, sf, badge: ""), _dragAndTargetBtn("1", AppTheme.actionPoints, "add_pts_1", baseSize, feedSize, sf, badge: "FTM"), - _dragAndTargetBtn("1", AppTheme.actionPoints, "sub_pts_1", baseSize, feedSize, sf, badge: "FTA", isX: true), + // ❌ 3ª Linha: Agora "miss_1" (Falhados) + _dragAndTargetBtn("1", AppTheme.actionPoints, "miss_1", baseSize, feedSize, sf, badge: "FTA", isX: true), _dragAndTargetBtn("STL", AppTheme.actionSteal, "add_stl", baseSize, feedSize, sf, badge: "STL"), ], gap), SizedBox(width: gap), _columnBtn([ - _dragAndTargetBtn("-2", AppTheme.actionMiss, "miss_2", baseSize, feedSize, sf, badge: ""), + // 🔴 1ª Linha: Agora "sub_pts_2" (Anular pontos) + _dragAndTargetBtn("-2", AppTheme.actionMiss, "sub_pts_2", baseSize, feedSize, sf, badge: ""), _dragAndTargetBtn("2", AppTheme.actionPoints, "add_pts_2", baseSize, feedSize, sf, badge: "2PM"), - _dragAndTargetBtn("2", AppTheme.actionPoints, "sub_pts_2", baseSize, feedSize, sf, badge: "2PA", isX: true), + // ❌ 3ª Linha: Agora "miss_2" (Falhados) + _dragAndTargetBtn("2", AppTheme.actionPoints, "miss_2", baseSize, feedSize, sf, badge: "2PA", isX: true), _dragAndTargetBtn("AST", AppTheme.actionAssist, "add_ast", baseSize, feedSize, sf, badge: "AST"), ], gap), SizedBox(width: gap), _columnBtn([ - _dragAndTargetBtn("-3", AppTheme.actionMiss, "miss_3", baseSize, feedSize, sf, badge: ""), + // 🔴 1ª Linha: Agora "sub_pts_3" (Anular pontos) + _dragAndTargetBtn("-3", AppTheme.actionMiss, "sub_pts_3", baseSize, feedSize, sf, badge: ""), _dragAndTargetBtn("3", AppTheme.actionPoints, "add_pts_3", baseSize, feedSize, sf, badge: "3PM"), - _dragAndTargetBtn("3", AppTheme.actionPoints, "sub_pts_3", baseSize, feedSize, sf, badge: "3PA", isX: true), + // ❌ 3ª Linha: Agora "miss_3" (Falhados) + _dragAndTargetBtn("3", AppTheme.actionPoints, "miss_3", baseSize, feedSize, sf, badge: "3PA", isX: true), _dragAndTargetBtn("TOV", AppTheme.actionMiss, "add_tov", baseSize, feedSize, sf, badge: "TOV"), ], gap), SizedBox(width: gap), @@ -53,7 +56,6 @@ class ActionButtonsPanel extends StatelessWidget { ), ); } - Widget _columnBtn(List children, double gap) { return Column( mainAxisSize: MainAxisSize.min,