Skip to content

Commit 2bb988a

Browse files
committed
Slider control
1 parent f25872a commit 2bb988a

File tree

6 files changed

+8507
-2
lines changed

6 files changed

+8507
-2
lines changed

client/lib/controls/create_control.dart

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ import 'progress_ring.dart';
2222
import 'radio.dart';
2323
import 'radio_group.dart';
2424
import 'row.dart';
25+
import 'slider.dart';
2526
import 'snack_bar.dart';
2627
import 'stack.dart';
2728
import 'switch.dart';
@@ -131,6 +132,11 @@ Widget createControl(Control? parent, String id, bool parentDisabled) {
131132
parent: parent,
132133
control: controlView.control,
133134
parentDisabled: parentDisabled);
135+
case ControlType.slider:
136+
return SliderControl(
137+
parent: parent,
138+
control: controlView.control,
139+
parentDisabled: parentDisabled);
134140
case ControlType.radioGroup:
135141
return RadioGroupControl(
136142
parent: parent,

client/lib/controls/slider.dart

Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
import 'dart:async';
2+
3+
import 'package:flutter/material.dart';
4+
import 'package:flutter_redux/flutter_redux.dart';
5+
6+
import '../actions.dart';
7+
import '../models/app_state.dart';
8+
import '../models/control.dart';
9+
import '../protocol/update_control_props_payload.dart';
10+
import '../web_socket_client.dart';
11+
import 'create_control.dart';
12+
13+
class SliderControl extends StatefulWidget {
14+
final Control? parent;
15+
final Control control;
16+
final bool parentDisabled;
17+
18+
const SliderControl(
19+
{Key? key,
20+
this.parent,
21+
required this.control,
22+
required this.parentDisabled})
23+
: super(key: key);
24+
25+
@override
26+
State<SliderControl> createState() => _SliderControlState();
27+
}
28+
29+
class _SliderControlState extends State<SliderControl> {
30+
double _value = 0;
31+
Timer? _debounce;
32+
33+
@override
34+
void initState() {
35+
super.initState();
36+
}
37+
38+
@override
39+
void dispose() {
40+
_debounce?.cancel();
41+
super.dispose();
42+
}
43+
44+
void onChange(double value, Function dispatch) {
45+
var svalue = value.toString();
46+
debugPrint(svalue);
47+
setState(() {
48+
_value = value;
49+
});
50+
51+
if (_debounce?.isActive ?? false) _debounce!.cancel();
52+
List<Map<String, String>> props = [
53+
{"i": widget.control.id, "value": svalue}
54+
];
55+
dispatch(UpdateControlPropsAction(UpdateControlPropsPayload(props: props)));
56+
57+
_debounce = Timer(const Duration(milliseconds: 100), () {
58+
ws.updateControlProps(props: props);
59+
ws.pageEventFromWeb(
60+
eventTarget: widget.control.id,
61+
eventName: "change",
62+
eventData: svalue);
63+
});
64+
}
65+
66+
@override
67+
Widget build(BuildContext context) {
68+
debugPrint("SliderControl build: ${widget.control.id}");
69+
70+
String? label = widget.control.attrString("label");
71+
bool disabled = widget.control.isDisabled || widget.parentDisabled;
72+
73+
double min = widget.control.attrDouble("min", 0)!;
74+
double max = widget.control.attrDouble("max", 1)!;
75+
int? divisions = widget.control.attrInt("divisions");
76+
77+
return StoreConnector<AppState, Function>(
78+
distinct: true,
79+
converter: (store) => store.dispatch,
80+
builder: (context, dispatch) {
81+
debugPrint(
82+
"SliderControl StoreConnector build: ${widget.control.id}");
83+
84+
double value = widget.control.attrDouble("value", 0)!;
85+
if (_value != value) {
86+
_value = value;
87+
}
88+
89+
var slider = Slider(
90+
value: _value,
91+
min: min,
92+
max: max,
93+
divisions: divisions,
94+
label: label?.replaceAll("{value}", _value.toString()),
95+
onChanged: !disabled
96+
? (double value) {
97+
onChange(value, dispatch);
98+
}
99+
: null);
100+
101+
return constrainedControl(slider, widget.parent, widget.control);
102+
});
103+
}
104+
}

0 commit comments

Comments
 (0)