merge svghmi
authorEdouard Tisserant <edouard.tisserant@gmail.com>
Fri, 03 Apr 2020 08:13:47 +0200
branchsvghmi
changeset 2914 99ba78619ffa
parent 2909 0519fdce9a59 (current diff)
parent 2913 ac4328e69079 (diff)
child 2915 48c9a5f6ce38
merge
--- a/svghmi/detachable_pages.ysl2	Wed Apr 01 18:10:45 2020 +0200
+++ b/svghmi/detachable_pages.ysl2	Fri Apr 03 08:13:47 2020 +0200
@@ -7,6 +7,9 @@
 const "hmi_pages_descs", "$parsed_widgets/widget[@type = 'Page']";
 const "hmi_pages", "$hmi_elements[@id = $hmi_pages_descs/@id]";
 
+const "keypads_descs", "$parsed_widgets/widget[@type = 'Keypad']";
+const "keypads", "$hmi_elements[@id = $keypads_descs/@id]";
+
 const "default_page" choose {
     when "count($hmi_pages) > 1" {
         choose {
@@ -58,7 +61,7 @@
 
 const "required_elements",
     """//svg:defs/descendant-or-self::svg:*
-       | func:required_elements($hmi_pages)/ancestor-or-self::svg:*""";
+       | func:required_elements($hmi_pages | $keypads)/ancestor-or-self::svg:*""";
 
 const "discardable_elements", "//svg:*[not(@id = $required_elements/@id)]";
 
@@ -88,7 +91,7 @@
 }
 
 // Avoid nested detachables
-const "_detachable_elements", "func:detachable_elements($hmi_pages)";
+const "_detachable_elements", "func:detachable_elements($hmi_pages | $keypads)";
 const "detachable_elements", "$_detachable_elements[not(ancestor::*/@id = $_detachable_elements/@id)]";
 
 const "forEach_widgets_ids", "$parsed_widgets/widget[@type = 'ForEach']/@id";
--- a/svghmi/gen_index_xhtml.xslt	Wed Apr 01 18:10:45 2020 +0200
+++ b/svghmi/gen_index_xhtml.xslt	Fri Apr 03 08:13:47 2020 +0200
@@ -127,6 +127,9 @@
                 <xsl:attribute name="index">
                   <xsl:value-of select="$item/@index"/>
                 </xsl:attribute>
+                <xsl:attribute name="type">
+                  <xsl:value-of select="local-name($item)"/>
+                </xsl:attribute>
               </xsl:if>
             </path>
           </xsl:if>
@@ -259,6 +262,8 @@
   </func:function>
   <xsl:variable name="hmi_pages_descs" select="$parsed_widgets/widget[@type = 'Page']"/>
   <xsl:variable name="hmi_pages" select="$hmi_elements[@id = $hmi_pages_descs/@id]"/>
+  <xsl:variable name="keypads_descs" select="$parsed_widgets/widget[@type = 'Keypad']"/>
+  <xsl:variable name="keypads" select="$hmi_elements[@id = $keypads_descs/@id]"/>
   <xsl:variable name="default_page">
     <xsl:choose>
       <xsl:when test="count($hmi_pages) &gt; 1">
@@ -311,7 +316,7 @@
       </xsl:otherwise>
     </xsl:choose>
   </func:function>
-  <xsl:variable name="required_elements" select="//svg:defs/descendant-or-self::svg:*&#10;       | func:required_elements($hmi_pages)/ancestor-or-self::svg:*"/>
+  <xsl:variable name="required_elements" select="//svg:defs/descendant-or-self::svg:*&#10;       | func:required_elements($hmi_pages | $keypads)/ancestor-or-self::svg:*"/>
   <xsl:variable name="discardable_elements" select="//svg:*[not(@id = $required_elements/@id)]"/>
   <func:function name="func:sumarized_elements">
     <xsl:param name="elements"/>
@@ -331,7 +336,7 @@
       </xsl:otherwise>
     </xsl:choose>
   </func:function>
-  <xsl:variable name="_detachable_elements" select="func:detachable_elements($hmi_pages)"/>
+  <xsl:variable name="_detachable_elements" select="func:detachable_elements($hmi_pages | $keypads)"/>
   <xsl:variable name="detachable_elements" select="$_detachable_elements[not(ancestor::*/@id = $_detachable_elements/@id)]"/>
   <xsl:variable name="forEach_widgets_ids" select="$parsed_widgets/widget[@type = 'ForEach']/@id"/>
   <xsl:variable name="forEach_widgets" select="$hmi_elements[@id = $forEach_widgets_ids]"/>
@@ -726,8 +731,6 @@
     <xsl:param name="hmi_element"/>
     <xsl:text>    on_click: function(evt) {
 </xsl:text>
-    <xsl:text>        console.log("Back !");
-</xsl:text>
     <xsl:text>        if(jump_history.length &gt; 1){
 </xsl:text>
     <xsl:text>           jump_history.pop();
@@ -897,8 +900,12 @@
       <xsl:text>    frequency: 5,
 </xsl:text>
     </xsl:if>
+    <xsl:text>    last_val: undefined,
+</xsl:text>
     <xsl:text>    dispatch: function(value) {
 </xsl:text>
+    <xsl:text>        this.last_val = value;
+</xsl:text>
     <xsl:if test="$have_value">
       <xsl:text>        this.value_elt.textContent = String(value);
 </xsl:text>
@@ -911,33 +918,53 @@
     <xsl:if test="$edit_elt_id">
       <xsl:text>        id("</xsl:text>
       <xsl:value-of select="$edit_elt_id"/>
-      <xsl:text>").addEventListener(
-</xsl:text>
-      <xsl:text>            "click", 
-</xsl:text>
-      <xsl:text>            evt =&gt; alert('XXX TODO : Edit value'));
+      <xsl:text>").setAttribute("onclick", "hmi_widgets['</xsl:text>
+      <xsl:value-of select="$hmi_element/@id"/>
+      <xsl:text>'].on_edit_click()");
 </xsl:text>
     </xsl:if>
     <xsl:for-each select="$hmi_element/*[regexp:test(@inkscape:label,'^[=+\-].+')]">
       <xsl:text>        id("</xsl:text>
       <xsl:value-of select="@id"/>
-      <xsl:text>").addEventListener(
-</xsl:text>
-      <xsl:text>            "click", 
-</xsl:text>
-      <xsl:text>            evt =&gt; {let new_val = change_hmi_value(this.indexes[0], "</xsl:text>
+      <xsl:text>").setAttribute("onclick", "hmi_widgets['</xsl:text>
+      <xsl:value-of select="$hmi_element/@id"/>
+      <xsl:text>'].on_op_click('</xsl:text>
       <xsl:value-of select="func:escape_quotes(@inkscape:label)"/>
-      <xsl:text>");
-</xsl:text>
-      <xsl:if test="$have_value">
-        <xsl:text>                    this.value_elt.textContent = String(new_val);
-</xsl:text>
-      </xsl:if>
-      <xsl:text>                   });
+      <xsl:text>')");
 </xsl:text>
     </xsl:for-each>
     <xsl:text>    },
 </xsl:text>
+    <xsl:text>    on_op_click: function(opstr) {
+</xsl:text>
+    <xsl:text>        let new_val = change_hmi_value(this.indexes[0], opstr);
+</xsl:text>
+    <xsl:if test="$have_value">
+      <xsl:text>        this.value_elt.textContent = String(new_val);
+</xsl:text>
+    </xsl:if>
+    <xsl:text>    },
+</xsl:text>
+    <xsl:text>    on_edit_click: function(opstr) {
+</xsl:text>
+    <xsl:text>        edit_value("</xsl:text>
+    <xsl:value-of select="path/@value"/>
+    <xsl:text>", "</xsl:text>
+    <xsl:value-of select="path/@type"/>
+    <xsl:text>", this.edit_callback, this.last_val);
+</xsl:text>
+    <xsl:text>    },
+</xsl:text>
+    <xsl:text>    edit_callback: function(new_val) {
+</xsl:text>
+    <xsl:text>        apply_hmi_value(this.indexes[0], opstr);
+</xsl:text>
+    <xsl:if test="$have_value">
+      <xsl:text>        this.value_elt.textContent = String(new_val);
+</xsl:text>
+    </xsl:if>
+    <xsl:text>    },
+</xsl:text>
   </xsl:template>
   <xsl:template name="jump_widget_activity">
     <xsl:param name="hmi_element"/>
@@ -987,8 +1014,6 @@
 </xsl:text>
         <xsl:text>        this.disabled = !Number(value);
 </xsl:text>
-        <xsl:text>        console.log("disbled",value);
-</xsl:text>
         <xsl:text>        this.update();
 </xsl:text>
         <xsl:text>    },
@@ -1161,6 +1186,12 @@
       </xsl:if>
     </xsl:if>
   </xsl:template>
+  <xsl:template mode="widget_defs" match="widget[@type='Keypad']">
+    <xsl:text>    init: function() {
+</xsl:text>
+    <xsl:text>    },
+</xsl:text>
+  </xsl:template>
   <xsl:template mode="widget_defs" match="widget[@type='Meter']">
     <xsl:param name="hmi_element"/>
     <xsl:text>    frequency: 10,
@@ -1288,6 +1319,7 @@
     <xsl:comment>
       <xsl:text>Made with SVGHMI. https://beremiz.org</xsl:text>
     </xsl:comment>
+    <xsl:apply-templates mode="debug_as_comment" select="document('')/*/reflect:*"/>
     <html xmlns:svg="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns="http://www.w3.org/1999/xhtml">
       <head/>
       <body style="margin:0;overflow:hidden;">
@@ -1367,6 +1399,26 @@
     <xsl:apply-templates mode="page_desc" select="$hmi_pages"/>
     <xsl:text>}
 </xsl:text>
+    <xsl:text>var keypads = {
+</xsl:text>
+    <xsl:for-each select="$keypads_descs">
+      <xsl:variable name="keypad_id" select="@id"/>
+      <xsl:for-each select="arg">
+        <xsl:variable name="g" select="$geometry[@Id = $keypad_id]"/>
+        <xsl:text>    "</xsl:text>
+        <xsl:value-of select="@value"/>
+        <xsl:text>":["</xsl:text>
+        <xsl:value-of select="$keypad_id"/>
+        <xsl:text>", </xsl:text>
+        <xsl:value-of select="$g/@x"/>
+        <xsl:text>, </xsl:text>
+        <xsl:value-of select="$g/@y"/>
+        <xsl:text>],
+</xsl:text>
+      </xsl:for-each>
+    </xsl:for-each>
+    <xsl:text>}
+</xsl:text>
     <xsl:text>
 </xsl:text>
     <xsl:text>var default_page = "</xsl:text>
@@ -1859,6 +1911,20 @@
 </xsl:text>
     <xsl:text>
 </xsl:text>
+    <xsl:text>function apply_hmi_value(index, new_val) {
+</xsl:text>
+    <xsl:text>    let old_val = cache[index]
+</xsl:text>
+    <xsl:text>    if(new_val != undefined &amp;&amp; old_val != new_val)
+</xsl:text>
+    <xsl:text>        send_hmi_value(index, new_val);
+</xsl:text>
+    <xsl:text>    return new_val;
+</xsl:text>
+    <xsl:text>}
+</xsl:text>
+    <xsl:text>
+</xsl:text>
     <xsl:text>function change_hmi_value(index, opstr) {
 </xsl:text>
     <xsl:text>    let op = opstr[0];
@@ -2189,8 +2255,6 @@
 </xsl:text>
     <xsl:text>    requestHMIAnimation();
 </xsl:text>
-    <xsl:text>    console.log(opstr, new_item_offset);
-</xsl:text>
     <xsl:text>}
 </xsl:text>
     <xsl:text>
@@ -2301,5 +2365,47 @@
 </xsl:text>
     <xsl:text>};
 </xsl:text>
+    <xsl:text>
+</xsl:text>
+    <xsl:text>var edit_callback;
+</xsl:text>
+    <xsl:text>function edit_value(path, valuetype, callback, initial) {
+</xsl:text>
+    <xsl:text>
+</xsl:text>
+    <xsl:text>    let [keypadid, xcoord, ycoord] = keypads[valuetype];
+</xsl:text>
+    <xsl:text>    console.log('XXX TODO : Edit value', path, valuetype, callback, initial, keypadid);
+</xsl:text>
+    <xsl:text>    edit_callback = callback;
+</xsl:text>
+    <xsl:text>
+</xsl:text>
+    <xsl:text>    let [element, parent] = detachable_elements[keypadid];
+</xsl:text>
+    <xsl:text>    tmpgrp = document.createElement("g");
+</xsl:text>
+    <xsl:text>    tmpgrpattr = document.createAttribute("transform");
+</xsl:text>
+    <xsl:text>
+</xsl:text>
+    <xsl:text>    let [xdest,ydest] = page_desc[current_visible_page].bbox;
+</xsl:text>
+    <xsl:text>    tmpgrpattr.value = "translate("+String(xdest-xcoord)+","+String(ydest-ycoord)+")";
+</xsl:text>
+    <xsl:text>    tmpgrp.setAttributeNode(tmpgrpattr);
+</xsl:text>
+    <xsl:text>
+</xsl:text>
+    <xsl:text>    tmpgrp.appendChild(element);
+</xsl:text>
+    <xsl:text>    parent.appendChild(tmpgrp);
+</xsl:text>
+    <xsl:text>
+</xsl:text>
+    <xsl:text>};
+</xsl:text>
+    <xsl:text>
+</xsl:text>
   </xsl:template>
 </xsl:stylesheet>
--- a/svghmi/gen_index_xhtml.ysl2	Wed Apr 01 18:10:45 2020 +0200
+++ b/svghmi/gen_index_xhtml.ysl2	Fri Apr 03 08:13:47 2020 +0200
@@ -109,6 +109,17 @@
         apply "$hmi_pages", mode="page_desc";
         | }
 
+        | var keypads = {
+        foreach "$keypads_descs"{
+            const "keypad_id","@id";
+            foreach "arg"{
+                const "g", "$geometry[@Id = $keypad_id]"; 
+        |     "«@value»":["«$keypad_id»", «$g/@x», «$g/@y»],
+            }
+        }
+        | }
+
+
         |
         | var default_page = "«$default_page»";
         | var svg_root = id("«/svg:svg/@id»");
--- a/svghmi/hmi_tree.ysl2	Wed Apr 01 18:10:45 2020 +0200
+++ b/svghmi/hmi_tree.ysl2	Fri Apr 03 08:13:47 2020 +0200
@@ -93,8 +93,10 @@
                 attrib "value" > «.»
                 const "path", ".";
                 const "item", "$indexed_hmitree/*[@hmipath = $path]";
-                if "count($item) = 1"
+                if "count($item) = 1" {
                     attrib "index" > «$item/@index»
+                    attrib "type" > «local-name($item)»
+                }
             }
         }
     }
--- a/svghmi/svghmi.js	Wed Apr 01 18:10:45 2020 +0200
+++ b/svghmi/svghmi.js	Fri Apr 03 08:13:47 2020 +0200
@@ -239,6 +239,13 @@
     cache[index] = value;
 };
 
+function apply_hmi_value(index, new_val) {
+    let old_val = cache[index]
+    if(new_val != undefined && old_val != new_val)
+        send_hmi_value(index, new_val);
+    return new_val;
+}
+
 function change_hmi_value(index, opstr) {
     let op = opstr[0];
     let given_val = opstr.slice(1);
@@ -404,7 +411,6 @@
     need_cache_apply.push(this);
     jumps_need_update = true;
     requestHMIAnimation();
-    console.log(opstr, new_item_offset);
 }
 
 
@@ -460,3 +466,24 @@
     alert("Connection closed. code:"+evt.code+" reason:"+evt.reason+" wasClean:"+evt.wasClean+".");
 
 };
+
+var edit_callback;
+function edit_value(path, valuetype, callback, initial) {
+
+    let [keypadid, xcoord, ycoord] = keypads[valuetype];
+    console.log('XXX TODO : Edit value', path, valuetype, callback, initial, keypadid);
+    edit_callback = callback;
+
+    let [element, parent] = detachable_elements[keypadid];
+    tmpgrp = document.createElement("g");
+    tmpgrpattr = document.createAttribute("transform");
+
+    let [xdest,ydest] = page_desc[current_visible_page].bbox;
+    tmpgrpattr.value = "translate("+String(xdest-xcoord)+","+String(ydest-ycoord)+")";
+    tmpgrp.setAttributeNode(tmpgrpattr);
+
+    tmpgrp.appendChild(element);
+    parent.appendChild(tmpgrp);
+
+};
+
--- a/svghmi/widget_back.ysl2	Wed Apr 01 18:10:45 2020 +0200
+++ b/svghmi/widget_back.ysl2	Fri Apr 03 08:13:47 2020 +0200
@@ -4,7 +4,6 @@
     param "hmi_element";
 
     |     on_click: function(evt) {
-    |         console.log("Back !");
     |         if(jump_history.length > 1){
     |            jump_history.pop();
     |            let [page_name, index] = jump_history.pop();
--- a/svghmi/widget_input.ysl2	Wed Apr 01 18:10:45 2020 +0200
+++ b/svghmi/widget_input.ysl2	Fri Apr 03 08:13:47 2020 +0200
@@ -9,9 +9,9 @@
     value "$value_elt";
     if "$have_value"
     |     frequency: 5,
-
+    |     last_val: undefined,
     |     dispatch: function(value) {
-
+    |         this.last_val = value;
     if "$have_value"
     |         this.value_elt.textContent = String(value);
 
@@ -19,19 +19,28 @@
     const "edit_elt_id","$hmi_element/*[@inkscape:label='edit'][1]/@id";
     |     init: function() {
     if "$edit_elt_id" {
-    |         id("«$edit_elt_id»").addEventListener(
-    |             "click", 
-    |             evt => alert('XXX TODO : Edit value'));
+    |         id("«$edit_elt_id»").setAttribute("onclick", "hmi_widgets['«$hmi_element/@id»'].on_edit_click()");
     }
     foreach "$hmi_element/*[regexp:test(@inkscape:label,'^[=+\-].+')]" {
-    |         id("«@id»").addEventListener(
-    |             "click", 
-    |             evt => {let new_val = change_hmi_value(this.indexes[0], "«func:escape_quotes(@inkscape:label)»");
-        if "$have_value"{
-    |                     this.value_elt.textContent = String(new_val);
-        }
-    |                    });
-                          /* TODO gray out value until refreshed */
+    |         id("«@id»").setAttribute("onclick", "hmi_widgets['«$hmi_element/@id»'].on_op_click('«func:escape_quotes(@inkscape:label)»')");
     }
     |     },
+    |     on_op_click: function(opstr) {
+    |         let new_val = change_hmi_value(this.indexes[0], opstr);
+        if "$have_value"{
+    |         this.value_elt.textContent = String(new_val);
+              /* TODO gray out value until refreshed */
+        }
+    |     },
+    |     on_edit_click: function(opstr) {
+    |         edit_value("«path/@value»", "«path/@type»", this.edit_callback, this.last_val);
+    |     },
+
+    |     edit_callback: function(new_val) {
+    |         apply_hmi_value(this.indexes[0], opstr);
+        if "$have_value"{
+    |         this.value_elt.textContent = String(new_val);
+              /* TODO gray out value until refreshed */
+        }
+    |     },
 }
--- a/svghmi/widget_jump.ysl2	Wed Apr 01 18:10:45 2020 +0200
+++ b/svghmi/widget_jump.ysl2	Fri Apr 03 08:13:47 2020 +0200
@@ -25,7 +25,6 @@
     |     frequency: 2,
     |     dispatch: function(value) {
     |         this.disabled = !Number(value);
-    |         console.log("disbled",value);
     |         this.update();
     |     },
     }
--- a/svghmi/widget_keypad.ysl2	Wed Apr 01 18:10:45 2020 +0200
+++ b/svghmi/widget_keypad.ysl2	Fri Apr 03 08:13:47 2020 +0200
@@ -1,4 +1,6 @@
 // widget_keypad.ysl2
 
 template "widget[@type='Keypad']", mode="widget_defs" {
+    |     init: function() {
+    |     },
 }