import 'package:flutter/material.dart'; import 'package:get/get.dart'; import '../services/gnss/gnss_connection.dart'; import '../services/gnss/gnss_device_service.dart'; import '../services/gnss/gnss_service.dart'; import 'gnss_device_picker_dialog.dart'; /// GNSS kapcsolat + fix minőség chip az AppBar-ban. /// /// Tapintásra megnyitja az eszközkiválasztó dialógot. /// Kompakt: csak az AppBar-ban lévő kis helyet foglalja el. /// /// Állapotok: /// - Szürke: nincs eszköz kiválasztva /// - Piros: eszköz kiválasztva, nincs kapcsolat /// - Narancs: csatlakozva, nincs GPS fix /// - Sárga: autonóm GPS (quality 1) /// - Kék: DGPS (quality 2) /// - Világoszöld: RTK Float (quality 5) /// - Zöld: RTK Fix (quality 4) ← ideális állapot class GnssStatusChip extends StatelessWidget { const GnssStatusChip({super.key}); @override Widget build(BuildContext context) { return Obx(() { final connState = GnssService.to.connectionState.value; final quality = GnssService.to.gpsQuality.value; final device = GnssDeviceService.to.selectedDevice.value; final sats = GnssService.to.satelliteCount.value; final isConnected = connState == GnssConnectionState.connected; final isConnecting = connState == GnssConnectionState.connecting; final color = _chipColor(isConnected, quality); final label = _chipLabel(connState, quality, device?.name); return GestureDetector( onTap: () => GnssDevicePickerDialog.show(), child: AnimatedContainer( duration: const Duration(milliseconds: 300), padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 4), decoration: BoxDecoration( color: color.withOpacity(0.15), borderRadius: BorderRadius.circular(8), border: Border.all(color: color.withOpacity(0.5)), ), child: Row(mainAxisSize: MainAxisSize.min, children: [ // Állapot ikon if (isConnecting) SizedBox( width: 10, height: 10, child: CircularProgressIndicator( strokeWidth: 1.5, color: color, ), ) else Icon( _chipIcon(isConnected, quality), size: 12, color: color, ), const SizedBox(width: 4), // Felirat Text( label, style: TextStyle( fontSize: 11, fontWeight: FontWeight.w600, color: color, ), ), // Műholdak száma (csak ha van fix) if (isConnected && quality > 0) ...[ const SizedBox(width: 4), Text( '($sats)', style: TextStyle( fontSize: 10, color: color.withOpacity(0.8), ), ), ], ]), ), ); }); } Color _chipColor(bool connected, int quality) { if (!connected) return Colors.grey; return switch (quality) { 4 => Colors.greenAccent, 5 => Colors.lightGreen, 2 => Colors.blue, 1 => Colors.orange, _ => Colors.orange.shade300, }; } IconData _chipIcon(bool connected, int quality) { if (!connected) return Icons.gps_off; if (quality == 0) return Icons.gps_not_fixed; return Icons.gps_fixed; } String _chipLabel( GnssConnectionState state, int quality, String? deviceName) { return switch (state) { GnssConnectionState.connecting => 'Kapcsolódás...', GnssConnectionState.disconnected => deviceName != null ? 'Nincs kapcsolat' : 'Nincs eszköz', GnssConnectionState.error => 'Hiba', GnssConnectionState.connected => switch (quality) { 4 => 'RTK Fix', 5 => 'RTK Float', 2 => 'DGPS', 1 => 'GPS', _ => 'Fix nélkül', }, }; } } /// NTRIP kapcsolat chip az AppBar-ban. /// /// Tapintásra az NTRIP beállítások oldalra navigál. /// Csak akkor látható, ha van kiválasztott GNSS eszköz. class NtripStatusChip extends StatelessWidget { /// NTRIP csatlakozva van-e — a controllerből kapja. final RxBool isConnected; /// Csatlakozás / leválasztás callback. final VoidCallback? onToggle; /// NTRIP beállítások megnyitása. final VoidCallback? onSettings; const NtripStatusChip({ super.key, required this.isConnected, this.onToggle, this.onSettings, }); @override Widget build(BuildContext context) { return Obx(() { final connected = isConnected.value; final color = connected ? Colors.greenAccent : Colors.grey; return GestureDetector( onTap: onToggle, onLongPress: onSettings, child: AnimatedContainer( duration: const Duration(milliseconds: 300), padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 4), decoration: BoxDecoration( color: color.withOpacity(0.12), borderRadius: BorderRadius.circular(8), border: Border.all(color: color.withOpacity(0.45)), ), child: Row(mainAxisSize: MainAxisSize.min, children: [ Icon( Icons.cell_tower, size: 12, color: color, ), const SizedBox(width: 4), Text( connected ? 'NTRIP' : 'NTRIP off', style: TextStyle( fontSize: 11, fontWeight: FontWeight.w600, color: color, ), ), ]), ), ); }); } }