diff --git a/lib/pages/map_survey/presentations/controllers/map_survey_controller.dart b/lib/pages/map_survey/presentations/controllers/map_survey_controller.dart index 17a3e57..890200f 100644 --- a/lib/pages/map_survey/presentations/controllers/map_survey_controller.dart +++ b/lib/pages/map_survey/presentations/controllers/map_survey_controller.dart @@ -46,6 +46,7 @@ import 'package:terepi_seged/services/gnss/gnss_device_service.dart'; import 'package:terepi_seged/services/gnss/gnss_service.dart'; import 'package:terepi_seged/services/ntrip_service.dart'; import 'package:terepi_seged/services/project_service.dart'; +import 'package:terepi_seged/widgets/map/all_layer_overlay.dart'; import 'package:terepi_seged/widgets/map/imported_layer_overlay.dart'; import 'package:terepi_seged/widgets/map/team_member_widget.dart'; import 'package:terepi_seged/widgets/map_edit_tools/color_row.dart'; @@ -196,6 +197,10 @@ class MapSurveyController extends GetxController { final teamTrackPoints = >{}.obs; RealtimeChannel? _teamChannel; + final showPoints = true.obs; + final showLines = true.obs; + final showPolygons = true.obs; + late final PolygonEditorController polygonEditorController; final activeEditColor = const Color(0xFF185FA5).obs; @@ -1757,21 +1762,7 @@ class MapSurveyController extends GetxController { ), ), ), - Padding( - padding: const EdgeInsets.fromLTRB(20, 0, 20, 20), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - const Text('Importált rétegek', - style: TextStyle( - fontSize: 18, fontWeight: FontWeight.w600)), - const SizedBox(height: 16), - ImportLayerPanel( - onFitBounds: fitImportedLayer, - ), - ], - ), - ), + AllLayersPanel(ctrl: this) ], ), ), @@ -1985,4 +1976,10 @@ class MapSurveyController extends GetxController { alignment: Alignment.bottomCenter, child: TeamMemberWidget(name: name, color: color)); } + + void toggleShowPoints() => showPoints.value = !showPoints.value; + + void toggleShowLines() => showLines.value = !showLines.value; + + void toggleShowPolygons() => showPolygons.value = !showPolygons.value; } diff --git a/lib/pages/map_survey/presentations/views/map_survey_view.dart b/lib/pages/map_survey/presentations/views/map_survey_view.dart index ed42afb..86ae288 100644 --- a/lib/pages/map_survey/presentations/views/map_survey_view.dart +++ b/lib/pages/map_survey/presentations/views/map_survey_view.dart @@ -126,25 +126,31 @@ class MapSurveyView extends GetView { return MarkerLayer(markers: controller.pointNotesMarker.toList()); }), Obx(() { + // Pontok - terepi bejárás if (controller.mode.value != MapSurveyMode.fieldWalk) { return const SizedBox.shrink(); } + if (!controller.showPoints.value) return const SizedBox.shrink(); return MarkerLayer(markers: [...controller.pointNotes]); }), Obx(() { + // Vonalak - terepbejárás if (controller.mode.value != MapSurveyMode.fieldWalk) { return const SizedBox.shrink(); } + if (!controller.showLines.value) return const SizedBox.shrink(); return PolylineLayer( hitNotifier: controller.polylineHitNotifier, polylines: [...controller.polylineNotes]); }), Obx(() { + // Poligonok - terepbejárás if (controller.mode.value != MapSurveyMode.fieldWalk) { return const SizedBox.shrink(); } + if (!controller.showPolygons.value) return const SizedBox.shrink(); return PolygonLayer( hitNotifier: controller.polygonHitNotifier, diff --git a/lib/widgets/map/all_layer_overlay.dart b/lib/widgets/map/all_layer_overlay.dart new file mode 100644 index 0000000..a5bc164 --- /dev/null +++ b/lib/widgets/map/all_layer_overlay.dart @@ -0,0 +1,155 @@ +// Egységes rétegkezelő panel: +// 1. Geometria rétegek (pontok, vonalak, területek) — láthatóság kapcsoló +// 2. Importált rétegek (KML, KMZ, GeoJSON) — meglévő ImportLayerPanel + +import 'package:flutter/material.dart'; +import 'package:get/get.dart'; + +import '../../pages/map_survey/presentations/controllers/map_survey_controller.dart'; +import '../../services/layer_import_service.dart'; +import 'imported_layer_overlay.dart'; // ImportLayerPanel + +class AllLayersPanel extends StatelessWidget { + final MapSurveyController ctrl; + const AllLayersPanel({super.key, required this.ctrl}); + + @override + Widget build(BuildContext context) { + final cs = Theme.of(context).colorScheme; + + return Column( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisSize: MainAxisSize.min, + children: [ + // ── Szekció 1: Geometria rétegek ────────────────────────── + Padding( + padding: const EdgeInsets.fromLTRB(20, 4, 20, 0), + child: Text('Geometria rétegek', + style: TextStyle(fontSize: 18, fontWeight: FontWeight.w600)), + ), + const SizedBox(height: 8), + + Obx(() => _GeometryLayerTile( + icon: Icons.location_on, + color: Colors.orange, + label: 'Pontok', + count: ctrl.pointNotes.length, + visible: ctrl.showPoints.value, + onToggle: ctrl.toggleShowPoints, + )), + + Obx(() => _GeometryLayerTile( + icon: Icons.show_chart, + color: Colors.blue, + label: 'Vonalak', + count: ctrl.polylineNotes.length, + visible: ctrl.showLines.value, + onToggle: ctrl.toggleShowLines, + )), + + Obx(() => _GeometryLayerTile( + icon: Icons.pentagon_outlined, + color: Colors.green, + label: 'Területek', + count: ctrl.polygonNotes.length, + visible: ctrl.showPolygons.value, + onToggle: ctrl.toggleShowPolygons, + )), + + const Divider(height: 28), + + // ── Szekció 2: Importált rétegek ────────────────────────── + Padding( + padding: const EdgeInsets.fromLTRB(20, 0, 20, 12), + child: Row(children: [ + Text('Importált rétegek', + style: TextStyle(fontSize: 18, fontWeight: FontWeight.w600)), + const SizedBox(width: 8), + Obx(() { + final count = LayerImportService.to.layers.length; + if (count == 0) return const SizedBox.shrink(); + return Container( + padding: const EdgeInsets.symmetric(horizontal: 7, vertical: 2), + decoration: BoxDecoration( + color: cs.primaryContainer, + borderRadius: BorderRadius.circular(10), + ), + child: Text('$count', + style: TextStyle( + fontSize: 12, + fontWeight: FontWeight.w600, + color: cs.onPrimaryContainer)), + ); + }), + ]), + ), + + ImportLayerPanel( + onFitBounds: ctrl.fitImportedLayer, + ), + + const SizedBox(height: 16), + ], + ); + } +} + +// ─── Egy geometria réteg sor ────────────────────────────────────────────────── + +class _GeometryLayerTile extends StatelessWidget { + final IconData icon; + final Color color; + final String label; + final int count; + final bool visible; + final VoidCallback onToggle; + + const _GeometryLayerTile({ + required this.icon, + required this.color, + required this.label, + required this.count, + required this.visible, + required this.onToggle, + }); + + @override + Widget build(BuildContext context) { + final cs = Theme.of(context).colorScheme; + + return ListTile( + contentPadding: const EdgeInsets.symmetric(horizontal: 20, vertical: 0), + leading: Container( + width: 36, + height: 36, + decoration: BoxDecoration( + color: (visible ? color : Colors.grey).withOpacity(0.12), + borderRadius: BorderRadius.circular(8), + border: Border.all( + color: (visible ? color : Colors.grey).withOpacity(0.3), + ), + ), + child: Icon(icon, size: 18, color: visible ? color : Colors.grey), + ), + title: Text(label, + style: TextStyle( + fontWeight: FontWeight.w500, + color: visible ? null : cs.onSurfaceVariant, + )), + subtitle: count > 0 + ? Text('$count objektum', style: const TextStyle(fontSize: 11)) + : Text('Nincs rögzített geometria', + style: TextStyle(fontSize: 11, color: cs.onSurfaceVariant)), + trailing: Switch( + value: visible, + onChanged: (_) => onToggle(), + activeColor: color, + trackColor: WidgetStateProperty.resolveWith((states) => + states.contains(WidgetState.selected) + ? color.withOpacity(0.3) + : null), + ), + onTap: onToggle, + ); + } +}