# HG changeset patch # User Edouard Tisserant # Date 1603095326 -7200 # Node ID c369a742443dcb5224591265f127cc91393c2465 # Parent 4b44d09c48a7c532a8b0f5432c3b4741f23cbdb7 SVGHMI: non significant cosmetic changes diff -r 4b44d09c48a7 -r c369a742443d svghmi/gen_index_xhtml.xslt --- a/svghmi/gen_index_xhtml.xslt Mon Oct 19 09:29:11 2020 +0200 +++ b/svghmi/gen_index_xhtml.xslt Mon Oct 19 10:15:26 2020 +0200 @@ -1475,6 +1475,180 @@ + + class AnimateWidget extends Widget{ + + frequency = 5; + + speed = 0; + + start = false; + + widget_center = undefined; + + + + dispatch(value) { + + this.speed = value / 5; + + + + //reconfigure animation + + this.request_animate(); + + } + + + + animate(){ + + // change animation properties + + for(let child of this.element.children){ + + if(child.nodeName.startsWith("animate")){ + + if(this.speed != 0 && !this.start){ + + this.start = true; + + this.element.beginElement(); + + } + + + + if(this.speed > 0){ + + child.setAttribute("dur", this.speed+"s"); + + } + + else if(this.speed < 0){ + + child.setAttribute("dur", (-1)*this.speed+"s"); + + } + + else{ + + this.start = false; + + this.element.endElement(); + + } + + } + + } + + } + + + + init() { + + let widget_pos = this.element.getBBox(); + + this.widget_center = [(widget_pos.x+widget_pos.width/2), (widget_pos.y+widget_pos.height/2)]; + + } + + } + + + + + + + + + class AnimateRotationWidget extends Widget{ + + frequency = 5; + + speed = 0; + + widget_center = undefined; + + + + dispatch(value) { + + this.speed = value / 5; + + + + //reconfigure animation + + this.request_animate(); + + } + + + + animate(){ + + // change animation properties + + for(let child of this.element.children){ + + if(child.nodeName == "animateTransform"){ + + if(this.speed > 0){ + + child.setAttribute("dur", this.speed+"s"); + + child.setAttribute("from", "0 "+this.widget_center[0]+" "+this.widget_center[1]); + + child.setAttribute("to", "360 "+this.widget_center[0]+" "+this.widget_center[1]); + + } + + else if(this.speed < 0){ + + child.setAttribute("dur", (-1)*this.speed+"s"); + + child.setAttribute("from", "360 "+this.widget_center[0]+" "+this.widget_center[1]); + + child.setAttribute("to", "0 "+this.widget_center[0]+" "+this.widget_center[1]); + + } + + else{ + + child.setAttribute("from", "0 "+this.widget_center[0]+" "+this.widget_center[1]); + + child.setAttribute("to", "0 "+this.widget_center[0]+" "+this.widget_center[1]); + + } + + } + + } + + } + + + + init() { + + let widget_pos = this.element.getBBox(); + + this.widget_center = [(widget_pos.x+widget_pos.width/2), (widget_pos.y+widget_pos.height/2)]; + + } + + } + + + + + + + class BackWidget extends Widget{ @@ -1506,7 +1680,9 @@ frequency = 5; - state = 0; + state_plc = 0; + + state_hmi = 0; plc_lock = false; @@ -1518,89 +1694,113 @@ dispatch(value) { - if(value){ - - this.button_release(); + this.state_plc = value; + + if(this.plc_lock){ + + if(this.state_plc == 1){ + + this.apply_hmi_value(0, 0); + + this.plc_lock = false; + + } } - } - - - - on_mouse_down(evt) { - - if (this.active_style && this.inactive_style) { - - this.active_elt.setAttribute("style", this.active_style); - - this.inactive_elt.setAttribute("style", "display:none"); - - } - - this.apply_hmi_value(0, 1); - - this.plc_lock = false; - - } - - - - on_mouse_up(evt) { - - this.button_release(); - - } - - - - button_release(){ - - if(!this.plc_lock){ - - this.plc_lock = true; + + + //redraw button + + this.state_hmi = this.state_plc; + + this.request_animate(); + + } + + + + animate(){ + + if (this.active_style && this.inactive_style) { + + // redraw button on screen refresh + + if (this.state_hmi) { + + this.active_elt.setAttribute("style", this.active_style); + + this.inactive_elt.setAttribute("style", "display:none"); + + } else { + + this.inactive_elt.setAttribute("style", this.inactive_style); + + this.active_elt.setAttribute("style", "display:none"); + + } + + } + + } + + + + on_click(evt) { + + //set state and apply if plc is 0 + + this.plc_lock = true; + + if(this.state_plc == 0){ + + this.apply_hmi_value(0, 1); } - else{ - - if (this.active_style && this.inactive_style) { - - this.active_elt.setAttribute("style", "display:none"); - - this.inactive_elt.setAttribute("style", this.inactive_style); - - } - - this.apply_hmi_value(0, 0); + //redraw button + + this.request_animate(); + + } + + + + on_press(evt) { + + //set graphic + + this.state_hmi = 1; + + //redraw button + + this.request_animate(); + + } + + + + init() { + + this.active_style = this.active_elt ? this.active_elt.style.cssText : undefined; + + this.inactive_style = this.inactive_elt ? this.inactive_elt.style.cssText : undefined; + + + + if (this.active_style && this.inactive_style) { + + this.active_elt.setAttribute("style", "display:none"); + + this.inactive_elt.setAttribute("style", this.inactive_style); } - } - - - - init() { - - this.active_style = this.active_elt ? this.active_elt.style.cssText : undefined; - - this.inactive_style = this.inactive_elt ? this.inactive_elt.style.cssText : undefined; - - - - if (this.active_style && this.inactive_style) { - - this.active_elt.setAttribute("style", "display:none"); - - this.inactive_elt.setAttribute("style", this.inactive_style); - - } - - - - this.element.setAttribute("onmousedown", "hmi_widgets["+this.element_id+"].on_mouse_down(evt)"); - - this.element.setAttribute("onmouseup", "hmi_widgets["+this.element_id+"].on_mouse_up(evt)"); + + + this.element.setAttribute("onclick", "hmi_widgets['"+this.element_id+"'].on_click(evt)"); + + this.element.setAttribute("onmousedown", "hmi_widgets['"+this.element_id+"'].on_press(evt)"); } @@ -1738,7 +1938,7 @@ handle_pos = undefined; - svg_dist = undefined; + curr_value = 0; drag = false; @@ -1750,13 +1950,47 @@ dispatch(value) { + let [min,max,start,totallength] = this.range; + + //save current value inside widget + + this.curr_value = value; + + + + //check if in range + + if (this.curr_value > max){ + + this.curr_value = max; + + this.apply_hmi_value(0, this.curr_value); + + } + + else if (this.curr_value < min){ + + this.curr_value = min; + + this.apply_hmi_value(0, this.curr_value); + + } + + + if(this.value_elt) this.value_elt.textContent = String(value); - this.update_DOM(value, this.handle_elt); + //don't update if draging and setpoint ghost doesn't exist + + if(!this.drag || (this.setpoint_elt != undefined)){ + + this.update_DOM(value, this.handle_elt); + + } } @@ -1774,6 +2008,8 @@ + // show or hide ghost if exists + if(this.setpoint_elt != undefined){ if(this.last_drag!= this.drag){ @@ -1800,6 +2036,8 @@ on_release(evt) { + //unbind events + window.removeEventListener("touchmove", this.on_bound_drag, true); window.removeEventListener("mousemove", this.on_bound_drag, true); @@ -1812,12 +2050,20 @@ window.removeEventListener("touchcancel", this.bound_on_release, true); + + + //reset drag flag + if(this.drag){ this.drag = false; } + + + // get final position + this.update_position(evt); } @@ -1826,10 +2072,14 @@ on_drag(evt){ + //ignore drag event for X amount of time and if not selected + if(this.enTimer && this.drag){ this.update_position(evt); + + //reset timer this.enTimer = false; @@ -1930,37 +2180,35 @@ if(fi<fiEnd){ - this.svg_dist=(fi)/(fiEnd)*(this.range[1]-this.range[0]); + this.curr_value=(fi)/(fiEnd)*(this.range[1]-this.range[0]); } else if(fiEnd<fi && fi<fiEnd+minMax){ - this.svg_dist = this.range[1]; + this.curr_value = this.range[1]; } else{ - this.svg_dist = this.range[0]; + this.curr_value = this.range[0]; } - - - this.apply_hmi_value(0, Math.ceil(this.svg_dist)); - - - - // update ghost cursor - - if(this.setpoint_elt != undefined){ - - this.request_animate(); - - } + //apply value to hmi + + this.apply_hmi_value(0, Math.ceil(this.curr_value)); + + + + //redraw handle + + this.request_animate(); + + } @@ -1972,7 +2220,21 @@ animate(){ - this.update_DOM(this.svg_dist, this.setpoint_elt); + // redraw handle on screen refresh + + // check if setpoint(ghost) handle exsist otherwise update main handle + + if(this.setpoint_elt != undefined){ + + this.update_DOM(this.curr_value, this.setpoint_elt); + + } + + else{ + + this.update_DOM(this.curr_value, this.handle_elt); + + } } @@ -1980,24 +2242,40 @@ on_select(evt){ + //enable drag flag and timer + this.drag = true; this.enTimer = true; + + + //bind events + 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("mouseup", this.bound_on_release, true); window.addEventListener("touchend", this.bound_on_release, true); window.addEventListener("touchcancel", this.bound_on_release, true); + + + //update postion on mouse press + this.update_position(evt); + + + //prevent next events + + evt.stopPropagation(); + } @@ -2074,13 +2352,21 @@ - //init events + this.handle_elt.addEventListener("mousedown", this.bound_on_select); this.element.addEventListener("mousedown", this.bound_on_select); this.element.addEventListener("touchstart", this.bound_on_select); - + //touch recognised as page drag without next command + + document.body.addEventListener("touchstart", function(e){}, false); + + + + //save ghost style + + //save ghost style if(this.setpoint_elt != undefined){ @@ -2092,22 +2378,6 @@ - - - window.addEventListener("touchmove", hmi_widgets[this.element_id].update_position.bind(this)); - - window.addEventListener("mousemove", hmi_widgets[this.element_id].update_position.bind(this)); - - - - window.addEventListener("mouseup", hmi_widgets[this.element_id].on_release.bind(this)) - - window.addEventListener("touchend", hmi_widgets[this.element_id].on_release.bind(this)); - - window.addEventListener("touchcancel", hmi_widgets[this.element_id].on_release.bind(this)); - - - } } @@ -2124,13 +2394,66 @@ - value min max + value min max setpoint + + class CustomHtmlWidget extends Widget{ + + frequency = 5; + + widget_size = undefined; + + + + dispatch(value) { + + this.request_animate(); + + } + + + + animate(){ + + } + + + + init() { + + this.widget_size = this.container_elt.getBBox(); + + this.element.innerHTML ='<foreignObject x="'+ + + this.widget_size.x+'" y="'+this.widget_size.y+ + + '" width="'+this.widget_size.width+'" height="'+this.widget_size.height+'"> '+ + + this.code_elt.textContent+ + + ' </foreignObject>'; + + } + + } + + + + + + + + container code + + + + + class DisplayWidget extends Widget{ @@ -2162,7 +2485,9 @@ "" - 0 + + 0 + , @@ -3501,7 +3826,7 @@ class JsonTableWidget extends Widget{ - cache = []; + cache = [100,50]; do_http_request(...opt) { @@ -3509,7 +3834,9 @@ args: this.args, - vars: this.cache, + range: this.cache[1], + + position: this.cache[2], visible: this.visible, @@ -3848,6 +4175,8 @@ this.apply_hmi_value(2, position); + this.apply_hmi_value(3, this.visible); + console.log(range,position,jdata); @@ -4756,7 +5085,11 @@ handle_orig = undefined; - scroll_size = 10; + scroll_size = undefined; + + scroll_range = 0; + + scroll_visible = 7; min_size = 0.07; @@ -4774,17 +5107,59 @@ - dispatch(value) { - - //save current value inside widget - - this.curr_value = value; - - - - if(this.value_elt) - - this.value_elt.textContent = String(value); + dispatch(value,oldval, index) { + + if (index == 0){ + + let [min,max,start,totallength] = this.range; + + //save current value inside widget + + this.curr_value = value; + + + + //check if in range + + if (this.curr_value > max){ + + this.curr_value = max; + + this.apply_hmi_value(0, this.curr_value); + + } + + else if (this.curr_value < min){ + + this.curr_value = min; + + this.apply_hmi_value(0, this.curr_value); + + } + + + + if(this.value_elt) + + this.value_elt.textContent = String(value); + + } + + else if(index == 1){ + + this.scroll_range = value; + + this.set_scroll(); + + } + + else if(index == 2){ + + this.scroll_visible = value; + + this.set_scroll(); + + } @@ -4792,7 +5167,7 @@ if(!this.drag || (this.setpoint_elt != undefined)){ - this.update_DOM(value, this.handle_elt); + this.update_DOM(this.curr_value, this.handle_elt); } @@ -4800,6 +5175,34 @@ + set_scroll(){ + + //check if range is bigger than visible and set scroll size + + if(this.scroll_range > this.scroll_visible){ + + this.scroll_size = this.scroll_range - this.scroll_visible; + + this.range[0] = 0; + + this.range[1] = this.scroll_size; + + } + + else{ + + this.scroll_size = 1; + + this.range[0] = 0; + + this.range[1] = 1; + + } + + } + + + update_DOM(value, elt){ let [min,max,start,totallength] = this.range; @@ -4946,7 +5349,7 @@ - window.removeEventListener("mouseup", this.bound_on_release, true) + window.removeEventListener("mouseup", this.bound_on_release, true); window.removeEventListener("touchend", this.bound_on_release, true); @@ -5138,7 +5541,7 @@ - //check if in range + //check if in range and apply if (this.curr_value > max){ @@ -5152,8 +5555,6 @@ } - - this.apply_hmi_value(0, this.curr_value); @@ -5208,7 +5609,7 @@ - window.addEventListener("mouseup", this.bound_on_release, true) + window.addEventListener("mouseup", this.bound_on_release, true); window.addEventListener("touchend", this.bound_on_release, true); @@ -5264,7 +5665,11 @@ evt.stopPropagation(); - } + + + } + + @@ -5286,6 +5691,8 @@ + + // save initial parameters this.range_elt.style.strokeMiterlimit="0"; @@ -5318,7 +5725,13 @@ this.element.addEventListener("touchstart", this.bound_on_select); - + //touch recognised as page drag without next command + + document.body.addEventListener("touchstart", function(e){}, false); + + + + //save ghost style if(this.setpoint_elt != undefined){ @@ -5425,68 +5838,84 @@ dispatch(value) { - if(this.state != value){ - - this.state = value; - - if (this.state) { - - this.active_elt.setAttribute("style", this.active_style); - - this.inactive_elt.setAttribute("style", "display:none"); - - } else { - - this.inactive_elt.setAttribute("style", this.inactive_style); - - this.active_elt.setAttribute("style", "display:none"); - - } + this.state = value; + + //redraw toggle button + + this.request_animate(); + + } + + + + on_click(evt) { + + //toggle state and apply + + if (this.state) { + + this.state = 0; + + } else { + + this.state = 1; } - } - - - - on_click(evt) { - - if (this.state) { + this.apply_hmi_value(0, this.state); + + + + //redraw toggle button + + this.request_animate(); + + } + + + + animate(){ + + // redraw toggle button on screen refresh + + if (this.state) { + + this.active_elt.setAttribute("style", this.active_style); + + this.inactive_elt.setAttribute("style", "display:none"); + + } else { + + this.inactive_elt.setAttribute("style", this.inactive_style); + + this.active_elt.setAttribute("style", "display:none"); + + } + + } + + + + init() { + + this.active_style = this.active_elt ? this.active_elt.style.cssText : undefined; + + this.inactive_style = this.inactive_elt ? this.inactive_elt.style.cssText : undefined; + + + + if (this.active_style && this.inactive_style) { + + this.active_elt.setAttribute("style", "display:none"); this.inactive_elt.setAttribute("style", this.inactive_style); - this.active_elt.setAttribute("style", "display:none"); - - this.state = 0; - - } else { - - this.active_elt.setAttribute("style", this.active_style); - - this.inactive_elt.setAttribute("style", "display:none"); - - this.state = 1; - } - this.apply_hmi_value(0, this.state); - - } - - - - init() { - - this.active_style = this.active_elt.style.cssText; - - this.inactive_style = this.inactive_elt.style.cssText; + this.element.setAttribute("onclick", "hmi_widgets['"+this.element_id+"'].on_click(evt)"); - this.inactive_elt.setAttribute("style", this.inactive_style); - - this.active_elt.setAttribute("style", "display:none"); - } } @@ -5499,6 +5928,7 @@ active inactive + diff -r 4b44d09c48a7 -r c369a742443d svghmi/widget_display.ysl2 --- a/svghmi/widget_display.ysl2 Mon Oct 19 09:29:11 2020 +0200 +++ b/svghmi/widget_display.ysl2 Mon Oct 19 10:15:26 2020 +0200 @@ -20,7 +20,7 @@ const "field_initializer" foreach "path" { choose{ when "@type='HMI_STRING'" > "" - otherwise 0 + otherwise > 0 } if "position()!=last()" > , } diff -r 4b44d09c48a7 -r c369a742443d svghmi/widget_jsontable.ysl2 --- a/svghmi/widget_jsontable.ysl2 Mon Oct 19 09:29:11 2020 +0200 +++ b/svghmi/widget_jsontable.ysl2 Mon Oct 19 10:15:26 2020 +0200 @@ -3,11 +3,12 @@ template "widget[@type='JsonTable']", mode="widget_class" || class JsonTableWidget extends Widget{ - cache = []; + cache = [100,50]; do_http_request(...opt) { const query = { args: this.args, - vars: this.cache, + range: this.cache[1], + position: this.cache[2], visible: this.visible, options: opt }; diff -r 4b44d09c48a7 -r c369a742443d tests/svghmi/py_ext_0@py_ext/pyfile.xml --- a/tests/svghmi/py_ext_0@py_ext/pyfile.xml Mon Oct 19 09:29:11 2020 +0200 +++ b/tests/svghmi/py_ext_0@py_ext/pyfile.xml Mon Oct 19 10:15:26 2020 +0200 @@ -30,8 +30,9 @@ def render_POST(self, request): newstr = request.content.getvalue() newdata = json.loads(newstr) - vars = newdata[u'vars'] args = newdata[u'args'] + range_feedback = newdata[u'range'] + slider_position = newdata[u'position'] visible = newdata[u'visible'] options = newdata[u'options'] @@ -40,14 +41,11 @@ if action == "onClick[acknowledge]": AlarmIndex[int(alarmid)][2] = "ack" - svars = (vars + [0,0])[:3] - range_feedback = svars[1] - slider_position = svars[2] - answer = self.renderTable(range_feedback, slider_position, visible, *(args+svars[3:])) + answer = self.renderTable(range_feedback, slider_position, visible) janswer = json.dumps(answer) return janswer - def renderTable(self, old_range, old_position, visible, *options): + def renderTable(self, old_range, old_position, visible): new_range = len(Alarms) delta = new_range - visible new_position = 0 if delta <= 0 else delta if old_position > delta else old_position