- 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>
84 lines
2.3 KiB
Dart
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),
|
|
),
|
|
),
|
|
),
|
|
],
|
|
);
|
|
},
|
|
);
|
|
}
|
|
}
|