fix(analysis): appliquer la rotation du crop sur l'image en modes calibration et plotting
This commit is contained in:
@@ -23,11 +23,8 @@ import '../crop/crop_screen.dart';
|
||||
import '../capture/capture_screen.dart';
|
||||
import 'widgets/target_overlay.dart';
|
||||
import 'widgets/target_calibration.dart';
|
||||
import 'widgets/target_overlay.dart';
|
||||
import 'widgets/score_card.dart';
|
||||
import 'widgets/grouping_stats.dart';
|
||||
import '../capture/capture_screen.dart'; // Si ton écran principal s'appelle comme ça
|
||||
import '../crop/crop_screen.dart';
|
||||
|
||||
class AnalysisScreen extends StatelessWidget {
|
||||
final String imagePath;
|
||||
@@ -57,12 +54,20 @@ class AnalysisScreen extends StatelessWidget {
|
||||
: null;
|
||||
|
||||
return ChangeNotifierProvider(
|
||||
create: (context) => AnalysisProvider(
|
||||
detectionService: context.read<TargetDetectionService>(),
|
||||
scoreCalculatorService: context.read<ScoreCalculatorService>(),
|
||||
groupingAnalyzerService: context.read<GroupingAnalyzerService>(),
|
||||
sessionRepository: context.read<SessionRepository>(),
|
||||
)..analyzeImage(imagePath, targetType, autoAnalyze: false, manualCenter: manualCenterOffset),
|
||||
create: (context) {
|
||||
final p = AnalysisProvider(
|
||||
detectionService: context.read<TargetDetectionService>(),
|
||||
scoreCalculatorService: context.read<ScoreCalculatorService>(),
|
||||
groupingAnalyzerService: context.read<GroupingAnalyzerService>(),
|
||||
sessionRepository: context.read<SessionRepository>(),
|
||||
);
|
||||
// Sauvegarde de l'angle de rotation d'origine directement dans l'état global
|
||||
if (cropRotation != null) {
|
||||
p.setCropRotation(cropRotation!);
|
||||
}
|
||||
p.analyzeImage(imagePath, targetType, autoAnalyze: false, manualCenter: manualCenterOffset);
|
||||
return p;
|
||||
},
|
||||
child: _AnalysisScreenContent(
|
||||
cropScale: cropScale,
|
||||
cropOffset: cropOffset,
|
||||
@@ -207,7 +212,7 @@ class _AnalysisScreenContentState extends State<_AnalysisScreenContent> {
|
||||
),
|
||||
),
|
||||
|
||||
// SECTION CORRIGÉE : Utilise maintenant widget.cropRotation sans aucune erreur !
|
||||
// SECTION CORRIGÉE : Utilise maintenant la réactivité du provider globale
|
||||
AspectRatio(
|
||||
aspectRatio: provider.imageAspectRatio,
|
||||
child: _isCalibrating
|
||||
@@ -217,19 +222,15 @@ class _AnalysisScreenContentState extends State<_AnalysisScreenContent> {
|
||||
ClipRect(
|
||||
child: Builder(
|
||||
builder: (context) {
|
||||
final double rotationAngle = widget.cropRotation ?? 0.0;
|
||||
|
||||
return Transform(
|
||||
transform: Matrix4.identity()
|
||||
..translate(widget.cropOffset?.dx ?? 0.0, widget.cropOffset?.dy ?? 0.0)
|
||||
..scale(1.0, 1.0), // Zoom ignoré au plotting pour rester en vue globale
|
||||
..setTranslationRaw(widget.cropOffset?.dx ?? 0.0, widget.cropOffset?.dy ?? 0.0, 0.0)
|
||||
..scale(1.0, 1.0) // Zoom ignoré au plotting pour rester en vue globale
|
||||
..rotateZ((provider.cropRotation) * (math.pi / 180)), // FIX : Utilisation du provider dynamique
|
||||
alignment: Alignment.center,
|
||||
child: Transform.rotate(
|
||||
angle: rotationAngle * (math.pi / 180),
|
||||
child: Image.file(
|
||||
File(provider.imagePath!),
|
||||
fit: BoxFit.contain,
|
||||
),
|
||||
child: Image.file(
|
||||
File(provider.imagePath!),
|
||||
fit: BoxFit.contain,
|
||||
),
|
||||
);
|
||||
}
|
||||
@@ -486,10 +487,18 @@ class _AnalysisScreenContentState extends State<_AnalysisScreenContent> {
|
||||
},
|
||||
child: Stack(
|
||||
children: [
|
||||
Image.file(
|
||||
File(provider.imagePath!),
|
||||
key: _imageKey,
|
||||
fit: BoxFit.fill,
|
||||
// FIX CRITIQUE PLOTTING : L'image de fond doit appliquer exactement le même angle de rotation qu'en calibration !
|
||||
Transform(
|
||||
transform: Matrix4.identity()
|
||||
..setTranslationRaw(widget.cropOffset?.dx ?? 0.0, widget.cropOffset?.dy ?? 0.0, 0.0)
|
||||
..scale(1.0, 1.0)
|
||||
..rotateZ((provider.cropRotation) * (math.pi / 180)),
|
||||
alignment: Alignment.center,
|
||||
child: Image.file(
|
||||
File(provider.imagePath!),
|
||||
key: _imageKey,
|
||||
fit: BoxFit.contain, // Remplace BoxFit.fill pour s'aligner sur la Calibration
|
||||
),
|
||||
),
|
||||
TargetOverlay(
|
||||
targetCenterX: provider.targetCenterX,
|
||||
@@ -568,6 +577,7 @@ class _AnalysisScreenContentState extends State<_AnalysisScreenContent> {
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
void _showSaveSessionDialog(BuildContext context, AnalysisProvider provider) {
|
||||
showDialog(
|
||||
context: context,
|
||||
@@ -645,7 +655,7 @@ class _AnalysisScreenContentState extends State<_AnalysisScreenContent> {
|
||||
weaponName: sessionProvider.currentWeapon,
|
||||
weaponId: sessionProvider.currentWeaponId,
|
||||
distance: sessionProvider.distance,
|
||||
date: sessionProvider.sessionDate, // <-- CORRECTION : Prise en compte de la date ici aussi !
|
||||
date: sessionProvider.sessionDate,
|
||||
);
|
||||
|
||||
if (context.mounted) {
|
||||
@@ -667,4 +677,4 @@ class _AnalysisScreenContentState extends State<_AnalysisScreenContent> {
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user