finished bullet adjustment
This commit is contained in:
@@ -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(),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
|
|||||||
Reference in New Issue
Block a user