import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import '../blocs/camera/camera_bloc.dart'; import '../blocs/camera/camera_event.dart'; import '../blocs/camera/camera_state.dart'; import '../blocs/monitor/monitor_bloc.dart'; import '../blocs/monitor/monitor_state.dart'; class CameraGrid extends StatelessWidget { final int columns; const CameraGrid({super.key, this.columns = 8}); @override Widget build(BuildContext context) { return BlocBuilder( builder: (context, cameraState) { return BlocBuilder( builder: (context, monitorState) { final cameras = cameraState.availableCameras; return Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Padding( padding: const EdgeInsets.only(bottom: 8), child: Text( 'CAMERAS', style: Theme.of(context).textTheme.titleMedium?.copyWith( fontWeight: FontWeight.bold, ), ), ), Wrap( spacing: 4, runSpacing: 4, children: cameras.map((cameraId) { final isSelected = cameraState.selectedCameraId == cameraId; final isOnSelectedMonitor = monitorState.selectedMonitorCamera == cameraId; return _CameraButton( cameraId: cameraId, isSelected: isSelected, isOnSelectedMonitor: isOnSelectedMonitor, onPressed: () => _onCameraPressed( context, cameraId, monitorState.selectedMonitorId, ), ); }).toList(), ), ], ); }, ); }, ); } void _onCameraPressed(BuildContext context, int cameraId, int? monitorId) { final cameraBloc = context.read(); if (monitorId != null) { // Monitor is selected, connect camera to it cameraBloc.add(ConnectCameraToMonitor( cameraId: cameraId, monitorId: monitorId, )); } else { // Just select the camera cameraBloc.add(SelectCamera(cameraId)); } } } class _CameraButton extends StatelessWidget { final int cameraId; final bool isSelected; final bool isOnSelectedMonitor; final VoidCallback onPressed; const _CameraButton({ required this.cameraId, required this.isSelected, required this.isOnSelectedMonitor, required this.onPressed, }); @override Widget build(BuildContext context) { Color backgroundColor; Color foregroundColor; if (isSelected) { backgroundColor = Theme.of(context).colorScheme.primary; foregroundColor = Theme.of(context).colorScheme.onPrimary; } else if (isOnSelectedMonitor) { backgroundColor = Theme.of(context).colorScheme.secondary; foregroundColor = Theme.of(context).colorScheme.onSecondary; } else { backgroundColor = Theme.of(context).colorScheme.surfaceContainerHighest; foregroundColor = Theme.of(context).colorScheme.onSurface; } return SizedBox( width: 48, height: 40, child: ElevatedButton( onPressed: onPressed, style: ElevatedButton.styleFrom( backgroundColor: backgroundColor, foregroundColor: foregroundColor, padding: EdgeInsets.zero, shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(4), ), ), child: Text( '$cameraId', style: const TextStyle(fontSize: 14, fontWeight: FontWeight.bold), ), ), ); } }