diameter/lib/components/forms/duration_form_field.dart

124 lines
3.4 KiB
Dart
Raw Normal View History

2022-03-21 00:07:29 +00:00
import 'package:flutter/material.dart';
class DurationFormField extends StatefulWidget {
final String label;
final int minutes;
final void Function(int?) onChanged;
final bool showSteppers;
final bool readOnly;
final int min;
final int? max;
final int step;
const DurationFormField(
{Key? key,
required this.label,
this.minutes = 0,
required this.onChanged,
this.showSteppers = false,
this.readOnly = false,
this.min = 0,
this.max,
this.step = 5})
: super(key: key);
@override
_DurationFormFieldState createState() => _DurationFormFieldState();
}
class _DurationFormFieldState extends State<DurationFormField> {
late Duration duration;
final TextEditingController controller = TextEditingController(text: '');
@override
void initState() {
super.initState();
updateDuration();
}
void updateDuration() {
duration = Duration(minutes: widget.minutes);
int days = duration.inDays;
int hours = duration.inHours - days * 24;
int minutes = duration.inMinutes - hours * 60;
int seconds = duration.inSeconds - minutes * 60;
String daysString = days > 9 ? '$days d' : days > 0 ? '0$days d' : '00 d';
String hoursString = hours > 9 ? ' $hours h' : hours > 0 ? ' 0$hours h' : ' 00 h';
String minutesString = minutes > 9 ? ' $minutes m' : minutes > 0 ? ' 0$minutes m' : ' 00 m';
String secondsString = seconds > 9 ? ' $seconds s' : seconds > 0 ? ' 0$seconds s' : ' 00 s';
controller.text = '$daysString $hoursString $minutesString $secondsString'.trim();
}
void handleChange(String value) async {
await Future.delayed(const Duration(seconds: 1));
int days = int.tryParse(value.split(' d')[0]) ?? 0;
int hours = int.tryParse(value.split('d')[1].split(' h')[0]) ?? 0;
int minutes = int.tryParse(value.split('h')[1].split(' m')[0]) ?? 0;
int seconds = int.tryParse(value.split('m')[1].split(' s')[0]) ?? 0;
int updatedMinutes =
Duration(days: days, hours: hours, minutes: minutes, seconds: seconds)
.inMinutes;
widget.onChanged(updatedMinutes);
setState(() {
updateDuration();
});
}
void onIncrease() {
if (widget.max == null || widget.minutes + widget.step <= widget.max!) {
int value = widget.minutes + widget.step;
widget.onChanged(value);
setState(() {
updateDuration();
});
}
}
void onDecrease() {
if (widget.minutes - widget.step >= widget.min) {
int value = widget.minutes - widget.step;
widget.onChanged(value);
setState(() {
updateDuration();
});
}
}
@override
Widget build(BuildContext context) {
return Row(
mainAxisSize: MainAxisSize.min,
children: [
widget.showSteppers
? IconButton(
onPressed: onDecrease,
icon: const Icon(Icons.remove),
)
: Container(),
Expanded(
child: TextFormField(
controller: controller,
decoration: InputDecoration(
labelText: widget.label,
),
keyboardType: TextInputType.numberWithOptions(
decimal: true, signed: widget.min.isNegative),
onChanged: handleChange,
),
),
widget.showSteppers
? IconButton(
onPressed: onIncrease,
icon: const Icon(Icons.add),
)
: Container(),
],
);
}
}