feat: accessoires en armurerie, comparateur de sessions stats, croix de centrage pixel par pixel
This commit is contained in:
@@ -76,26 +76,11 @@ class _WeaponListScreenState extends State<WeaponListScreen> {
|
||||
itemCount: _weapons.length,
|
||||
itemBuilder: (context, index) {
|
||||
final weapon = _weapons[index];
|
||||
final accessories = _accessoryChips(weapon);
|
||||
return Card(
|
||||
margin: const EdgeInsets.only(bottom: 12),
|
||||
child: ListTile(
|
||||
leading: CircleAvatar(
|
||||
backgroundColor: AppTheme.primaryColor.withValues(alpha: 0.1),
|
||||
child: Icon(
|
||||
weapon.type == WeaponType.handgun ? Icons.shield : Icons.ads_click,
|
||||
color: AppTheme.primaryColor,
|
||||
),
|
||||
),
|
||||
title: Text(weapon.displayName, style: const TextStyle(fontWeight: FontWeight.bold)),
|
||||
subtitle: Text('${weapon.type.displayName} • ${weapon.caliber}'),
|
||||
trailing: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
crossAxisAlignment: CrossAxisAlignment.end,
|
||||
children: [
|
||||
Text('${weapon.magazineCount} chargeurs', style: const TextStyle(fontSize: 12)),
|
||||
Text('${weapon.magazineCapacity} coups', style: const TextStyle(fontSize: 12, color: Colors.grey)),
|
||||
],
|
||||
),
|
||||
child: InkWell(
|
||||
borderRadius: BorderRadius.circular(12),
|
||||
onTap: () async {
|
||||
await Navigator.push(
|
||||
context,
|
||||
@@ -104,12 +89,96 @@ class _WeaponListScreenState extends State<WeaponListScreen> {
|
||||
_loadWeapons(); // Reload in case it was edited or maintenance was added
|
||||
},
|
||||
onLongPress: () => _confirmDelete(context, weapon),
|
||||
child: Padding(
|
||||
// La hauteur du cadre s'adapte automatiquement à la liste d'accessoires.
|
||||
padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 12),
|
||||
child: Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
children: [
|
||||
CircleAvatar(
|
||||
backgroundColor: AppTheme.primaryColor.withValues(alpha: 0.1),
|
||||
child: Icon(
|
||||
weapon.type == WeaponType.handgun ? Icons.shield : Icons.ads_click,
|
||||
color: AppTheme.primaryColor,
|
||||
),
|
||||
),
|
||||
const SizedBox(width: 16),
|
||||
Expanded(
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
Text(weapon.displayName, style: const TextStyle(fontWeight: FontWeight.bold)),
|
||||
if (accessories.isNotEmpty) ...[
|
||||
const SizedBox(height: 6),
|
||||
Wrap(
|
||||
spacing: 6,
|
||||
runSpacing: 6,
|
||||
children: accessories,
|
||||
),
|
||||
const SizedBox(height: 6),
|
||||
] else
|
||||
const SizedBox(height: 2),
|
||||
Text(
|
||||
'${weapon.type.displayName} • ${weapon.caliber}',
|
||||
style: const TextStyle(fontSize: 13, color: Colors.grey),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
const SizedBox(width: 12),
|
||||
Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
crossAxisAlignment: CrossAxisAlignment.end,
|
||||
children: [
|
||||
Text('${weapon.magazineCount} chargeurs', style: const TextStyle(fontSize: 12)),
|
||||
Text('${weapon.magazineCapacity} coups', style: const TextStyle(fontSize: 12, color: Colors.grey)),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
// Construit la liste des "puces" d'accessoires renseignés pour une arme.
|
||||
// Seuls les accessoires effectivement définis sont affichés ; la card
|
||||
// s'agrandit donc en fonction du nombre d'accessoires.
|
||||
List<Widget> _accessoryChips(Weapon weapon) {
|
||||
final items = <(IconData, String)>[];
|
||||
if (weapon.optic != null && weapon.optic!.isNotEmpty) {
|
||||
items.add((Icons.center_focus_strong, weapon.optic!));
|
||||
}
|
||||
if (weapon.silencer != null && weapon.silencer!.isNotEmpty) {
|
||||
items.add((Icons.volume_off, weapon.silencer!));
|
||||
}
|
||||
if (weapon.trigger != null && weapon.trigger!.isNotEmpty) {
|
||||
items.add((Icons.touch_app, weapon.trigger!));
|
||||
}
|
||||
|
||||
return items.map((item) {
|
||||
return Container(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 3),
|
||||
decoration: BoxDecoration(
|
||||
color: AppTheme.primaryColor.withValues(alpha: 0.08),
|
||||
borderRadius: BorderRadius.circular(20),
|
||||
border: Border.all(color: AppTheme.primaryColor.withValues(alpha: 0.25)),
|
||||
),
|
||||
child: Row(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
Icon(item.$1, size: 13, color: AppTheme.primaryColor),
|
||||
const SizedBox(width: 4),
|
||||
Text(item.$2, style: const TextStyle(fontSize: 12)),
|
||||
],
|
||||
),
|
||||
);
|
||||
}).toList();
|
||||
}
|
||||
|
||||
void _showAddWeaponDialog(BuildContext context) async {
|
||||
final nameController = TextEditingController();
|
||||
final caliberController = TextEditingController();
|
||||
|
||||
Reference in New Issue
Block a user