Terepbejárás geometriák szerkesztése: kontrollpontok és tulajdonságok.
This commit is contained in:
parent
1276ac0610
commit
0257beec38
1
lib/enums/note_type.dart
Normal file
1
lib/enums/note_type.dart
Normal file
@ -0,0 +1 @@
|
||||
enum NoteType { point, line, polygon }
|
||||
183
lib/models/note_item.dart
Normal file
183
lib/models/note_item.dart
Normal file
@ -0,0 +1,183 @@
|
||||
import 'dart:convert';
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_map/flutter_map.dart';
|
||||
import 'package:latlong2/latlong.dart';
|
||||
|
||||
import '../enums/note_type.dart';
|
||||
|
||||
class NoteItem {
|
||||
final int? id;
|
||||
final int? projectId;
|
||||
final NoteType type;
|
||||
final List<LatLng> points; // ← szerkesztéshez mindig elérhető
|
||||
final Color color;
|
||||
final double opacity;
|
||||
final double strokeWidth;
|
||||
final Color strokeColor;
|
||||
final String label;
|
||||
final DateTime createdAt;
|
||||
|
||||
const NoteItem(
|
||||
{this.id,
|
||||
this.projectId,
|
||||
required this.type,
|
||||
required this.points,
|
||||
required this.color,
|
||||
this.opacity = 0.5,
|
||||
this.strokeWidth = 3.0,
|
||||
required this.strokeColor,
|
||||
this.label = '',
|
||||
required this.createdAt});
|
||||
|
||||
NoteItem copyWith({
|
||||
List<LatLng>? points,
|
||||
Color? color,
|
||||
double? opacity,
|
||||
double? strokeWidth,
|
||||
Color? strokeColor,
|
||||
String? label,
|
||||
}) =>
|
||||
NoteItem(
|
||||
id: id,
|
||||
projectId: projectId,
|
||||
type: type,
|
||||
points: points ?? this.points,
|
||||
color: color ?? this.color,
|
||||
opacity: opacity ?? this.opacity,
|
||||
strokeWidth: strokeWidth ?? this.strokeWidth,
|
||||
strokeColor: strokeColor ?? this.strokeColor,
|
||||
label: label ?? this.label,
|
||||
createdAt: createdAt,
|
||||
);
|
||||
// ── Koordináta ↔ GeoJSON ────────────────────────────────────────
|
||||
|
||||
static List<LatLng> _parsePoints(String json) {
|
||||
final geom = jsonDecode(json) as Map<String, dynamic>;
|
||||
final gType = geom['type'] as String;
|
||||
final coords = geom['coordinates'];
|
||||
|
||||
switch (gType) {
|
||||
case 'Point':
|
||||
final c = coords as List;
|
||||
return [
|
||||
LatLng(
|
||||
(c[1] as num).toDouble(),
|
||||
(c[0] as num).toDouble(),
|
||||
)
|
||||
];
|
||||
|
||||
case 'LineString':
|
||||
return (coords as List)
|
||||
.map((c) => LatLng(
|
||||
(c[1] as num).toDouble(),
|
||||
(c[0] as num).toDouble(),
|
||||
))
|
||||
.toList();
|
||||
|
||||
case 'Polygon':
|
||||
// Külső gyűrű (index 0)
|
||||
return ((coords as List)[0] as List)
|
||||
.map((c) => LatLng(
|
||||
(c[1] as num).toDouble(),
|
||||
(c[0] as num).toDouble(),
|
||||
))
|
||||
.toList();
|
||||
|
||||
default:
|
||||
return [];
|
||||
}
|
||||
}
|
||||
|
||||
String _toPointsJson() {
|
||||
List<dynamic> coords;
|
||||
String gType;
|
||||
|
||||
switch (type) {
|
||||
case NoteType.point:
|
||||
// GeoJSON: [lon, lat]
|
||||
gType = 'Point';
|
||||
coords = [points.first.longitude, points.first.latitude];
|
||||
|
||||
case NoteType.line:
|
||||
gType = 'LineString';
|
||||
coords = points.map((p) => [p.longitude, p.latitude]).toList();
|
||||
|
||||
case NoteType.polygon:
|
||||
gType = 'Polygon';
|
||||
final ring = points.map((p) => [p.longitude, p.latitude]).toList();
|
||||
// Polygon zárt: első = utolsó pont
|
||||
if (ring.isNotEmpty) {
|
||||
final first = ring.first;
|
||||
final last = ring.last;
|
||||
final isClosed = first[0] == last[0] && first[1] == last[1];
|
||||
|
||||
if (!isClosed) ring.add(List.from(first));
|
||||
}
|
||||
coords = [ring];
|
||||
}
|
||||
|
||||
return jsonEncode({'type': gType, 'coordinates': coords});
|
||||
}
|
||||
// ── SQLite ↔ Map ────────────────────────────────────────────────
|
||||
|
||||
static Color _parseColor(String hex) {
|
||||
final h = hex.replaceFirst('#', '');
|
||||
return Color(int.parse(h.length == 6 ? 'FF$h' : h, radix: 16));
|
||||
}
|
||||
|
||||
static String _colorHex(Color c) =>
|
||||
'#${c.value.toRadixString(16).padLeft(8, '0').substring(2).toUpperCase()}';
|
||||
|
||||
Map<String, dynamic> toMap() => {
|
||||
if (id != null) 'id': id,
|
||||
if (projectId != null) 'project_id': projectId,
|
||||
'type': type.name,
|
||||
'points_json': _toPointsJson(),
|
||||
'color': _colorHex(color),
|
||||
'opacity': opacity,
|
||||
'stroke_width': strokeWidth,
|
||||
'stroke_color': _colorHex(strokeColor),
|
||||
'label': label,
|
||||
'created_at': createdAt.toIso8601String(),
|
||||
};
|
||||
|
||||
factory NoteItem.fromMap(Map<String, dynamic> m) => NoteItem(
|
||||
id: m['id'] as int?,
|
||||
projectId: m['project_id'] as int?,
|
||||
type: NoteType.values.firstWhere((t) => t.name == (m['type'] as String),
|
||||
orElse: () => NoteType.point),
|
||||
points: _parsePoints(m['points_json'] as String),
|
||||
color: _parseColor(m['color'] as String? ?? '#185FA5'),
|
||||
opacity: (m['opacity'] as num?)?.toDouble() ?? 0.5,
|
||||
strokeWidth: (m['stroke_width'] as num?)?.toDouble() ?? 3.0,
|
||||
strokeColor: _parseColor(m['stroke_color'] as String? ?? '#FFD700'),
|
||||
label: m['label'] as String? ?? '',
|
||||
createdAt: DateTime.parse(m['created_at'] as String),
|
||||
);
|
||||
|
||||
/// Kitöltési szín az opacity-val alkalmazva.
|
||||
Color get fillColor => Color.fromARGB(
|
||||
(opacity * 255).round(),
|
||||
color.red,
|
||||
color.green,
|
||||
color.blue,
|
||||
);
|
||||
|
||||
// Rendereléshez — a hitValue hordozza az id-t a tap detektáláshoz
|
||||
Polyline<int> toPolyline() => Polyline(
|
||||
points: points,
|
||||
color: color,
|
||||
strokeWidth: strokeWidth,
|
||||
hitValue: id!,
|
||||
);
|
||||
|
||||
Polygon<int> toPolygon() => Polygon(
|
||||
points: points,
|
||||
color: color.withOpacity(opacity),
|
||||
borderColor: strokeColor,
|
||||
borderStrokeWidth: strokeWidth,
|
||||
label: label.isEmpty ? null : label,
|
||||
hitValue: id!,
|
||||
);
|
||||
}
|
||||
@ -23,8 +23,10 @@ import 'package:terepi_seged/controls/geoid_grid.dart';
|
||||
import 'package:terepi_seged/controls/wgs84_coordinate_formatter.dart';
|
||||
import 'package:terepi_seged/enums/map_edit_tool.dart';
|
||||
import 'package:terepi_seged/enums/map_survey_mode.dart';
|
||||
import 'package:terepi_seged/enums/note_type.dart';
|
||||
import 'package:terepi_seged/eov/convert_coordinate.dart';
|
||||
import 'package:terepi_seged/eov/eov.dart';
|
||||
import 'package:terepi_seged/models/note_item.dart';
|
||||
import 'package:terepi_seged/models/point_to_measure.dart';
|
||||
import 'package:terepi_seged/models/point_with_description_model.dart';
|
||||
import 'package:shared_preferences/shared_preferences.dart';
|
||||
@ -32,11 +34,13 @@ import 'package:terepi_seged/pages/map_survey/presentations/views/measured_point
|
||||
import 'package:terepi_seged/pages/ntrip_settings/presentation/controllers/ntrip_settings_controller.dart';
|
||||
import 'package:terepi_seged/pages/ntrip_settings/presentation/views/ntrip_settings_sheet.dart';
|
||||
import 'package:terepi_seged/pages/tracking/presentation/controllers/tracking_controller.dart';
|
||||
import 'package:terepi_seged/services/app_database.dart';
|
||||
import 'package:terepi_seged/services/coord_converter_service.dart';
|
||||
import 'package:terepi_seged/services/gnss/gnss_connection.dart';
|
||||
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_edit_tools/map_feature_save_sheet.dart';
|
||||
|
||||
class MapSurveyController extends GetxController {
|
||||
@ -120,6 +124,9 @@ class MapSurveyController extends GetxController {
|
||||
|
||||
final MapController mapController = MapController();
|
||||
|
||||
final polylineHitNotifier = ValueNotifier<LayerHitResult<int>?>(null);
|
||||
final polygonHitNotifier = ValueNotifier<LayerHitResult<int>?>(null);
|
||||
|
||||
final currentLocationMarker = <Marker>[].obs;
|
||||
final pointNotesMarker = <Marker>[].obs;
|
||||
final pointsToMeasureMarker = <Marker>[].obs;
|
||||
@ -166,8 +173,8 @@ class MapSurveyController extends GetxController {
|
||||
final activeEditTool = MapEditTool.none.obs;
|
||||
final editorPointCount = 0.obs;
|
||||
final pointNotes = <Marker>[].obs;
|
||||
final polylineNotes = <Polyline<Object>>[].obs;
|
||||
final polygonNotes = <Polygon<Object>>[].obs;
|
||||
final polylineNotes = <Polyline<int>>[].obs;
|
||||
final polygonNotes = <Polygon<int>>[].obs;
|
||||
|
||||
late final PolygonEditorController polygonEditorController;
|
||||
|
||||
@ -181,6 +188,13 @@ class MapSurveyController extends GetxController {
|
||||
const PolygonLabelPlacementCalculator.centroid();
|
||||
|
||||
bool get isMapEditing => activeEditTool.value != MapEditTool.none;
|
||||
final selectedNoteItemId = Rx<int?>(null);
|
||||
final selectedNoteItemType = NoteType.line.obs;
|
||||
int? _editingNoteItemId;
|
||||
bool get isGeometryEditing => _editingNoteItemId != null;
|
||||
|
||||
// NoteItem? get selectedPoint =>
|
||||
// pointNotes.firstWhereOrNull((n) => n.id == selectedNoteItemId.value);
|
||||
|
||||
// ─────────────────────────────────────────────────────────────────
|
||||
// Lifecycle
|
||||
@ -229,6 +243,10 @@ class MapSurveyController extends GetxController {
|
||||
await _initStorage();
|
||||
|
||||
gpsHeightController.text = '1.8';
|
||||
|
||||
ever(ProjectService.to.activeProject, (_) => _loadNoteItems());
|
||||
|
||||
await _loadNoteItems();
|
||||
}
|
||||
|
||||
@override
|
||||
@ -962,6 +980,9 @@ class MapSurveyController extends GetxController {
|
||||
void cancelEditing() {
|
||||
polygonEditorController.clear();
|
||||
activeEditTool.value = MapEditTool.none;
|
||||
_editingNoteItemId = null;
|
||||
selectedNoteItemId.value = null;
|
||||
editorPointCount.value = 0;
|
||||
}
|
||||
|
||||
void openFeatureList() {
|
||||
@ -1005,73 +1026,437 @@ class MapSurveyController extends GetxController {
|
||||
//draftPoints.clear();
|
||||
}
|
||||
|
||||
Future<void> finishDraft() async {
|
||||
if (polygonEditorController.mode == PolygonEditorMode.line) {
|
||||
print("Points number in line: ${polygonEditorController.points.length}");
|
||||
print(
|
||||
"1. point coords: ${polygonEditorController.points[0].latitude} - ${polygonEditorController.points[0].longitude}");
|
||||
if (polygonEditorController.points.length < 2) return;
|
||||
Marker _markerFromNoteItem(NoteItem item) {
|
||||
return Marker(
|
||||
key: ValueKey('note_point_${item.id}'),
|
||||
point: item.points.first,
|
||||
width: 32.0,
|
||||
height: 32.0,
|
||||
child: GestureDetector(
|
||||
onTap: () => selectedNoteItem(item.id!),
|
||||
child: Obx(() {
|
||||
final isSelected = selectedNoteItemId.value == item.id;
|
||||
return Center(
|
||||
child: AnimatedContainer(
|
||||
duration: const Duration(milliseconds: 200),
|
||||
width: isSelected ? 26.0 : 20.0,
|
||||
height: isSelected ? 26.0 : 20.0,
|
||||
decoration: BoxDecoration(
|
||||
color: item.color,
|
||||
shape: BoxShape.circle,
|
||||
border: Border.all(
|
||||
width: isSelected ? 3.0 : 1.5,
|
||||
color: isSelected ? Colors.white : item.strokeColor),
|
||||
boxShadow: [
|
||||
BoxShadow(
|
||||
color: Colors.black.withValues(alpha: 0.3),
|
||||
blurRadius: isSelected ? 8 : 3)
|
||||
]),
|
||||
));
|
||||
}),
|
||||
),
|
||||
);
|
||||
}
|
||||
// ── SQLite mentés ─────────────────────────────────────────────────
|
||||
|
||||
Polyline polyline = Polyline(
|
||||
points: List.from(polygonEditorController.points),
|
||||
color: activeEditColor.value,
|
||||
strokeWidth: activeEditStrokeWidth.value,
|
||||
// hitValue: (
|
||||
// title: 'Purple Line',
|
||||
// subtitle: 'Nothing really special here...',
|
||||
// ),
|
||||
Future<NoteItem?> _saveItem({
|
||||
required NoteType type,
|
||||
required List<LatLng> points,
|
||||
}) async {
|
||||
final projectId = ProjectService.to.activeProject.value?.id;
|
||||
|
||||
final item = NoteItem(
|
||||
projectId: projectId, // projekt nélkül is mentődik
|
||||
type: type,
|
||||
points: points,
|
||||
color: activeEditColor.value,
|
||||
opacity: activeEditOpacity.value,
|
||||
strokeWidth: activeEditStrokeWidth.value,
|
||||
strokeColor: activeEditStrokeColor.value,
|
||||
label: activeEditLabel.value,
|
||||
createdAt: DateTime.now(),
|
||||
);
|
||||
|
||||
try {
|
||||
final id = await AppDatabase.instance.insertNoteItem(item);
|
||||
// id-vel visszaadott NoteItem — a hitValue ehhez az id-hez kötődik
|
||||
return NoteItem(
|
||||
id: id,
|
||||
projectId: item.projectId,
|
||||
type: item.type,
|
||||
points: item.points,
|
||||
color: item.color,
|
||||
opacity: item.opacity,
|
||||
strokeWidth: item.strokeWidth,
|
||||
strokeColor: item.strokeColor,
|
||||
label: item.label,
|
||||
createdAt: item.createdAt,
|
||||
);
|
||||
polylineNotes.add(polyline);
|
||||
// polylineNotes.refresh();
|
||||
|
||||
print("Points number in polylineNotes: ${polylineNotes.length}");
|
||||
print(
|
||||
"1. point coords of polyline: ${polyline.points[0].latitude} - ${polyline.points[0].longitude}");
|
||||
|
||||
polygonEditorController.clear();
|
||||
activeEditTool.value = MapEditTool.none;
|
||||
}
|
||||
if (polygonEditorController.mode == PolygonEditorMode.polygon) {
|
||||
print(
|
||||
"Points number in polygon: ${polygonEditorController.points.length}");
|
||||
|
||||
Polygon polygon = Polygon(
|
||||
points: List.from(polygonEditorController.points),
|
||||
color: activeEditColor.value.withValues(alpha: activeEditOpacity.value),
|
||||
borderColor: activeEditStrokeColor.value,
|
||||
borderStrokeWidth: activeEditStrokeWidth.value,
|
||||
label: activeEditLabel.value,
|
||||
labelPlacementCalculator: _labelPlacementCalculator,
|
||||
// hitValue: (
|
||||
// title: 'Basic Filled Polygon',
|
||||
// subtitle: 'Nothing really special here...',
|
||||
);
|
||||
|
||||
polygonNotes.add(polygon);
|
||||
//polygonNotes.refresh();
|
||||
//update();
|
||||
|
||||
print("Points number in polygonNotes: ${polygonNotes.length}");
|
||||
|
||||
polygonEditorController.clear();
|
||||
activeEditTool.value = MapEditTool.none;
|
||||
} catch (e) {
|
||||
print('_saveItem hiba: $e');
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
void saveEditedPoint({required LatLng point}) {
|
||||
Marker marker = Marker(
|
||||
point: point,
|
||||
width: 15.0,
|
||||
height: 15.0,
|
||||
child: Container(
|
||||
width: 15.0,
|
||||
height: 15.0,
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.amber[700],
|
||||
shape: BoxShape.circle,
|
||||
border: Border.all(width: 1.0, color: Colors.black)),
|
||||
));
|
||||
pointNotes.add(marker);
|
||||
// ── SQLite betöltés (onReady-ben hívandó) ─────────────────────────
|
||||
|
||||
Future<void> _loadNoteItems() async {
|
||||
final projectId = ProjectService.to.activeProject.value?.id;
|
||||
final items = await AppDatabase.instance.listNoteItems(projectId);
|
||||
|
||||
// Listák resetelése
|
||||
pointNotes.clear();
|
||||
polylineNotes.clear();
|
||||
polygonNotes.clear();
|
||||
|
||||
for (final item in items) {
|
||||
switch (item.type) {
|
||||
case NoteType.point:
|
||||
pointNotes.add(_markerFromNoteItem(item));
|
||||
case NoteType.line:
|
||||
polylineNotes.add(item.toPolyline());
|
||||
case NoteType.polygon:
|
||||
polygonNotes.add(item.toPolygon());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> finishDraft() async {
|
||||
if (_editingNoteItemId != null) {
|
||||
if (polygonEditorController.points.isEmpty) {
|
||||
await _finishStyleUpdate();
|
||||
} else {
|
||||
// ── FRISSÍTÉSI MÓD ──────────────────────────────────────────
|
||||
await _finishGeometryUpdate();
|
||||
}
|
||||
} else {
|
||||
// ── LÉTREHOZÁSI MÓD (eredeti logika) ────────────────────────
|
||||
await _finishCreate();
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> _finishStyleUpdate() async {
|
||||
final id = _editingNoteItemId!;
|
||||
final existing = await AppDatabase.instance.getNoteItem(id);
|
||||
if (existing == null) return;
|
||||
|
||||
final updated = existing.copyWith(
|
||||
color: activeEditColor.value,
|
||||
opacity: activeEditOpacity.value,
|
||||
strokeWidth: activeEditStrokeWidth.value,
|
||||
strokeColor: activeEditStrokeColor.value,
|
||||
label: activeEditLabel.value,
|
||||
);
|
||||
|
||||
await updateNoteItem(updated);
|
||||
_editingNoteItemId = null;
|
||||
}
|
||||
|
||||
Future<void> deleteEditingItem() async {
|
||||
final id = _editingNoteItemId;
|
||||
if (id == null) return;
|
||||
final item = await AppDatabase.instance.getNoteItem(id);
|
||||
if (item != null) await deleteNoteItem(item);
|
||||
_editingNoteItemId = null;
|
||||
selectedNoteItemId.value = null;
|
||||
activeEditTool.value = MapEditTool.none;
|
||||
}
|
||||
|
||||
// Future<void> finishDraft() async {
|
||||
// if (polygonEditorController.mode == PolygonEditorMode.line) {
|
||||
// print("Points number in line: ${polygonEditorController.points.length}");
|
||||
// print(
|
||||
// "1. point coords: ${polygonEditorController.points[0].latitude} - ${polygonEditorController.points[0].longitude}");
|
||||
// if (polygonEditorController.points.length < 2) return;
|
||||
|
||||
// final saved = await _saveItem(
|
||||
// type: NoteType.line,
|
||||
// points: List.from(polygonEditorController.points));
|
||||
|
||||
// if (saved != null) {
|
||||
// polylineNotes.add(saved.toPolyline());
|
||||
// }
|
||||
|
||||
// polygonEditorController.clear();
|
||||
// activeEditTool.value = MapEditTool.none;
|
||||
// }
|
||||
// if (polygonEditorController.mode == PolygonEditorMode.polygon) {
|
||||
// if (polygonEditorController.points.length < 3) return;
|
||||
|
||||
// final saved = await _saveItem(
|
||||
// type: NoteType.polygon,
|
||||
// points: List.from(polygonEditorController.points));
|
||||
|
||||
// if (saved != null) {
|
||||
// polygonNotes.add(saved.toPolygon());
|
||||
// }
|
||||
|
||||
// polygonEditorController.clear();
|
||||
// activeEditTool.value = MapEditTool.none;
|
||||
// }
|
||||
// }
|
||||
|
||||
void saveEditedPoint({required LatLng point}) {
|
||||
if (_editingNoteItemId != null) {
|
||||
// ── PONT FRISSÍTÉSI MÓD ──────────────────────────────────────
|
||||
final id = _editingNoteItemId!;
|
||||
_editingNoteItemId = null;
|
||||
activeEditTool.value = MapEditTool.none;
|
||||
|
||||
AppDatabase.instance.getNoteItem(id).then((existing) async {
|
||||
if (existing == null) return;
|
||||
final updated = existing.copyWith(points: [point]);
|
||||
await updateNoteItem(updated);
|
||||
});
|
||||
} else {
|
||||
// ── ÚJ PONT LÉTREHOZÁS (eredeti logika) ─────────────────────
|
||||
_saveItem(
|
||||
type: NoteType.point,
|
||||
points: [point],
|
||||
).then((saved) {
|
||||
if (saved == null) return;
|
||||
pointNotes.add(_markerFromNoteItem(saved));
|
||||
});
|
||||
activeEditTool.value = MapEditTool.none;
|
||||
}
|
||||
}
|
||||
|
||||
// void saveEditedPoint({required LatLng point}) {
|
||||
// _saveItem(type: NoteType.point, points: [point]).then((saved) {
|
||||
// if (saved == null) return;
|
||||
// pointNotes.add(_markerFromNoteItem(saved));
|
||||
// });
|
||||
|
||||
// // Marker marker = Marker(
|
||||
// // point: point,
|
||||
// // width: 15.0,
|
||||
// // height: 15.0,
|
||||
// // child: Container(
|
||||
// // width: 15.0,
|
||||
// // height: 15.0,
|
||||
// // decoration: BoxDecoration(
|
||||
// // color: Colors.amber[700],
|
||||
// // shape: BoxShape.circle,
|
||||
// // border: Border.all(width: 1.0, color: Colors.black)),
|
||||
// // ));
|
||||
// //pointNotes.add(marker);
|
||||
// activeEditTool.value = MapEditTool.none;
|
||||
// }
|
||||
|
||||
Future<void> selectedNoteItem(int id) async {
|
||||
selectedNoteItemId.value = id;
|
||||
|
||||
final item = await AppDatabase.instance.getNoteItem(id);
|
||||
if (item == null) return;
|
||||
|
||||
_editingNoteItemId = item.id;
|
||||
activeEditColor.value = item.color;
|
||||
activeEditOpacity.value = item.opacity;
|
||||
activeEditStrokeWidth.value = item.strokeWidth;
|
||||
activeEditStrokeColor.value = item.strokeColor;
|
||||
activeEditLabel.value = item.label;
|
||||
activeEditTool.value = switch (item.type) {
|
||||
NoteType.point => MapEditTool.point,
|
||||
NoteType.line => MapEditTool.line,
|
||||
NoteType.polygon => MapEditTool.polygon
|
||||
};
|
||||
|
||||
Get.bottomSheet(
|
||||
DraggableScrollableSheet(
|
||||
initialChildSize: 0.52,
|
||||
minChildSize: 0.35,
|
||||
maxChildSize: 0.85,
|
||||
snap: true,
|
||||
snapSizes: const [0.35, 0.52, 0.85],
|
||||
expand: false,
|
||||
builder: (_, scrollCtrl) =>
|
||||
MapFeatureSaveSheet(ctrl: this, scrollCtrl: scrollCtrl)),
|
||||
isScrollControlled: true,
|
||||
backgroundColor: Colors.transparent,
|
||||
ignoreSafeArea: false)
|
||||
.whenComplete(() {
|
||||
selectedNoteItemId.value = null;
|
||||
//_editingNoteItemId = null;
|
||||
if (!isGeometryEditing) {
|
||||
activeEditTool.value = MapEditTool.none;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void clearNoteItemSelection() {
|
||||
selectedNoteItemId.value = null;
|
||||
}
|
||||
|
||||
Future<void> updateNoteItem(NoteItem updated) async {
|
||||
await AppDatabase.instance.updateNoteItem(updated);
|
||||
|
||||
switch (updated.type) {
|
||||
case NoteType.line:
|
||||
final idx = polylineNotes.indexWhere((p) => p.hitValue == updated.id);
|
||||
if (idx >= 0) {
|
||||
polylineNotes[idx] = updated.toPolyline();
|
||||
polylineNotes.refresh();
|
||||
}
|
||||
case NoteType.polygon:
|
||||
final idx = polygonNotes.indexWhere((p) => p.hitValue == updated.id);
|
||||
if (idx >= 0) {
|
||||
polygonNotes[idx] = updated.toPolygon();
|
||||
polygonNotes.refresh();
|
||||
}
|
||||
case NoteType.point:
|
||||
final idx = _findPointMarkerIndex(updated.id!);
|
||||
if (idx >= 0) {
|
||||
pointNotes[idx] = _markerFromNoteItem(updated);
|
||||
pointNotes.refresh();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> deleteNoteItem(NoteItem item) async {
|
||||
await AppDatabase.instance.deleteNoteItem(item.id!);
|
||||
|
||||
switch (item.type) {
|
||||
case NoteType.line:
|
||||
polylineNotes.removeWhere((p) => p.hitValue == item.id);
|
||||
case NoteType.polygon:
|
||||
polygonNotes.removeWhere((p) => p.hitValue == item.id);
|
||||
case NoteType.point:
|
||||
// Pontot tag-elt Key alapján keresünk
|
||||
final idx = _findPointMarkerIndex(item.id!);
|
||||
if (idx >= 0) pointNotes.removeAt(idx);
|
||||
}
|
||||
selectedNoteItemId.value = null;
|
||||
}
|
||||
|
||||
/// Pont marker indexének megkeresése.
|
||||
/// A marker Key-je hordozza a NoteItem id-t.
|
||||
int _findPointMarkerIndex(int noteId) {
|
||||
return pointNotes.indexWhere(
|
||||
(m) => m.key == ValueKey('note_point_$noteId'),
|
||||
);
|
||||
}
|
||||
// ── Geometria szerkesztés indítása ────────────────────────────────────
|
||||
|
||||
Future<void> startGeometryEdit() async {
|
||||
final id = _editingNoteItemId;
|
||||
if (id == null) return;
|
||||
|
||||
final item = await AppDatabase.instance.getNoteItem(id);
|
||||
if (item == null) return;
|
||||
|
||||
if (item.type == NoteType.point) {
|
||||
// Pontnál: régi törlése, új elhelyezés vár
|
||||
activeEditTool.value = MapEditTool.point;
|
||||
return;
|
||||
}
|
||||
|
||||
// Editor mód beállítása a típus szerint
|
||||
final editorMode = item.type == NoteType.line
|
||||
? PolygonEditorMode.line
|
||||
: PolygonEditorMode.polygon;
|
||||
|
||||
// PolygonEditorController újraindítása a meglévő pontokkal
|
||||
// Dispose → újra létrehozás szükséges ha a controller már él
|
||||
polygonEditorController.clear();
|
||||
polygonEditorController.setMode(editorMode);
|
||||
|
||||
// Meglévő pontok betöltése az editorba
|
||||
for (final point in item.points) {
|
||||
polygonEditorController.addPoint(point);
|
||||
}
|
||||
|
||||
editorPointCount.value = item.points.length;
|
||||
|
||||
// Szerkesztési mód aktiválása
|
||||
activeEditTool.value =
|
||||
item.type == NoteType.line ? MapEditTool.line : MapEditTool.polygon;
|
||||
}
|
||||
|
||||
// ── Geometria szerkesztés megszakítása ────────────────────────────────
|
||||
|
||||
void cancelGeometryEdit() {
|
||||
_editingNoteItemId = null;
|
||||
polygonEditorController.clear();
|
||||
activeEditTool.value = MapEditTool.none;
|
||||
editorPointCount.value = 0;
|
||||
}
|
||||
|
||||
Future<void> _finishGeometryUpdate() async {
|
||||
final id = _editingNoteItemId!;
|
||||
|
||||
if (polygonEditorController.points.length < _minPoints) {
|
||||
Get.snackbar(
|
||||
'Figyelem',
|
||||
'Nincs elég pont a geometriához.',
|
||||
snackPosition: SnackPosition.BOTTOM,
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
// Meglévő elem lekérése az adatbázisból
|
||||
final existing = await AppDatabase.instance.getNoteItem(id);
|
||||
if (existing == null) return;
|
||||
|
||||
// Frissítés: csak a pontok változnak, a stílus marad
|
||||
final updated = existing.copyWith(
|
||||
points: List<LatLng>.from(polygonEditorController.points),
|
||||
// Ha a stílus is változott a szerkesztés közben:
|
||||
color: activeEditColor.value,
|
||||
opacity: activeEditOpacity.value,
|
||||
strokeWidth: activeEditStrokeWidth.value,
|
||||
strokeColor: activeEditStrokeColor.value,
|
||||
label: activeEditLabel.value,
|
||||
);
|
||||
|
||||
// SQLite + display lista frissítése
|
||||
await updateNoteItem(updated);
|
||||
|
||||
// Reset
|
||||
_editingNoteItemId = null;
|
||||
polygonEditorController.clear();
|
||||
activeEditTool.value = MapEditTool.none;
|
||||
editorPointCount.value = 0;
|
||||
|
||||
Get.snackbar(
|
||||
'Geometria frissítve',
|
||||
updated.label.isNotEmpty ? updated.label : '',
|
||||
snackPosition: SnackPosition.BOTTOM,
|
||||
duration: const Duration(seconds: 2),
|
||||
);
|
||||
}
|
||||
|
||||
Future<void> _finishCreate() async {
|
||||
if (polygonEditorController.mode == PolygonEditorMode.line) {
|
||||
if (polygonEditorController.points.length < 2) return;
|
||||
|
||||
final saved = await _saveItem(
|
||||
type: NoteType.line,
|
||||
points: List.from(polygonEditorController.points),
|
||||
);
|
||||
if (saved != null) {
|
||||
polylineNotes.add(saved.toPolyline());
|
||||
}
|
||||
polygonEditorController.clear();
|
||||
activeEditTool.value = MapEditTool.none;
|
||||
}
|
||||
|
||||
if (polygonEditorController.mode == PolygonEditorMode.polygon) {
|
||||
if (polygonEditorController.points.length < 3) return;
|
||||
|
||||
final saved = await _saveItem(
|
||||
type: NoteType.polygon,
|
||||
points: List.from(polygonEditorController.points),
|
||||
);
|
||||
if (saved != null) {
|
||||
polygonNotes.add(saved.toPolygon());
|
||||
}
|
||||
polygonEditorController.clear();
|
||||
activeEditTool.value = MapEditTool.none;
|
||||
}
|
||||
}
|
||||
|
||||
int get _minPoints {
|
||||
if (polygonEditorController.mode == PolygonEditorMode.line) return 2;
|
||||
return 3; // polygon
|
||||
}
|
||||
}
|
||||
|
||||
@ -41,6 +41,23 @@ class MapSurveyView extends GetView<MapSurveyController> {
|
||||
controller.polygonEditorController.addPoint(point);
|
||||
}
|
||||
},
|
||||
onTap: (tapPosition, point) {
|
||||
if (controller.mode.value != MapSurveyMode.fieldWalk) return;
|
||||
if (controller.isMapEditing) return;
|
||||
final polygonHit = controller.polygonHitNotifier.value;
|
||||
if (polygonHit != null && polygonHit.hitValues.isNotEmpty) {
|
||||
final id = polygonHit.hitValues.first;
|
||||
controller.selectedNoteItem(id);
|
||||
return;
|
||||
}
|
||||
final polylineHit = controller.polylineHitNotifier.value;
|
||||
if (polylineHit != null && polylineHit.hitValues.isNotEmpty) {
|
||||
final id = polylineHit.hitValues.first;
|
||||
controller.selectedNoteItem(id);
|
||||
return;
|
||||
}
|
||||
controller.clearNoteItemSelection();
|
||||
},
|
||||
layers: [
|
||||
Obx(() =>
|
||||
MarkerLayer(markers: controller.currentLocationMarker.toList())),
|
||||
@ -55,14 +72,6 @@ class MapSurveyView extends GetView<MapSurveyController> {
|
||||
return _buildTrackLayer();
|
||||
}
|
||||
}),
|
||||
Obx(() {
|
||||
if (controller.mode.value != MapSurveyMode.fieldWalk) {
|
||||
return const SizedBox.shrink();
|
||||
}
|
||||
return PolygonEditor(
|
||||
controller: controller.polygonEditorController,
|
||||
throttleDuration: Duration.zero);
|
||||
}),
|
||||
Obx(() {
|
||||
if (controller.mode.value != MapSurveyMode.fieldWalk) {
|
||||
return const SizedBox.shrink();
|
||||
@ -75,7 +84,9 @@ class MapSurveyView extends GetView<MapSurveyController> {
|
||||
return const SizedBox.shrink();
|
||||
}
|
||||
|
||||
return PolylineLayer(polylines: [...controller.polylineNotes]);
|
||||
return PolylineLayer(
|
||||
hitNotifier: controller.polylineHitNotifier,
|
||||
polylines: [...controller.polylineNotes]);
|
||||
}),
|
||||
Obx(() {
|
||||
if (controller.mode.value != MapSurveyMode.fieldWalk) {
|
||||
@ -83,8 +94,56 @@ class MapSurveyView extends GetView<MapSurveyController> {
|
||||
}
|
||||
|
||||
return PolygonLayer(
|
||||
polygons: [...controller.polygonNotes], useAltRendering: true);
|
||||
})
|
||||
hitNotifier: controller.polygonHitNotifier,
|
||||
polygons: [...controller.polygonNotes],
|
||||
useAltRendering: true);
|
||||
}),
|
||||
Obx(() {
|
||||
if (controller.mode.value != MapSurveyMode.fieldWalk) {
|
||||
return const SizedBox.shrink();
|
||||
}
|
||||
final selectedId = controller.selectedNoteItemId.value;
|
||||
if (selectedId == null) return const SizedBox.shrink();
|
||||
|
||||
// Polygon kiemelés
|
||||
final selectedPolygon = controller.polygonNotes
|
||||
.where((p) => p.hitValue == selectedId)
|
||||
.firstOrNull;
|
||||
if (selectedPolygon != null) {
|
||||
return PolygonLayer(polygons: [
|
||||
Polygon(
|
||||
points: selectedPolygon.points,
|
||||
color: Colors.transparent,
|
||||
borderColor: Colors.white,
|
||||
borderStrokeWidth: selectedPolygon.borderStrokeWidth + 3,
|
||||
),
|
||||
]);
|
||||
}
|
||||
|
||||
// Polyline kiemelés
|
||||
final selectedPolyline = controller.polylineNotes
|
||||
.where((p) => p.hitValue == selectedId)
|
||||
.firstOrNull;
|
||||
if (selectedPolyline != null) {
|
||||
return PolylineLayer(polylines: [
|
||||
Polyline(
|
||||
points: selectedPolyline.points,
|
||||
color: Colors.white.withOpacity(0.6),
|
||||
strokeWidth: selectedPolyline.strokeWidth + 4,
|
||||
),
|
||||
]);
|
||||
}
|
||||
|
||||
return const SizedBox.shrink();
|
||||
}),
|
||||
Obx(() {
|
||||
if (controller.mode.value != MapSurveyMode.fieldWalk) {
|
||||
return const SizedBox.shrink();
|
||||
}
|
||||
return PolygonEditor(
|
||||
controller: controller.polygonEditorController,
|
||||
throttleDuration: Duration.zero);
|
||||
}),
|
||||
],
|
||||
),
|
||||
Positioned(
|
||||
|
||||
@ -3,6 +3,8 @@ import 'dart:io';
|
||||
import 'package:path_provider/path_provider.dart';
|
||||
import 'package:sqflite/sqflite.dart';
|
||||
import 'package:path/path.dart' as p;
|
||||
import 'package:terepi_seged/enums/note_type.dart';
|
||||
import 'package:terepi_seged/models/note_item.dart';
|
||||
import 'package:terepi_seged/models/track.dart';
|
||||
import 'package:uuid/uuid.dart';
|
||||
import '../models/project.dart';
|
||||
@ -116,7 +118,7 @@ class AppDatabase {
|
||||
await db.execute('''
|
||||
CREATE TABLE IF NOT EXISTS note_items (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
project_id INTEGER NOT NULL REFERENCES projects(id) ON DELETE CASCADE,
|
||||
project_id INTEGER REFERENCES projects(id) ON DELETE CASCADE,
|
||||
type TEXT NOT NULL,
|
||||
points_json TEXT NOT NULL,
|
||||
color TEXT NOT NULL DEFAULT '#185FA5',
|
||||
@ -381,4 +383,80 @@ class AppDatabase {
|
||||
whereArgs: ['synced'],
|
||||
);
|
||||
}
|
||||
|
||||
// ------------------- Terepbejárás pontok, vonalak, területek
|
||||
|
||||
/// Elem mentése - visszaadja a kapott AQLite id-t
|
||||
Future<int> insertNoteItem(NoteItem item) async {
|
||||
final db = await database;
|
||||
return db.insert('note_items', item.toMap());
|
||||
}
|
||||
|
||||
/// Elem frissítése (szín, label, koordináták módosítása után).
|
||||
Future<void> updateNoteItem(NoteItem item) async {
|
||||
final db = await database;
|
||||
await db.update(
|
||||
'note_items',
|
||||
item.toMap(),
|
||||
where: 'id = ?',
|
||||
whereArgs: [item.id],
|
||||
);
|
||||
}
|
||||
|
||||
/// Egy elem törlése.
|
||||
Future<void> deleteNoteItem(int id) async {
|
||||
final db = await database;
|
||||
await db.delete(
|
||||
'note_items',
|
||||
where: 'id = ?',
|
||||
whereArgs: [id],
|
||||
);
|
||||
}
|
||||
|
||||
/// Projekt összes eleme — opcionálisan típus szerint szűrve.
|
||||
Future<List<NoteItem>> listNoteItems(int? projectId, {NoteType? type}) async {
|
||||
final db = await database;
|
||||
|
||||
String? where;
|
||||
List<Object?> whereArgs = [];
|
||||
|
||||
if (projectId != null) {
|
||||
where = type != null ? 'project_id = ? AND type = ?' : 'project_id = ?';
|
||||
whereArgs = type != null ? [projectId, type.name] : [projectId];
|
||||
} else {
|
||||
// Projekt nélküli elemek
|
||||
where = type != null ? 'type = ?' : null;
|
||||
whereArgs = type != null ? [type.name] : [];
|
||||
}
|
||||
|
||||
final rows = await db.query(
|
||||
'note_items',
|
||||
where: where,
|
||||
whereArgs: whereArgs,
|
||||
orderBy: 'created_at ASC',
|
||||
);
|
||||
return rows.map(NoteItem.fromMap).toList();
|
||||
}
|
||||
|
||||
/// Egyetlen elem lekérése id alapján.
|
||||
Future<NoteItem?> getNoteItem(int id) async {
|
||||
final db = await database;
|
||||
final rows = await db.query(
|
||||
'note_items',
|
||||
where: 'id = ?',
|
||||
whereArgs: [id],
|
||||
limit: 1,
|
||||
);
|
||||
return rows.isEmpty ? null : NoteItem.fromMap(rows.first);
|
||||
}
|
||||
|
||||
/// Projekt összes elemének törlése.
|
||||
Future<void> deleteAllNoteItems(int projectId) async {
|
||||
final db = await database;
|
||||
await db.delete(
|
||||
'note_items',
|
||||
where: 'project_id = ?',
|
||||
whereArgs: [projectId],
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,4 +1,5 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:get/get.dart';
|
||||
import 'package:terepi_seged/enums/map_edit_tool.dart';
|
||||
import 'package:terepi_seged/pages/map_survey/presentations/controllers/map_survey_controller.dart';
|
||||
|
||||
@ -56,10 +57,14 @@ class MapFeatureSaveSheet extends StatelessWidget {
|
||||
const SizedBox(height: 18),
|
||||
OpacitySlider(ctrl: ctrl),
|
||||
const SizedBox(height: 10),
|
||||
if (ctrl.activeEditTool.value != MapEditTool.point) ...[
|
||||
StrokeSlider(ctrl: ctrl),
|
||||
const SizedBox(height: 10),
|
||||
],
|
||||
Obx(() => ctrl.activeEditTool.value != MapEditTool.point
|
||||
? Column(children: [
|
||||
StrokeSlider(ctrl: ctrl),
|
||||
const SizedBox(
|
||||
height: 1,
|
||||
)
|
||||
])
|
||||
: const SizedBox.shrink()),
|
||||
LabelField(ctrl: ctrl),
|
||||
const SizedBox(height: 24),
|
||||
SaveSheetActions(ctrl: ctrl),
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:get/get.dart';
|
||||
import 'package:terepi_seged/enums/map_edit_tool.dart';
|
||||
import 'package:terepi_seged/pages/map_survey/presentations/controllers/map_survey_controller.dart';
|
||||
|
||||
class SaveSheetActions extends StatelessWidget {
|
||||
@ -8,44 +9,142 @@ class SaveSheetActions extends StatelessWidget {
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Row(children: [
|
||||
// ← Vissza — bezárja a sheet-et, folytatja a rajzolást
|
||||
Expanded(
|
||||
child: OutlinedButton.icon(
|
||||
style: OutlinedButton.styleFrom(
|
||||
padding: const EdgeInsets.symmetric(vertical: 14),
|
||||
shape:
|
||||
RoundedRectangleBorder(borderRadius: BorderRadius.circular(10)),
|
||||
),
|
||||
icon: const Icon(Icons.arrow_back, size: 18),
|
||||
label: const Text('Vissza'),
|
||||
onPressed: () => Navigator.pop(context),
|
||||
),
|
||||
),
|
||||
const SizedBox(width: 12),
|
||||
return Obx(() {
|
||||
final isEditing = ctrl.isGeometryEditing;
|
||||
final tool = ctrl.activeEditTool.value;
|
||||
final isPoint = tool == MapEditTool.point;
|
||||
|
||||
// Mentés — végleges mentés, mindkét sheet bezárása
|
||||
Expanded(
|
||||
flex: 2,
|
||||
child: Obx(() => FilledButton.icon(
|
||||
style: FilledButton.styleFrom(
|
||||
backgroundColor: ctrl.activeEditColor.value,
|
||||
padding: const EdgeInsets.symmetric(vertical: 14),
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(10)),
|
||||
return Column(mainAxisSize: MainAxisSize.min, children: [
|
||||
Row(children: [
|
||||
Expanded(
|
||||
child: OutlinedButton.icon(
|
||||
style: OutlinedButton.styleFrom(
|
||||
padding: const EdgeInsets.symmetric(vertical: 14),
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(10))),
|
||||
icon: Icon(
|
||||
isEditing ? Icons.close : Icons.arrow_back,
|
||||
size: 18,
|
||||
),
|
||||
label: Text(isEditing ? 'Mégse' : 'Vissza'),
|
||||
onPressed: () => Get.back(),
|
||||
),
|
||||
),
|
||||
const SizedBox(width: 12),
|
||||
Expanded(
|
||||
flex: 2,
|
||||
child: FilledButton.icon(
|
||||
style: FilledButton.styleFrom(
|
||||
backgroundColor: ctrl.activeEditColor.value,
|
||||
padding: const EdgeInsets.symmetric(vertical: 14),
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(10))),
|
||||
icon: const Icon(Icons.check, size: 18),
|
||||
label: const Text(
|
||||
'Mentés',
|
||||
style: TextStyle(fontWeight: FontWeight.w600, fontSize: 15),
|
||||
),
|
||||
onPressed: () async {
|
||||
//Navigator.pop(context); // style sheet bezárás
|
||||
Get.back();
|
||||
await ctrl.finishDraft();
|
||||
},
|
||||
)),
|
||||
),
|
||||
]);
|
||||
),
|
||||
)
|
||||
]),
|
||||
if (isEditing && !isPoint) ...[
|
||||
const SizedBox(height: 8),
|
||||
SizedBox(
|
||||
width: double.infinity,
|
||||
child: OutlinedButton.icon(
|
||||
style: OutlinedButton.styleFrom(
|
||||
padding: const EdgeInsets.symmetric(vertical: 12),
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(10)),
|
||||
),
|
||||
icon: const Icon(Icons.edit_outlined, size: 18),
|
||||
label: const Text('Geometria szerkesztése'),
|
||||
onPressed: () {
|
||||
Get.back();
|
||||
ctrl.startGeometryEdit();
|
||||
},
|
||||
),
|
||||
),
|
||||
],
|
||||
if (isEditing) ...[
|
||||
const SizedBox(height: 8),
|
||||
SizedBox(
|
||||
width: double.infinity,
|
||||
child: OutlinedButton.icon(
|
||||
style: OutlinedButton.styleFrom(
|
||||
foregroundColor: Colors.red,
|
||||
side: const BorderSide(color: Colors.red),
|
||||
padding: const EdgeInsets.symmetric(vertical: 12),
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(10))),
|
||||
icon: const Icon(Icons.delete_outline, size: 18),
|
||||
label: const Text('Törlés'),
|
||||
onPressed: () => _confirmDelete(context, ctrl),
|
||||
),
|
||||
)
|
||||
]
|
||||
]);
|
||||
});
|
||||
}
|
||||
// return Row(children: [
|
||||
// // ← Vissza — bezárja a sheet-et, folytatja a rajzolást
|
||||
// Expanded(
|
||||
// child: OutlinedButton.icon(
|
||||
// style: OutlinedButton.styleFrom(
|
||||
// padding: const EdgeInsets.symmetric(vertical: 14),
|
||||
// shape: RoundedRectangleBorder(
|
||||
// borderRadius: BorderRadius.circular(10)),
|
||||
// ),
|
||||
// icon: const Icon(Icons.arrow_back, size: 18),
|
||||
// label: const Text('Vissza'),
|
||||
// onPressed: () => Navigator.pop(context),
|
||||
// ),
|
||||
// ),
|
||||
// const SizedBox(width: 12),
|
||||
|
||||
// // Mentés — végleges mentés, mindkét sheet bezárása
|
||||
// Expanded(
|
||||
// flex: 2,
|
||||
// child: Obx(() => FilledButton.icon(
|
||||
// style: FilledButton.styleFrom(
|
||||
// backgroundColor: ctrl.activeEditColor.value,
|
||||
// padding: const EdgeInsets.symmetric(vertical: 14),
|
||||
// shape: RoundedRectangleBorder(
|
||||
// borderRadius: BorderRadius.circular(10)),
|
||||
// ),
|
||||
// icon: const Icon(Icons.check, size: 18),
|
||||
// label: const Text(
|
||||
// 'Mentés',
|
||||
// style: TextStyle(fontWeight: FontWeight.w600, fontSize: 15),
|
||||
// ),
|
||||
// onPressed: () async {
|
||||
// //Navigator.pop(context); // style sheet bezárás
|
||||
// Get.back();
|
||||
// await ctrl.finishDraft();
|
||||
// },
|
||||
// )),
|
||||
// ),
|
||||
// ]);
|
||||
void _confirmDelete(BuildContext context, MapSurveyController ctrl) {
|
||||
Get.dialog(AlertDialog(
|
||||
title: const Text('Elem törlése'),
|
||||
content: const Text('Ez az elem véglegesen törlődik.'),
|
||||
actions: [
|
||||
TextButton(onPressed: Get.back, child: const Text('Mégse')),
|
||||
FilledButton(
|
||||
style: FilledButton.styleFrom(backgroundColor: Colors.red),
|
||||
onPressed: () async {
|
||||
Get.back(); // dialóg
|
||||
Get.back(); // sheet
|
||||
await ctrl.deleteEditingItem();
|
||||
},
|
||||
child: const Text('Törlés'),
|
||||
),
|
||||
],
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
@ -8,6 +8,7 @@ class SharedMapWidget extends StatelessWidget {
|
||||
final MapController mapController;
|
||||
final List<Widget> layers;
|
||||
final void Function(TapPosition, LatLng)? onLongPress;
|
||||
final void Function(TapPosition, LatLng)? onTap;
|
||||
final void Function(MapCamera, bool)? onPositionChanged;
|
||||
|
||||
final MapControls controls;
|
||||
@ -33,6 +34,7 @@ class SharedMapWidget extends StatelessWidget {
|
||||
required this.mapController,
|
||||
this.layers = const [],
|
||||
this.onLongPress,
|
||||
this.onTap,
|
||||
this.onPositionChanged,
|
||||
this.controls = const MapControls(),
|
||||
this.initialCenter = const LatLng(47.5, 19.0),
|
||||
@ -61,6 +63,7 @@ class SharedMapWidget extends StatelessWidget {
|
||||
minZoom: minZoom,
|
||||
maxZoom: maxZoom,
|
||||
onLongPress: onLongPress,
|
||||
onTap: onTap,
|
||||
onPositionChanged: onPositionChanged,
|
||||
interactionOptions: const InteractionOptions(
|
||||
flags: InteractiveFlag.all,
|
||||
|
||||
Loading…
Reference in New Issue
Block a user