Updated app with modfications and new UI for graphs

This commit is contained in:
2026-03-07 21:25:53 +01:00
parent d253a9c4a3
commit c58ca5cf15
7 changed files with 833 additions and 289 deletions
+185 -127
View File
@@ -149,19 +149,52 @@ class _PreviewScreenState extends State<PreviewScreen> {
Color get _editColor => Colors.deepOrangeAccent;
Color get _activeColor => _isEditMode ? _editColor : _bulletColor;
Color get _activeColorWithOpacity => _activeColor.withValues(alpha: _bulletOpacity);
Color get _activeColorWithOpacity =>
_activeColor.withValues(alpha: _bulletOpacity);
String _selectedLanguage = 'English';
Color _backgroundColor = Colors.grey[900]!;
String _currentFolderName = '';
String _currentDate = '';
@override
void initState() {
super.initState();
_realImageDetections = widget.detections;
targetAssetPath = 'assets/target.png'; // Default
_loadCurrentFolderInfo();
_initializeScreen();
}
Future<void> _loadCurrentFolderInfo() async {
try {
final directory = await getApplicationDocumentsDirectory();
final saveDirectory = Directory('${directory.path}/saved_images');
if (await saveDirectory.exists()) {
final folders =
saveDirectory.listSync().whereType<Directory>().toList();
if (folders.isNotEmpty) {
// Sort by modification date to get the most recent folder
folders.sort(
(a, b) => b.statSync().changed.compareTo(a.statSync().changed));
final lastFolder = folders.first.path.split('/').last;
final today = DateTime.now();
final formattedDate =
"${today.day.toString().padLeft(2, '0')}-${today.month.toString().padLeft(2, '0')}-${today.year.toString().substring(2)}"; // DD-MM-YY format
setState(() {
_currentFolderName = lastFolder;
_currentDate = formattedDate;
});
}
}
} catch (e) {
print("Error loading current folder info: $e");
}
}
Future<void> _initializeScreen() async {
await Future.wait([
_loadDefaultTarget(), // Load default target for scale reference
@@ -316,7 +349,7 @@ class _PreviewScreenState extends State<PreviewScreen> {
return const Color(0xFF000000); // Black
case 'assets/targets/Target24.jpg':
return const Color(0xFF000000); // Black
return const Color(0xFFb7b7b7); // Gray
case 'assets/targets/Target25.jpg':
return const Color(0xFF040308); // Very dark gray
@@ -822,7 +855,8 @@ class _PreviewScreenState extends State<PreviewScreen> {
return null;
}
folders.sort((a, b) => b.statSync().changed.compareTo(a.statSync().changed));
folders
.sort((a, b) => b.statSync().changed.compareTo(a.statSync().changed));
return folders.first.path.split('/').last;
}
@@ -1283,6 +1317,29 @@ class _PreviewScreenState extends State<PreviewScreen> {
_t('Detection Preview'),
style: const TextStyle(color: Colors.white),
),
actions: [
IconButton(
icon: Icon(
_mode == PreviewMode.mappedTarget
? Icons.camera_alt
: Icons.center_focus_strong,
color: Colors.white,
size: 24,
),
onPressed: () async {
setState(() {
_mode = _mode == PreviewMode.mappedTarget
? PreviewMode.cameraWithDetections
: PreviewMode.mappedTarget;
});
await _loadSelectedTarget();
},
tooltip: _mode == PreviewMode.mappedTarget
? _t("Show Camera Detections")
: _t("Show Mapped Target"),
),
const SizedBox(width: 8),
],
),
body: _isLoading
? const Center(child: CircularProgressIndicator())
@@ -1290,6 +1347,38 @@ class _PreviewScreenState extends State<PreviewScreen> {
children: [
Column(
children: [
// Training/Tournament Banner
Container(
color: Colors.grey[300],
padding: const EdgeInsets.symmetric(
horizontal: 16, vertical: 10),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Expanded(
child: Text(
_currentFolderName.isNotEmpty
? _currentFolderName
: 'No training selected',
style: const TextStyle(
color: Colors.black,
fontSize: 13,
fontWeight: FontWeight.w600,
),
overflow: TextOverflow.ellipsis,
),
),
if (_currentDate.isNotEmpty)
Text(
_currentDate,
style: const TextStyle(
color: Colors.black,
fontSize: 11,
),
),
],
),
),
Expanded(
child: LayoutBuilder(
builder: (context, constraints) {
@@ -1362,7 +1451,8 @@ class _PreviewScreenState extends State<PreviewScreen> {
child: Align(
alignment: Alignment.topLeft,
child: Container(
color: Colors.green.withValues(alpha: 0.5),
color: Colors.green
.withValues(alpha: 0.5),
padding: const EdgeInsets.symmetric(
horizontal: 4, vertical: 2),
child: Text(
@@ -1422,11 +1512,11 @@ class _PreviewScreenState extends State<PreviewScreen> {
final Color bulletFillColor =
isSelectedForEdit ||
(!_isEditMode && isHighlighted)
? Colors.red
.withValues(alpha: _bulletOpacity)
? Colors.red.withValues(
alpha: _bulletOpacity)
: isManual
? Colors.red
.withValues(alpha: _bulletOpacity)
? Colors.red.withValues(
alpha: _bulletOpacity)
: _activeColorWithOpacity;
return Positioned(
@@ -1459,7 +1549,7 @@ class _PreviewScreenState extends State<PreviewScreen> {
},
),
),
const SizedBox(height: 12),
const SizedBox(height: 24),
if (_mappedBullets.isNotEmpty)
Column(
children: [
@@ -1711,46 +1801,32 @@ class _PreviewScreenState extends State<PreviewScreen> {
mainAxisSize: MainAxisSize.min,
children: [
// Top bar - Total Score
BottomAppBar(
color: Colors.grey[900],
padding: EdgeInsets.zero,
child: SizedBox(
height: 60,
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Padding(
padding: const EdgeInsets.symmetric(horizontal: 16),
child: FittedBox(
fit: BoxFit.scaleDown,
child: Row(
children: [
const Icon(Icons.track_changes,
size: 24, color: Colors.white),
const SizedBox(width: 8),
Text(
_t("Total score:"),
style: const TextStyle(
fontSize: 24,
fontWeight: FontWeight.bold,
color: Colors.white,
),
),
const SizedBox(width: 16),
Text(
"$_totalScore",
style: const TextStyle(
fontSize: 24,
fontWeight: FontWeight.bold,
color: Colors.white,
),
),
],
),
),
Container(
color: Colors.grey[300],
padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 10),
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
const Icon(Icons.track_changes, size: 20, color: Colors.black),
const SizedBox(width: 8),
Text(
_t("Total score:"),
style: const TextStyle(
fontSize: 13,
fontWeight: FontWeight.bold,
color: Colors.black,
),
],
),
),
const SizedBox(width: 12),
Text(
"$_totalScore",
style: const TextStyle(
fontSize: 20,
fontWeight: FontWeight.bold,
color: Colors.black,
),
),
],
),
),
// Bottom bar - Action Buttons
@@ -1760,96 +1836,78 @@ class _PreviewScreenState extends State<PreviewScreen> {
child: SizedBox(
height: 60,
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
// Toggle view button
IconButton(
icon: Icon(
_mode == PreviewMode.mappedTarget
? Icons.camera_alt
: Icons.center_focus_strong,
color: Colors.white,
size: 24,
),
onPressed: () async {
setState(() {
_mode = _mode == PreviewMode.mappedTarget
? PreviewMode.cameraWithDetections
: PreviewMode.mappedTarget;
});
await _loadSelectedTarget();
},
tooltip: _mode == PreviewMode.mappedTarget
? _t("Show Camera Detections")
: _t("Show Mapped Target"),
),
// Split Save button
Padding(
padding: const EdgeInsets.symmetric(horizontal: 8),
child: SizedBox(
width: 120,
height: 40,
child: Container(
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(8),
),
child: Row(
// Plus button (left, no background)
Expanded(
child: Center(
child: IconButton(
icon: Stack(
alignment: Alignment.center,
children: [
// Save to last folder
Expanded(
child: Material(
color: Colors.transparent,
child: InkWell(
onTap: _saveToLastFolder,
borderRadius: const BorderRadius.only(
topLeft: Radius.circular(8),
bottomLeft: Radius.circular(8),
),
child: const Icon(Icons.save,
color: Colors.black, size: 20),
),
),
),
// Divider
Container(
width: 1,
color: Colors.grey[300],
),
// New folder
Expanded(
child: Material(
color: Colors.transparent,
child: InkWell(
onTap: _saveTargetDataWithDialog,
borderRadius: const BorderRadius.only(
topRight: Radius.circular(8),
bottomRight: Radius.circular(8),
),
child: Icon(Icons.add,
color: Colors.black, size: 24),
const Icon(Icons.folder, color: Colors.white, size: 24),
Positioned(
bottom: 0,
right: 0,
child: Container(
decoration: const BoxDecoration(
color: Colors.white,
shape: BoxShape.circle,
),
padding: const EdgeInsets.all(2),
child: const Icon(Icons.add, color: Colors.grey, size: 10),
),
),
],
),
onPressed: _saveTargetDataWithDialog,
),
),
),
// Edit button
IconButton(
icon: Icon(
_isEditMode ? Icons.check : Icons.edit,
color: _isEditMode ? Colors.red : Colors.white,
size: 24,
// Save button (center with white background)
Expanded(
child: Center(
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 8),
child: SizedBox(
width: 60,
height: 40,
child: Container(
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(8),
),
child: Material(
color: Colors.transparent,
child: InkWell(
onTap: _saveToLastFolder,
borderRadius: BorderRadius.circular(8),
child: const Icon(Icons.save,
color: Colors.black, size: 20),
),
),
),
),
),
),
),
// Edit button (right)
Expanded(
child: Center(
child: IconButton(
icon: Icon(
_isEditMode ? Icons.check : Icons.edit,
color: _isEditMode ? Colors.red : Colors.white,
size: 24,
),
onPressed: () {
setState(() {
_isEditMode = !_isEditMode;
_selectedBulletIndexInEdit = null;
});
},
tooltip: _isEditMode ? _t("Done Editing") : _t("Edit Mode"),
),
),
onPressed: () {
setState(() {
_isEditMode = !_isEditMode;
_selectedBulletIndexInEdit = null;
});
},
tooltip: _isEditMode ? _t("Done Editing") : _t("Edit Mode"),
),
],
),