Dash page and smart-serow's palette, boxed widgets, attitude and G-meter
Ported from smart-serow's HUD: the four-colour palette with dark/bright variants (same theme JSON format, loaded at runtime; YUKART_THEME picks one), StatBox and StatBoxMain, WhiskeyMark and AccelGraph. The whole app takes its colours from the palette. Dash: attitude, G-meter, RPM, GNSS speed, pedal, coolant and telltales, each from its contracts signal; missing and stale draw in subdued. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01DDwfd6Ki8UfG4hK6W5YpJz
This commit is contained in:
+30
-13
@@ -8,8 +8,10 @@ import 'package:flutter/material.dart';
|
||||
import 'boundary.dart';
|
||||
import 'camview.dart';
|
||||
import 'checklist.dart';
|
||||
import 'dash.dart';
|
||||
import 'linktest.dart';
|
||||
import 'net.dart';
|
||||
import 'theme/palette.dart';
|
||||
|
||||
/// Override for development, e.g. `--dart-define=YUKART_GW=ws://halogen.local:7700/`.
|
||||
const defaultUrl = String.fromEnvironment(
|
||||
@@ -19,6 +21,7 @@ const defaultUrl = String.fromEnvironment(
|
||||
|
||||
Future<void> main() async {
|
||||
WidgetsFlutterBinding.ensureInitialized();
|
||||
themes = await Themes.load();
|
||||
final usb = UsbLink();
|
||||
await usb.bindFor(Uri.parse(defaultUrl));
|
||||
final boundary = Boundary(defaultUrl)..start();
|
||||
@@ -58,6 +61,9 @@ Future<void> main() async {
|
||||
|
||||
final navigatorKey = GlobalKey<NavigatorState>();
|
||||
|
||||
/// The palette (lib/theme/palette.dart), loaded before the first frame.
|
||||
late final Themes themes;
|
||||
|
||||
Widget linkTestPage(Boundary b, LinkTest t, UsbLink usb) => LinkTestPage(
|
||||
test: t,
|
||||
host: Uri.parse(b.url).host,
|
||||
@@ -77,19 +83,21 @@ class YukartApp extends StatelessWidget {
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return MaterialApp(
|
||||
title: 'Yukart',
|
||||
navigatorKey: navigatorKey,
|
||||
debugShowCheckedModeBanner: false,
|
||||
theme: ThemeData(
|
||||
colorSchemeSeed: Colors.teal,
|
||||
brightness: Brightness.dark,
|
||||
useMaterial3: true,
|
||||
),
|
||||
home: ListenableBuilder(
|
||||
listenable: Listenable.merge([boundary, usb]),
|
||||
builder: (context, _) =>
|
||||
Readout(boundary: boundary, usb: usb, linkTest: linkTest),
|
||||
// Every page takes its colours from the palette; switching dark/bright rebuilds them all.
|
||||
return ListenableBuilder(
|
||||
listenable: themes,
|
||||
builder: (context, _) => MaterialApp(
|
||||
title: 'Yukart',
|
||||
navigatorKey: navigatorKey,
|
||||
debugShowCheckedModeBanner: false,
|
||||
theme: themes.material(),
|
||||
builder: (context, child) =>
|
||||
AppTheme(palette: themes.current, child: child!),
|
||||
home: ListenableBuilder(
|
||||
listenable: Listenable.merge([boundary, usb]),
|
||||
builder: (context, _) =>
|
||||
Readout(boundary: boundary, usb: usb, linkTest: linkTest),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
@@ -233,6 +241,15 @@ class LinkBar extends StatelessWidget {
|
||||
Text(
|
||||
'USB link ${usb.up ? 'up' : 'absent'}${usb.bound ? ', bound' : ''}',
|
||||
),
|
||||
TextButton.icon(
|
||||
onPressed: () => Navigator.of(context).push(
|
||||
MaterialPageRoute<void>(
|
||||
builder: (_) => DashPage(boundary: b, themes: themes),
|
||||
),
|
||||
),
|
||||
icon: const Icon(Icons.dashboard),
|
||||
label: const Text('Dash'),
|
||||
),
|
||||
TextButton.icon(
|
||||
onPressed: () => Navigator.of(context).push(
|
||||
MaterialPageRoute<void>(
|
||||
|
||||
Reference in New Issue
Block a user