import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import '../blocs/ptz/ptz_bloc.dart'; import '../blocs/ptz/ptz_event.dart'; import '../blocs/ptz/ptz_state.dart'; import '../blocs/monitor/monitor_bloc.dart'; import '../blocs/monitor/monitor_state.dart'; class PtzControl extends StatelessWidget { const PtzControl({super.key}); @override Widget build(BuildContext context) { return BlocBuilder( builder: (context, monitorState) { return BlocBuilder( builder: (context, ptzState) { final cameraId = monitorState.selectedMonitorCamera; final isEnabled = cameraId != null && cameraId > 0; return Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Padding( padding: const EdgeInsets.only(bottom: 8), child: Row( children: [ Text( 'PTZ CONTROL', style: Theme.of(context).textTheme.titleMedium?.copyWith( fontWeight: FontWeight.bold, ), ), if (cameraId != null && cameraId > 0) ...[ const SizedBox(width: 8), Container( padding: const EdgeInsets.symmetric( horizontal: 8, vertical: 2), decoration: BoxDecoration( color: Theme.of(context).colorScheme.primaryContainer, borderRadius: BorderRadius.circular(4), ), child: Text( 'Camera $cameraId', style: TextStyle( fontSize: 12, color: Theme.of(context) .colorScheme .onPrimaryContainer, ), ), ), ], ], ), ), _buildPtzPad(context, cameraId, isEnabled), const SizedBox(height: 8), _buildZoomControls(context, cameraId, isEnabled), ], ); }, ); }, ); } Widget _buildPtzPad(BuildContext context, int? cameraId, bool isEnabled) { return Column( children: [ // Up Row( mainAxisAlignment: MainAxisAlignment.center, children: [ _PtzButton( icon: Icons.arrow_upward, onPressStart: isEnabled && cameraId != null ? () => context.read().add( PtzTiltStart(cameraId: cameraId, direction: 'up'), ) : null, onPressEnd: isEnabled && cameraId != null ? () => context.read().add(PtzStop(cameraId)) : null, ), ], ), // Left, Stop, Right Row( mainAxisAlignment: MainAxisAlignment.center, children: [ _PtzButton( icon: Icons.arrow_back, onPressStart: isEnabled && cameraId != null ? () => context.read().add( PtzPanStart(cameraId: cameraId, direction: 'left'), ) : null, onPressEnd: isEnabled && cameraId != null ? () => context.read().add(PtzStop(cameraId)) : null, ), const SizedBox(width: 4), _PtzButton( icon: Icons.stop, isStop: true, onPressStart: isEnabled && cameraId != null ? () => context.read().add(PtzStop(cameraId)) : null, ), const SizedBox(width: 4), _PtzButton( icon: Icons.arrow_forward, onPressStart: isEnabled && cameraId != null ? () => context.read().add( PtzPanStart(cameraId: cameraId, direction: 'right'), ) : null, onPressEnd: isEnabled && cameraId != null ? () => context.read().add(PtzStop(cameraId)) : null, ), ], ), // Down Row( mainAxisAlignment: MainAxisAlignment.center, children: [ _PtzButton( icon: Icons.arrow_downward, onPressStart: isEnabled && cameraId != null ? () => context.read().add( PtzTiltStart(cameraId: cameraId, direction: 'down'), ) : null, onPressEnd: isEnabled && cameraId != null ? () => context.read().add(PtzStop(cameraId)) : null, ), ], ), ], ); } Widget _buildZoomControls( BuildContext context, int? cameraId, bool isEnabled) { return Row( mainAxisAlignment: MainAxisAlignment.center, children: [ _PtzButton( icon: Icons.zoom_out, onPressStart: isEnabled && cameraId != null ? () => context.read().add( PtzZoomStart(cameraId: cameraId, direction: 'out'), ) : null, onPressEnd: isEnabled && cameraId != null ? () => context.read().add(PtzStop(cameraId)) : null, ), const SizedBox(width: 4), _PtzButton( icon: Icons.zoom_in, onPressStart: isEnabled && cameraId != null ? () => context.read().add( PtzZoomStart(cameraId: cameraId, direction: 'in'), ) : null, onPressEnd: isEnabled && cameraId != null ? () => context.read().add(PtzStop(cameraId)) : null, ), ], ); } } class _PtzButton extends StatelessWidget { final IconData icon; final VoidCallback? onPressStart; final VoidCallback? onPressEnd; final bool isStop; const _PtzButton({ required this.icon, this.onPressStart, this.onPressEnd, this.isStop = false, }); @override Widget build(BuildContext context) { final isEnabled = onPressStart != null; return GestureDetector( onTapDown: isEnabled ? (_) => onPressStart?.call() : null, onTapUp: isEnabled ? (_) => onPressEnd?.call() : null, onTapCancel: isEnabled ? () => onPressEnd?.call() : null, child: Container( width: 48, height: 48, decoration: BoxDecoration( color: isEnabled ? (isStop ? Theme.of(context).colorScheme.errorContainer : Theme.of(context).colorScheme.primaryContainer) : Theme.of(context).colorScheme.surfaceContainerHighest, borderRadius: BorderRadius.circular(8), border: Border.all( color: isEnabled ? (isStop ? Theme.of(context).colorScheme.error : Theme.of(context).colorScheme.primary) : Theme.of(context).colorScheme.outline, width: 1, ), ), child: Icon( icon, color: isEnabled ? (isStop ? Theme.of(context).colorScheme.onErrorContainer : Theme.of(context).colorScheme.onPrimaryContainer) : Theme.of(context).colorScheme.onSurface.withValues(alpha: 0.4), ), ), ); } }