// Bemérés mód alsó panel: // - Aktuális koordináták (WGS84 + EOV) // - GPS minőség + pontosság // - Rögzített pontok száma // - Nagy "Pont rögzítése" gomb import 'package:flutter/material.dart'; import 'package:get/get.dart'; import 'package:terepi_seged/services/gnss/gnss_connection.dart'; import 'package:terepi_seged/services/gnss/gnss_service.dart'; import '../../pages/map_survey/presentations/controllers/map_survey_controller.dart'; class MeasureBottomPanel extends StatelessWidget { final MapSurveyController ctrl; const MeasureBottomPanel({super.key, required this.ctrl}); @override Widget build(BuildContext context) { final cs = Theme.of(context).colorScheme; return Container( decoration: BoxDecoration( color: cs.surface, boxShadow: [ BoxShadow( color: Colors.black.withOpacity(0.12), blurRadius: 12, offset: const Offset(0, -3), ), ], ), child: SafeArea( top: false, child: Padding( padding: const EdgeInsets.fromLTRB(16, 10, 16, 8), child: Column( mainAxisSize: MainAxisSize.min, children: [ // ── Koordináta sor ───────────────────────────────────── Obx(() { final lat = ctrl.gpsLatitude.value; final lon = ctrl.gpsLongitude.value; final eovY = ctrl.eovY.value; final eovX = ctrl.eovX.value; final hasGps = GnssService.to.connectionState.value == GnssConnectionState.connected; if (!hasGps) { return Padding( padding: const EdgeInsets.only(bottom: 8), child: Text( 'GPS pozíció nem elérhető', style: TextStyle(color: cs.onSurfaceVariant, fontSize: 12), ), ); } return Padding( padding: const EdgeInsets.only(bottom: 8), child: Row( children: [ // WGS84 Expanded( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text('WGS84', style: TextStyle( fontSize: 10, color: cs.onSurfaceVariant, fontWeight: FontWeight.w500)), Text( '${lat.toStringAsFixed(7)}°', style: const TextStyle( fontSize: 12, fontFeatures: [FontFeature.tabularFigures()]), ), Text( '${lon.toStringAsFixed(7)}°', style: const TextStyle( fontSize: 12, fontFeatures: [FontFeature.tabularFigures()]), ), ], ), ), Container( width: 1, height: 36, color: cs.outlineVariant, margin: const EdgeInsets.symmetric(horizontal: 10)), // EOV Expanded( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text('EOV', style: TextStyle( fontSize: 10, color: cs.onSurfaceVariant, fontWeight: FontWeight.w500)), Text( 'Y: ${eovY == 0 ? "–" : eovY.toStringAsFixed(1)}', style: const TextStyle( fontSize: 12, fontFeatures: [FontFeature.tabularFigures()]), ), Text( 'X: ${eovX == 0 ? "–" : eovX.toStringAsFixed(1)}', style: const TextStyle( fontSize: 12, fontFeatures: [FontFeature.tabularFigures()]), ), ], ), ), Container( width: 1, height: 36, color: cs.outlineVariant, margin: const EdgeInsets.symmetric(horizontal: 10)), // Pontosság Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text('Pontosság', style: TextStyle( fontSize: 10, color: cs.onSurfaceVariant, fontWeight: FontWeight.w500)), Obx(() => Text( 'H: ${ctrl.horizontalAccuracyText}', style: TextStyle( fontSize: 12, color: _accuracyColor( ctrl.gpsLatitudeError.value, ctrl.gpsLongitudeError.value), fontWeight: FontWeight.w600, fontFeatures: const [ FontFeature.tabularFigures() ], ), )), Obx(() => Text( 'V: ${ctrl.verticalAccuracyText}', style: TextStyle( fontSize: 12, color: _accuracyColor( ctrl.gpsAltitudeError.value, ctrl.gpsAltitudeError.value), fontWeight: FontWeight.w600, fontFeatures: const [ FontFeature.tabularFigures() ], ), )), ], ), ], ), ); }), const Divider(height: 1), const SizedBox(height: 8), // ── Minőség chip + rögzített pontok + gomb ───────────── Row( children: [ // GPS minőség chip Obx(() { final q = ctrl.gpsQuality.value; final color = ctrl.getCurrentLocationMarkerColor(q); final label = ctrl.getGpsQualityIndicator(quality: q); return Container( padding: const EdgeInsets.symmetric( horizontal: 8, vertical: 4), decoration: BoxDecoration( color: color.withOpacity(0.15), borderRadius: BorderRadius.circular(6), border: Border.all(color: color.withOpacity(0.5)), ), child: Row(mainAxisSize: MainAxisSize.min, children: [ Container( width: 7, height: 7, decoration: BoxDecoration( color: color, shape: BoxShape.circle), ), const SizedBox(width: 5), Text(label, style: TextStyle( fontSize: 11, color: color, fontWeight: FontWeight.w600)), ]), ); }), const SizedBox(width: 8), // Rögzített pontok száma Obx(() { final count = ctrl.pointWithDescriptionList.length; return Container( padding: const EdgeInsets.symmetric( horizontal: 8, vertical: 4), decoration: BoxDecoration( color: cs.surfaceContainerHighest, borderRadius: BorderRadius.circular(6), ), child: Row(mainAxisSize: MainAxisSize.min, children: [ Icon(Icons.location_on, size: 13, color: Colors.amber.shade700), const SizedBox(width: 4), Text('$count pont', style: const TextStyle( fontSize: 11, fontWeight: FontWeight.w500)), ]), ); }), const Spacer(), IconButton( onPressed: ctrl.openMeasuredPointsList, icon: const Icon(Icons.list_alt_outlined), tooltip: 'Bemért pontok'), const SizedBox(width: 4), // Pont rögzítése gomb Obx(() { final hasGps = GnssService.to.connectionState.value == GnssConnectionState.connected; return FilledButton.icon( onPressed: hasGps ? ctrl.showAddPointDialog : null, icon: const Icon(Icons.add_location_alt, size: 18), label: const Text('Rögzítés'), style: FilledButton.styleFrom( padding: const EdgeInsets.symmetric( horizontal: 16, vertical: 10), ), ); }) ], ), ], ), ), ), ); } Color _accuracyColor(double e1, double e2) { final e = e1 > e2 ? e1 : e2; if (e <= 0.05) return Colors.green; if (e <= 0.20) return Colors.lightGreen; if (e <= 1.00) return Colors.orange; return Colors.red; } }