# HG changeset patch # User Edouard Tisserant # Date 1598607078 -7200 # Node ID c113904f0e62558358568e46b38d82b808b43a10 # Parent d1bb0c09e412d938e76230d9c8baeb94bc62a6d1# Parent f6d428330e0471cbb7c4f75a4c8edf7785f3cd4f Merged diff -r d1bb0c09e412 -r c113904f0e62 svghmi/gen_index_xhtml.xslt --- a/svghmi/gen_index_xhtml.xslt Fri Aug 28 11:27:07 2020 +0200 +++ b/svghmi/gen_index_xhtml.xslt Fri Aug 28 11:31:18 2020 +0200 @@ -1583,10 +1583,98 @@ + + class CircularBarWidget extends Widget{ + + frequency = 10; + + range = undefined; + + + + dispatch(value) { + + if(this.value_elt) + + this.value_elt.textContent = String(value); + + let [min,max,start,end] = this.range; + + let [cx,cy] = this.center; + + let [rx,ry] = this.proportions; + + let tip = start + (end-start)*Number(value)/(max-min); + + let size = 0; + + if (tip-start > Math.PI) { + + size = 1; + + } else { + + size = 0; + + } + + this.path_elt.setAttribute('d', "M "+(cx+rx*Math.cos(start))+","+(cy+ry*Math.sin(start))+" A "+rx+","+ry+" 0 "+size+" 1 "+(cx+rx*Math.cos(tip))+","+(cy+ry*Math.sin(tip))); + + } + + + + init() { + + let start = Number(this.path_elt.getAttribute('sodipodi:start')); + + let end = Number(this.path_elt.getAttribute('sodipodi:end')); + + let cx = Number(this.path_elt.getAttribute('sodipodi:cx')); + + let cy = Number(this.path_elt.getAttribute('sodipodi:cy')); + + let rx = Number(this.path_elt.getAttribute('sodipodi:rx')); + + let ry = Number(this.path_elt.getAttribute('sodipodi:ry')); + + if (ry == 0) { + + ry = rx; + + } + + if (start > end) { + + end = end + 2*Math.PI; + + } + + 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, start, end]; + + this.center = [cx, cy]; + + this.proportions = [rx, ry]; + + } + + } + + - frequency: 10, - @@ -1600,83 +1688,7 @@ - dispatch: function(value) { - - if(this.value_elt) - - this.value_elt.textContent = String(value); - - let [min,max,start,end] = this.range; - - let [cx,cy] = this.center; - - let [rx,ry] = this.proportions; - - let tip = start + (end-start)*Number(value)/(max-min); - - let size = 0; - - if (tip-start > Math.PI) { - - size = 1; - - } else { - - size = 0; - - } - - this.path_elt.setAttribute('d', "M "+(cx+rx*Math.cos(start))+","+(cy+ry*Math.sin(start))+" A "+rx+","+ry+" 0 "+size+" 1 "+(cx+rx*Math.cos(tip))+","+(cy+ry*Math.sin(tip))); - - }, - - range: undefined, - - init: function() { - - let start = Number(this.path_elt.getAttribute('sodipodi:start')); - - let end = Number(this.path_elt.getAttribute('sodipodi:end')); - - let cx = Number(this.path_elt.getAttribute('sodipodi:cx')); - - let cy = Number(this.path_elt.getAttribute('sodipodi:cy')); - - let rx = Number(this.path_elt.getAttribute('sodipodi:rx')); - - let ry = Number(this.path_elt.getAttribute('sodipodi:ry')); - - if (ry == 0) { - - ry = rx; - - } - - if (start > end) { - - end = end + 2*Math.PI; - - } - - 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, start, end]; - - this.center = [cx, cy]; - - this.proportions = [rx, ry]; - - }, + @@ -1690,23 +1702,59 @@ handle_pos = undefined; + svg_dist = undefined; + drag = false; enTimer = false; + last_drag = false; + dispatch(value) { - if(!this.drag){ - - if(this.value_elt) - - this.value_elt.textContent = String(value); - - - - this.handle_position(value); + if(this.value_elt) + + this.value_elt.textContent = String(value); + + + + this.update_DOM(value, this.handle_elt); + + } + + + + update_DOM(value, elt){ + + let [min,max,totalDistance] = this.range; + + let length = Math.max(0,Math.min((totalDistance),(Number(value)-min)/(max-min)*(totalDistance))); + + let tip = this.range_elt.getPointAtLength(length); + + elt.setAttribute('transform',"translate("+(tip.x-this.handle_pos.x)+","+(tip.y-this.handle_pos.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; + + } } @@ -1714,28 +1762,46 @@ - handle_position(value){ - - let [min,max,totalDistance] = this.range; - - let length = Math.max(0,Math.min((totalDistance),(Number(value)-min)/(max-min)*(totalDistance))); - - let tip = this.range_elt.getPointAtLength(length); - - this.handle_elt.setAttribute('transform',"translate("+(tip.x-this.handle_pos.x)+","+(tip.y-this.handle_pos.y)+")"); - - } - - - 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); + + } + } @@ -1828,41 +1894,37 @@ if(fi<fiEnd){ - svg_dist=(fi)/(fiEnd)*(this.range[1]-this.range[0]); + this.svg_dist=(fi)/(fiEnd)*(this.range[1]-this.range[0]); } else if(fiEnd<fi && fi<fiEnd+minMax){ - svg_dist = this.range[1]; + this.svg_dist = this.range[1]; } else{ - svg_dist = this.range[0]; + this.svg_dist = this.range[0]; } - //redraw handle --TODO is it fast enough if I just call change_hmi_value??? - - this.handle_position(svg_dist); - - if(this.value_elt) - - this.value_elt.textContent = String(Math.ceil(svg_dist)); - - this.apply_hmi_value(0, Math.ceil(svg_dist)); - - - - //reset timer - - this.enTimer = false; - - setTimeout("{hmi_widgets['"+this.element_id+"'].enTimer = true;}", 100); + + + this.apply_hmi_value(0, Math.ceil(this.svg_dist)); + + + + // update ghost cursor + + if(this.setpoint_elt != undefined){ + + this.request_animate(); + + } } @@ -1872,12 +1934,32 @@ + 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); } @@ -1946,13 +2028,33 @@ + //bind functions + + 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); + + + //init events - this.handle_elt.addEventListener("touchstart", hmi_widgets[this.element_id].on_select.bind(this)); - - this.handle_elt.addEventListener("mousedown", hmi_widgets[this.element_id].on_select.bind(this)); - - this.element.addEventListener("mousedown", hmi_widgets[this.element_id].on_select.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"); + + } + + @@ -3973,7 +4075,7 @@ moving = undefined; - enTimer = undefined; + click = undefined; offset = undefined; @@ -3983,7 +4085,21 @@ this.moving = true; - this.enTimer = true; + + + // chatch window events + + window.addEventListener("touchmove", this.bound_on_drag, true); + + window.addEventListener("mousemove", this.bound_on_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); @@ -4017,7 +4133,23 @@ - off_position_click(evt) { + on_release(evt) { + + //relase binds + + window.removeEventListener("touchmove", this.bound_on_drag, true); + + window.removeEventListener("mousemove", this.bound_on_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.moving) @@ -4027,63 +4159,65 @@ - on_move(evt) { - - if(this.moving && this.enTimer){ - - //get keyboard pos in html - - let [eltid, tmpgrp] = current_modal; - - let [xcoord,ycoord] = this.coordinates; - - let [xdest,ydest,svgWidth,svgHeight] = page_desc[current_visible_page].bbox; - - - - //get mouse coordinates - - var clickX = undefined; - - var clickY = undefined; - - if (evt.type == "touchmove"){ - - clickX = Math.ceil(evt.touches[0].clientX); - - clickY = Math.ceil(evt.touches[0].clientY); - - } - - else{ - - clickX = evt.pageX; - - clickY = evt.pageY; - - } - - - - //translate keyboard position - - let mouseX = ((clickX-this.offset[0])/window.innerWidth)*svgWidth; - - let mouseY = ((clickY-this.offset[1])/window.innerHeight)*svgHeight; - - tmpgrp.setAttribute("transform","translate("+String(xdest-xcoord+mouseX)+","+String(ydest-ycoord+mouseY)+")"); - - - - //reset timer - - this.enTimer = false; - - setTimeout("{hmi_widgets['"+this.element_id+"'].enTimer = true;}", 100); - - } - - + on_drag(evt) { + + if(this.moving) + + //get mouse coordinates + + var clickX = undefined; + + var clickY = undefined; + + if (evt.type == "touchmove"){ + + clickX = Math.ceil(evt.touches[0].clientX); + + clickY = Math.ceil(evt.touches[0].clientY); + + } + + else{ + + clickX = evt.pageX; + + clickY = evt.pageY; + + } + + this.click = [clickX,clickY] + + + + //requeset redraw + + this.request_animate(); + + } + + + + animate(){ + + //get keyboard pos in html + + let [eltid, tmpgrp] = current_modal; + + let [xcoord,ycoord] = this.coordinates; + + let [clickX,clickY] = this.click; + + let [xdest,ydest,svgWidth,svgHeight] = page_desc[current_visible_page].bbox; + + + + //translate keyboard position + + let mouseX = ((clickX-this.offset[0])/window.innerWidth)*svgWidth; + + let mouseY = ((clickY-this.offset[1])/window.innerHeight)*svgHeight; + + tmpgrp.setAttribute("transform","translate("+String(xdest-xcoord+mouseX)+","+String(ydest-ycoord+mouseY)+")"); } @@ -4329,20 +4463,16 @@ if(this.position_elt){ + this.bound_on_release = this.on_release.bind(this); + + this.bound_on_drag = this.on_drag.bind(this); + + + this.position_elt.setAttribute("onmousedown", "hmi_widgets['"+this.element_id+"'].on_position_click(evt)"); this.position_elt.setAttribute("ontouchstart", "hmi_widgets['"+this.element_id+"'].on_position_click(evt)"); - window.addEventListener("mouseup", hmi_widgets[this.element_id].off_position_click.bind(this)); - - window.addEventListener("touchend", hmi_widgets[this.element_id].off_position_click.bind(this)); - - window.addEventListener("touchcancel", hmi_widgets[this.element_id].off_position_click.bind(this)); - - window.addEventListener("mousemove", hmi_widgets[this.element_id].on_move.bind(this)); - - window.addEventListener("touchmove", hmi_widgets[this.element_id].on_move.bind(this)); - } }, @@ -4388,10 +4518,62 @@ }, + + class MeterWidget extends Widget{ + + frequency = 10; + + origin = undefined; + + range = undefined; + + + + dispatch(value) { + + if(this.value_elt) + + this.value_elt.textContent = String(value); + + let [min,max,totallength] = this.range; + + let length = Math.max(0,Math.min(totallength,(Number(value)-min)*totallength/(max-min))); + + let tip = this.range_elt.getPointAtLength(length); + + this.needle_elt.setAttribute('d', "M "+this.origin.x+","+this.origin.y+" "+tip.x+","+tip.y); + + } + + + + 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.getTotalLength()] + + this.origin = this.needle_elt.getPointAtLength(0); + + } + + + + } + + - frequency: 10, - @@ -4405,45 +4587,7 @@ - dispatch: function(value) { - - if(this.value_elt) - - this.value_elt.textContent = String(value); - - let [min,max,totallength] = this.range; - - let length = Math.max(0,Math.min(totallength,(Number(value)-min)*totallength/(max-min))); - - let tip = this.range_elt.getPointAtLength(length); - - this.needle_elt.setAttribute('d', "M "+this.origin.x+","+this.origin.y+" "+tip.x+","+tip.y); - - }, - - origin: undefined, - - range: undefined, - - init: function() { - - 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.getTotalLength()] - - this.origin = this.needle_elt.getPointAtLength(0); - - }, + @@ -4568,6 +4712,8 @@ fi = undefined; + svg_dist = undefined; + drag = false; enTimer = false; diff -r d1bb0c09e412 -r c113904f0e62 svghmi/widget_circularbar.ysl2 --- a/svghmi/widget_circularbar.ysl2 Fri Aug 28 11:27:07 2020 +0200 +++ b/svghmi/widget_circularbar.ysl2 Fri Aug 28 11:31:18 2020 +0200 @@ -1,48 +1,57 @@ // widget_circularbar.ysl2 +template "widget[@type='CircularBar']", mode="widget_class"{ + || + class CircularBarWidget extends Widget{ + frequency = 10; + range = undefined; + + dispatch(value) { + if(this.value_elt) + this.value_elt.textContent = String(value); + let [min,max,start,end] = this.range; + let [cx,cy] = this.center; + let [rx,ry] = this.proportions; + let tip = start + (end-start)*Number(value)/(max-min); + let size = 0; + if (tip-start > Math.PI) { + size = 1; + } else { + size = 0; + } + this.path_elt.setAttribute('d', "M "+(cx+rx*Math.cos(start))+","+(cy+ry*Math.sin(start))+" A "+rx+","+ry+" 0 "+size+" 1 "+(cx+rx*Math.cos(tip))+","+(cy+ry*Math.sin(tip))); + } + + init() { + let start = Number(this.path_elt.getAttribute('sodipodi:start')); + let end = Number(this.path_elt.getAttribute('sodipodi:end')); + let cx = Number(this.path_elt.getAttribute('sodipodi:cx')); + let cy = Number(this.path_elt.getAttribute('sodipodi:cy')); + let rx = Number(this.path_elt.getAttribute('sodipodi:rx')); + let ry = Number(this.path_elt.getAttribute('sodipodi:ry')); + if (ry == 0) { + ry = rx; + } + if (start > end) { + end = end + 2*Math.PI; + } + 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, start, end]; + this.center = [cx, cy]; + this.proportions = [rx, ry]; + } + } + || +} template "widget[@type='CircularBar']", mode="widget_defs" { param "hmi_element"; - | frequency: 10, labels("path"); optional_labels("value min max"); - | dispatch: function(value) { - | if(this.value_elt) - | this.value_elt.textContent = String(value); - | let [min,max,start,end] = this.range; - | let [cx,cy] = this.center; - | let [rx,ry] = this.proportions; - | let tip = start + (end-start)*Number(value)/(max-min); - | let size = 0; - | if (tip-start > Math.PI) { - | size = 1; - | } else { - | size = 0; - | } - | this.path_elt.setAttribute('d', "M "+(cx+rx*Math.cos(start))+","+(cy+ry*Math.sin(start))+" A "+rx+","+ry+" 0 "+size+" 1 "+(cx+rx*Math.cos(tip))+","+(cy+ry*Math.sin(tip))); - | }, - | range: undefined, - | init: function() { - | let start = Number(this.path_elt.getAttribute('sodipodi:start')); - | let end = Number(this.path_elt.getAttribute('sodipodi:end')); - | let cx = Number(this.path_elt.getAttribute('sodipodi:cx')); - | let cy = Number(this.path_elt.getAttribute('sodipodi:cy')); - | let rx = Number(this.path_elt.getAttribute('sodipodi:rx')); - | let ry = Number(this.path_elt.getAttribute('sodipodi:ry')); - | if (ry == 0) { - | ry = rx; - | } - | if (start > end) { - | end = end + 2*Math.PI; - | } - | 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, start, end]; - | this.center = [cx, cy]; - | this.proportions = [rx, ry]; - | }, + |, } \ No newline at end of file diff -r d1bb0c09e412 -r c113904f0e62 svghmi/widget_circularslider.ysl2 --- a/svghmi/widget_circularslider.ysl2 Fri Aug 28 11:27:07 2020 +0200 +++ b/svghmi/widget_circularslider.ysl2 Fri Aug 28 11:31:18 2020 +0200 @@ -7,29 +7,56 @@ range = undefined; circle = undefined; handle_pos = undefined; + svg_dist = undefined; drag = false; enTimer = false; + last_drag = false; dispatch(value) { - if(!this.drag){ - if(this.value_elt) - this.value_elt.textContent = String(value); - - this.handle_position(value); - } - } - - handle_position(value){ + if(this.value_elt) + this.value_elt.textContent = String(value); + + this.update_DOM(value, this.handle_elt); + } + + update_DOM(value, elt){ let [min,max,totalDistance] = this.range; let length = Math.max(0,Math.min((totalDistance),(Number(value)-min)/(max-min)*(totalDistance))); let tip = this.range_elt.getPointAtLength(length); - this.handle_elt.setAttribute('transform',"translate("+(tip.x-this.handle_pos.x)+","+(tip.y-this.handle_pos.y)+")"); + elt.setAttribute('transform',"translate("+(tip.x-this.handle_pos.x)+","+(tip.y-this.handle_pos.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){ @@ -76,31 +103,39 @@ //get handle distance from mouse position if(fi= 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.getTotalLength()] + this.origin = this.needle_elt.getPointAtLength(0); + } + + } + || +} template "widget[@type='Meter']", mode="widget_defs" { param "hmi_element"; - | frequency: 10, labels("needle range"); optional_labels("value min max"); - | dispatch: function(value) { - | if(this.value_elt) - | this.value_elt.textContent = String(value); - | let [min,max,totallength] = this.range; - | let length = Math.max(0,Math.min(totallength,(Number(value)-min)*totallength/(max-min))); - | let tip = this.range_elt.getPointAtLength(length); - | this.needle_elt.setAttribute('d', "M "+this.origin.x+","+this.origin.y+" "+tip.x+","+tip.y); - | }, - | origin: undefined, - | range: undefined, - | init: function() { - | 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.getTotalLength()] - | this.origin = this.needle_elt.getPointAtLength(0); - | }, + |, } diff -r d1bb0c09e412 -r c113904f0e62 svghmi/widget_slider.ysl2 --- a/svghmi/widget_slider.ysl2 Fri Aug 28 11:27:07 2020 +0200 +++ b/svghmi/widget_slider.ysl2 Fri Aug 28 11:31:18 2020 +0200 @@ -6,6 +6,7 @@ frequency = 5; range = undefined; fi = undefined; + svg_dist = undefined; drag = false; enTimer = false;