finished bullet adjustment

This commit is contained in:
2025-04-07 20:02:16 +02:00
parent 208819dba9
commit aeda7ddd2e
+86 -58
View File
@@ -47,7 +47,7 @@ class _PreviewScreenState extends State<PreviewScreen> {
final List<int> _manualBulletScores = []; final List<int> _manualBulletScores = [];
Color _bulletColor = Colors.blue; // default fallback Color _bulletColor = Colors.blue; // default fallback
double get _bulletOpacity => 0.7; double get _bulletOpacity => 0.8;
bool _isEditMode = false; bool _isEditMode = false;
int? _selectedBulletIndexInEdit; int? _selectedBulletIndexInEdit;
@@ -204,35 +204,23 @@ Color _getColorFromName(String colorName) {
_cachedTargetImage = Uint8List.fromList(img.encodePng(_targetImageDecoded!)); _cachedTargetImage = Uint8List.fromList(img.encodePng(_targetImageDecoded!));
} }
// 10. Update UI // 10. Update state with mapped bullets
final missing = widget.bulletCount - mappedBullets.length;
setState(() { setState(() {
_mappedBullets = mappedBullets; _mappedBullets = mappedBullets;
_isLoading = false; _isLoading = false;
}); });
if (missing > 0) {
final result = await _showMismatchOptionsDialog(mappedBullets.length);
if (result == 'retry') {
Navigator.pop(context); // Go back to camera screen
} else if (result == 'manual') {
_manualScoreEntry(); // Reuse your original manual dialog
}
}
} catch (e, stack) { } catch (e, stack) {
debugPrint("❌ Error during detection mapping: $e"); debugPrint("❌ Error during detection mapping: $e");
debugPrint(stack.toString()); debugPrint(stack.toString());
setState(() => _isLoading = false); setState(() {
_mappedBullets = [];
_isLoading = false;
});
} }
} }
Future<String?> _showMismatchOptionsDialog(int detectedCount) async { Future<String?> _showMismatchOptionsDialog(int detectedCount) async {
return showDialog<String>( return showDialog<String>(
context: context, context: context,
@@ -780,6 +768,24 @@ void _moveBullet(Offset offsetDelta) {
return autoScore + manualScore; return autoScore + manualScore;
} }
Color _getBulletButtonColor(int index) {
final isSelected = _isEditMode
? index == _selectedBulletIndexInEdit
: index == _highlightedBulletIndex;
if (isSelected) return Colors.red;
final manualStart = _mappedBullets.length - _manualBulletScores.length;
final isManual = index >= manualStart;
if (isManual) return Colors.redAccent; // ⬅️ Light red for manual bullets
if (_isEditMode) return _editColor;
return _bulletColor;
}
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Scaffold( return Scaffold(
@@ -822,6 +828,51 @@ Widget build(BuildContext context) {
? const Center(child: CircularProgressIndicator()) ? const Center(child: CircularProgressIndicator())
: Stack( : Stack(
children: [ children: [
if (_mappedBullets.isNotEmpty)
Padding(
padding: const EdgeInsets.fromLTRB(16, 12, 16, 8),
child: SizedBox(
width: double.infinity,
child: ElevatedButton.icon(
onPressed: () async {
if (!_isEditMode && _mappedBullets.length < widget.bulletCount) {
final result = await _showMismatchOptionsDialog(_mappedBullets.length);
if (result == 'retry') {
Navigator.pop(context);
return;
} else if (result == 'manual') {
_manualScoreEntry();
return;
} else {
return;
}
}
setState(() {
_isEditMode = !_isEditMode;
_selectedBulletIndexInEdit = null;
});
},
icon: Icon(
_isEditMode ? Icons.check : Icons.edit,
color: Colors.white,
size: 20,
),
label: Text(
_isEditMode ? "Done Editing" : "Edit Bullets",
style: const TextStyle(color: Colors.white, fontSize: 16),
),
style: ElevatedButton.styleFrom(
backgroundColor: _activeColor,
padding: const EdgeInsets.symmetric(vertical: 14),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(12),
),
),
),
),
),
Column( Column(
children: [ children: [
Expanded( Expanded(
@@ -918,6 +969,14 @@ Widget build(BuildContext context) {
final isHighlighted = index == _highlightedBulletIndex; final isHighlighted = index == _highlightedBulletIndex;
final isSelectedForEdit = index == _selectedBulletIndexInEdit; final isSelectedForEdit = index == _selectedBulletIndexInEdit;
final manualStart = _mappedBullets.length - _manualBulletScores.length;
final isManual = index >= manualStart;
final Color bulletFillColor = isSelectedForEdit || (!_isEditMode && isHighlighted)
? Colors.red.withOpacity(_bulletOpacity)
: isManual
? Colors.red.withOpacity(_bulletOpacity)
: _activeColorWithOpacity;
return Positioned( return Positioned(
left: dx - bulletSize / 2, left: dx - bulletSize / 2,
@@ -926,12 +985,10 @@ Widget build(BuildContext context) {
width: bulletSize, width: bulletSize,
height: bulletSize, height: bulletSize,
decoration: BoxDecoration( decoration: BoxDecoration(
color: _activeColorWithOpacity, color: bulletFillColor,
shape: BoxShape.circle, shape: BoxShape.circle,
border: Border.all( border: Border.all(
color: isSelectedForEdit color: (isSelectedForEdit || (!_isEditMode && isHighlighted))
? _bulletColor
: (!_isEditMode && isHighlighted)
? Colors.red ? Colors.red
: Colors.black, : Colors.black,
width: (isSelectedForEdit || (!_isEditMode && isHighlighted)) ? 3 : 1, width: (isSelectedForEdit || (!_isEditMode && isHighlighted)) ? 3 : 1,
@@ -947,6 +1004,9 @@ Widget build(BuildContext context) {
), ),
const SizedBox(height: 12), const SizedBox(height: 12),
if (_mappedBullets.isNotEmpty) if (_mappedBullets.isNotEmpty)
Column(
children: [
// Score buttons
Padding( Padding(
padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 6), padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 6),
child: Row( child: Row(
@@ -961,7 +1021,6 @@ Widget build(BuildContext context) {
bullet, bullet,
_targetImageCenterForScoring ?? fixedRingTargetCenter, _targetImageCenterForScoring ?? fixedRingTargetCenter,
); );
final isSelected = index == (_isEditMode ? _selectedBulletIndexInEdit : _highlightedBulletIndex);
return Expanded( return Expanded(
child: Padding( child: Padding(
@@ -1024,9 +1083,7 @@ Widget build(BuildContext context) {
Expanded( Expanded(
child: Container( child: Container(
decoration: BoxDecoration( decoration: BoxDecoration(
color: isSelected color: _getBulletButtonColor(index),
? _editColor
: _activeColor,
borderRadius: const BorderRadius.only( borderRadius: const BorderRadius.only(
bottomLeft: Radius.circular(16), bottomLeft: Radius.circular(16),
bottomRight: Radius.circular(16), bottomRight: Radius.circular(16),
@@ -1053,41 +1110,12 @@ Widget build(BuildContext context) {
), ),
), ),
), ),
const SizedBox(height: 12),
], ],
), ),
Positioned( const SizedBox(height: 12),
top: 12, ],
right: 12,
child: ElevatedButton.icon(
onPressed: () {
setState(() {
_isEditMode = !_isEditMode;
_selectedBulletIndexInEdit = null;
});
},
icon: Icon(
_isEditMode ? Icons.check : Icons.edit,
color: Colors.white,
size: 20,
), ),
label: Text(
_isEditMode ? "Done" : "Edit Bullets",
style: const TextStyle(color: Colors.white),
),
style: ElevatedButton.styleFrom(
backgroundColor: _activeColor, // ← dynamic color depending on mode
padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 8),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(10),
),
elevation: 4,
),
),
),
_buildEditController(), _buildEditController(),
], ],
), ),