fixed controller and coloring
This commit is contained in:
@@ -442,45 +442,57 @@ void _manualScoreEntry() {
|
|||||||
right: 0,
|
right: 0,
|
||||||
child: Center(
|
child: Center(
|
||||||
child: Container(
|
child: Container(
|
||||||
padding: const EdgeInsets.all(8),
|
padding: const EdgeInsets.symmetric(vertical: 16, horizontal: 20),
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
color: Colors.black.withOpacity(0.75),
|
color: Colors.black.withOpacity(0.75),
|
||||||
borderRadius: BorderRadius.circular(12),
|
borderRadius: BorderRadius.circular(16),
|
||||||
),
|
),
|
||||||
child: Column(
|
child: Column(
|
||||||
mainAxisSize: MainAxisSize.min,
|
mainAxisSize: MainAxisSize.min,
|
||||||
children: [
|
children: [
|
||||||
|
// Up
|
||||||
IconButton(
|
IconButton(
|
||||||
icon: const Icon(Icons.arrow_drop_up, size: 32, color: Colors.white),
|
icon: const Icon(Icons.keyboard_arrow_up, size: 36, color: Colors.white),
|
||||||
onPressed: () => _moveBullet(const Offset(0, -3)),
|
onPressed: () => _moveBullet(const Offset(0, -3)),
|
||||||
splashRadius: 20,
|
splashRadius: 24,
|
||||||
),
|
),
|
||||||
|
|
||||||
|
// Left - Check - Right
|
||||||
Row(
|
Row(
|
||||||
mainAxisSize: MainAxisSize.min,
|
mainAxisSize: MainAxisSize.min,
|
||||||
children: [
|
children: [
|
||||||
IconButton(
|
IconButton(
|
||||||
icon: const Icon(Icons.arrow_left, size: 32, color: Colors.white),
|
icon: const Icon(Icons.keyboard_arrow_left, size: 36, color: Colors.white),
|
||||||
onPressed: () => _moveBullet(const Offset(-3, 0)),
|
onPressed: () => _moveBullet(const Offset(-3, 0)),
|
||||||
splashRadius: 20,
|
splashRadius: 24,
|
||||||
),
|
),
|
||||||
const SizedBox(width: 4),
|
const SizedBox(width: 8),
|
||||||
IconButton(
|
Container(
|
||||||
icon: const Icon(Icons.check, size: 28, color: Colors.greenAccent),
|
decoration: BoxDecoration(
|
||||||
onPressed: () => setState(() => _selectedBulletIndexInEdit = null),
|
shape: BoxShape.circle,
|
||||||
splashRadius: 20,
|
color: Colors.greenAccent.withOpacity(0.2),
|
||||||
|
border: Border.all(color: Colors.greenAccent, width: 2),
|
||||||
|
),
|
||||||
|
child: IconButton(
|
||||||
|
icon: const Icon(Icons.check, color: Colors.greenAccent, size: 28),
|
||||||
|
onPressed: () => setState(() => _selectedBulletIndexInEdit = null),
|
||||||
|
splashRadius: 22,
|
||||||
|
),
|
||||||
),
|
),
|
||||||
const SizedBox(width: 4),
|
const SizedBox(width: 8),
|
||||||
IconButton(
|
IconButton(
|
||||||
icon: const Icon(Icons.arrow_right, size: 32, color: Colors.white),
|
icon: const Icon(Icons.keyboard_arrow_right, size: 36, color: Colors.white),
|
||||||
onPressed: () => _moveBullet(const Offset(3, 0)),
|
onPressed: () => _moveBullet(const Offset(3, 0)),
|
||||||
splashRadius: 20,
|
splashRadius: 24,
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
|
|
||||||
|
// Down
|
||||||
IconButton(
|
IconButton(
|
||||||
icon: const Icon(Icons.arrow_drop_down, size: 32, color: Colors.white),
|
icon: const Icon(Icons.keyboard_arrow_down, size: 36, color: Colors.white),
|
||||||
onPressed: () => _moveBullet(const Offset(0, 3)),
|
onPressed: () => _moveBullet(const Offset(0, 3)),
|
||||||
splashRadius: 20,
|
splashRadius: 24,
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
@@ -490,6 +502,7 @@ void _manualScoreEntry() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void _moveBullet(Offset offsetDelta) {
|
void _moveBullet(Offset offsetDelta) {
|
||||||
setState(() {
|
setState(() {
|
||||||
final index = _selectedBulletIndexInEdit!;
|
final index = _selectedBulletIndexInEdit!;
|
||||||
@@ -864,7 +877,7 @@ Widget build(BuildContext context) {
|
|||||||
style: const TextStyle(color: Colors.white, fontSize: 16),
|
style: const TextStyle(color: Colors.white, fontSize: 16),
|
||||||
),
|
),
|
||||||
style: ElevatedButton.styleFrom(
|
style: ElevatedButton.styleFrom(
|
||||||
backgroundColor: _activeColor,
|
backgroundColor: Colors.red,
|
||||||
padding: const EdgeInsets.symmetric(vertical: 14),
|
padding: const EdgeInsets.symmetric(vertical: 14),
|
||||||
shape: RoundedRectangleBorder(
|
shape: RoundedRectangleBorder(
|
||||||
borderRadius: BorderRadius.circular(12),
|
borderRadius: BorderRadius.circular(12),
|
||||||
@@ -1009,10 +1022,12 @@ Widget build(BuildContext context) {
|
|||||||
// Score buttons
|
// Score buttons
|
||||||
Padding(
|
Padding(
|
||||||
padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 6),
|
padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 6),
|
||||||
child: Row(
|
child: AbsorbPointer(
|
||||||
children: List.generate(
|
absorbing: _isEditMode && _selectedBulletIndexInEdit != null,
|
||||||
_mappedBullets.length,
|
child: Row(
|
||||||
(index) {
|
children: List.generate(
|
||||||
|
_mappedBullets.length,
|
||||||
|
(index) {
|
||||||
final bullet = _mappedBullets[index];
|
final bullet = _mappedBullets[index];
|
||||||
final isManual = index >= (_mappedBullets.length - _manualBulletScores.length);
|
final isManual = index >= (_mappedBullets.length - _manualBulletScores.length);
|
||||||
final score = isManual
|
final score = isManual
|
||||||
@@ -1110,9 +1125,9 @@ Widget build(BuildContext context) {
|
|||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
],
|
),
|
||||||
),
|
],
|
||||||
|
),
|
||||||
const SizedBox(height: 12),
|
const SizedBox(height: 12),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
|
|||||||
+105
-88
@@ -43,7 +43,7 @@ class _TargetViewScreenState extends State<TargetViewScreen> {
|
|||||||
@override
|
@override
|
||||||
void initState() {
|
void initState() {
|
||||||
super.initState();
|
super.initState();
|
||||||
_loadBulletColor(); // 👈 this will load bullet color
|
_loadBulletColor();
|
||||||
_loadJsonAndImage();
|
_loadJsonAndImage();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -285,32 +285,33 @@ class _TargetViewScreenState extends State<TargetViewScreen> {
|
|||||||
child: Image.memory(_targetImageBytes!, fit: BoxFit.fill),
|
child: Image.memory(_targetImageBytes!, fit: BoxFit.fill),
|
||||||
),
|
),
|
||||||
..._bullets.asMap().entries.map((entry) {
|
..._bullets.asMap().entries.map((entry) {
|
||||||
final i = entry.key;
|
final i = entry.key;
|
||||||
final bullet = entry.value;
|
final bullet = entry.value;
|
||||||
final dx = bullet.dx * scaleX + offsetX;
|
final dx = bullet.dx * scaleX + offsetX;
|
||||||
final dy = bullet.dy * scaleY + offsetY;
|
final dy = bullet.dy * scaleY + offsetY;
|
||||||
final score = _scoreForBullet(bullet, _targetCenter!);
|
final score = _scoreForBullet(bullet, _targetCenter ?? Offset.zero);
|
||||||
final isHighlighted = widget.isCombinedView
|
final isHighlighted = widget.isCombinedView
|
||||||
? (_pressedScoreGroup == score)
|
? (_pressedScoreGroup == score)
|
||||||
: (i == _highlightedBulletIndex);
|
: (i == _highlightedBulletIndex);
|
||||||
|
|
||||||
return Positioned(
|
return Positioned(
|
||||||
left: dx - bulletSize / 2,
|
left: dx - bulletSize / 2,
|
||||||
top: dy - bulletSize / 2,
|
top: dy - bulletSize / 2,
|
||||||
child: Container(
|
child: Container(
|
||||||
width: bulletSize,
|
width: bulletSize,
|
||||||
height: bulletSize,
|
height: bulletSize,
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
color: _bulletColor.withOpacity(0.8),
|
color: _bulletColor.withOpacity(0.8),
|
||||||
shape: BoxShape.circle,
|
shape: BoxShape.circle,
|
||||||
border: Border.all(
|
border: Border.all(
|
||||||
color: isHighlighted ? Colors.red : Colors.black,
|
color: isHighlighted ? Colors.red : Colors.black,
|
||||||
width: isHighlighted ? 3 : 1,
|
width: isHighlighted ? 3 : 1,
|
||||||
),
|
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
);
|
),
|
||||||
}).toList(),
|
);
|
||||||
|
})
|
||||||
|
.toList(),
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
@@ -355,7 +356,11 @@ class _TargetViewScreenState extends State<TargetViewScreen> {
|
|||||||
scoreGroups[score] = (scoreGroups[score] ?? 0) + 1;
|
scoreGroups[score] = (scoreGroups[score] ?? 0) + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
return scoreGroups.entries.map((entry) {
|
// Sort scores descending (10 → 0)
|
||||||
|
final sortedEntries = scoreGroups.entries.toList()
|
||||||
|
..sort((a, b) => b.key.compareTo(a.key));
|
||||||
|
|
||||||
|
return sortedEntries.map((entry) {
|
||||||
final score = entry.key;
|
final score = entry.key;
|
||||||
final count = entry.value;
|
final count = entry.value;
|
||||||
|
|
||||||
@@ -370,10 +375,10 @@ class _TargetViewScreenState extends State<TargetViewScreen> {
|
|||||||
height: 100,
|
height: 100,
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
borderRadius: BorderRadius.circular(16),
|
borderRadius: BorderRadius.circular(16),
|
||||||
boxShadow: [
|
boxShadow: const [
|
||||||
BoxShadow(
|
BoxShadow(
|
||||||
color: Colors.black26,
|
color: Colors.black26,
|
||||||
offset: const Offset(0, 2),
|
offset: Offset(0, 2),
|
||||||
blurRadius: 6,
|
blurRadius: 6,
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
@@ -406,8 +411,8 @@ class _TargetViewScreenState extends State<TargetViewScreen> {
|
|||||||
child: Container(
|
child: Container(
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
color: _pressedScoreGroup == score
|
color: _pressedScoreGroup == score
|
||||||
? Colors.red[400]
|
? Colors.red[400]
|
||||||
: _bulletColor.withOpacity(0.85),
|
: _bulletColor.withOpacity(0.85),
|
||||||
borderRadius: const BorderRadius.only(
|
borderRadius: const BorderRadius.only(
|
||||||
bottomLeft: Radius.circular(16),
|
bottomLeft: Radius.circular(16),
|
||||||
bottomRight: Radius.circular(16),
|
bottomRight: Radius.circular(16),
|
||||||
@@ -437,79 +442,91 @@ class _TargetViewScreenState extends State<TargetViewScreen> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
List<Widget> _buildIndividualScoreButtons() {
|
|
||||||
return List.generate(_bullets.length, (index) {
|
|
||||||
final bullet = _bullets[index];
|
|
||||||
final score = _scoreForBullet(bullet, _targetCenter!);
|
|
||||||
|
|
||||||
return Expanded(
|
List<Widget> _buildIndividualScoreButtons() {
|
||||||
child: Padding(
|
final scoredBullets = _bullets.asMap().entries.map((entry) {
|
||||||
padding: const EdgeInsets.symmetric(horizontal: 6),
|
final index = entry.key;
|
||||||
child: GestureDetector(
|
final bullet = entry.value;
|
||||||
onTapDown: (_) => setState(() => _highlightedBulletIndex = index),
|
final score = _scoreForBullet(bullet, _targetCenter ?? Offset.zero);
|
||||||
onTapUp: (_) => setState(() => _highlightedBulletIndex = null),
|
return {'index': index, 'score': score, 'bullet': bullet};
|
||||||
onTapCancel: () => setState(() => _highlightedBulletIndex = null),
|
}).toList();
|
||||||
child: Container(
|
|
||||||
height: 100,
|
// Sort descending by score
|
||||||
decoration: BoxDecoration(
|
scoredBullets.sort((a, b) => (b['score'] as int).compareTo(a['score'] as int));
|
||||||
borderRadius: BorderRadius.circular(16),
|
|
||||||
boxShadow: [
|
return scoredBullets.map((entry) {
|
||||||
BoxShadow(
|
final int index = entry['index'] as int;
|
||||||
color: Colors.black26,
|
final int score = entry['score'] as int;
|
||||||
offset: const Offset(0, 2),
|
|
||||||
blurRadius: 6,
|
return Expanded(
|
||||||
|
child: Padding(
|
||||||
|
padding: const EdgeInsets.symmetric(horizontal: 6),
|
||||||
|
child: GestureDetector(
|
||||||
|
onTapDown: (_) => setState(() => _highlightedBulletIndex = index),
|
||||||
|
onTapUp: (_) => setState(() => _highlightedBulletIndex = null),
|
||||||
|
onTapCancel: () => setState(() => _highlightedBulletIndex = null),
|
||||||
|
child: Container(
|
||||||
|
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),
|
||||||
|
),
|
||||||
),
|
),
|
||||||
],
|
alignment: Alignment.center,
|
||||||
),
|
child: Text(
|
||||||
child: Column(
|
'${index + 1}',
|
||||||
children: [
|
style: const TextStyle(
|
||||||
Container(
|
fontWeight: FontWeight.bold,
|
||||||
height: 30,
|
fontSize: 14,
|
||||||
|
color: Colors.black87,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Expanded(
|
||||||
|
child: Container(
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
color: Colors.grey[300],
|
color: _highlightedBulletIndex == index
|
||||||
|
? Colors.red[400]
|
||||||
|
: _bulletColor.withOpacity(0.85),
|
||||||
borderRadius: const BorderRadius.only(
|
borderRadius: const BorderRadius.only(
|
||||||
topLeft: Radius.circular(16),
|
bottomLeft: Radius.circular(16),
|
||||||
topRight: Radius.circular(16),
|
bottomRight: Radius.circular(16),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
alignment: Alignment.center,
|
alignment: Alignment.center,
|
||||||
child: Text(
|
child: Text(
|
||||||
'${index + 1}',
|
'$score',
|
||||||
style: const TextStyle(
|
style: const TextStyle(
|
||||||
|
fontSize: 28,
|
||||||
fontWeight: FontWeight.bold,
|
fontWeight: FontWeight.bold,
|
||||||
fontSize: 14,
|
color: Colors.white,
|
||||||
color: Colors.black87,
|
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
Expanded(
|
),
|
||||||
child: Container(
|
],
|
||||||
decoration: BoxDecoration(
|
|
||||||
color: _highlightedBulletIndex == index
|
|
||||||
? Colors.red[400]
|
|
||||||
: _bulletColor.withOpacity(0.85),
|
|
||||||
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,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
);
|
),
|
||||||
});
|
);
|
||||||
}
|
}).toList();
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user