Files
recipe_journal/lib/widgets/duration_picker.dart

270 lines
8.1 KiB
Dart

import 'package:flutter/material.dart';
class DurationPicker extends StatefulWidget {
const DurationPicker({
super.key,
required this.onChangedCallback,
required this.width,
required this.height,
this.initialDuration = const Duration(),
});
final void Function(Duration duration) onChangedCallback;
final double width;
final double height;
final Duration initialDuration;
@override
State<DurationPicker> createState() => _DurationPickerState();
}
class _DurationPickerState extends State<DurationPicker> {
String _timeString = '';
@override
void initState() {
super.initState();
if (widget.initialDuration.inMinutes != 0) {
_timeString =
'${widget.initialDuration.inHours}${widget.initialDuration.inMinutes % 60}';
}
}
@override
Widget build(BuildContext context) {
return Column(
mainAxisSize: MainAxisSize.min,
children: [
SizedBox(
width: widget.width,
height: widget.height / 4,
child: Row(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.end,
children: [
Text(
_timeString.padLeft(4, '0').substring(0, 2),
style: Theme.of(context).textTheme.displayMedium,
),
Padding(padding: EdgeInsets.only(left: 5)),
Text(
'h',
style:
Theme.of(context).textTheme.bodyLarge!.copyWith(height: 2),
),
Padding(padding: EdgeInsets.only(left: 10)),
Text(
_timeString.padLeft(4, '0').substring(2, 4),
style: Theme.of(context).textTheme.displayMedium,
),
Padding(padding: EdgeInsets.only(left: 5)),
Text(
'm',
style:
Theme.of(context).textTheme.bodyLarge!.copyWith(height: 2),
),
],
),
),
Padding(padding: EdgeInsets.only(top: 10)),
Row(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.center,
children: [
SizedBox(
width: widget.width / 3,
height: widget.height / 4,
child: Padding(
padding: const EdgeInsets.fromLTRB(8, 0, 8, 8),
child: ElevatedButton(
style: _buttonTheme,
onPressed: () => _addTime(7),
child: Text('7'),
),
),
),
SizedBox(
width: widget.width / 3,
height: widget.height / 4,
child: Padding(
padding: const EdgeInsets.fromLTRB(8, 0, 8, 8),
child: ElevatedButton(
style: _buttonTheme,
onPressed: () => _addTime(8),
child: Text('8'),
),
),
),
SizedBox(
width: widget.width / 3,
height: widget.height / 4,
child: Padding(
padding: const EdgeInsets.fromLTRB(8, 0, 8, 8),
child: ElevatedButton(
style: _buttonTheme,
onPressed: () => _addTime(9),
child: Text('9'),
),
),
),
],
),
Row(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.center,
children: [
SizedBox(
width: widget.width / 3,
height: widget.height / 4,
child: Padding(
padding: const EdgeInsets.fromLTRB(8, 0, 8, 8),
child: ElevatedButton(
style: _buttonTheme,
onPressed: () => _addTime(4),
child: Text('4'),
),
),
),
SizedBox(
width: widget.width / 3,
height: widget.height / 4,
child: Padding(
padding: const EdgeInsets.fromLTRB(8, 0, 8, 8),
child: ElevatedButton(
style: _buttonTheme,
onPressed: () => _addTime(5),
child: Text('5'),
),
),
),
SizedBox(
width: widget.width / 3,
height: widget.height / 4,
child: Padding(
padding: const EdgeInsets.fromLTRB(8, 0, 8, 8),
child: ElevatedButton(
style: _buttonTheme,
onPressed: () => _addTime(6),
child: Text('6'),
),
),
),
],
),
Row(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.center,
children: [
SizedBox(
width: widget.width / 3,
height: widget.height / 4,
child: Padding(
padding: const EdgeInsets.fromLTRB(8, 0, 8, 8),
child: ElevatedButton(
style: _buttonTheme,
onPressed: () => _addTime(1),
child: Text('1'),
),
),
),
SizedBox(
width: widget.width / 3,
height: widget.height / 4,
child: Padding(
padding: const EdgeInsets.fromLTRB(8, 0, 8, 8),
child: ElevatedButton(
style: _buttonTheme,
onPressed: () => _addTime(2),
child: Text('2'),
),
),
),
SizedBox(
width: widget.width / 3,
height: widget.height / 4,
child: Padding(
padding: const EdgeInsets.fromLTRB(8, 0, 8, 8),
child: ElevatedButton(
style: _buttonTheme,
onPressed: () => _addTime(3),
child: Text('3'),
),
),
),
],
),
Row(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.center,
children: [
SizedBox(
width: widget.width / 3,
height: widget.height / 4,
child: Padding(padding: EdgeInsets.all(0)),
),
SizedBox(
width: widget.width / 3,
height: widget.height / 4,
child: Padding(
padding: const EdgeInsets.fromLTRB(8, 0, 8, 8),
child: ElevatedButton(
style: _buttonTheme,
onPressed: () => _addTime(0),
child: Text('0'),
),
),
),
SizedBox(
width: widget.width / 3,
height: widget.height / 4,
child: Padding(
padding: const EdgeInsets.fromLTRB(8, 0, 8, 8),
child: ElevatedButton(
style: _buttonTheme,
onPressed: _removeTime,
child: Icon(
Icons.backspace,
size: 24,
),
),
),
),
],
),
],
);
}
void _addTime(int time) {
if (_timeString.length >= 4) return;
if (_timeString.isEmpty && time == 0) return;
setState(() {
_timeString += time.toString();
});
widget.onChangedCallback(_duration);
}
void _removeTime() {
if (_timeString.isEmpty) return;
setState(() {
_timeString = _timeString.substring(0, _timeString.length - 1);
});
widget.onChangedCallback(_duration);
}
Duration get _duration {
return Duration(
hours: int.parse(_timeString.padLeft(4, '0').substring(0, 2)),
minutes: int.parse(_timeString.padLeft(4, '0').substring(2, 4)),
);
}
ButtonStyle get _buttonTheme => ElevatedButton.styleFrom(
textStyle: Theme.of(context).textTheme.displaySmall,
);
}