189 lines
5.7 KiB
Dart
189 lines
5.7 KiB
Dart
|
|
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,
|
||
|
|
),
|
||
|
|
),
|
||
|
|
]),
|
||
|
|
),
|
||
|
|
);
|
||
|
|
});
|
||
|
|
}
|
||
|
|
}
|