Feat: Ajout d'un switch pour masquer ou afficher le slider d'espacement de la cible

This commit is contained in:
qguillaume
2026-05-25 03:12:37 +02:00
parent a9ff826246
commit 48b8313be8

View File

@@ -4,7 +4,6 @@
/// Les anneaux sont répartis proportionnellement. /// Les anneaux sont répartis proportionnellement.
library; library;
import 'dart:math' as math;
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import '../../../core/theme/app_theme.dart'; import '../../../core/theme/app_theme.dart';
import '../../../data/models/target_type.dart'; import '../../../data/models/target_type.dart';
@@ -18,13 +17,13 @@ class TargetCalibration extends StatefulWidget {
final TargetType targetType; final TargetType targetType;
final List<double>? initialRingRadii; final List<double>? initialRingRadii;
final Function( final Function(
double centerX, double centerX,
double centerY, double centerY,
double innerRadius, double innerRadius,
double radius, double radius,
int ringCount, { int ringCount, {
List<double>? ringRadii, List<double>? ringRadii,
}) })
onCalibrationChanged; onCalibrationChanged;
const TargetCalibration({ const TargetCalibration({
@@ -55,6 +54,9 @@ class TargetCalibrationState extends State<TargetCalibration> {
bool _isDraggingRadius = false; bool _isDraggingRadius = false;
bool _isDraggingInnerRadius = false; bool _isDraggingInnerRadius = false;
// Contrôle de l'affichage du scroll d'espacement (désactivé par défaut)
bool _showEspacement = false;
@override @override
void initState() { void initState() {
super.initState(); super.initState();
@@ -138,13 +140,13 @@ class TargetCalibrationState extends State<TargetCalibration> {
ringRadii: _ringRadii, ringRadii: _ringRadii,
targetType: widget.targetType, targetType: widget.targetType,
isDraggingCenter: _isDraggingCenter, isDraggingCenter: _isDraggingCenter,
isDraggingRadius: false, // Plus de drag direct du rayon isDraggingRadius: false,
isDraggingInnerRadius: false, isDraggingInnerRadius: false,
), ),
), ),
), ),
// Slider pour le rayon (agrandissement) // Panneau de configuration des Sliders en haut
Positioned( Positioned(
top: 10, top: 10,
left: 40, left: 40,
@@ -152,6 +154,38 @@ class TargetCalibrationState extends State<TargetCalibration> {
child: Column( child: Column(
mainAxisSize: MainAxisSize.min, mainAxisSize: MainAxisSize.min,
children: [ 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( Container(
padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 4), padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 4),
decoration: BoxDecoration( decoration: BoxDecoration(
@@ -171,7 +205,6 @@ class TargetCalibrationState extends State<TargetCalibration> {
onChanged: (value) { onChanged: (value) {
setState(() { setState(() {
_radius = value; _radius = value;
// On force le recalcul car on change la taille
_initRingRadii(forceRecalculate: true); _initRingRadii(forceRecalculate: true);
}); });
_notifyChange(); _notifyChange();
@@ -182,37 +215,40 @@ class TargetCalibrationState extends State<TargetCalibration> {
], ],
), ),
), ),
const SizedBox(height: 8),
Container( // Affichage conditionnel du slider d'espacement orange
padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 4), if (_showEspacement) ...[
decoration: BoxDecoration( const SizedBox(height: 8),
color: Colors.black54, Container(
borderRadius: BorderRadius.circular(20), padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 4),
), decoration: BoxDecoration(
child: Row( color: Colors.black54,
children: [ borderRadius: BorderRadius.circular(20),
const Text('Espacement ', style: TextStyle(color: Colors.white, fontSize: 12, fontWeight: FontWeight.bold)), ),
const Icon(Icons.compress, color: Colors.white, size: 16), child: Row(
Expanded( children: [
child: Slider( const Text('Espacement ', style: TextStyle(color: Colors.white, fontSize: 12, fontWeight: FontWeight.bold)),
value: (_innerRadius / _radius).clamp(0.01, 0.9), const Icon(Icons.compress, color: Colors.white, size: 16),
min: 0.01, Expanded(
max: 0.9, child: Slider(
activeColor: Colors.orange, value: (_innerRadius / _radius).clamp(0.01, 0.9),
onChanged: (value) { min: 0.01,
setState(() { max: 0.9,
// On ajuste l'innerRadius comme un ratio du radius global activeColor: Colors.orange,
_innerRadius = _radius * value; onChanged: (value) {
_initRingRadii(forceRecalculate: true); setState(() {
}); _innerRadius = _radius * value;
_notifyChange(); _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<TargetCalibration> {
children: [ children: [
_buildDirectionButton( _buildDirectionButton(
Icons.keyboard_arrow_up, Icons.keyboard_arrow_up,
() => _moveCenterByPixels(0, -1, size), () => _moveCenterByPixels(0, -1, size),
), ),
Row( Row(
mainAxisSize: MainAxisSize.min, mainAxisSize: MainAxisSize.min,
children: [ children: [
_buildDirectionButton( _buildDirectionButton(
Icons.keyboard_arrow_left, Icons.keyboard_arrow_left,
() => _moveCenterByPixels(-1, 0, size), () => _moveCenterByPixels(-1, 0, size),
), ),
const SizedBox(width: 40), const SizedBox(width: 40),
_buildDirectionButton( _buildDirectionButton(
Icons.keyboard_arrow_right, Icons.keyboard_arrow_right,
() => _moveCenterByPixels(1, 0, size), () => _moveCenterByPixels(1, 0, size),
), ),
], ],
), ),
_buildDirectionButton( _buildDirectionButton(
Icons.keyboard_arrow_down, Icons.keyboard_arrow_down,
() => _moveCenterByPixels(0, 1, size), () => _moveCenterByPixels(0, 1, size),
), ),
], ],
), ),
@@ -312,11 +348,9 @@ class TargetCalibrationState extends State<TargetCalibration> {
void _onPanUpdate(DragUpdateDetails details, Size size) { void _onPanUpdate(DragUpdateDetails details, Size size) {
final deltaX = details.delta.dx / size.width; final deltaX = details.delta.dx / size.width;
final deltaY = details.delta.dy / size.height; final deltaY = details.delta.dy / size.height;
final minDim = math.min(size.width, size.height);
setState(() { setState(() {
if (_isDraggingCenter) { if (_isDraggingCenter) {
// Move center
_centerX = _centerX + deltaX; _centerX = _centerX + deltaX;
_centerY = _centerY + deltaY; _centerY = _centerY + deltaY;
} }
@@ -370,7 +404,6 @@ class _CalibrationPainter extends CustomPainter {
final centerPx = Offset(centerX * size.width, centerY * size.height); final centerPx = Offset(centerX * size.width, centerY * size.height);
final minDim = size.width < size.height ? size.width : size.height; final minDim = size.width < size.height ? size.width : size.height;
final baseRadiusPx = radius * minDim; final baseRadiusPx = radius * minDim;
final innerRadiusPx = innerRadius * minDim;
if (targetType == TargetType.concentric) { if (targetType == TargetType.concentric) {
_drawConcentricZones(canvas, size, centerPx, baseRadiusPx); _drawConcentricZones(canvas, size, centerPx, baseRadiusPx);
@@ -378,7 +411,6 @@ class _CalibrationPainter extends CustomPainter {
_drawSilhouetteZones(canvas, size, centerPx, baseRadiusPx); _drawSilhouetteZones(canvas, size, centerPx, baseRadiusPx);
} }
// Fullscreen crosshairs when dragging center
if (isDraggingCenter) { if (isDraggingCenter) {
final crosshairLinePaint = Paint() final crosshairLinePaint = Paint()
..color = Colors.red.withValues(alpha: 0.5) ..color = Colors.red.withValues(alpha: 0.5)
@@ -395,20 +427,16 @@ class _CalibrationPainter extends CustomPainter {
); );
} }
// Draw center handle
_drawCenterHandle(canvas, centerPx); _drawCenterHandle(canvas, centerPx);
// Draw instructions
_drawInstructions(canvas, size); _drawInstructions(canvas, size);
} }
void _drawConcentricZones( void _drawConcentricZones(
Canvas canvas, Canvas canvas,
Size size, Size size,
Offset center, Offset center,
double baseRadius, double baseRadius,
) { ) {
// Generate colors for zones
List<Color> zoneColors = []; List<Color> zoneColors = [];
for (int i = 0; i < ringCount; i++) { for (int i = 0; i < ringCount; i++) {
final ratio = i / ringCount; final ratio = i / ringCount;
@@ -431,7 +459,6 @@ class _CalibrationPainter extends CustomPainter {
..strokeWidth = 1 ..strokeWidth = 1
..color = Colors.red.withValues(alpha: 0.8); ..color = Colors.red.withValues(alpha: 0.8);
// Draw from outside to inside
for (int i = ringCount - 1; i >= 0; i--) { for (int i = ringCount - 1; i >= 0; i--) {
final ringRadius = ringRadii.length > i final ringRadius = ringRadii.length > i
? ringRadii[i] ? ringRadii[i]
@@ -443,7 +470,6 @@ class _CalibrationPainter extends CustomPainter {
canvas.drawCircle(center, zoneRadius, strokePaint); canvas.drawCircle(center, zoneRadius, strokePaint);
} }
// Draw zone labels (only if within visible area)
final textPainter = TextPainter(textDirection: TextDirection.ltr); final textPainter = TextPainter(textDirection: TextDirection.ltr);
for (int i = 0; i < ringCount; i++) { for (int i = 0; i < ringCount; i++) {
@@ -455,10 +481,7 @@ class _CalibrationPainter extends CustomPainter {
: 0.0; : 0.0;
final zoneRadius = baseRadius * (ringRadius + prevRingRadius) / 2; final zoneRadius = baseRadius * (ringRadius + prevRingRadius) / 2;
// Score: center = 10, decrement by 1 for each ring
final score = 10 - i; final score = 10 - i;
// Only draw label if it's within the visible area
final labelX = center.dx + zoneRadius; final labelX = center.dx + zoneRadius;
if (labelX < 0 || labelX > size.width) continue; if (labelX < 0 || labelX > size.width) continue;
@@ -473,7 +496,6 @@ class _CalibrationPainter extends CustomPainter {
); );
textPainter.layout(); textPainter.layout();
// Draw label on the right side of each zone
final labelY = center.dy - textPainter.height / 2; final labelY = center.dy - textPainter.height / 2;
if (labelY >= 0 && labelY <= size.height) { if (labelY >= 0 && labelY <= size.height) {
textPainter.paint( textPainter.paint(
@@ -485,17 +507,15 @@ class _CalibrationPainter extends CustomPainter {
} }
void _drawSilhouetteZones( void _drawSilhouetteZones(
Canvas canvas, Canvas canvas,
Size size, Size size,
Offset center, Offset center,
double radius, double radius,
) { ) {
// Simplified silhouette zones
final paint = Paint() final paint = Paint()
..style = PaintingStyle.stroke ..style = PaintingStyle.stroke
..strokeWidth = 2; ..strokeWidth = 2;
// Draw silhouette outline (simplified as rectangle for now)
final silhouetteWidth = radius * 0.8; final silhouetteWidth = radius * 0.8;
final silhouetteHeight = radius * 2; final silhouetteHeight = radius * 2;
@@ -511,43 +531,24 @@ class _CalibrationPainter extends CustomPainter {
} }
void _drawCenterHandle(Canvas canvas, Offset center) { void _drawCenterHandle(Canvas canvas, Offset center) {
// Outer circle
final outerPaint = Paint() final outerPaint = Paint()
..color = isDraggingCenter ? Colors.redAccent : Colors.red ..color = isDraggingCenter ? Colors.redAccent : Colors.red
..style = PaintingStyle.stroke ..style = PaintingStyle.stroke
..strokeWidth = 3; ..strokeWidth = 3;
canvas.drawCircle(center, 15, outerPaint); canvas.drawCircle(center, 15, outerPaint);
// Inner dot
final innerPaint = Paint() final innerPaint = Paint()
..color = isDraggingCenter ? Colors.redAccent : Colors.red ..color = isDraggingCenter ? Colors.redAccent : Colors.red
..style = PaintingStyle.fill; ..style = PaintingStyle.fill;
canvas.drawCircle(center, 5, innerPaint); canvas.drawCircle(center, 5, innerPaint);
// Crosshair
final crossPaint = Paint() final crossPaint = Paint()
..color = isDraggingCenter ? Colors.redAccent : Colors.red ..color = isDraggingCenter ? Colors.redAccent : Colors.red
..strokeWidth = 2; ..strokeWidth = 2;
canvas.drawLine( canvas.drawLine(Offset(center.dx - 20, center.dy), Offset(center.dx - 8, center.dy), crossPaint);
Offset(center.dx - 20, center.dy), canvas.drawLine(Offset(center.dx + 8, center.dy), Offset(center.dx + 20, center.dy), crossPaint);
Offset(center.dx - 8, center.dy), canvas.drawLine(Offset(center.dx, center.dy - 20), Offset(center.dx, center.dy - 8), crossPaint);
crossPaint, canvas.drawLine(Offset(center.dx, center.dy + 8), Offset(center.dx, center.dy + 20), 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) { void _drawInstructions(Canvas canvas, Size size) {