From aeda7ddd2e0bf4babc83bbbb73831a1c7f63ce03 Mon Sep 17 00:00:00 2001 From: Bl3kiiie Date: Mon, 7 Apr 2025 20:02:16 +0200 Subject: [PATCH] finished bullet adjustment --- lib/screens/preview_screen.dart | 334 +++++++++++++++++--------------- 1 file changed, 181 insertions(+), 153 deletions(-) diff --git a/lib/screens/preview_screen.dart b/lib/screens/preview_screen.dart index 5808da1..ab1aa0a 100644 --- a/lib/screens/preview_screen.dart +++ b/lib/screens/preview_screen.dart @@ -47,7 +47,7 @@ class _PreviewScreenState extends State { final List _manualBulletScores = []; Color _bulletColor = Colors.blue; // default fallback - double get _bulletOpacity => 0.7; + double get _bulletOpacity => 0.8; bool _isEditMode = false; int? _selectedBulletIndexInEdit; @@ -204,35 +204,23 @@ Color _getColorFromName(String colorName) { _cachedTargetImage = Uint8List.fromList(img.encodePng(_targetImageDecoded!)); } - // 10. Update UI - final missing = widget.bulletCount - mappedBullets.length; - + // 10. Update state with mapped bullets setState(() { _mappedBullets = mappedBullets; _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) { debugPrint("❌ Error during detection mapping: $e"); debugPrint(stack.toString()); - setState(() => _isLoading = false); + setState(() { + _mappedBullets = []; + _isLoading = false; + }); } } + Future _showMismatchOptionsDialog(int detectedCount) async { return showDialog( context: context, @@ -780,6 +768,24 @@ void _moveBullet(Offset offsetDelta) { 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 Widget build(BuildContext context) { return Scaffold( @@ -822,6 +828,51 @@ Widget build(BuildContext context) { ? const Center(child: CircularProgressIndicator()) : Stack( 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( children: [ Expanded( @@ -918,6 +969,14 @@ Widget build(BuildContext context) { final isHighlighted = index == _highlightedBulletIndex; 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( left: dx - bulletSize / 2, @@ -926,17 +985,15 @@ Widget build(BuildContext context) { width: bulletSize, height: bulletSize, decoration: BoxDecoration( - color: _activeColorWithOpacity, + color: bulletFillColor, shape: BoxShape.circle, border: Border.all( - color: isSelectedForEdit - ? _bulletColor - : (!_isEditMode && isHighlighted) - ? Colors.red - : Colors.black, - width: (isSelectedForEdit || (!_isEditMode && isHighlighted)) ? 3 : 1, + color: (isSelectedForEdit || (!_isEditMode && isHighlighted)) + ? Colors.red + : Colors.black, + width: (isSelectedForEdit || (!_isEditMode && isHighlighted)) ? 3 : 1, + ), ), - ), ), ); }).toList(), @@ -947,147 +1004,118 @@ Widget build(BuildContext context) { ), const SizedBox(height: 12), if (_mappedBullets.isNotEmpty) - Padding( - padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 6), - child: Row( - children: List.generate( - _mappedBullets.length, - (index) { - final bullet = _mappedBullets[index]; - final isManual = index >= (_mappedBullets.length - _manualBulletScores.length); - final score = isManual - ? _manualBulletScores[index - (_mappedBullets.length - _manualBulletScores.length)] - : _scoreForBullet( - bullet, - _targetImageCenterForScoring ?? fixedRingTargetCenter, - ); - final isSelected = index == (_isEditMode ? _selectedBulletIndexInEdit : _highlightedBulletIndex); + Column( + children: [ + // Score buttons + Padding( + padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 6), + child: Row( + children: List.generate( + _mappedBullets.length, + (index) { + final bullet = _mappedBullets[index]; + final isManual = index >= (_mappedBullets.length - _manualBulletScores.length); + final score = isManual + ? _manualBulletScores[index - (_mappedBullets.length - _manualBulletScores.length)] + : _scoreForBullet( + bullet, + _targetImageCenterForScoring ?? fixedRingTargetCenter, + ); - return Expanded( - child: Padding( - padding: const EdgeInsets.symmetric(horizontal: 6), - child: GestureDetector( - onTap: () { - if (_isEditMode) { - setState(() => _selectedBulletIndexInEdit = index); - } - }, - onTapDown: (_) { - if (!_isEditMode) { - setState(() => _highlightedBulletIndex = index); - } - }, - onTapUp: (_) { - if (!_isEditMode) { - setState(() => _highlightedBulletIndex = null); - } - }, - onTapCancel: () { - if (!_isEditMode) { - setState(() => _highlightedBulletIndex = null); - } - }, - child: AnimatedContainer( - duration: const Duration(milliseconds: 200), - height: 100, - decoration: BoxDecoration( - borderRadius: BorderRadius.circular(16), - boxShadow: const [ - BoxShadow( - color: Colors.black26, - offset: Offset(0, 2), - blurRadius: 6, - ), - ], - ), - child: Column( - children: [ - Container( - height: 30, - decoration: BoxDecoration( - color: Colors.grey[300], - borderRadius: const BorderRadius.only( - topLeft: Radius.circular(16), - topRight: Radius.circular(16), + return Expanded( + child: Padding( + padding: const EdgeInsets.symmetric(horizontal: 6), + child: GestureDetector( + onTap: () { + if (_isEditMode) { + setState(() => _selectedBulletIndexInEdit = index); + } + }, + onTapDown: (_) { + if (!_isEditMode) { + setState(() => _highlightedBulletIndex = index); + } + }, + onTapUp: (_) { + if (!_isEditMode) { + setState(() => _highlightedBulletIndex = null); + } + }, + onTapCancel: () { + if (!_isEditMode) { + setState(() => _highlightedBulletIndex = null); + } + }, + child: AnimatedContainer( + duration: const Duration(milliseconds: 200), + height: 100, + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(16), + boxShadow: const [ + BoxShadow( + color: Colors.black26, + offset: Offset(0, 2), + blurRadius: 6, ), - ), - alignment: Alignment.center, - child: Text( - '${index + 1}', - style: const TextStyle( - fontWeight: FontWeight.bold, - fontSize: 14, - color: Colors.black87, - ), - ), + ], ), - Expanded( - child: Container( - decoration: BoxDecoration( - color: isSelected - ? _editColor - : _activeColor, - borderRadius: const BorderRadius.only( - bottomLeft: Radius.circular(16), - bottomRight: Radius.circular(16), + child: Column( + children: [ + Container( + height: 30, + decoration: BoxDecoration( + color: Colors.grey[300], + borderRadius: const BorderRadius.only( + topLeft: Radius.circular(16), + topRight: Radius.circular(16), + ), + ), + alignment: Alignment.center, + child: Text( + '${index + 1}', + style: const TextStyle( + fontWeight: FontWeight.bold, + fontSize: 14, + color: Colors.black87, + ), ), ), - alignment: Alignment.center, - child: Text( - '$score', - style: const TextStyle( - fontSize: 28, - fontWeight: FontWeight.bold, - color: Colors.white, + Expanded( + child: Container( + decoration: BoxDecoration( + color: _getBulletButtonColor(index), + borderRadius: const BorderRadius.only( + bottomLeft: Radius.circular(16), + bottomRight: Radius.circular(16), + ), + ), + alignment: Alignment.center, + child: Text( + '$score', + style: const TextStyle( + fontSize: 28, + fontWeight: FontWeight.bold, + color: Colors.white, + ), + ), ), ), - ), + ], ), - ], + ), ), ), - ), - ), - ); - }, + ); + }, + ), + ), ), - ), + ], ), + const SizedBox(height: 12), ], ), - - Positioned( - 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(), ], ),