hondavert-dev/lib/ui/screens/dashboard/dashboard_horizontal.dart
HVBT Dev 763821171c feat: Add ECU Frame Debug Screen and DTC Screen
- 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.
2026-07-26 23:14:58 +05:30

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);
},
),
);
}
}