diff --git a/lib/features/analysis/analysis_screen.dart b/lib/features/analysis/analysis_screen.dart index 80a423bd..6c43d991 100644 --- a/lib/features/analysis/analysis_screen.dart +++ b/lib/features/analysis/analysis_screen.dart @@ -5,6 +5,7 @@ library; import 'dart:io'; +import 'dart:math' as math; import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; import '../../core/constants/app_constants.dart'; @@ -182,6 +183,7 @@ class _AnalysisScreenContentState extends State<_AnalysisScreenContent> { ), body: Stack( children: [ + Navigator.canPop(context) ? const SizedBox.shrink() : const SizedBox.shrink(), // Garde structurellement invisible SingleChildScrollView( controller: _scrollController, child: Column( @@ -434,25 +436,63 @@ class _AnalysisScreenContentState extends State<_AnalysisScreenContent> { minScale: 1.0, maxScale: 10.0, boundaryMargin: const EdgeInsets.all(double.infinity), - child: Stack( - children: [ - Image.file( - File(provider.imagePath!), - key: _imageKey, - fit: BoxFit.fill, - ), - TargetOverlay( - targetCenterX: provider.targetCenterX, - targetCenterY: provider.targetCenterY, - targetRadius: provider.targetRadius, - targetType: provider.targetType!, - shots: provider.shots, - showRings: true, - zoomScale: _currentZoomScale, - onShotTapped: (shot) => _showShotDetails(context, provider, shot), - onAddShot: (relX, relY) => provider.addShot(relX, relY), - ), - ], + child: GestureDetector( + // CORRECTION : Utilisation de onDoubleTapDown (compatible toutes versions Flutter) + onDoubleTapDown: (TapDownDetails details) { + final RenderBox? box = _imageKey.currentContext?.findRenderObject() as RenderBox?; + if (box == null) return; + + final localOffset = box.globalToLocal(details.globalPosition); + + // Coordonnées relatives (entre 0.0 et 1.0) sous le doigt + final relX = localOffset.dx / box.size.width; + final relY = localOffset.dy / box.size.height; + + if (provider.shots.isEmpty) return; + + // Recherche de l'impact le plus proche du double-clic + Shot? closestShot; + double minDistance = double.infinity; + + // Seuil de tolérance de détection (environ 5% de la taille de la cible) + const double clickTolerance = 0.05; + + for (final shot in provider.shots) { + final dx = shot.x - relX; + final dy = shot.y - relY; + final distance = math.sqrt(dx * dx + dy * dy); + + if (distance < minDistance && distance < clickTolerance) { + minDistance = distance; + closestShot = shot; + } + } + + // Si un impact est détecté sous le double-clic, on ouvre ses options ! + if (closestShot != null) { + _showShotDetails(context, provider, closestShot); + } + }, + child: Stack( + children: [ + Image.file( + File(provider.imagePath!), + key: _imageKey, + fit: BoxFit.fill, + ), + TargetOverlay( + targetCenterX: provider.targetCenterX, + targetCenterY: provider.targetCenterY, + targetRadius: provider.targetRadius, + targetType: provider.targetType!, + shots: provider.shots, + showRings: true, + zoomScale: _currentZoomScale, + onShotTapped: (shot) => _showShotDetails(context, provider, shot), + onAddShot: (relX, relY) => provider.addShot(relX, relY), + ), + ], + ), ), ); }