mirror of
https://github.com/SyncrowIOT/web.git
synced 2025-07-10 07:07:19 +00:00
146 lines
4.5 KiB
Dart
146 lines
4.5 KiB
Dart
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;
|
|
final double dividendOfRange;
|
|
|
|
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,
|
|
required this.dividendOfRange,
|
|
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,
|
|
dividendOfRange: dividendOfRange,
|
|
),
|
|
],
|
|
);
|
|
}
|
|
|
|
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,
|
|
suffixStyle: context.textTheme.headlineMedium!.copyWith(
|
|
color: ColorsManager.primaryColorWithOpacity,
|
|
),
|
|
),
|
|
),
|
|
const SizedBox(height: 8),
|
|
Row(
|
|
mainAxisSize: MainAxisSize.min,
|
|
children: [
|
|
Text(
|
|
'Min: ${sliderRange.$1}',
|
|
style: context.textTheme.labelSmall!.copyWith(
|
|
color: ColorsManager.lightGrayColor,
|
|
),
|
|
),
|
|
const Spacer(),
|
|
Text(
|
|
'Max: ${sliderRange.$2}',
|
|
style: context.textTheme.labelSmall!.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;
|
|
}
|
|
}
|