--- a/svghmi/gen_index_xhtml.xslt Mon Mar 23 21:44:28 2020 +0100
+++ b/svghmi/gen_index_xhtml.xslt Tue Mar 24 14:03:19 2020 +0100
@@ -747,9 +747,7 @@
<xsl:value-of select="$hmi_element/@id"/>
<xsl:text>'].on_click(evt)");*/
+ <xsl:text> this.items = [ <xsl:variable name="items_regex" select="concat('^',$prefix,'[0-9]+')"/>
<xsl:variable name="unordered_items" select="$hmi_element//*[regexp:test(@inkscape:label, $items_regex)]"/>
@@ -758,7 +756,7 @@
<xsl:variable name="elt" select="$unordered_items[@inkscape:label = $elt_label]"/>
<xsl:variable name="pos" select="position()"/>
<xsl:variable name="item_path" select="$items_paths[$pos]"/>
- <xsl:text> [ /* item="</xsl:text>
+ <xsl:text> [ /* item="</xsl:text> <xsl:value-of select="$elt_label"/>
<xsl:text>" path="</xsl:text>
<xsl:value-of select="$item_path"/>
@@ -786,7 +784,7 @@
- <xsl:text> hmi_widgets["</xsl:text>
+ <xsl:text> hmi_widgets["</xsl:text> <xsl:value-of select="@id"/>
<xsl:if test="position()!=last()">
@@ -795,26 +793,30 @@
- <xsl:text> ]</xsl:text>
+ <xsl:text> ]</xsl:text> <xsl:if test="position()!=last()">
+ <xsl:text> item_offset: 0, <xsl:template mode="widget_subscribe" match="widget[@type='ForEach']">
<xsl:text> sub: function(off){
- <xsl:text> /*subscribe.call(this,off);*/
+ <xsl:text> subscribe_foreach.call(this,off); <xsl:text> unsub: function(){
- <xsl:text> /*unsubscribe.call(this);*/
+ <xsl:text> unsubscribe_foreach.call(this); @@ -1315,6 +1317,14 @@
+ <xsl:text> if(current_subscribed_page_index != current_visible_page_index){ + <xsl:text> apply_cache(); <xsl:text> apply_updates();
<xsl:text> requestAnimationFrameID = null;
@@ -1649,6 +1659,10 @@
<xsl:text>var current_subscribed_page;
+ <xsl:text>var current_visible_page_index; + <xsl:text>var current_subscribed_page_index; <xsl:text>function prepare_svg() {
@@ -1675,16 +1689,16 @@
- <xsl:text> } else if(page_name == current_visible_page){
- <xsl:text> /* already in that page */
- <xsl:text> /* TODO LOG ERROR */
+ <xsl:text> if(page_name == undefined) + <xsl:text> page_name = current_subscribed_page; <xsl:text> switch_subscribed_page(page_name, page_index);
@@ -1703,19 +1717,17 @@
<xsl:text>function unsubscribe(){
- <xsl:text> widget = this;
<xsl:text> /* remove subsribers */
- <xsl:text> for(let index of widget.indexes){
- <xsl:text> let idx = index + widget.offset;
- <xsl:text> subscribers[idx].delete(widget);
+ <xsl:text> for(let index of this.indexes){ + <xsl:text> let idx = index + this.offset; + <xsl:text> subscribers[idx].delete(this); - <xsl:text> widget.offset = 0;
+ <xsl:text> this.offset = 0; @@ -1723,17 +1735,55 @@
<xsl:text>function subscribe(new_offset=0){
- <xsl:text> widget = this;
<xsl:text> /* set the offset because relative */
- <xsl:text> widget.offset = new_offset;
- <xsl:text> /* add widget's subsribers */
- <xsl:text> for(let index of widget.indexes){
- <xsl:text> subscribers[index + new_offset].add(widget);
+ <xsl:text> this.offset = new_offset; + <xsl:text> /* add this's subsribers */ + <xsl:text> for(let index of this.indexes){ + <xsl:text> subscribers[index + new_offset].add(this); + <xsl:text>function unsubscribe_foreach(){ + <xsl:text> for(let item of this.items){ + <xsl:text> for(let widget of item) { + <xsl:text> unsubscribe.call(widget); + <xsl:text>function subscribe_foreach(new_offset=0){ + <xsl:text> for(let i = 0; i < this.items.length; i++) { + <xsl:text> let item = this.items[i]; + <xsl:text> let orig_item_index = this.index_pool[i]; + <xsl:text> let item_index = this.index_pool[i+this.item_offset]; + <xsl:text> let item_index_offset = item_index - orig_item_index; + <xsl:text> for(let widget of item) { + <xsl:text> subscribe.call(widget,new_offset + item_index_offset); @@ -1789,6 +1839,8 @@
<xsl:text> current_subscribed_page = page_name;
+ <xsl:text> current_subscribed_page_index = page_index; <xsl:text> requestHMIAnimation();
@@ -1847,30 +1899,42 @@
+ <xsl:text> svg_root.setAttribute('viewBox',new_desc.bbox.join(" ")); + <xsl:text> current_visible_page = page_name; + <xsl:text>function apply_cache() { + <xsl:text> let new_desc = page_desc[current_visible_page]; <xsl:text> for(let widget of chain(new_desc.absolute_widgets,new_desc.relative_widgets)){
<xsl:text> for(let index of widget.indexes){
<xsl:text> /* dispatch current cache in newly opened page widgets */
- <xsl:text> let cached_val = cache[index];
+ <xsl:text> let realindex = index+widget.offset; + <xsl:text> let cached_val = cache[realindex]; <xsl:text> if(cached_val != undefined)
- <xsl:text> dispatch_value_to_widget(widget, index, cached_val, cached_val);
+ <xsl:text> dispatch_value_to_widget(widget, realindex, cached_val, cached_val); + <xsl:text> current_visible_page_index = current_subscribed_page_index; - <xsl:text> svg_root.setAttribute('viewBox',new_desc.bbox.join(" "));
- <xsl:text> current_visible_page = page_name;
--- a/svghmi/svghmi.js Mon Mar 23 21:44:28 2020 +0100
+++ b/svghmi/svghmi.js Tue Mar 24 14:03:19 2020 +0100
@@ -86,6 +86,10 @@
if(current_subscribed_page != current_visible_page){
switch_visible_page(current_subscribed_page);
+ if(current_subscribed_page_index != current_visible_page_index){ requestAnimationFrameID = null;
@@ -253,6 +257,8 @@
var current_visible_page;
var current_subscribed_page;
+var current_visible_page_index; +var current_subscribed_page_index; for(let eltid in detachable_elements){
@@ -266,11 +272,11 @@
/* page switch already going */
- } else if(page_name == current_visible_page){
- /* already in that page */
+ if(page_name == undefined) + page_name = current_subscribed_page; switch_subscribed_page(page_name, page_index);
@@ -280,22 +286,40 @@
- for(let index of widget.indexes){
- let idx = index + widget.offset;
- subscribers[idx].delete(widget);
+ for(let index of this.indexes){ + let idx = index + this.offset; + subscribers[idx].delete(this);
function subscribe(new_offset=0){
/* set the offset because relative */
- widget.offset = new_offset;
- /* add widget's subsribers */
- for(let index of widget.indexes){
- subscribers[index + new_offset].add(widget);
+ this.offset = new_offset; + /* add this's subsribers */ + for(let index of this.indexes){ + subscribers[index + new_offset].add(this); +function unsubscribe_foreach(){ + for(let item of this.items){ + for(let widget of item) { + unsubscribe.call(widget); +function subscribe_foreach(new_offset=0){ + for(let i = 0; i < this.items.length; i++) { + let item = this.items[i]; + let orig_item_index = this.index_pool[i]; + let item_index = this.index_pool[i+this.item_offset]; + let item_index_offset = item_index - orig_item_index; + for(let widget of item) { + subscribe.call(widget,new_offset + item_index_offset); @@ -323,6 +347,7 @@
current_subscribed_page = page_name;
+ current_subscribed_page_index = page_index; @@ -352,18 +377,24 @@
+ svg_root.setAttribute('viewBox',new_desc.bbox.join(" ")); + current_visible_page = page_name; +function apply_cache() { + let new_desc = page_desc[current_visible_page]; for(let widget of chain(new_desc.absolute_widgets,new_desc.relative_widgets)){
for(let index of widget.indexes){
/* dispatch current cache in newly opened page widgets */
- let cached_val = cache[index];
+ let realindex = index+widget.offset; + let cached_val = cache[realindex]; if(cached_val != undefined)
- dispatch_value_to_widget(widget, index, cached_val, cached_val);
+ dispatch_value_to_widget(widget, realindex, cached_val, cached_val); + current_visible_page_index = current_subscribed_page_index; - svg_root.setAttribute('viewBox',new_desc.bbox.join(" "));
- current_visible_page = page_name;
// Once connection established
--- a/svghmi/widget_foreach.ysl2 Mon Mar 23 21:44:28 2020 +0100
+++ b/svghmi/widget_foreach.ysl2 Tue Mar 24 14:03:19 2020 +0100
@@ -25,9 +25,8 @@
| /* TODO elt.setAttribute("onclick", "hmi_widgets['«$hmi_element/@id»'].on_click(evt)");*/
const "items_regex","concat('^',$prefix,'[0-9]+')";
const "unordered_items","$hmi_element//*[regexp:test(@inkscape:label, $items_regex)]";
foreach "$unordered_items" {
@@ -35,27 +34,27 @@
const "elt","$unordered_items[@inkscape:label = $elt_label]";
const "pos","position()";
const "item_path", "$items_paths[$pos]";
- | [ /* item="«$elt_label»" path="«$item_path»" */
+ | [ /* item="«$elt_label»" path="«$item_path»" */ if "count($elt)=0" error > Missing item labeled «$elt_label» in ForEach widget «$hmi_element/@id»
foreach "func:refered_elements($elt)[@id = $hmi_elements/@id][not(@id = $elt/@id)]" {
if "not(func:is_descendant_path(func:widget(@id)/path/@value, $item_path))"
error > Widget id="«@id»" label="«@inkscape:label»" is having wrong path. Accroding to ForEach widget ancestor id="«$hmi_element/@id»", path should be descendant of «$item_path».
- | hmi_widgets["«@id»"]`if "position()!=last()" > ,`
+ | hmi_widgets["«@id»"]`if "position()!=last()" > ,` - | ]`if "position()!=last()" > ,`
+ | ]`if "position()!=last()" > ,`
template "widget[@type='ForEach']", mode="widget_subscribe"{
- | /*subscribe.call(this,off);*/
+ | subscribe_foreach.call(this,off); - | /*unsubscribe.call(this);*/
+ | unsubscribe_foreach.call(this);