From c8cc5861ade1320986c09c8164884bda2e8d74d7 Mon Sep 17 00:00:00 2001 From: marco Date: Mon, 10 Feb 2025 23:46:29 +0100 Subject: [PATCH] added duration picker --- lib/widgets/duration_picker.dart | 158 +++++++++++++++++++++++++++++++ 1 file changed, 158 insertions(+) create mode 100644 lib/widgets/duration_picker.dart diff --git a/lib/widgets/duration_picker.dart b/lib/widgets/duration_picker.dart new file mode 100644 index 0000000..a82b6d5 --- /dev/null +++ b/lib/widgets/duration_picker.dart @@ -0,0 +1,158 @@ +import 'package:flutter/material.dart'; + +class DurationPicker extends StatefulWidget { + const DurationPicker({super.key, required this.onChangedCallback}); + + final void Function(Duration duration) onChangedCallback; + + @override + State createState() => _DurationPickerState(); +} + +class _DurationPickerState extends State { + String _timeString = ''; + + @override + Widget build(BuildContext context) { + return SizedBox( + width: 400, + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + 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)), + Expanded( + child: GridView.count( + crossAxisSpacing: 10, + mainAxisSpacing: 10, + crossAxisCount: 3, + physics: NeverScrollableScrollPhysics(), + children: [ + ElevatedButton( + style: _buttonTheme, + onPressed: () => _addTime(7), + child: _getTextWidget('7'), + ), + ElevatedButton( + style: _buttonTheme, + onPressed: () => _addTime(8), + child: _getTextWidget('8'), + ), + ElevatedButton( + style: _buttonTheme, + onPressed: () => _addTime(9), + child: _getTextWidget('9'), + ), + ElevatedButton( + style: _buttonTheme, + onPressed: () => _addTime(4), + child: _getTextWidget('4'), + ), + ElevatedButton( + style: _buttonTheme, + onPressed: () => _addTime(5), + child: _getTextWidget('5'), + ), + ElevatedButton( + style: _buttonTheme, + onPressed: () => _addTime(6), + child: _getTextWidget('6'), + ), + ElevatedButton( + style: _buttonTheme, + onPressed: () => _addTime(1), + child: _getTextWidget('1'), + ), + ElevatedButton( + style: _buttonTheme, + onPressed: () => _addTime(2), + child: _getTextWidget('2'), + ), + ElevatedButton( + style: _buttonTheme, + onPressed: () => _addTime(3), + child: _getTextWidget('3'), + ), + Padding(padding: EdgeInsets.all(0)), + ElevatedButton( + style: _buttonTheme, + onPressed: () => _addTime(0), + child: _getTextWidget('0'), + ), + ElevatedButton( + style: _buttonTheme, + onPressed: _removeTime, + child: Icon( + Icons.backspace, + size: 24, + ), + ), + ], + ), + ), + ], + ), + ); + } + + Text _getTextWidget(String text) { + return Text(text); + } + + void _addTime(int time) { + if (_timeString.length >= 4) 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, + ); +}