SVGHMI - added simple Meter widget. svghmi
authorEdouard Tisserant
Mon, 28 Oct 2019 10:30:20 +0100
branchsvghmi
changeset 2807 7fa21b3b5f9f
parent 2806 7d0e81cdedb0
child 2808 dc78ffa5253d
SVGHMI - added simple Meter widget.
svghmi/gen_index_xhtml.xslt
svghmi/gen_index_xhtml.ysl2
tests/svghmi/svghmi_0@svghmi/svghmi.svg
--- a/svghmi/gen_index_xhtml.xslt	Sun Oct 27 22:28:51 2019 +0100
+++ b/svghmi/gen_index_xhtml.xslt	Mon Oct 28 10:30:20 2019 +0100
@@ -850,8 +850,51 @@
 </xsl:text>
   </xsl:template>
   <xsl:template mode="widget_defs" match="widget[@type='Meter']">
+    <xsl:param name="hmi_element"/>
     <xsl:text>frequency: 10,
 </xsl:text>
+    <xsl:for-each select="str:split('value min max needle range')">
+      <xsl:variable name="name" select="."/>
+      <xsl:variable name="elt_id" select="$hmi_element//*[@inkscape:label=$name][1]/@id"/>
+      <xsl:if test="not($elt_id)">
+        <xsl:message terminate="yes">
+          <xsl:text>Meter widget must have a </xsl:text>
+          <xsl:value-of select="$name"/>
+          <xsl:text> element</xsl:text>
+        </xsl:message>
+      </xsl:if>
+      <xsl:value-of select="$name"/>
+      <xsl:text>_elt: document.getElementById("</xsl:text>
+      <xsl:value-of select="$elt_id"/>
+      <xsl:text>"),
+</xsl:text>
+    </xsl:for-each>
+    <xsl:text>dispatch: function(value) {
+</xsl:text>
+    <xsl:text>    this.value_elt.textContent = String(value);
+</xsl:text>
+    <xsl:text>    let [min,max,totallength] = this.range;
+</xsl:text>
+    <xsl:text>    let length = Math.max(0,Math.min(totallength,(Number(value)-min)*totallength/(max-min)));
+</xsl:text>
+    <xsl:text>    let tip = this.range_elt.getPointAtLength(length);
+</xsl:text>
+    <xsl:text>    this.needle_elt.setAttribute('d', "M "+this.origin.x+","+this.origin.y+" "+tip.x+","+tip.y);
+</xsl:text>
+    <xsl:text>},
+</xsl:text>
+    <xsl:text>origin: undefined,
+</xsl:text>
+    <xsl:text>range: undefined,
+</xsl:text>
+    <xsl:text>init: function() {
+</xsl:text>
+    <xsl:text>    this.range = [Number(this.min_elt.textContent), Number(this.max_elt.textContent), this.range_elt.getTotalLength()]
+</xsl:text>
+    <xsl:text>    this.origin = this.needle_elt.getPointAtLength(0);
+</xsl:text>
+    <xsl:text>},
+</xsl:text>
   </xsl:template>
   <xsl:template mode="widget_defs" match="widget[@type='Input']">
     <xsl:param name="hmi_element"/>
--- a/svghmi/gen_index_xhtml.ysl2	Sun Oct 27 22:28:51 2019 +0100
+++ b/svghmi/gen_index_xhtml.ysl2	Mon Oct 28 10:30:20 2019 +0100
@@ -324,8 +324,29 @@
 
     }
     template "widget[@type='Meter']", mode="widget_defs" {
+        param "hmi_element";
         | frequency: 10,
-    }
+        foreach "str:split('value min max needle range')" {
+            const "name",".";
+            const "elt_id","$hmi_element//*[@inkscape:label=$name][1]/@id";
+            if "not($elt_id)" error > Meter widget must have a «$name» element
+            | «$name»_elt: document.getElementById("«$elt_id»"),
+        }
+        | dispatch: function(value) {
+        |     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() {
+        |     this.range = [Number(this.min_elt.textContent), Number(this.max_elt.textContent), this.range_elt.getTotalLength()]
+        |     this.origin = this.needle_elt.getPointAtLength(0);
+        | },
+    }
+
     template "widget[@type='Input']", mode="widget_defs" {
         param "hmi_element";
         | frequency: 5,
--- a/tests/svghmi/svghmi_0@svghmi/svghmi.svg	Sun Oct 27 22:28:51 2019 +0100
+++ b/tests/svghmi/svghmi_0@svghmi/svghmi.svg	Mon Oct 28 10:30:20 2019 +0100
@@ -80,8 +80,8 @@
      showgrid="false"
      units="px"
      inkscape:zoom="0.84375"
-     inkscape:cx="-391.07334"
-     inkscape:cy="346.23071"
+     inkscape:cx="197.3711"
+     inkscape:cy="361.63812"
      inkscape:window-width="1600"
      inkscape:window-height="886"
      inkscape:window-x="0"
@@ -323,7 +323,7 @@
        sodipodi:nodetypes="cc"
        inkscape:label="needle" />
     <text
-       inkscape:label="minimum"
+       inkscape:label="min"
        id="text4505"
        y="4.9187088"
        x="49.132977"
@@ -335,7 +335,7 @@
          id="tspan4503"
          sodipodi:role="line">0</tspan></text>
     <text
-       inkscape:label="maximum"
+       inkscape:label="max"
        xml:space="preserve"
        style="font-style:normal;font-weight:normal;font-size:10.58333302px;line-height:125%;font-family:sans-serif;text-align:center;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#ff6600;fill-opacity:1;stroke:none;stroke-width:0.26458332px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
        x="127.48073"
@@ -345,7 +345,7 @@
          id="tspan4507"
          x="127.48073"
          y="-78.144218"
-         style="text-align:center;text-anchor:middle;fill:#ff6600;stroke-width:0.26458332px">10</tspan></text>
+         style="text-align:center;text-anchor:middle;fill:#ff6600;stroke-width:0.26458332px">10000</tspan></text>
     <text
        inkscape:label="value"
        id="text4517"