// * Widget for managing wildlife observation hints and indicators // * Features: // * - Checkbox selection for common observation types // * - Custom text input for additional observations // * - Automatic text aggregation of selected items // * Available observation types: // * - Resting places (Liegestelle) // * - Animal carcasses (Wildtierkadaver) // * - Direct sightings (Sichtung) // * - Howling (Heulen) // * - Other observations (Sonstiges) import 'package:fforte/enums/databases.dart'; import 'package:fforte/screens/sharedWidgets/var_text_field.dart'; import 'package:flutter/material.dart'; import 'package:fforte/l10n/app_localizations.dart'; /// Widget for recording various types of wildlife observations /// Combines predefined categories with custom input options class Hinweise extends StatefulWidget { /// Controller for the combined observation text final TextEditingController hinweise; const Hinweise({super.key, required this.hinweise}); @override State createState() => _HinweiseState(); } /// State class for the observations widget class _HinweiseState extends State { // Checkbox state variables /// Whether resting place was observed late bool liegestelleChecked; /// Whether animal carcass was found late bool kadaverChecked; /// Whether direct sighting occurred late bool sichtungChecked; /// Whether howling was heard late bool heulenChecked; /// Whether other observations exist bool sonstigesChecked = false; /// Controller for additional observations text TextEditingController sonstigesController = TextEditingController(); @override void initState() { sonstigesController.addListener(updateController); // Initialize checkboxes based on existing text liegestelleChecked = widget.hinweise.text.contains("Liegestelle") ? true : false; kadaverChecked = widget.hinweise.text.contains("Wildtierkadaver") ? true : false; sichtungChecked = widget.hinweise.text.contains("Sichtung") ? true : false; heulenChecked = widget.hinweise.text.contains("Heulen") ? true : false; bool firstRun = true; // Parse existing other observations for (String val in widget.hinweise.text.split(",")) { if (val != "Liegestelle" && val != "Wildtierkadaver" && val != "Sichtung" && val != "Heulen" && val != "") { sonstigesChecked = true; if (!firstRun) sonstigesController.text += ","; sonstigesController.text += val; firstRun = false; } } super.initState(); } @override void dispose() { sonstigesController.dispose(); super.dispose(); } /// Update the main controller text based on selected options /// Combines all checked items and additional text into a comma-separated string void updateController() { Map props = { "Liegestelle": liegestelleChecked, "Wildtierkadaver": kadaverChecked, "Sichtung": sichtungChecked, "Heulen": heulenChecked, "sonstiges": sonstigesChecked }; bool firstRun = true; widget.hinweise.text = ""; // Build combined text from selected options for (String key in props.keys) { if (!firstRun && props[key]!) { widget.hinweise.text += ","; } else if (firstRun && props[key]!) { firstRun = false; } if (key == "sonstiges") { widget.hinweise.text += sonstigesController.text; } else if (props[key]!){ widget.hinweise.text += key; } } debugPrint(widget.hinweise.text); } @override Widget build(BuildContext context) { return Column( children: [ // Resting place checkbox CheckboxListTile( title: Text(AppLocalizations.of(context)!.liegestelle), value: liegestelleChecked, onChanged: (bool? value) { setState(() => liegestelleChecked = value ?? false); updateController(); }), // Animal carcass checkbox CheckboxListTile( title: Text(AppLocalizations.of(context)!.wildtierKadaver), value: kadaverChecked, onChanged: (bool? value) { setState(() => kadaverChecked = value ?? false); updateController(); }), // Direct sighting checkbox CheckboxListTile( title: Text(AppLocalizations.of(context)!.sichtung), value: sichtungChecked, onChanged: (bool? value) { setState(() => sichtungChecked = value ?? false); updateController(); }), // Howling checkbox CheckboxListTile( title: Text(AppLocalizations.of(context)!.heulen), value: heulenChecked, onChanged: (bool? value) { setState(() => heulenChecked = value ?? false); updateController(); }), // Other observations checkbox and input field CheckboxListTile( title: Text(AppLocalizations.of(context)!.sonstiges), value: sonstigesChecked, onChanged: (bool? value) { if (!value!) sonstigesController.text = ""; setState(() => sonstigesChecked = value); updateController(); }), if (sonstigesChecked) VarTextField( textController: sonstigesController, localization: AppLocalizations.of(context)!.sonstiges, dbName: "HinweiseSonstiges", required: false, dbDesignation: DatabasesEnum.excursion) ], ); } }