pakutz79 c19c9d1a98 feat: navigation drawer, EMS setup, scheduler, tarifs, paramètres app
- Drawer custom (overlay Stack) avec mode installateur PIN SHA-256
- GoRouter + ShellRoute : navigation préservée entre onglets
- 6 providers : NavigationProvider, InstallerModeProvider, AppSettingsProvider,
  EnergySetupProvider, SchedulerProvider, TariffProvider
- Écrans Energy Manager : RoleConfigFlow (3 étapes), Scheduler, Tarifs, Timeline
- Écrans Paramètres : Apparence, Écrans actifs, AppSettingsScreen
- DrawerMenuButton présent dans les 5 AppBars principaux
- Simulation : _thingClasses générées avec interfaces EMS pour filtrage des rôles
- Compteur solaire : ajout smartmeter aux interfaces compatibles
- Thème ETM (etm_theme.dart), ProLockBadge, widgets PowerBar/RoleCard/TimelineSlotCard
- Dépendances : go_router, shared_preferences, crypto, url_launcher

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-24 14:52:32 +01:00

84 lines
2.3 KiB
Dart

import 'package:flutter/material.dart';
/// Barre de puissance horizontale normalisée.
///
/// Affiche une barre colorée proportionnelle à [value] / [maxValue].
/// Si [signed] = true, la barre est centrée (positif = droite, négatif = gauche).
class PowerBar extends StatelessWidget {
final double value;
final double maxValue;
final Color color;
final bool signed;
final double height;
final double borderRadius;
const PowerBar({
super.key,
required this.value,
required this.maxValue,
required this.color,
this.signed = false,
this.height = 8,
this.borderRadius = 4,
});
@override
Widget build(BuildContext context) {
final frac = maxValue > 0
? (value.abs() / maxValue).clamp(0.0, 1.0)
: 0.0;
return LayoutBuilder(
builder: (context, constraints) {
final w = constraints.maxWidth;
if (signed) {
return Stack(
children: [
Container(
height: height,
decoration: BoxDecoration(
color: Colors.grey.withValues(alpha: 0.15),
borderRadius: BorderRadius.circular(borderRadius),
),
),
Positioned(
left: value >= 0 ? w / 2 : w / 2 - frac * w / 2,
child: Container(
width: frac * w / 2,
height: height,
decoration: BoxDecoration(
color: color,
borderRadius: BorderRadius.circular(borderRadius),
),
),
),
],
);
}
return Stack(
children: [
Container(
height: height,
decoration: BoxDecoration(
color: Colors.grey.withValues(alpha: 0.15),
borderRadius: BorderRadius.circular(borderRadius),
),
),
FractionallySizedBox(
widthFactor: frac,
child: Container(
height: height,
decoration: BoxDecoration(
color: color,
borderRadius: BorderRadius.circular(borderRadius),
),
),
),
],
);
},
);
}
}