--- 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" {
@@ -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 name="type"> + <xsl:value-of select="local-name($item)"/> @@ -259,6 +262,8 @@
<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:when test="count($hmi_pages) > 1">
@@ -311,7 +316,7 @@
- <xsl:variable name="required_elements" select="//svg:defs/descendant-or-self::svg:* | func:required_elements($hmi_pages)/ancestor-or-self::svg:*"/>
+ <xsl:variable name="required_elements" select="//svg:defs/descendant-or-self::svg:* | 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: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> console.log("Back !");
<xsl:text> if(jump_history.length > 1){
<xsl:text> jump_history.pop();
@@ -897,8 +900,12 @@
+ <xsl:text> last_val: undefined, <xsl:text> dispatch: function(value) {
+ <xsl:text> this.last_val = value; <xsl:if test="$have_value">
<xsl:text> this.value_elt.textContent = String(value);
@@ -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> evt => 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:for-each select="$hmi_element/*[regexp:test(@inkscape:label,'^[=+\-].+')]">
<xsl:text> id("</xsl:text>
<xsl:value-of select="@id"/>
- <xsl:text>").addEventListener(
- <xsl:text> evt => {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:if test="$have_value">
- <xsl:text> this.value_elt.textContent = String(new_val);
+ <xsl:text> on_op_click: function(opstr) { + <xsl:text> let new_val = change_hmi_value(this.indexes[0], opstr); + <xsl:if test="$have_value"> + <xsl:text> this.value_elt.textContent = String(new_val); + <xsl:text> on_edit_click: function(opstr) { + <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> edit_callback: function(new_val) { + <xsl:text> apply_hmi_value(this.indexes[0], opstr); + <xsl:if test="$have_value"> + <xsl:text> this.value_elt.textContent = String(new_val); <xsl:template name="jump_widget_activity">
<xsl:param name="hmi_element"/>
@@ -987,8 +1014,6 @@
<xsl:text> this.disabled = !Number(value);
- <xsl:text> console.log("disbled",value);
<xsl:text> this.update();
@@ -1161,6 +1186,12 @@
+ <xsl:template mode="widget_defs" match="widget[@type='Keypad']"> + <xsl:text> init: function() { <xsl:template mode="widget_defs" match="widget[@type='Meter']">
<xsl:param name="hmi_element"/>
<xsl:text> frequency: 10,
@@ -1288,6 +1319,7 @@
<xsl:text>Made with SVGHMI. https://beremiz.org</xsl:text>
+ <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">
<body style="margin:0;overflow:hidden;">
@@ -1367,6 +1399,26 @@
<xsl:apply-templates mode="page_desc" select="$hmi_pages"/>
+ <xsl:text>var keypads = { + <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>var default_page = "</xsl:text>
@@ -1859,6 +1911,20 @@
+ <xsl:text>function apply_hmi_value(index, new_val) { + <xsl:text> let old_val = cache[index] + <xsl:text> if(new_val != undefined && old_val != new_val) + <xsl:text> send_hmi_value(index, new_val); + <xsl:text> return new_val; <xsl:text>function change_hmi_value(index, opstr) {
<xsl:text> let op = opstr[0];
@@ -2189,8 +2255,6 @@
<xsl:text> requestHMIAnimation();
- <xsl:text> console.log(opstr, new_item_offset);
@@ -2301,5 +2365,47 @@
+ <xsl:text>var edit_callback; + <xsl:text>function edit_value(path, valuetype, callback, initial) { + <xsl:text> let [keypadid, xcoord, ycoord] = keypads[valuetype]; + <xsl:text> console.log('XXX TODO : Edit value', path, valuetype, callback, initial, keypadid); + <xsl:text> edit_callback = callback; + <xsl:text> let [element, parent] = detachable_elements[keypadid]; + <xsl:text> tmpgrp = document.createElement("g"); + <xsl:text> tmpgrpattr = document.createAttribute("transform"); + <xsl:text> let [xdest,ydest] = page_desc[current_visible_page].bbox; + <xsl:text> tmpgrpattr.value = "translate("+String(xdest-xcoord)+","+String(ydest-ycoord)+")"; + <xsl:text> tmpgrp.setAttributeNode(tmpgrpattr); + <xsl:text> tmpgrp.appendChild(element); + <xsl:text> parent.appendChild(tmpgrp); --- 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";
+ foreach "$keypads_descs"{ + const "keypad_id","@id"; + 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 @@
const "item", "$indexed_hmitree/*[@hmipath = $path]";
+ 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 @@
+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); function change_hmi_value(index, opstr) {
let given_val = opstr.slice(1);
@@ -404,7 +411,6 @@
need_cache_apply.push(this);
jumps_need_update = true;
- console.log(opstr, new_item_offset);
@@ -460,3 +466,24 @@
alert("Connection closed. code:"+evt.code+" reason:"+evt.reason+" wasClean:"+evt.wasClean+".");
+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 @@
| on_click: function(evt) {
- | console.log("Back !");
| if(jump_history.length > 1){
| 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 @@
| dispatch: function(value) {
+ | this.last_val = value; | this.value_elt.textContent = String(value);
@@ -19,19 +19,28 @@
const "edit_elt_id","$hmi_element/*[@inkscape:label='edit'][1]/@id";
- | id("«$edit_elt_id»").addEventListener(
- | 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(
- | evt => {let new_val = change_hmi_value(this.indexes[0], "«func:escape_quotes(@inkscape:label)»");
- | 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); + | 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); + | this.value_elt.textContent = String(new_val); + /* TODO gray out value until refreshed */