import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:latlong2/latlong.dart'; import '../providers/current_mission_provider.dart'; import '../providers/follow_drone_provider.dart'; import '../providers/map_controller_provider.dart'; import '../providers/telemetry_provider.dart'; import 'drone_follow_icon.dart'; import 'nav_icon_button.dart'; /// Kartensteuerung im Fly-Modus (Doku 3.11): Ortssuche/Home entfallen hier /// (keine Missionsbearbeitung), stattdessen schaltet der Drohnen-Button den /// Kartenfolgemodus um (followDroneProvider) - "Home" (erster Wegpunkt) ist /// waehrend des Flugs kein sinnvoller Bezugspunkt mehr, der Fit-Button /// (gesamte Route) bleibt dagegen unveraendert wie im Plan-Modus erhalten. class FlyMapControls extends ConsumerWidget { const FlyMapControls({super.key}); /// Zielzoom beim Aktivieren des Folgemodus - deutlich weiter herausgezoomt /// als der Standard-Kartenzoom (siehe MissionMap._initialZoom), damit /// waehrend des Verfolgens genug Gelaende/Route um die Drohne herum /// sichtbar bleibt statt nur ihrer unmittelbaren Umgebung. static const _followZoom = 16.0; /// Erster Tap zoomt auf die aktuelle Telemetrieposition und aktiviert den /// Folgemodus (FlyScreen haengt sich darauf ein, zieht die Karte bei /// jedem neuen Telemetrie-Frame nach und bricht bei manueller /// Karteninteraktion selbststaendig wieder ab). Zweiter Tap beendet ihn /// wieder, ohne die Kamera zu bewegen. void _onDronePressed(BuildContext context, WidgetRef ref) { if (ref.read(followDroneProvider)) { ref.read(followDroneProvider.notifier).set(false); return; } final frame = ref.read(telemetryProvider).value; if (frame == null) { ScaffoldMessenger.of(context) .showSnackBar(const SnackBar(content: Text('No telemetry yet'))); return; } ref.read(mapControllerProvider).move(LatLng(frame.lat, frame.lon), _followZoom); ref.read(followDroneProvider.notifier).set(true); } /// Beendet den Folgemodus explizit, statt sich auf den Abbruch bei /// manueller Karteninteraktion in FlyScreen zu verlassen (FlyScreen._ /// onMapEvent) - fitMapToWaypoints() bewegt die Kamera ueber denselben /// MapController (source == mapController), gilt dort also nicht als /// manuelle Geste und wuerde den Folgemodus sonst aktiv lassen. Ohne /// diesen Abbruch wuerde der naechste Telemetrie-Frame die Kamera sofort /// wieder von der gerade eingestellten Missionsuebersicht weg auf die /// Drohne zurueckziehen. void _onFitPressed(BuildContext context, WidgetRef ref) { final waypoints = ref.read(currentMissionProvider); if (waypoints.isEmpty) { ScaffoldMessenger.of(context) .showSnackBar(const SnackBar(content: Text('No waypoints to fit'))); return; } ref.read(followDroneProvider.notifier).set(false); fitMapToWaypoints(ref, waypoints); } @override Widget build(BuildContext context, WidgetRef ref) { final following = ref.watch(followDroneProvider); return Row( mainAxisSize: MainAxisSize.min, children: [ NavIconButton( iconWidget: DroneFollowIcon(active: following), onTap: () => _onDronePressed(context, ref), ), const SizedBox(width: 8), NavIconButton( icon: Icons.crop_free, onTap: () => _onFitPressed(context, ref), ), ], ); } }