--- a/svghmi/detachable_pages.ysl2 Thu Mar 26 14:21:52 2020 +0100
+++ b/svghmi/detachable_pages.ysl2 Fri Mar 27 14:25:24 2020 +0100
@@ -131,11 +131,20 @@
| hmi_widgets["«@id»"]`if "position()!=last()" > ,`
+ foreach "$parsed_widgets/widget[@id = $all_page_widgets/@id and @type='Jump']" { + const "opts" call "jump_widget_activity" with "hmi_element", "$hmi_elements[@id=$_id]"; + if "string-length($opts)>0" + | hmi_widgets["«@id»"]`if "position()!=last()" > ,` | required_detachables: {
foreach "$required_detachables" {
| "«@id»": detachable_elements["«@id»"]`if "position()!=last()" > ,`
+ /* TODO generate some code for init() instead */ apply "$parsed_widgets/widget[@id = $all_page_widgets/@id]", mode="per_page_widget_template"{
with "page_desc", "$desc";
--- a/svghmi/gen_index_xhtml.xslt Thu Mar 26 14:21:52 2020 +0100
+++ b/svghmi/gen_index_xhtml.xslt Fri Mar 27 14:25:24 2020 +0100
@@ -404,6 +404,28 @@
+ <xsl:for-each select="$parsed_widgets/widget[@id = $all_page_widgets/@id and @type='Jump']"> + <xsl:variable name="_id" select="@id"/> + <xsl:variable name="opts"> + <xsl:call-template name="jump_widget_activity"> + <xsl:with-param name="hmi_element" select="$hmi_elements[@id=$_id]"/> + <xsl:if test="string-length($opts)>0"> + <xsl:text> hmi_widgets["</xsl:text> + <xsl:value-of select="@id"/> + <xsl:text>"]</xsl:text> + <xsl:if test="position()!=last()"> <xsl:text> required_detachables: {
<xsl:for-each select="$required_detachables">
@@ -911,8 +933,25 @@
+ <xsl:template name="jump_widget_activity"> + <xsl:param name="hmi_element"/> + <xsl:call-template name="defs_by_labels"> + <xsl:with-param name="hmi_element" select="$hmi_element"/> + <xsl:with-param name="labels"> + <xsl:text>active inactive</xsl:text> + <xsl:with-param name="mandatory" select="'no'"/> <xsl:template mode="widget_defs" match="widget[@type='Jump']">
<xsl:param name="hmi_element"/>
+ <xsl:variable name="opts"> + <xsl:call-template name="jump_widget_activity"> + <xsl:with-param name="hmi_element" select="$hmi_element"/> + <xsl:variable name="have_opt" select="string-length($opts)>0"/> + <xsl:value-of select="$opts"/> <xsl:text> on_click: function(evt) {
<xsl:text> const index = this.indexes.length > 0 ? this.indexes[0] + this.offset : undefined;
@@ -923,12 +962,54 @@
+ <xsl:if test="$have_opt"> + <xsl:text> notify_page_change: function(page_name, index){ + <xsl:text> const ref_index = this.indexes.length > 0 ? this.indexes[0] + this.offset : undefined; + <xsl:text> const ref_name = this.args[0]; + <xsl:text> if((ref_name == undefined || ref_name == page_name) && index == ref_index) { + <xsl:text> console.log("active", ref_name, ref_index, page_name, index); + <xsl:text> /* show active */ + <xsl:text> this.active_elt.setAttribute("style", this.active_elt_style); + <xsl:text> /* hide inactive */ + <xsl:text> this.inactive_elt.setAttribute("style", "display:none"); + <xsl:text> console.log("inactive",ref_name, ref_index, page_name, index); + <xsl:text> /* show inactive */ + <xsl:text> this.inactive_elt.setAttribute("style", this.inactive_elt_style); + <xsl:text> /* hide active */ + <xsl:text> this.active_elt.setAttribute("style", "display:none"); <xsl:text> init: function() {
<xsl:text> this.element.setAttribute("onclick", "hmi_widgets['</xsl:text>
<xsl:value-of select="$hmi_element/@id"/>
<xsl:text>'].on_click(evt)");
+ <xsl:if test="$have_opt"> + <xsl:text> this.active_elt_style = this.active_elt.getAttribute("style"); + <xsl:text> this.inactive_elt_style = this.inactive_elt.getAttribute("style"); @@ -1224,6 +1305,8 @@
<xsl:text>var need_cache_apply = [];
+ <xsl:text>var jumps_need_update = false; <xsl:text>var jump_history = [[default_page, undefined]];
@@ -1404,6 +1487,10 @@
+ <xsl:text> if(jumps_need_update) update_jumps(); <xsl:text> apply_updates();
<xsl:text> requestAnimationFrameID = null;
@@ -1738,6 +1825,8 @@
<xsl:text>var current_subscribed_page;
+ <xsl:text>var current_page_index; <xsl:text>function prepare_svg() {
@@ -1774,7 +1863,71 @@
- <xsl:text> return switch_subscribed_page(page_name, page_index);
+ <xsl:text> let old_desc = page_desc[current_subscribed_page]; + <xsl:text> let new_desc = page_desc[page_name]; + <xsl:text> if(new_desc == undefined){ + <xsl:text> /* TODO LOG ERROR */ + <xsl:text> return false; + <xsl:text> if(page_index == undefined){ + <xsl:text> page_index = new_desc.page_index; + <xsl:text> if(old_desc){ + <xsl:text> old_desc.absolute_widgets.map(w=>w.unsub()); + <xsl:text> old_desc.relative_widgets.map(w=>w.unsub()); + <xsl:text> new_desc.absolute_widgets.map(w=>w.sub()); + <xsl:text> var new_offset = page_index == undefined ? 0 : page_index - new_desc.page_index; + <xsl:text> new_desc.relative_widgets.map(w=>w.sub(new_offset)); + <xsl:text> update_subscriptions(); + <xsl:text> current_subscribed_page = page_name; + <xsl:text> current_page_index = page_index; + <xsl:text> jumps_need_update = true; + <xsl:text> requestHMIAnimation(); + <xsl:text> jump_history.push([page_name, page_index]); + <xsl:text> return true; @@ -1946,6 +2099,8 @@
<xsl:text> need_cache_apply.push(this);
+ <xsl:text> jumps_need_update = true; <xsl:text> requestHMIAnimation();
<xsl:text> console.log(opstr, new_item_offset);
@@ -1954,68 +2109,6 @@
- <xsl:text>function switch_subscribed_page(page_name, page_index) {
- <xsl:text> let old_desc = page_desc[current_subscribed_page];
- <xsl:text> let new_desc = page_desc[page_name];
- <xsl:text> if(new_desc == undefined){
- <xsl:text> /* TODO LOG ERROR */
- <xsl:text> return false;
- <xsl:text> if(page_index == undefined){
- <xsl:text> page_index = new_desc.page_index;
- <xsl:text> if(old_desc){
- <xsl:text> old_desc.absolute_widgets.map(w=>w.unsub());
- <xsl:text> old_desc.relative_widgets.map(w=>w.unsub());
- <xsl:text> new_desc.absolute_widgets.map(w=>w.sub());
- <xsl:text> var new_offset = page_index == undefined ? 0 : page_index - new_desc.page_index;
- <xsl:text> new_desc.relative_widgets.map(w=>w.sub(new_offset));
- <xsl:text> update_subscriptions();
- <xsl:text> current_subscribed_page = page_name;
- <xsl:text> requestHMIAnimation();
- <xsl:text> jump_history.push([page_name, page_index]);
- <xsl:text> return true;
<xsl:text>function switch_visible_page(page_name) {
@@ -2076,6 +2169,18 @@
+ <xsl:text>function update_jumps() { + <xsl:text> page_desc[current_visible_page].jumps.map(w=>w.notify_page_change(current_visible_page,current_page_index)); + <xsl:text> jumps_need_update = false; <xsl:text>// Once connection established
<xsl:text>ws.onopen = function (evt) {
--- a/svghmi/svghmi.js Thu Mar 26 14:21:52 2020 +0100
+++ b/svghmi/svghmi.js Fri Mar 27 14:25:24 2020 +0100
@@ -3,6 +3,7 @@
var cache = hmitree_types.map(_ignored => undefined);
var need_cache_apply = [];
+var jumps_need_update = false; var jump_history = [[default_page, undefined]];
function dispatch_value_to_widget(widget, index, value, oldval) {
@@ -93,6 +94,8 @@
+ if(jumps_need_update) update_jumps(); requestAnimationFrameID = null;
@@ -260,6 +263,7 @@
var current_visible_page;
var current_subscribed_page;
for(let eltid in detachable_elements){
@@ -278,7 +282,39 @@
if(page_name == undefined)
page_name = current_subscribed_page;
- return switch_subscribed_page(page_name, page_index);
+ let old_desc = page_desc[current_subscribed_page]; + let new_desc = page_desc[page_name]; + if(new_desc == undefined){ + if(page_index == undefined){ + page_index = new_desc.page_index; + old_desc.absolute_widgets.map(w=>w.unsub()); + old_desc.relative_widgets.map(w=>w.unsub()); + new_desc.absolute_widgets.map(w=>w.sub()); + var new_offset = page_index == undefined ? 0 : page_index - new_desc.page_index; + new_desc.relative_widgets.map(w=>w.sub(new_offset)); + update_subscriptions(); + current_subscribed_page = page_name; + current_page_index = page_index; + jumps_need_update = true; + jump_history.push([page_name, page_index]); @@ -364,41 +400,11 @@
foreach_subscribe.call(this,off);
need_cache_apply.push(this);
+ jumps_need_update = true; console.log(opstr, new_item_offset);
-function switch_subscribed_page(page_name, page_index) {
- let old_desc = page_desc[current_subscribed_page];
- let new_desc = page_desc[page_name];
- if(new_desc == undefined){
- if(page_index == undefined){
- page_index = new_desc.page_index;
- old_desc.absolute_widgets.map(w=>w.unsub());
- old_desc.relative_widgets.map(w=>w.unsub());
- new_desc.absolute_widgets.map(w=>w.sub());
- var new_offset = page_index == undefined ? 0 : page_index - new_desc.page_index;
- new_desc.relative_widgets.map(w=>w.sub(new_offset));
- update_subscriptions();
- current_subscribed_page = page_name;
- jump_history.push([page_name, page_index]);
function switch_visible_page(page_name) {
@@ -429,6 +435,12 @@
current_visible_page = page_name;
+function update_jumps() { + page_desc[current_visible_page].jumps.map(w=>w.notify_page_change(current_visible_page,current_page_index)); + jumps_need_update = false; // Once connection established
ws.onopen = function (evt) {
--- a/svghmi/widget_jump.ysl2 Thu Mar 26 14:21:52 2020 +0100
+++ b/svghmi/widget_jump.ysl2 Fri Mar 27 14:25:24 2020 +0100
@@ -1,13 +1,39 @@
+function "jump_widget_activity" { + optional_labels("active inactive"); template "widget[@type='Jump']", mode="widget_defs" {
+ const "opts" call "jump_widget_activity" with "hmi_element", "$hmi_element"; + const "have_opt","string-length($opts)>0"; | on_click: function(evt) {
| const index = this.indexes.length > 0 ? this.indexes[0] + this.offset : undefined;
| const name = this.args[0];
| switch_page(name, index);
+ | notify_page_change: function(page_name, index){ + | const ref_index = this.indexes.length > 0 ? this.indexes[0] + this.offset : undefined; + | const ref_name = this.args[0]; + | if((ref_name == undefined || ref_name == page_name) && index == ref_index) { + | console.log("active", ref_name, ref_index, page_name, index); + | this.active_elt.setAttribute("style", this.active_elt_style); + | this.inactive_elt.setAttribute("style", "display:none"); + | console.log("inactive",ref_name, ref_index, page_name, index); + | this.inactive_elt.setAttribute("style", this.inactive_elt_style); + | this.active_elt.setAttribute("style", "display:none"); /* registering event this way does not "click" through svg:use
| this.element.onclick = evt => switch_page(this.args[0]);
@@ -15,6 +41,10 @@
TODO : generalize mouse event handling by global event capture + getElementsAtPoint()
| this.element.setAttribute("onclick", "hmi_widgets['«$hmi_element/@id»'].on_click(evt)");
+ | this.active_elt_style = this.active_elt.getAttribute("style"); + | this.inactive_elt_style = this.inactive_elt.getAttribute("style");