250 lines
10 KiB
Dart
250 lines
10 KiB
Dart
// * Widget for tracking various wildlife monitoring quantities
|
|
// * Features:
|
|
// * - Tracking of droppings (Losung) counts and samples
|
|
// * - Urine marking spot counts and samples
|
|
// * - Estrus blood sample tracking
|
|
// * - Hair sample tracking
|
|
// * All fields support genetic sample counting
|
|
|
|
import 'package:flutter/material.dart';
|
|
import 'package:fforte/l10n/app_localizations.dart';
|
|
|
|
/// Widget for managing counts of various wildlife monitoring samples
|
|
/// Provides input fields for different types of samples and their genetic subsets
|
|
class Anzahlen extends StatefulWidget {
|
|
/// Controller for number of droppings found
|
|
final TextEditingController losungAnz;
|
|
/// Controller for number of droppings collected
|
|
final TextEditingController losungGes;
|
|
/// Controller for number of genetic samples from droppings
|
|
final TextEditingController losungGen;
|
|
/// Controller for number of urine marking spots
|
|
final TextEditingController urinAnz;
|
|
/// Controller for number of genetic samples from urine
|
|
final TextEditingController urinGen;
|
|
/// Controller for number of estrus blood spots
|
|
final TextEditingController oestrAnz;
|
|
/// Controller for number of genetic samples from estrus blood
|
|
final TextEditingController oestrGen;
|
|
/// Controller for number of hair samples
|
|
final TextEditingController haarAnz;
|
|
/// Controller for number of genetic samples from hair
|
|
final TextEditingController haarGen;
|
|
|
|
const Anzahlen(
|
|
{super.key,
|
|
required this.losungAnz,
|
|
required this.losungGes,
|
|
required this.losungGen,
|
|
required this.urinAnz,
|
|
required this.urinGen,
|
|
required this.oestrAnz,
|
|
required this.oestrGen,
|
|
required this.haarAnz,
|
|
required this.haarGen});
|
|
|
|
@override
|
|
AnzahlenState createState() => AnzahlenState();
|
|
}
|
|
|
|
/// State class for the quantity tracking widget
|
|
class AnzahlenState extends State<Anzahlen> {
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
return Column(
|
|
children: [
|
|
Column(
|
|
children: [
|
|
Column(
|
|
children: [
|
|
// Droppings count section
|
|
Row(
|
|
children: [
|
|
Expanded(
|
|
flex: 2,
|
|
child: Align(
|
|
alignment: Alignment.bottomLeft,
|
|
child: Text(
|
|
AppLocalizations.of(context)!.anzahlLosungen)),
|
|
),
|
|
const SizedBox(width: 20),
|
|
Expanded(
|
|
child: Align(
|
|
alignment: Alignment.centerLeft, child: TextField(
|
|
keyboardType: TextInputType.number,
|
|
controller: widget.losungAnz,
|
|
onTap: () => widget.losungAnz.selection = TextSelection(baseOffset: 0, extentOffset: widget.losungAnz.value.text.length),
|
|
)),
|
|
),
|
|
const SizedBox(width: 20),
|
|
Expanded(
|
|
flex: 2,
|
|
child: Align(
|
|
alignment: Alignment.bottomLeft,
|
|
child: Text(
|
|
AppLocalizations.of(context)!.davonEingesammelt)),
|
|
),
|
|
const SizedBox(width: 20),
|
|
Expanded(
|
|
child: Align(
|
|
alignment: Alignment.centerLeft, child: TextField(
|
|
keyboardType: TextInputType.number,
|
|
controller: widget.losungGes,
|
|
onTap: () => widget.losungGes.selection = TextSelection(baseOffset: 0, extentOffset: widget.losungGes.value.text.length),
|
|
)),
|
|
),
|
|
const SizedBox(height: 20),
|
|
],
|
|
),
|
|
// Genetic samples from droppings
|
|
Row(
|
|
crossAxisAlignment: CrossAxisAlignment.end,
|
|
children: [
|
|
Expanded(
|
|
flex: 6,
|
|
child: Align(
|
|
alignment: Alignment.bottomLeft,
|
|
child: Text(
|
|
AppLocalizations.of(context)!.davonGenetikproben),
|
|
),
|
|
),
|
|
const SizedBox(width: 20),
|
|
Expanded(
|
|
child: Align(
|
|
alignment: Alignment.centerLeft, child: TextField(
|
|
keyboardType: TextInputType.number,
|
|
controller: widget.losungGen,
|
|
onTap: () => widget.losungGen.selection = TextSelection(baseOffset: 0, extentOffset: widget.losungGen.value.text.length),
|
|
)),
|
|
),
|
|
],
|
|
),
|
|
const Divider(height: 40),
|
|
// Urine marking spots section
|
|
Row(
|
|
children: [
|
|
Expanded(
|
|
flex: 2,
|
|
child: Align(
|
|
alignment: Alignment.bottomLeft,
|
|
child: Text(AppLocalizations.of(context)!
|
|
.anzahlUrinMakierstellen)),
|
|
),
|
|
const SizedBox(width: 20),
|
|
Expanded(
|
|
child: Align(
|
|
alignment: Alignment.centerLeft, child: TextField(
|
|
keyboardType: TextInputType.number,
|
|
controller: widget.urinAnz,
|
|
onTap: () => widget.urinAnz.selection = TextSelection(baseOffset: 0, extentOffset: widget.urinAnz.value.text.length),
|
|
)),
|
|
),
|
|
const SizedBox(width: 20),
|
|
Expanded(
|
|
flex: 2,
|
|
child: Align(
|
|
alignment: Alignment.bottomLeft,
|
|
child: Text(AppLocalizations.of(context)!
|
|
.davonGenetikproben)),
|
|
),
|
|
const SizedBox(width: 20),
|
|
Expanded(
|
|
child: Align(
|
|
alignment: Alignment.centerLeft, child: TextField(
|
|
keyboardType: TextInputType.number,
|
|
controller: widget.urinGen,
|
|
onTap: () => widget.urinGen.selection = TextSelection(baseOffset: 0, extentOffset: widget.urinGen.value.text.length),
|
|
)),
|
|
),
|
|
const SizedBox(height: 20),
|
|
],
|
|
),
|
|
const Divider(height: 40),
|
|
// Estrus blood section
|
|
Row(
|
|
children: [
|
|
Expanded(
|
|
flex: 2,
|
|
child: Align(
|
|
alignment: Alignment.bottomLeft,
|
|
child: Text(
|
|
AppLocalizations.of(context)!.anzahlOestrusblut)),
|
|
),
|
|
const SizedBox(width: 20),
|
|
Expanded(
|
|
child: Align(
|
|
alignment: Alignment.centerLeft, child: TextField(
|
|
keyboardType: TextInputType.number,
|
|
controller: widget.oestrAnz,
|
|
onTap: () => widget.oestrAnz.selection = TextSelection(baseOffset: 0, extentOffset: widget.oestrAnz.value.text.length),
|
|
)),
|
|
),
|
|
const SizedBox(width: 20),
|
|
Expanded(
|
|
flex: 2,
|
|
child: Align(
|
|
alignment: Alignment.bottomLeft,
|
|
child: Text(AppLocalizations.of(context)!
|
|
.davonGenetikproben)),
|
|
),
|
|
const SizedBox(width: 20),
|
|
Expanded(
|
|
child: Align(
|
|
alignment: Alignment.centerLeft, child: TextField(
|
|
keyboardType: TextInputType.number,
|
|
controller: widget.oestrGen,
|
|
onTap: () => widget.oestrGen.selection = TextSelection(baseOffset: 0, extentOffset: widget.oestrGen.value.text.length),
|
|
)),
|
|
),
|
|
const SizedBox(height: 20),
|
|
],
|
|
),
|
|
const Divider(height: 40),
|
|
// Hair samples section
|
|
Row(
|
|
children: [
|
|
Expanded(
|
|
flex: 2,
|
|
child: Align(
|
|
alignment: Alignment.bottomLeft,
|
|
child: Text(
|
|
AppLocalizations.of(context)!.anzahlHaarproben)),
|
|
),
|
|
const SizedBox(width: 20),
|
|
Expanded(
|
|
child: Align(
|
|
alignment: Alignment.centerLeft, child: TextField(
|
|
keyboardType: TextInputType.number,
|
|
controller: widget.haarAnz,
|
|
onTap: () => widget.haarAnz.selection = TextSelection(baseOffset: 0, extentOffset: widget.haarAnz.value.text.length),
|
|
)),
|
|
),
|
|
const SizedBox(width: 20),
|
|
Expanded(
|
|
flex: 2,
|
|
child: Align(
|
|
alignment: Alignment.bottomLeft,
|
|
child: Text(AppLocalizations.of(context)!
|
|
.davonGenetikproben)),
|
|
),
|
|
const SizedBox(width: 20),
|
|
Expanded(
|
|
child: Align(
|
|
alignment: Alignment.centerLeft, child: TextField(
|
|
keyboardType: TextInputType.number,
|
|
controller: widget.haarGen,
|
|
onTap: () => widget.haarGen.selection = TextSelection(baseOffset: 0, extentOffset: widget.haarGen.value.text.length),
|
|
)),
|
|
),
|
|
const SizedBox(height: 20),
|
|
],
|
|
),
|
|
],
|
|
)
|
|
],
|
|
)
|
|
],
|
|
);
|
|
}
|
|
}
|