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) { usveticic@3012: if(!this.drag){ usveticic@3012: if(this.value_elt) usveticic@3012: this.value_elt.textContent = String(value); usveticic@3012: usveticic@3012: this.handle_position(value); usveticic@3012: } usveticic@3012: } usveticic@3012: usveticic@3012: handle_position(value){ 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); usveticic@3012: this.handle_elt.setAttribute('transform',"translate("+(tip.x-start.x)+","+(tip.y-start.y)+")"); usveticic@3012: } usveticic@3012: usveticic@3012: on_release(evt) { usveticic@3012: if(this.drag){ usveticic@3012: this.drag = false; usveticic@3012: } usveticic@3012: } usveticic@3012: usveticic@3012: update_position(evt){ usveticic@3012: if(this.drag && this.enTimer){ usveticic@3012: var html_dist = 0; usveticic@3012: var svg_dist = 0; usveticic@3012: usveticic@3012: //calculate size of widget in html usveticic@3012: var range_borders = this.range_elt.getBoundingClientRect(); usveticic@3012: var range_length = Math.sqrt( range_borders.height*range_borders.height + range_borders.width*range_borders.width ); usveticic@3012: var [minX,minY,maxX,maxY] = [range_borders.left,range_borders.bottom,range_borders.right,range_borders.top]; usveticic@3012: usveticic@3012: //get range and mouse coordinates usveticic@3012: var mouseX = undefined; usveticic@3012: var mouseY = undefined; usveticic@3012: if (evt.type.startsWith("touch")){ usveticic@3012: mouseX = Math.ceil(evt.touches[0].clientX); usveticic@3012: mouseY = Math.ceil(evt.touches[0].clientY); usveticic@3012: } usveticic@3012: else{ usveticic@3012: mouseX = evt.pageX; usveticic@3012: mouseY = evt.pageY; usveticic@3012: } usveticic@3012: usveticic@3012: //get handle distance from mouse position usveticic@3012: if (minX > mouseX && minY < mouseY){ usveticic@3012: html_dist = 0; usveticic@3012: } usveticic@3012: else if (maxX < mouseX && maxY > mouseY){ usveticic@3012: html_dist = range_length; usveticic@3012: } usveticic@3012: else{ usveticic@3012: // calculate distace usveticic@3012: if(this.fi > 0.7){ usveticic@3012: html_dist = (minY - mouseY)/Math.sin(this.fi); usveticic@3012: } usveticic@3012: else{ usveticic@3012: html_dist = (mouseX - minX)/Math.cos(this.fi); usveticic@3012: } usveticic@3012: usveticic@3012: //check if in range usveticic@3012: if (html_dist > range_length){ usveticic@3012: html_dist = range_length; usveticic@3012: } usveticic@3012: else if (html_dist < 0){ usveticic@3012: html_dist = 0; usveticic@3012: } usveticic@3012: } usveticic@3012: //redraw handle usveticic@3012: this.handle_position(svg_dist=(html_dist/range_length)*this.range[1]); usveticic@3012: this.value_elt.textContent = String(Math.ceil(svg_dist)); Edouard@3018: this.apply_hmi_value(0, Math.ceil(svg_dist)); usveticic@3012: //reset timer usveticic@3012: this.enTimer = false; usveticic@3012: setTimeout("{hmi_widgets['"+this.element_id+"'].enTimer = true;}", 100); usveticic@3012: } usveticic@3012: usveticic@3012: } usveticic@3012: usveticic@3012: on_select(evt){ usveticic@3012: this.drag = true; usveticic@3012: this.enTimer = 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: usveticic@3012: usveticic@3012: this.handle_elt.addEventListener("touchstart", hmi_widgets[this.element_id].on_select.bind(this)); usveticic@3012: this.handle_elt.addEventListener("mousedown", hmi_widgets[this.element_id].on_select.bind(this)); usveticic@3012: this.element.addEventListener("mousedown", hmi_widgets[this.element_id].on_select.bind(this)); usveticic@3012: usveticic@3012: window.addEventListener("touchmove", hmi_widgets[this.element_id].update_position.bind(this)); usveticic@3012: window.addEventListener("mousemove", hmi_widgets[this.element_id].update_position.bind(this)); usveticic@3012: usveticic@3012: window.addEventListener("mouseup", hmi_widgets[this.element_id].on_release.bind(this)) usveticic@3012: window.addEventListener("touchend", hmi_widgets[this.element_id].on_release.bind(this)); usveticic@3012: window.addEventListener("touchcancel", hmi_widgets[this.element_id].on_release.bind(this)); 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"); usveticic@3012: optional_labels("value min max"); usveticic@3012: |, Edouard@3018: }