Files
dmc/app/lib/ui/widgets/fly_map_controls.dart
T

74 lines
2.8 KiB
Dart

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 '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 - naeher als der
/// Standard-Kartenzoom (siehe MissionMap._initialZoom), damit der Sprung
/// tatsaechlich als Zoom wahrgenommen wird und nicht nur als Verschieben.
static const _followZoom = 18.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);
}
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;
}
fitMapToWaypoints(ref, waypoints);
}
@override
Widget build(BuildContext context, WidgetRef ref) {
final following = ref.watch(followDroneProvider);
return Row(
mainAxisSize: MainAxisSize.min,
children: [
NavIconButton(
icon: following ? Icons.gps_fixed : Icons.my_location,
active: following,
onTap: () => _onDronePressed(context, ref),
),
const SizedBox(width: 8),
NavIconButton(
icon: Icons.crop_free,
onTap: () => _onFitPressed(context, ref),
),
],
);
}
}