Files
app-flutter/lib/widgets/telltale.dart
T
mikkeli 3aeb09d61f
/ crosscheck (push) Successful in 0s
CI / Analyze & Test (push) Successful in 13s
CI / Debug APK (push) Successful in 22s
Palette: seven roles (accent, good, caution added; highlight renamed alarm); no hard-coded colours left
background, foreground, subdued, accent (emphasis without danger), and the state
gradient good → caution → alarm; surface and onFill derived. smart-serow's
four-key themes still load (highlight = alarm; the new roles fall back).
Material's scheme follows: buttons in accent instead of the alarm colour.
Link state, mock banner, signal tiles, raw log, checklist button and marks,
camera page all take palette roles.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DDwfd6Ki8UfG4hK6W5YpJz
2026-10-14 13:55:52 +09:00

73 lines
2.0 KiB
Dart

// An on/off lamp in the boxed pattern (lib/widgets/stat_box.dart): the label is the
// lamp. Takes a [Reading] (lib/reading.dart) so missing and stale draw as they do elsewhere.
import 'package:flutter/material.dart';
import '../reading.dart';
import '../theme/palette.dart';
/// An on/off lamp in the boxed pattern: the label is the lamp. Lit in foreground
/// (alarm when [warn]), dark in subdued; missing shows as a dash.
class Telltale extends StatelessWidget {
const Telltale({
super.key,
required this.label,
required this.reading,
this.icon,
this.warn = false,
this.flex = 1,
});
final String label;
/// Drawn instead of the label when set. Glyphs like ◀ ▶ come out as emoji on Android.
final IconData? icon;
final Reading reading;
final bool warn;
final int flex;
@override
Widget build(BuildContext context) {
final p = AppTheme.of(context);
final missing = reading.value == null;
final lit = reading.on && !reading.dim;
final color = lit
? (warn ? p.alarm : p.foreground)
: p.subdued.withValues(alpha: missing ? 0.35 : 0.6);
return Expanded(
flex: flex,
child: LayoutBuilder(
builder: (context, c) {
final size = c.maxHeight * 0.3;
if (icon != null && !missing) {
return Center(
child: Icon(
icon,
size: c.maxHeight * 0.7,
color: color,
semanticLabel: label,
),
);
}
return Center(
child: FittedBox(
fit: BoxFit.scaleDown,
child: Text(
missing ? '—' : label,
maxLines: 1,
style: TextStyle(
fontFamily: hudFont,
fontSize: size,
fontWeight: lit ? FontWeight.w700 : FontWeight.w400,
color: color,
letterSpacing: 1,
),
),
),
);
},
),
);
}
}