- Implemented RawFrameDebugScreen for displaying ECU frame data and diagnostics. - Created DtcScreen to show active Diagnostic Trouble Codes (DTCs) with detailed descriptions. - Added DtcRow widget for individual DTC representation. - Introduced GraphScreen for visualizing sensor data over time with customizable time windows. - Developed SensorListScreen to display available sensors and their current values. - Enhanced SettingsScreen with options for Bluetooth connection, ECU protocol selection, polling interval, and theme settings. - Added AppColors and AppTheme for consistent theming across the application. - Implemented BtStatusChip to show Bluetooth connection status in the app bar. - Created RecordFab for starting and stopping data recording sessions.
114 lines
3.8 KiB
Dart
114 lines
3.8 KiB
Dart
import 'package:flutter/material.dart';
|
|
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
|
import '../../../core/providers/sensor_provider.dart';
|
|
import '../../../core/providers/theme_provider.dart';
|
|
import '../../../ui/theme/app_colors.dart';
|
|
import 'widgets/analog_gauge.dart';
|
|
import 'widgets/flag_pill.dart';
|
|
import 'widgets/sensor_tile.dart';
|
|
import 'widgets/sensor_picker_sheet.dart';
|
|
import 'dashboard_slots_provider.dart';
|
|
|
|
class DashboardHorizontal extends ConsumerWidget {
|
|
const DashboardHorizontal({super.key});
|
|
|
|
@override
|
|
Widget build(BuildContext context, WidgetRef ref) {
|
|
final state = ref.watch(latestSensorProvider);
|
|
final themeVariant = ref.watch(themeProvider);
|
|
final colors = AppColors.forTheme(themeVariant);
|
|
final slots = ref.watch(dashboardSlotsProvider);
|
|
|
|
return Container(
|
|
color: const Color(0xFF0A0A0A),
|
|
padding: const EdgeInsets.all(8),
|
|
child: Column(
|
|
children: [
|
|
Expanded(
|
|
child: Row(
|
|
crossAxisAlignment: CrossAxisAlignment.stretch,
|
|
children: [
|
|
// Left tiles (slots 0-2)
|
|
SizedBox(
|
|
width: 140,
|
|
child: Column(
|
|
children: [
|
|
for (int i = 0; i < 3; i++)
|
|
Expanded(
|
|
child: Padding(
|
|
padding: const EdgeInsets.only(bottom: 6),
|
|
child: SensorTile(
|
|
slotIndex: i,
|
|
sensorId: slots[i],
|
|
state: state,
|
|
accentColor: colors.accent,
|
|
onTap: () => _pickSensor(context, ref, i),
|
|
),
|
|
),
|
|
),
|
|
],
|
|
),
|
|
),
|
|
const SizedBox(width: 8),
|
|
// Center gauge
|
|
Expanded(
|
|
child: Center(
|
|
child: AnalogGauge(
|
|
value: state.rpm,
|
|
minValue: 0,
|
|
maxValue: 9000,
|
|
label: 'RPM',
|
|
unit: 'rpm',
|
|
accentColor: colors.accent,
|
|
),
|
|
),
|
|
),
|
|
const SizedBox(width: 8),
|
|
// Right tiles (slots 3-5)
|
|
SizedBox(
|
|
width: 140,
|
|
child: Column(
|
|
children: [
|
|
for (int i = 3; i < 6; i++)
|
|
Expanded(
|
|
child: Padding(
|
|
padding: const EdgeInsets.only(bottom: 6),
|
|
child: SensorTile(
|
|
slotIndex: i,
|
|
sensorId: slots[i],
|
|
state: state,
|
|
accentColor: colors.accent,
|
|
onTap: () => _pickSensor(context, ref, i),
|
|
),
|
|
),
|
|
),
|
|
],
|
|
),
|
|
),
|
|
],
|
|
),
|
|
),
|
|
// Flag pills row
|
|
Padding(
|
|
padding: const EdgeInsets.only(top: 6),
|
|
child: FlagRow(state: state, accentColor: colors.accent),
|
|
),
|
|
],
|
|
),
|
|
);
|
|
}
|
|
|
|
void _pickSensor(BuildContext context, WidgetRef ref, int slotIndex) {
|
|
showModalBottomSheet<void>(
|
|
context: context,
|
|
builder: (_) => SensorPickerSheet(
|
|
currentId: ref.read(dashboardSlotsProvider)[slotIndex],
|
|
onSelected: (id) {
|
|
ref.read(dashboardSlotsProvider.notifier).setSlot(slotIndex, id);
|
|
Navigator.pop(context);
|
|
},
|
|
),
|
|
);
|
|
}
|
|
}
|