From 48b8313be8dcb50df0a2c8ab88acddb74f4659cc Mon Sep 17 00:00:00 2001 From: qguillaume Date: Mon, 25 May 2026 03:12:37 +0200 Subject: [PATCH] Feat: Ajout d'un switch pour masquer ou afficher le slider d'espacement de la cible --- .../analysis/widgets/target_calibration.dart | 193 +++++++++--------- 1 file changed, 97 insertions(+), 96 deletions(-) diff --git a/lib/features/analysis/widgets/target_calibration.dart b/lib/features/analysis/widgets/target_calibration.dart index a3a1ce1b..de68789a 100644 --- a/lib/features/analysis/widgets/target_calibration.dart +++ b/lib/features/analysis/widgets/target_calibration.dart @@ -4,7 +4,6 @@ /// Les anneaux sont répartis proportionnellement. library; -import 'dart:math' as math; import 'package:flutter/material.dart'; import '../../../core/theme/app_theme.dart'; import '../../../data/models/target_type.dart'; @@ -18,13 +17,13 @@ class TargetCalibration extends StatefulWidget { final TargetType targetType; final List? initialRingRadii; final Function( - double centerX, - double centerY, - double innerRadius, - double radius, - int ringCount, { - List? ringRadii, - }) + double centerX, + double centerY, + double innerRadius, + double radius, + int ringCount, { + List? ringRadii, + }) onCalibrationChanged; const TargetCalibration({ @@ -55,6 +54,9 @@ class TargetCalibrationState extends State { bool _isDraggingRadius = false; bool _isDraggingInnerRadius = false; + // Contrôle de l'affichage du scroll d'espacement (désactivé par défaut) + bool _showEspacement = false; + @override void initState() { super.initState(); @@ -138,13 +140,13 @@ class TargetCalibrationState extends State { ringRadii: _ringRadii, targetType: widget.targetType, isDraggingCenter: _isDraggingCenter, - isDraggingRadius: false, // Plus de drag direct du rayon + isDraggingRadius: false, isDraggingInnerRadius: false, ), ), ), - - // Slider pour le rayon (agrandissement) + + // Panneau de configuration des Sliders en haut Positioned( top: 10, left: 40, @@ -152,6 +154,38 @@ class TargetCalibrationState extends State { child: Column( mainAxisSize: MainAxisSize.min, children: [ + // Ligne d'activation pour afficher ou masquer l'espacement + Container( + margin: const EdgeInsets.only(bottom: 8), // CORRECTION de la syntaxe de marge + padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 2), + decoration: BoxDecoration( + color: Colors.black54, + borderRadius: BorderRadius.circular(20), + ), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + const Text( + 'Options d\'espacement avancées', + style: TextStyle(color: Colors.white70, fontSize: 11, fontWeight: FontWeight.w500), + ), + SizedBox( + height: 28, + child: Switch( + value: _showEspacement, + activeThumbColor: const Color(0xFF00FF00), // CORRECTION du paramètre déprécié + onChanged: (bool value) { + setState(() { + _showEspacement = value; + }); + }, + ), + ), + ], + ), + ), + + // Slider pour la taille (toujours visible) Container( padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 4), decoration: BoxDecoration( @@ -171,7 +205,6 @@ class TargetCalibrationState extends State { onChanged: (value) { setState(() { _radius = value; - // On force le recalcul car on change la taille _initRingRadii(forceRecalculate: true); }); _notifyChange(); @@ -182,37 +215,40 @@ class TargetCalibrationState extends State { ], ), ), - const SizedBox(height: 8), - Container( - padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 4), - decoration: BoxDecoration( - color: Colors.black54, - borderRadius: BorderRadius.circular(20), - ), - child: Row( - children: [ - const Text('Espacement ', style: TextStyle(color: Colors.white, fontSize: 12, fontWeight: FontWeight.bold)), - const Icon(Icons.compress, color: Colors.white, size: 16), - Expanded( - child: Slider( - value: (_innerRadius / _radius).clamp(0.01, 0.9), - min: 0.01, - max: 0.9, - activeColor: Colors.orange, - onChanged: (value) { - setState(() { - // On ajuste l'innerRadius comme un ratio du radius global - _innerRadius = _radius * value; - _initRingRadii(forceRecalculate: true); - }); - _notifyChange(); - }, + + // Affichage conditionnel du slider d'espacement orange + if (_showEspacement) ...[ + const SizedBox(height: 8), + Container( + padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 4), + decoration: BoxDecoration( + color: Colors.black54, + borderRadius: BorderRadius.circular(20), + ), + child: Row( + children: [ + const Text('Espacement ', style: TextStyle(color: Colors.white, fontSize: 12, fontWeight: FontWeight.bold)), + const Icon(Icons.compress, color: Colors.white, size: 16), + Expanded( + child: Slider( + value: (_innerRadius / _radius).clamp(0.01, 0.9), + min: 0.01, + max: 0.9, + activeColor: Colors.orange, + onChanged: (value) { + setState(() { + _innerRadius = _radius * value; + _initRingRadii(forceRecalculate: true); + }); + _notifyChange(); + }, + ), ), - ), - const Icon(Icons.expand, color: Colors.white, size: 16), - ], + const Icon(Icons.expand, color: Colors.white, size: 16), + ], + ), ), - ), + ], ], ), ), @@ -236,25 +272,25 @@ class TargetCalibrationState extends State { children: [ _buildDirectionButton( Icons.keyboard_arrow_up, - () => _moveCenterByPixels(0, -1, size), + () => _moveCenterByPixels(0, -1, size), ), Row( mainAxisSize: MainAxisSize.min, children: [ _buildDirectionButton( Icons.keyboard_arrow_left, - () => _moveCenterByPixels(-1, 0, size), + () => _moveCenterByPixels(-1, 0, size), ), const SizedBox(width: 40), _buildDirectionButton( Icons.keyboard_arrow_right, - () => _moveCenterByPixels(1, 0, size), + () => _moveCenterByPixels(1, 0, size), ), ], ), _buildDirectionButton( Icons.keyboard_arrow_down, - () => _moveCenterByPixels(0, 1, size), + () => _moveCenterByPixels(0, 1, size), ), ], ), @@ -301,7 +337,7 @@ class TargetCalibrationState extends State { final tapY = details.localPosition.dy / size.height; final distToCenter = _distance(tapX, tapY, _centerX, _centerY); - + if (distToCenter < 0.05 || distToCenter < _radius + 0.02) { setState(() { _isDraggingCenter = true; @@ -312,11 +348,9 @@ class TargetCalibrationState extends State { void _onPanUpdate(DragUpdateDetails details, Size size) { final deltaX = details.delta.dx / size.width; final deltaY = details.delta.dy / size.height; - final minDim = math.min(size.width, size.height); setState(() { if (_isDraggingCenter) { - // Move center _centerX = _centerX + deltaX; _centerY = _centerY + deltaY; } @@ -370,7 +404,6 @@ class _CalibrationPainter extends CustomPainter { final centerPx = Offset(centerX * size.width, centerY * size.height); final minDim = size.width < size.height ? size.width : size.height; final baseRadiusPx = radius * minDim; - final innerRadiusPx = innerRadius * minDim; if (targetType == TargetType.concentric) { _drawConcentricZones(canvas, size, centerPx, baseRadiusPx); @@ -378,7 +411,6 @@ class _CalibrationPainter extends CustomPainter { _drawSilhouetteZones(canvas, size, centerPx, baseRadiusPx); } - // Fullscreen crosshairs when dragging center if (isDraggingCenter) { final crosshairLinePaint = Paint() ..color = Colors.red.withValues(alpha: 0.5) @@ -395,20 +427,16 @@ class _CalibrationPainter extends CustomPainter { ); } - // Draw center handle _drawCenterHandle(canvas, centerPx); - - // Draw instructions _drawInstructions(canvas, size); } void _drawConcentricZones( - Canvas canvas, - Size size, - Offset center, - double baseRadius, - ) { - // Generate colors for zones + Canvas canvas, + Size size, + Offset center, + double baseRadius, + ) { List zoneColors = []; for (int i = 0; i < ringCount; i++) { final ratio = i / ringCount; @@ -431,7 +459,6 @@ class _CalibrationPainter extends CustomPainter { ..strokeWidth = 1 ..color = Colors.red.withValues(alpha: 0.8); - // Draw from outside to inside for (int i = ringCount - 1; i >= 0; i--) { final ringRadius = ringRadii.length > i ? ringRadii[i] @@ -443,7 +470,6 @@ class _CalibrationPainter extends CustomPainter { canvas.drawCircle(center, zoneRadius, strokePaint); } - // Draw zone labels (only if within visible area) final textPainter = TextPainter(textDirection: TextDirection.ltr); for (int i = 0; i < ringCount; i++) { @@ -455,10 +481,7 @@ class _CalibrationPainter extends CustomPainter { : 0.0; final zoneRadius = baseRadius * (ringRadius + prevRingRadius) / 2; - // Score: center = 10, decrement by 1 for each ring final score = 10 - i; - - // Only draw label if it's within the visible area final labelX = center.dx + zoneRadius; if (labelX < 0 || labelX > size.width) continue; @@ -473,7 +496,6 @@ class _CalibrationPainter extends CustomPainter { ); textPainter.layout(); - // Draw label on the right side of each zone final labelY = center.dy - textPainter.height / 2; if (labelY >= 0 && labelY <= size.height) { textPainter.paint( @@ -485,17 +507,15 @@ class _CalibrationPainter extends CustomPainter { } void _drawSilhouetteZones( - Canvas canvas, - Size size, - Offset center, - double radius, - ) { - // Simplified silhouette zones + Canvas canvas, + Size size, + Offset center, + double radius, + ) { final paint = Paint() ..style = PaintingStyle.stroke ..strokeWidth = 2; - // Draw silhouette outline (simplified as rectangle for now) final silhouetteWidth = radius * 0.8; final silhouetteHeight = radius * 2; @@ -511,43 +531,24 @@ class _CalibrationPainter extends CustomPainter { } void _drawCenterHandle(Canvas canvas, Offset center) { - // Outer circle final outerPaint = Paint() ..color = isDraggingCenter ? Colors.redAccent : Colors.red ..style = PaintingStyle.stroke ..strokeWidth = 3; canvas.drawCircle(center, 15, outerPaint); - // Inner dot final innerPaint = Paint() ..color = isDraggingCenter ? Colors.redAccent : Colors.red ..style = PaintingStyle.fill; canvas.drawCircle(center, 5, innerPaint); - // Crosshair final crossPaint = Paint() ..color = isDraggingCenter ? Colors.redAccent : Colors.red ..strokeWidth = 2; - canvas.drawLine( - Offset(center.dx - 20, center.dy), - Offset(center.dx - 8, center.dy), - crossPaint, - ); - canvas.drawLine( - Offset(center.dx + 8, center.dy), - Offset(center.dx + 20, center.dy), - crossPaint, - ); - canvas.drawLine( - Offset(center.dx, center.dy - 20), - Offset(center.dx, center.dy - 8), - crossPaint, - ); - canvas.drawLine( - Offset(center.dx, center.dy + 8), - Offset(center.dx, center.dy + 20), - crossPaint, - ); + canvas.drawLine(Offset(center.dx - 20, center.dy), Offset(center.dx - 8, center.dy), crossPaint); + canvas.drawLine(Offset(center.dx + 8, center.dy), Offset(center.dx + 20, center.dy), crossPaint); + canvas.drawLine(Offset(center.dx, center.dy - 20), Offset(center.dx, center.dy - 8), crossPaint); + canvas.drawLine(Offset(center.dx, center.dy + 8), Offset(center.dx, center.dy + 20), crossPaint); } void _drawInstructions(Canvas canvas, Size size) { @@ -584,4 +585,4 @@ class _CalibrationPainter extends CustomPainter { isDraggingInnerRadius != oldDelegate.isDraggingInnerRadius || ringRadii != oldDelegate.ringRadii; } -} +} \ No newline at end of file