import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:syncrow_web/pages/routines/widgets/condition_toggle.dart'; import 'package:syncrow_web/pages/routines/widgets/function_slider.dart'; import 'package:syncrow_web/pages/routines/widgets/value_display.dart'; import 'package:syncrow_web/utils/color_manager.dart'; import 'package:syncrow_web/utils/extension/build_context_x.dart'; class SliderValueSelector extends StatelessWidget { final String? currentCondition; final String dialogType; final (double, double) sliderRange; final String displayedValue; final Object? initialValue; final void Function(String condition) onConditionChanged; final void Function(double value) onSliderChanged; final String unit; const SliderValueSelector({ required this.dialogType, required this.sliderRange, required this.displayedValue, required this.initialValue, required this.onConditionChanged, required this.onSliderChanged, required this.currentCondition, required this.unit, super.key, }); @override Widget build(BuildContext context) { if (dialogType == 'IF') { return Column( spacing: 16, mainAxisAlignment: MainAxisAlignment.center, children: [ ConditionToggle( currentCondition: currentCondition, onChanged: onConditionChanged, ), ValueDisplay( value: initialValue, label: displayedValue, unit: unit, ), FunctionSlider( initialValue: initialValue, range: sliderRange, onChanged: onSliderChanged, ), ], ); } return Row( mainAxisAlignment: MainAxisAlignment.center, crossAxisAlignment: CrossAxisAlignment.center, mainAxisSize: MainAxisSize.min, children: [ const Spacer(), Expanded( flex: 2, child: Column( mainAxisSize: MainAxisSize.min, children: [ TextFormField( onChanged: (value) => onSliderChanged(double.tryParse(value) ?? 0), expands: false, onTapOutside: (_) => FocusScope.of(context).unfocus(), initialValue: displayedValue, style: context.textTheme.headlineMedium!.copyWith( color: ColorsManager.primaryColorWithOpacity, ), inputFormatters: [ RangeInputFormatter(min: sliderRange.$1, max: sliderRange.$2), ], decoration: InputDecoration( border: OutlineInputBorder( borderSide: BorderSide.none, borderRadius: BorderRadius.circular(8), ), filled: true, fillColor: ColorsManager.textFieldGreyColor.withOpacity(0.5), suffixText: unit, hintStyle: context.textTheme.headlineMedium!.copyWith( color: ColorsManager.primaryColorWithOpacity, ), ), ), const SizedBox(height: 8), Row( mainAxisSize: MainAxisSize.min, children: [ Text( 'Min: ${sliderRange.$1}', style: context.textTheme.bodySmall!.copyWith( color: ColorsManager.lightGrayColor, ), ), const Spacer(), Text( 'Max: ${sliderRange.$2}', style: context.textTheme.bodySmall!.copyWith( color: ColorsManager.lightGrayColor, ), ), ], ), ], ), ), const Spacer(), ], ); } } class RangeInputFormatter extends TextInputFormatter { const RangeInputFormatter({required this.min, required this.max}); final double min; final double max; @override TextEditingValue formatEditUpdate( TextEditingValue oldValue, TextEditingValue newValue, ) { final text = newValue.text; if (text.isEmpty) { return newValue; } final value = double.tryParse(text); if (value == null || value < min || value > max) { return oldValue; } return newValue; } }