5 class CircularSliderWidget extends Widget{ |
5 class CircularSliderWidget extends Widget{ |
6 frequency = 5; |
6 frequency = 5; |
7 range = undefined; |
7 range = undefined; |
8 circle = undefined; |
8 circle = undefined; |
9 handle_pos = undefined; |
9 handle_pos = undefined; |
10 svg_dist = undefined; |
10 curr_value = 0; |
11 drag = false; |
11 drag = false; |
12 enTimer = false; |
12 enTimer = false; |
13 last_drag = false; |
13 last_drag = false; |
14 |
14 |
15 dispatch(value) { |
15 dispatch(value) { |
|
16 let [min,max,start,totallength] = this.range; |
|
17 //save current value inside widget |
|
18 this.curr_value = value; |
|
19 |
|
20 //check if in range |
|
21 if (this.curr_value > max){ |
|
22 this.curr_value = max; |
|
23 this.apply_hmi_value(0, this.curr_value); |
|
24 } |
|
25 else if (this.curr_value < min){ |
|
26 this.curr_value = min; |
|
27 this.apply_hmi_value(0, this.curr_value); |
|
28 } |
|
29 |
16 if(this.value_elt) |
30 if(this.value_elt) |
17 this.value_elt.textContent = String(value); |
31 this.value_elt.textContent = String(value); |
18 |
32 |
19 this.update_DOM(value, this.handle_elt); |
33 //don't update if draging and setpoint ghost doesn't exist |
|
34 if(!this.drag || (this.setpoint_elt != undefined)){ |
|
35 this.update_DOM(value, this.handle_elt); |
|
36 } |
20 } |
37 } |
21 |
38 |
22 update_DOM(value, elt){ |
39 update_DOM(value, elt){ |
23 let [min,max,totalDistance] = this.range; |
40 let [min,max,totalDistance] = this.range; |
24 let length = Math.max(0,Math.min((totalDistance),(Number(value)-min)/(max-min)*(totalDistance))); |
41 let length = Math.max(0,Math.min((totalDistance),(Number(value)-min)/(max-min)*(totalDistance))); |
25 let tip = this.range_elt.getPointAtLength(length); |
42 let tip = this.range_elt.getPointAtLength(length); |
26 elt.setAttribute('transform',"translate("+(tip.x-this.handle_pos.x)+","+(tip.y-this.handle_pos.y)+")"); |
43 elt.setAttribute('transform',"translate("+(tip.x-this.handle_pos.x)+","+(tip.y-this.handle_pos.y)+")"); |
27 |
44 |
|
45 // show or hide ghost if exists |
28 if(this.setpoint_elt != undefined){ |
46 if(this.setpoint_elt != undefined){ |
29 if(this.last_drag!= this.drag){ |
47 if(this.last_drag!= this.drag){ |
30 if(this.drag){ |
48 if(this.drag){ |
31 this.setpoint_elt.setAttribute("style", this.setpoint_style); |
49 this.setpoint_elt.setAttribute("style", this.setpoint_style); |
32 }else{ |
50 }else{ |
36 } |
54 } |
37 } |
55 } |
38 } |
56 } |
39 |
57 |
40 on_release(evt) { |
58 on_release(evt) { |
|
59 //unbind events |
41 window.removeEventListener("touchmove", this.on_bound_drag, true); |
60 window.removeEventListener("touchmove", this.on_bound_drag, true); |
42 window.removeEventListener("mousemove", this.on_bound_drag, true); |
61 window.removeEventListener("mousemove", this.on_bound_drag, true); |
43 |
62 |
44 window.removeEventListener("mouseup", this.bound_on_release, true) |
63 window.removeEventListener("mouseup", this.bound_on_release, true) |
45 window.removeEventListener("touchend", this.bound_on_release, true); |
64 window.removeEventListener("touchend", this.bound_on_release, true); |
46 window.removeEventListener("touchcancel", this.bound_on_release, true); |
65 window.removeEventListener("touchcancel", this.bound_on_release, true); |
|
66 |
|
67 //reset drag flag |
47 if(this.drag){ |
68 if(this.drag){ |
48 this.drag = false; |
69 this.drag = false; |
49 } |
70 } |
|
71 |
|
72 // get final position |
50 this.update_position(evt); |
73 this.update_position(evt); |
51 } |
74 } |
52 |
75 |
53 on_drag(evt){ |
76 on_drag(evt){ |
|
77 //ignore drag event for X amount of time and if not selected |
54 if(this.enTimer && this.drag){ |
78 if(this.enTimer && this.drag){ |
55 this.update_position(evt); |
79 this.update_position(evt); |
|
80 |
56 //reset timer |
81 //reset timer |
57 this.enTimer = false; |
82 this.enTimer = false; |
58 setTimeout("{hmi_widgets['"+this.element_id+"'].enTimer = true;}", 100); |
83 setTimeout("{hmi_widgets['"+this.element_id+"'].enTimer = true;}", 100); |
59 } |
84 } |
60 } |
85 } |
101 fi = fi + 2*Math.PI; |
126 fi = fi + 2*Math.PI; |
102 } |
127 } |
103 |
128 |
104 //get handle distance from mouse position |
129 //get handle distance from mouse position |
105 if(fi<fiEnd){ |
130 if(fi<fiEnd){ |
106 this.svg_dist=(fi)/(fiEnd)*(this.range[1]-this.range[0]); |
131 this.curr_value=(fi)/(fiEnd)*(this.range[1]-this.range[0]); |
107 } |
132 } |
108 else if(fiEnd<fi && fi<fiEnd+minMax){ |
133 else if(fiEnd<fi && fi<fiEnd+minMax){ |
109 this.svg_dist = this.range[1]; |
134 this.curr_value = this.range[1]; |
110 } |
135 } |
111 else{ |
136 else{ |
112 this.svg_dist = this.range[0]; |
137 this.curr_value = this.range[0]; |
113 } |
138 } |
114 |
139 |
115 |
140 //apply value to hmi |
116 this.apply_hmi_value(0, Math.ceil(this.svg_dist)); |
141 this.apply_hmi_value(0, Math.ceil(this.curr_value)); |
117 |
142 |
118 // update ghost cursor |
143 //redraw handle |
119 if(this.setpoint_elt != undefined){ |
144 this.request_animate(); |
120 this.request_animate(); |
145 |
121 } |
|
122 } |
146 } |
123 |
147 |
124 } |
148 } |
125 |
149 |
126 animate(){ |
150 animate(){ |
127 this.update_DOM(this.svg_dist, this.setpoint_elt); |
151 // redraw handle on screen refresh |
|
152 // check if setpoint(ghost) handle exsist otherwise update main handle |
|
153 if(this.setpoint_elt != undefined){ |
|
154 this.update_DOM(this.curr_value, this.setpoint_elt); |
|
155 } |
|
156 else{ |
|
157 this.update_DOM(this.curr_value, this.handle_elt); |
|
158 } |
128 } |
159 } |
129 |
160 |
130 on_select(evt){ |
161 on_select(evt){ |
|
162 //enable drag flag and timer |
131 this.drag = true; |
163 this.drag = true; |
132 this.enTimer = true; |
164 this.enTimer = true; |
|
165 |
|
166 //bind events |
133 window.addEventListener("touchmove", this.on_bound_drag, true); |
167 window.addEventListener("touchmove", this.on_bound_drag, true); |
134 window.addEventListener("mousemove", this.on_bound_drag, true); |
168 window.addEventListener("mousemove", this.on_bound_drag, true); |
135 |
169 |
136 window.addEventListener("mouseup", this.bound_on_release, true) |
170 window.addEventListener("mouseup", this.bound_on_release, true); |
137 window.addEventListener("touchend", this.bound_on_release, true); |
171 window.addEventListener("touchend", this.bound_on_release, true); |
138 window.addEventListener("touchcancel", this.bound_on_release, true); |
172 window.addEventListener("touchcancel", this.bound_on_release, true); |
|
173 |
|
174 //update postion on mouse press |
139 this.update_position(evt); |
175 this.update_position(evt); |
|
176 |
|
177 //prevent next events |
|
178 evt.stopPropagation(); |
140 } |
179 } |
141 |
180 |
142 init() { |
181 init() { |
143 //get min max |
182 //get min max |
144 let min = this.min_elt ? |
183 let min = this.min_elt ? |
173 //bind functions |
212 //bind functions |
174 this.bound_on_select = this.on_select.bind(this); |
213 this.bound_on_select = this.on_select.bind(this); |
175 this.bound_on_release = this.on_release.bind(this); |
214 this.bound_on_release = this.on_release.bind(this); |
176 this.on_bound_drag = this.on_drag.bind(this); |
215 this.on_bound_drag = this.on_drag.bind(this); |
177 |
216 |
178 //init events |
217 this.handle_elt.addEventListener("mousedown", this.bound_on_select); |
179 this.element.addEventListener("mousedown", this.bound_on_select); |
218 this.element.addEventListener("mousedown", this.bound_on_select); |
180 this.element.addEventListener("touchstart", this.bound_on_select); |
219 this.element.addEventListener("touchstart", this.bound_on_select); |
181 |
220 //touch recognised as page drag without next command |
|
221 document.body.addEventListener("touchstart", function(e){}, false); |
|
222 |
|
223 //save ghost style |
|
224 //save ghost style |
182 if(this.setpoint_elt != undefined){ |
225 if(this.setpoint_elt != undefined){ |
183 this.setpoint_style = this.setpoint_elt.getAttribute("style"); |
226 this.setpoint_style = this.setpoint_elt.getAttribute("style"); |
184 this.setpoint_elt.setAttribute("style", "display:none"); |
227 this.setpoint_elt.setAttribute("style", "display:none"); |
185 } |
228 } |
186 |
229 |
187 |
|
188 window.addEventListener("touchmove", hmi_widgets[this.element_id].update_position.bind(this)); |
|
189 window.addEventListener("mousemove", hmi_widgets[this.element_id].update_position.bind(this)); |
|
190 |
|
191 window.addEventListener("mouseup", hmi_widgets[this.element_id].on_release.bind(this)) |
|
192 window.addEventListener("touchend", hmi_widgets[this.element_id].on_release.bind(this)); |
|
193 window.addEventListener("touchcancel", hmi_widgets[this.element_id].on_release.bind(this)); |
|
194 |
|
195 } |
230 } |
196 } |
231 } |
197 || |
232 || |
198 |
233 |
199 template "widget[@type='CircularSlider']", mode="widget_defs" { |
234 template "widget[@type='CircularSlider']", mode="widget_defs" { |
200 param "hmi_element"; |
235 param "hmi_element"; |
201 labels("handle range"); |
236 labels("handle range"); |
202 optional_labels("value min max"); |
237 optional_labels("value min max setpoint"); |
203 |, |
238 |, |
204 } |
239 } |