import 'package:fcs/helpers/theme.dart'; import 'package:fcs/pages/widgets/local_text.dart'; import 'package:flutter/material.dart'; import 'input_text.dart'; const MAX_INC = 50.0; const MAX_FEET = 25.0; class LengthPicker extends StatefulWidget { final TextEditingController? controller; final String? lableKey; final bool isReadOnly; final bool displayFeet; const LengthPicker( {Key? key, this.controller, this.lableKey, this.isReadOnly = false, this.displayFeet = false}) : super(key: key); @override _LengthPickerState createState() => _LengthPickerState(); } class _LengthPickerState extends State { TextEditingController _controller = TextEditingController(); @override void initState() { super.initState(); if (widget.controller != null) { _setText(); widget.controller!.addListener(() { _setText(); }); } } _setText() { double v = double.parse(widget.controller!.text); int _v = v.toInt(); int f = (v / 12).floor(); int ins = (v % 12).round(); _controller.text = widget.displayFeet ? "$f' $ins\"" : "$_v\""; } @override Widget build(BuildContext context) { return InkWell( onTap: widget.isReadOnly ? null : () => _showDialog(context), child: Padding( padding: EdgeInsets.only(left: 8, right: 8), child: InputText( enabled: false, labelTextKey: widget.lableKey, controller: _controller, textInputType: TextInputType.number, textAlign: widget.displayFeet ? TextAlign.end : TextAlign.center, )), ); } void _showDialog(BuildContext context) { showDialog( context: context, builder: (BuildContext context) { return LengthPickerDialog( controller: widget.controller!, labelKey: widget.lableKey!, displayFeet: widget.displayFeet, ); }, ); } } class LengthPickerDialog extends StatefulWidget { final TextEditingController? controller; final String? labelKey; final bool? displayFeet; const LengthPickerDialog( {Key? key, this.controller, this.labelKey, this.displayFeet}) : super(key: key); @override _LengthPickerDialogState createState() => _LengthPickerDialogState(); } class _LengthPickerDialogState extends State { late int _valueFeet; late int _valueInc; TextEditingController inchInputController = TextEditingController(); TextEditingController feetInputController = TextEditingController(); final _focusNode = FocusNode(); @override void initState() { super.initState(); _valueFeet = 0; _valueInc = 0; if (widget.controller != null) { double v = double.parse(widget.controller!.text); _valueFeet = (v / 12).floor(); _valueInc = widget.displayFeet! ? (v % 12).toInt() : v.toInt(); inchInputController.text = _valueInc.toString(); feetInputController.text = _valueFeet.toString(); } _focusNode.addListener(() { if (_focusNode.hasFocus) { inchInputController.selection = TextSelection( baseOffset: 0, extentOffset: inchInputController.text.length); } }); } @override Widget build(BuildContext context) { final inchBox = Column( children: [ Text("Inch"), Row( children: [ Expanded( child: TextFormField( focusNode: _focusNode, autofocus: true, onChanged: _updateInputInch, textAlign: TextAlign.center, controller: inchInputController, cursorColor: primaryColor, keyboardType: TextInputType.numberWithOptions( signed: false, decimal: true), decoration: new InputDecoration( contentPadding: EdgeInsets.all(10), isDense: true, focusedBorder: OutlineInputBorder( borderSide: BorderSide(color: primaryColor, width: 1.0), ), enabledBorder: OutlineInputBorder( borderSide: BorderSide(color: Colors.grey.shade400, width: 1.0), ), ), ), ), Column( children: [ InkWell( onTap: () => _addInc(1), child: Padding( padding: const EdgeInsets.all(3.0), child: Icon( Icons.add, color: primaryColor, ), ), ), InkWell( onTap: () => _addInc(-1), child: Padding( padding: const EdgeInsets.all(3.0), child: Icon( Icons.remove, color: primaryColor, ), ), ) ], ) ], ) ], ); final feetBox = Column( children: [ Text("Feet"), Row( children: [ Expanded( child: TextFormField( onChanged: _updateInputFeet, textAlign: TextAlign.center, controller: feetInputController, keyboardType: TextInputType.numberWithOptions( signed: false, decimal: true), cursorColor: primaryColor, decoration: new InputDecoration( contentPadding: EdgeInsets.all(10), isDense: true, focusedBorder: OutlineInputBorder( borderSide: BorderSide(color: primaryColor, width: 1.0), ), enabledBorder: OutlineInputBorder( borderSide: BorderSide(color: Colors.grey.shade400, width: 1.0), ), ), ), ), Column( children: [ InkWell( onTap: () => _addFeet(1), child: Padding( padding: const EdgeInsets.all(3.0), child: Icon( Icons.add, color: primaryColor, ), ), ), InkWell( onTap: () => _addFeet(-1), child: Padding( padding: const EdgeInsets.all(3.0), child: Icon( Icons.remove, color: primaryColor, ), ), ) ], ) ], ) ], ); return SimpleDialog( title: Center( child: LocalText( context, widget.labelKey!, color: primaryColor, fontSize: 16, )), children: [ Row( mainAxisAlignment: MainAxisAlignment.spaceAround, children: widget.displayFeet! ? [ Container(width: 100, child: feetBox), Container(width: 100, child: inchBox), ] : [ Container(width: 100, child: inchBox), ], ), SizedBox( height: 10, ), widget.displayFeet! ? Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Padding( padding: const EdgeInsets.only(top: 8.0, left: 8), child: LocalText( context, "feet", color: primaryColor, fontSize: 12, ), ), Slider( inactiveColor: Colors.grey.shade200, activeColor: primaryColor, value: _valueFeet.toDouble() > MAX_FEET ? 0 : _valueFeet.toDouble(), min: 0, max: MAX_FEET, divisions: 100, label: _valueFeet.round().toString(), onChanged: (double v) { _updateFeet(v); }, ), ], ) : Container(), Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Padding( padding: const EdgeInsets.only(top: 8.0, left: 15), child: LocalText( context, "inch", color: primaryColor, fontSize: 12, ), ), Slider( inactiveColor: Colors.grey.shade200, activeColor: primaryColor, value: _valueInc.toDouble() > (widget.displayFeet! ? 11 : MAX_INC) ? 0 : _valueInc.toDouble(), min: 0, max: widget.displayFeet! ? 11 : MAX_INC, divisions: 100, label: _valueInc.round().toString(), onChanged: (double v) { _updateInc(v); }, ), ], ) ], ); } _updateFeet(double v) { setState(() { _valueFeet = v.toInt(); }); int _v = _valueInc.round() + _valueFeet.round() * 12; if (widget.controller != null) { widget.controller!.text = _v.toString(); } feetInputController.text = widget.displayFeet! ? _valueFeet.round().toString() : _v.toString(); } _updateInc(double v) { setState(() { _valueInc = v.toInt(); }); int _v = _valueInc.round() + _valueFeet.round() * 12; if (widget.controller != null) { widget.controller!.text = widget.displayFeet! ? _v.toString() : _valueInc.toString(); } inchInputController.text = _valueInc.toString(); } _updateInputInch(String value) { int val = int.tryParse(value) ?? _valueInc; setState(() { _valueInc = val.toInt(); }); int _v = _valueInc.round() + _valueFeet.round() * 12; if (widget.controller != null) { widget.controller!.text = widget.displayFeet! ? _v.toString() : _valueInc.toString(); } } _updateInputFeet(String value) { int val = int.tryParse(value) ?? _valueInc; setState(() { _valueFeet = val.toInt(); }); int _v = _valueInc.round() + _valueFeet.round() * 12; if (widget.controller != null) { widget.controller!.text = _v.toString(); } } _addInc(int v) { int value = int.tryParse(inchInputController.text) ?? 0; _updateInc((value + v).toDouble()); } _addFeet(int v) { int value = int.tryParse(feetInputController.text) ?? 0; _updateFeet((value + v).toDouble()); } }