beremiz

SVGHMI: Refactor the way JsonTable generate javascript code to access json data. Now support multiple assignments, used in the case of text to change both content and style on the same element.
// widget_slider.ysl2
template "widget[@type='Slider']", mode="widget_class"
||
class SliderWidget extends Widget{
frequency = 5;
range = undefined;
fi = undefined;
drag = false;
enTimer = false;
dispatch(value) {
if(this.value_elt)
this.value_elt.textContent = String(value);
this.update_DOM(value, this.handle_elt);
}
last_drag = false;
update_DOM(value, elt){
let [min,max,start,totallength] = this.range;
let length = Math.max(0,Math.min(totallength,(Number(value)-min)*totallength/(max-min)));
let tip = this.range_elt.getPointAtLength(length);
elt.setAttribute('transform',"translate("+(tip.x-start.x)+","+(tip.y-start.y)+")");
if(this.setpoint_elt != undefined){
if(this.last_drag!= this.drag){
if(this.drag){
this.setpoint_elt.setAttribute("style", this.setpoint_style);
}else{
this.setpoint_elt.setAttribute("style", "display:none");
}
this.last_drag = this.drag;
}
}
}
on_release(evt) {
window.removeEventListener("touchmove", this.on_bound_drag, true);
window.removeEventListener("mousemove", this.on_bound_drag, true);
window.removeEventListener("mouseup", this.bound_on_release, true)
window.removeEventListener("touchend", this.bound_on_release, true);
window.removeEventListener("touchcancel", this.bound_on_release, true);
if(this.drag){
this.drag = false;
}
this.update_position(evt);
}
on_drag(evt){
if(this.enTimer && this.drag){
this.update_position(evt);
//reset timer
this.enTimer = false;
setTimeout("{hmi_widgets['"+this.element_id+"'].enTimer = true;}", 100);
}
}
update_position(evt){
var html_dist = 0;
//calculate size of widget in html
var range_borders = this.range_elt.getBoundingClientRect();
var range_length = Math.sqrt( range_borders.height*range_borders.height + range_borders.width*range_borders.width );
var [minX,minY,maxX,maxY] = [range_borders.left,range_borders.bottom,range_borders.right,range_borders.top];
//get range and mouse coordinates
var mouseX = undefined;
var mouseY = undefined;
if (evt.type.startsWith("touch")){
mouseX = Math.ceil(evt.touches[0].clientX);
mouseY = Math.ceil(evt.touches[0].clientY);
}
else{
mouseX = evt.pageX;
mouseY = evt.pageY;
}
//get handle distance from mouse position
if (minX > mouseX && minY < mouseY){
html_dist = 0;
}
else if (maxX < mouseX && maxY > mouseY){
html_dist = range_length;
}
else{
// calculate distace
if(this.fi > 0.7){
html_dist = (minY - mouseY)/Math.sin(this.fi);
}
else{
html_dist = (mouseX - minX)/Math.cos(this.fi);
}
//check if in range
if (html_dist > range_length){
html_dist = range_length;
}
else if (html_dist < 0){
html_dist = 0;
}
}
this.svg_dist=Math.ceil((html_dist/range_length)*this.range[1]);
this.apply_hmi_value(0, this.svg_dist);
// update ghost cursor
if(this.setpoint_elt != undefined){
this.request_animate();
}
}
animate(){
this.update_DOM(this.svg_dist, this.setpoint_elt);
}
on_select(evt){
this.drag = true;
this.enTimer = true;
window.addEventListener("touchmove", this.on_bound_drag, true);
window.addEventListener("mousemove", this.on_bound_drag, true);
window.addEventListener("mouseup", this.bound_on_release, true)
window.addEventListener("touchend", this.bound_on_release, true);
window.addEventListener("touchcancel", this.bound_on_release, true);
this.update_position(evt);
}
init() {
let min = this.min_elt ?
Number(this.min_elt.textContent) :
this.args.length >= 1 ? this.args[0] : 0;
let max = this.max_elt ?
Number(this.max_elt.textContent) :
this.args.length >= 2 ? this.args[1] : 100;
this.range = [min, max, this.range_elt.getPointAtLength(0),this.range_elt.getTotalLength()];
let start = this.range_elt.getPointAtLength(0);
let end = this.range_elt.getPointAtLength(this.range_elt.getTotalLength());
this.fi = Math.atan2(start.y-end.y, end.x-start.x);
this.bound_on_select = this.on_select.bind(this);
this.bound_on_release = this.on_release.bind(this);
this.on_bound_drag = this.on_drag.bind(this);
this.element.addEventListener("mousedown", this.bound_on_select);
this.element.addEventListener("touchstart", this.bound_on_select);
if(this.setpoint_elt != undefined){
this.setpoint_style = this.setpoint_elt.getAttribute("style");
this.setpoint_elt.setAttribute("style", "display:none");
}
}
}
||
template "widget[@type='Slider']", mode="widget_defs" {
param "hmi_element";
labels("handle range");
optional_labels("value min max setpoint");
|,
}