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