Button and toggle reworked to use animate and dispatch svghmi
authorusveticic
Thu, 24 Sep 2020 11:52:40 +0200
branchsvghmi
changeset 3059 e0db3f6a5f39
parent 3058 6ea4b7e1a9ed
child 3061 6dc33dae4074
Button and toggle reworked to use animate and dispatch
Slider added buttons to incremente/decrement by 1
Init for animate widget
Changed test svg and plc
svghmi/widget_animate.ysl2
svghmi/widget_button.ysl2
svghmi/widget_slider.ysl2
svghmi/widget_tooglebutton.ysl2
tests/svghmi_v2/plc.xml
tests/svghmi_v2/svghmi_0@svghmi/svghmi.svg
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/svghmi/widget_animate.ysl2	Thu Sep 24 11:52:40 2020 +0200
@@ -0,0 +1,35 @@
+// widget_animate.ysl2
+
+template "widget[@type='Animate']", mode="widget_class"{
+    ||
+    class AnimateWidget extends Widget{
+        frequency = 5;
+        speed = 0;
+
+        dispatch(value) {
+            this.speed = value;
+
+            //reconfigure animation
+            this.request_animate();
+        }
+
+        animate(){
+           // change animation properties
+           this.element.children[0].setAttribute("dur", String(this.speed)+"s")
+        }
+
+        init() {
+             let width = this.element.getAttribute("width");
+             let height = this.element.getAttribute("height");
+             this.element.setAttribute("x",width/-2);
+             this.element.setAttribute("y",height/-2);
+        }
+    }
+    ||
+}
+
+
+template "widget[@type='Animate']", mode="widget_defs" {
+    param "hmi_element";
+    |,
+}
--- a/svghmi/widget_button.ysl2	Thu Sep 17 11:30:22 2020 +0200
+++ b/svghmi/widget_button.ysl2	Thu Sep 24 11:52:40 2020 +0200
@@ -4,42 +4,53 @@
     ||
     class ButtonWidget extends Widget{
         frequency = 5;
-        state = 0;
+        state_plc = 0;
+        state_hmi = 0;
         plc_lock = false;
         active_style = undefined;
         inactive_style = undefined;
 
         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;
+                }
             }
+
+            //redraw button
+            this.state_hmi = this.state_plc;
+            this.request_animate();
         }
 
-         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;
-         }
+        animate(){
+           // 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_mouse_up(evt) {
-             this.button_release();
-         }
+        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);
+            }
+            //redraw button
+            this.request_animate();
+        }
 
-         button_release(){
-            if(!this.plc_lock){
-                this.plc_lock = true;
-            }
-            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);
-            }
-         }
+        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;
@@ -50,8 +61,8 @@
                 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)");
          }
     }
     ||
--- a/svghmi/widget_slider.ysl2	Thu Sep 17 11:30:22 2020 +0200
+++ b/svghmi/widget_slider.ysl2	Thu Sep 24 11:52:40 2020 +0200
@@ -101,7 +101,7 @@
             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("mouseup", this.bound_on_release, true);
             window.removeEventListener("touchend", this.bound_on_release, true);
             window.removeEventListener("touchcancel", this.bound_on_release, true);
 
@@ -224,42 +224,74 @@
         }
 
         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("touchend", this.bound_on_release, true);
-            window.addEventListener("touchcancel", this.bound_on_release, true);
-
-            // check if handle was pressed
-            if (evt.currentTarget == this.handle_elt){
-                //get mouse position on the handle
-                let mouseX = undefined;
-                let mouseY = undefined;
-                if (evt.type.startsWith("touch")){
-                    mouseX = Math.ceil(evt.touches[0].clientX);
-                    mouseY = Math.ceil(evt.touches[0].clientY);
+            if (evt.currentTarget != this.up_elt || evt.currentTarget != this.down_elt){
+                //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("touchend", this.bound_on_release, true);
+                window.addEventListener("touchcancel", this.bound_on_release, true);
+
+                // check if handle was pressed
+                if (evt.currentTarget == this.handle_elt){
+                    //get mouse position on the handle
+                    let mouseX = undefined;
+                    let 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;
+                    }
+                    //save coordinates and orig value
+                    this.handle_click = [mouseX,mouseY,this.curr_value];
                 }
                 else{
-                    mouseX = evt.pageX;
-                    mouseY = evt.pageY;
-                }
-                //save coordinates and orig value
-                this.handle_click = [mouseX,mouseY,this.curr_value];
+                    // get new handle position and reset if handle was not pressed
+                    this.handle_click = undefined;
+                    this.update_position(evt);
+                }
+
+                //prevent next events
+                evt.stopPropagation();
             }
             else{
-                // get new handle position and reset if handle was not pressed
-                this.handle_click = undefined;
-                this.update_position(evt);
-            }
-
-            //prevent next events
-            evt.stopPropagation();
+                //prevent next events if up/down were pressed
+                evt.stopPropagation();
+            }
+        }
+
+        on_up_button(evt){
+            // go one position up and check if in bounds
+            this.curr_value = this.curr_value + 1;
+            if (this.curr_value > this.range[1]){
+                this.curr_value = this.range[1];
+            }
+
+            this.apply_hmi_value(0, this.curr_value);
+
+            //redraw handle
+            this.request_animate();
+        }
+
+        on_down_button(evt){
+            // go one position down
+            this.curr_value = this.curr_value - 1;
+            if (this.curr_value < this.range[0]){
+                this.curr_value = this.range[0];
+            }
+
+            this.apply_hmi_value(0, this.curr_value);
+
+            //redraw handle
+            this.request_animate();
         }
 
         init() {
@@ -271,6 +303,14 @@
                         Number(this.max_elt.textContent) :
                         this.args.length >= 2 ? this.args[1] : 100;
 
+            //init up down button if exists
+            if(this.up_elt){
+                this.up_elt.setAttribute("onclick", "hmi_widgets['"+this.element_id+"'].on_up_button(evt)");
+            }
+            if(this.down_elt){
+                this.down_elt.setAttribute("onclick", "hmi_widgets['"+this.element_id+"'].on_down_button(evt)");
+            }
+
             // save initial parameters
             this.range_elt.style.strokeMiterlimit="0";
             this.range = [min, max, this.range_elt.getPointAtLength(0),this.range_elt.getTotalLength()];
@@ -285,8 +325,8 @@
             this.on_bound_drag = this.on_drag.bind(this);
 
             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);
+            this.range_elt.addEventListener("mousedown", this.bound_on_select);
+            this.range_elt.addEventListener("touchstart", this.bound_on_select);
 
             if(this.setpoint_elt != undefined){
                 this.setpoint_style = this.setpoint_elt.getAttribute("style");
@@ -300,6 +340,6 @@
 template "widget[@type='Slider']", mode="widget_defs" {
     param "hmi_element";
     labels("handle range");
-    optional_labels("value min max setpoint");
+    optional_labels("value min max setpoint up down");
     |,
 }
--- a/svghmi/widget_tooglebutton.ysl2	Thu Sep 17 11:30:22 2020 +0200
+++ b/svghmi/widget_tooglebutton.ysl2	Thu Sep 24 11:52:40 2020 +0200
@@ -10,37 +10,45 @@
         inactive_style = undefined;
 
         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.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);
+
+            //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.style.cssText;
-            this.inactive_style = this.inactive_elt.style.cssText;
+            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("onclick", "hmi_widgets['"+this.element_id+"'].on_click(evt)");
-            this.inactive_elt.setAttribute("style", this.inactive_style);
-            this.active_elt.setAttribute("style", "display:none");
         }
     }
     ||
@@ -48,6 +56,6 @@
 
 template "widget[@type='ToggleButton']", mode="widget_defs" {
     param "hmi_element";
-    labels("active inactive");
+    optional_labels("active inactive");
     |,
 }
--- a/tests/svghmi_v2/plc.xml	Thu Sep 17 11:30:22 2020 +0200
+++ b/tests/svghmi_v2/plc.xml	Thu Sep 24 11:52:40 2020 +0200
@@ -1,7 +1,7 @@
 <?xml version='1.0' encoding='utf-8'?>
 <project xmlns:ns1="http://www.plcopen.org/xml/tc6_0201" xmlns:xhtml="http://www.w3.org/1999/xhtml" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="http://www.plcopen.org/xml/tc6_0201">
   <fileHeader companyName="Unknown" productName="Unnamed" productVersion="1" creationDateTime="2019-08-06T14:23:42"/>
-  <contentHeader name="Unnamed" modificationDateTime="2020-09-15T14:59:06">
+  <contentHeader name="Unnamed" modificationDateTime="2020-09-23T16:29:40">
     <coordinateInfo>
       <fbd>
         <scaling x="5" y="5"/>
@@ -75,6 +75,11 @@
                 <INT/>
               </type>
             </variable>
+            <variable name="Speed">
+              <type>
+                <derived name="HMI_REAL"/>
+              </type>
+            </variable>
           </localVars>
         </interface>
         <body>
--- a/tests/svghmi_v2/svghmi_0@svghmi/svghmi.svg	Thu Sep 17 11:30:22 2020 +0200
+++ b/tests/svghmi_v2/svghmi_0@svghmi/svghmi.svg	Thu Sep 24 11:52:40 2020 +0200
@@ -110,8 +110,8 @@
      showgrid="false"
      units="px"
      inkscape:zoom="1.4142136"
-     inkscape:cx="462.89448"
-     inkscape:cy="318.79031"
+     inkscape:cx="660.12647"
+     inkscape:cy="334.93826"
      inkscape:window-width="2503"
      inkscape:window-height="1416"
      inkscape:window-x="57"
@@ -183,6 +183,52 @@
          y="-121.97556"
          style="text-align:center;text-anchor:middle;fill:#ff6600;stroke-width:0.26458332px"
          id="tspan102-1">000</tspan></text>
+    <g
+       id="g1093"
+       inkscape:label="up"
+       transform="translate(-1.4499385)">
+      <rect
+         y="-70.520416"
+         x="97.492126"
+         height="8.8867111"
+         width="12.254309"
+         id="rect1075"
+         style="opacity:0.29800002;fill:#de2cc9;fill-opacity:1;stroke:none;stroke-width:0.13229167" />
+      <text
+         id="text1079"
+         y="-64.627113"
+         x="99.550095"
+         style="font-style:normal;font-weight:normal;font-size:5.29166698px;line-height:125%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.13229167px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+         xml:space="preserve"><tspan
+           style="stroke-width:0.13229167px"
+           y="-64.627113"
+           x="99.550095"
+           id="tspan1077"
+           sodipodi:role="line">UP</tspan></text>
+    </g>
+    <g
+       id="g1088"
+       inkscape:label="down"
+       transform="translate(0.28063515)">
+      <rect
+         y="1.415176"
+         x="96.088959"
+         height="8.8867111"
+         width="11.599497"
+         id="rect1073"
+         style="opacity:0.29800002;fill:#de2cc9;fill-opacity:1;stroke:none;stroke-width:0.12294135" />
+      <text
+         id="text1083"
+         y="7.4020147"
+         x="97.772751"
+         style="font-style:normal;font-weight:normal;font-size:5.29166698px;line-height:125%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.13229167px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+         xml:space="preserve"><tspan
+           style="stroke-width:0.13229167px"
+           y="7.4020147"
+           x="97.772751"
+           id="tspan1081"
+           sodipodi:role="line">DN</tspan></text>
+    </g>
   </g>
   <g
      id="g4557"
@@ -1535,7 +1581,7 @@
   <g
      transform="translate(63.639613)"
      id="g4791-3"
-     inkscape:label="HMI:ToggleButton@/TOGGLE">
+     inkscape:label="HMI:Button@/TOGGLE">
     <rect
        inkscape:label="active"
        y="46.127251"
@@ -1553,4 +1599,40 @@
        id="rect4772-6"
        style="opacity:1;fill:#ff0015;fill-opacity:1;stroke:none" />
   </g>
+  <g
+     transform="translate(153.9447,-0.96668484)"
+     id="g479hgjk"
+     inkscape:label="HMI:Button@/TOGGLE">
+    <rect
+       inkscape:label="active"
+       y="46.127251"
+       x="906.51086"
+       height="44.547726"
+       width="45.254833"
+       id="rect47fuzkj"
+       style="opacity:1;fill:#00ff03;fill-opacity:1;stroke:none" />
+    <rect
+       inkscape:label="inactive"
+       y="46.127251"
+       x="906.51086"
+       height="44.547726"
+       width="45.254833"
+       id="rect477hjoj"
+       style="opacity:1;fill:#ff0015;fill-opacity:1;stroke:none" />
+  </g>
+  <image
+     y="128.18585"
+     x="899.05353"
+     id="fan_rotatte"
+     xlink:href="data:image/png;base64,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 pwU/G0JIJP1/qNlc/9VTTLcAAAAASUVORK5CYII= "
+     preserveAspectRatio="none"
+     height="294"
+     width="312"
+     inkscape:label="HMI:Animate@/SPEED">
+    <animateMotion
+       path="M 1060.6274,332 A 22.627417,23.688076 0 0 1 1038,355.68808 22.627417,23.688076 0 0 1 1015.3726,332 22.627417,23.688076 0 0 1 1038,308.31192 22.627417,23.688076 0 0 1 1060.6274,332 Z"
+       dur="0.5s"
+       rotate="auto"
+       repeatCount="indefinite" />
+  </image>
 </svg>