SVGHMI: relative pages and page jumps svghmi
authorEdouard Tisserant
Fri, 13 Mar 2020 21:42:40 +0100
branchsvghmi
changeset 2870 634b43d69897
parent 2869 d9eb50c015d1
child 2871 ed9b16b33628
SVGHMI: relative pages and page jumps
svghmi/gen_index_xhtml.xslt
svghmi/gen_index_xhtml.ysl2
svghmi/svghmi.js
--- a/svghmi/gen_index_xhtml.xslt	Fri Mar 13 10:36:13 2020 +0100
+++ b/svghmi/gen_index_xhtml.xslt	Fri Mar 13 21:42:40 2020 +0100
@@ -199,9 +199,9 @@
     </xsl:apply-templates>
   </xsl:template>
   <func:function name="func:is_descendant_path">
+    <xsl:param name="descend"/>
     <xsl:param name="ancest"/>
-    <xsl:param name="descend"/>
-    <func:result select="starts-with($descend,$ancest)"/>
+    <func:result select="string-length($ancest) &gt; 0 and starts-with($descend,$ancest)"/>
   </func:function>
   <xsl:template mode="inline_svg" match="@* | node()">
     <xsl:if test="not(@id = $discardable_elements/@id)">
@@ -564,7 +564,7 @@
       <xsl:variable name="p" select="$geometry[@Id = $page/@id]"/>
       <xsl:variable name="page_all_elements" select="func:all_related_elements($page)"/>
       <xsl:variable name="all_page_widgets" select="$hmi_elements[@id = $page_all_elements/@id and @id != $page/@id]"/>
-      <xsl:variable name="page_relative_widgets" select="$all_page_widgets[func:is_descendant_path($desc/path/@value, path/@value)]"/>
+      <xsl:variable name="page_relative_widgets" select="$all_page_widgets[func:is_descendant_path(func:parselabel(@inkscape:label)/widget/path/@value, $desc/path/@value)]"/>
       <xsl:variable name="required_detachables" select="func:sumarized_elements($page_all_elements)/&#10;                   ancestor-or-self::*[@id = $detachable_elements/@id]"/>
       <xsl:text>  "</xsl:text>
       <xsl:value-of select="$desc/arg[1]/@value"/>
@@ -676,19 +676,31 @@
 </xsl:text>
     <xsl:text>    try {
 </xsl:text>
-    <xsl:text>        let idxidx = widget.indexes.indexOf(index);
+    <xsl:text>        let idx = widget.offset ? index - widget.offset : index;
+</xsl:text>
+    <xsl:text>        let idxidx = widget.indexes.indexOf(idx);
 </xsl:text>
     <xsl:text>        let d = widget.dispatch;
 </xsl:text>
+    <xsl:text>        console.log(index, idx, idxidx, value);
+</xsl:text>
     <xsl:text>        if(typeof(d) == "function" &amp;&amp; idxidx == 0){
 </xsl:text>
     <xsl:text>            d.call(widget, value, oldval);
 </xsl:text>
-    <xsl:text>        }else if(typeof(d) == "object" &amp;&amp; d.length &gt;= idxidx){
+    <xsl:text>        }
+</xsl:text>
+    <xsl:text>        /* TODO deal with multiple paths
+</xsl:text>
+    <xsl:text>           and dispatch according to index+page_offset */
+</xsl:text>
+    <xsl:text>        /*else if(typeof(d) == "object" &amp;&amp; d.length &gt;= idxidx){
 </xsl:text>
     <xsl:text>            d[idxidx].call(widget, value, oldval);
 </xsl:text>
-    <xsl:text>        }/* else dispatch_0, ..., dispatch_n ? */
+    <xsl:text>        }*/
+</xsl:text>
+    <xsl:text>        /* else dispatch_0, ..., dispatch_n ? */
 </xsl:text>
     <xsl:text>        /*else {
 </xsl:text>
@@ -1180,7 +1192,7 @@
 </xsl:text>
     <xsl:text>
 </xsl:text>
-    <xsl:text>function switch_page(page_name, root_index) {
+    <xsl:text>function switch_page(page_name, page_index) {
 </xsl:text>
     <xsl:text>    if(current_subscribed_page != current_visible_page){
 </xsl:text>
@@ -1200,7 +1212,7 @@
 </xsl:text>
     <xsl:text>    }
 </xsl:text>
-    <xsl:text>    switch_subscribed_page(page_name);
+    <xsl:text>    switch_subscribed_page(page_name, page_index);
 </xsl:text>
     <xsl:text>};
 </xsl:text>
@@ -1216,7 +1228,7 @@
 </xsl:text>
     <xsl:text>
 </xsl:text>
-    <xsl:text>function switch_subscribed_page(page_name) {
+    <xsl:text>function switch_subscribed_page(page_name, page_index) {
 </xsl:text>
     <xsl:text>    let old_desc = page_desc[current_subscribed_page];
 </xsl:text>
@@ -1234,9 +1246,17 @@
 </xsl:text>
     <xsl:text>
 </xsl:text>
+    <xsl:text>    if(page_index == undefined){
+</xsl:text>
+    <xsl:text>        page_index = new_desc.page_index;
+</xsl:text>
+    <xsl:text>    }
+</xsl:text>
+    <xsl:text>
+</xsl:text>
     <xsl:text>    if(old_desc){
 </xsl:text>
-    <xsl:text>        for(let widget of chain(old_desc.absolute_widgets,old_desc.relative_widgets)){
+    <xsl:text>        for(let widget of old_desc.absolute_widgets){
 </xsl:text>
     <xsl:text>            /* remove subsribers */
 </xsl:text>
@@ -1248,9 +1268,27 @@
 </xsl:text>
     <xsl:text>        }
 </xsl:text>
-    <xsl:text>    }
-</xsl:text>
-    <xsl:text>    for(let widget of chain(new_desc.absolute_widgets,new_desc.relative_widgets)){
+    <xsl:text>        for(let widget of old_desc.relative_widgets){
+</xsl:text>
+    <xsl:text>            /* remove subsribers */
+</xsl:text>
+    <xsl:text>            for(let index of widget.indexes){
+</xsl:text>
+    <xsl:text>                let idx = widget.offset ? index + widget.offset : index;
+</xsl:text>
+    <xsl:text>                subscribers[idx].delete(widget);
+</xsl:text>
+    <xsl:text>            }
+</xsl:text>
+    <xsl:text>            /* lose the offset */
+</xsl:text>
+    <xsl:text>            delete widget.offset;
+</xsl:text>
+    <xsl:text>        }
+</xsl:text>
+    <xsl:text>    }
+</xsl:text>
+    <xsl:text>    for(let widget of new_desc.absolute_widgets){
 </xsl:text>
     <xsl:text>        /* add widget's subsribers */
 </xsl:text>
@@ -1262,6 +1300,24 @@
 </xsl:text>
     <xsl:text>    }
 </xsl:text>
+    <xsl:text>    var new_offset = page_index == undefined ? 0 : page_index - new_desc.page_index;
+</xsl:text>
+    <xsl:text>    for(let widget of new_desc.relative_widgets){
+</xsl:text>
+    <xsl:text>        /* set the offset because relative */
+</xsl:text>
+    <xsl:text>        widget.offset = new_offset;
+</xsl:text>
+    <xsl:text>        /* add widget's subsribers */
+</xsl:text>
+    <xsl:text>        for(let index of widget.indexes){
+</xsl:text>
+    <xsl:text>            subscribers[index + new_offset].add(widget);
+</xsl:text>
+    <xsl:text>        }
+</xsl:text>
+    <xsl:text>    }
+</xsl:text>
     <xsl:text>
 </xsl:text>
     <xsl:text>    update_subscriptions();
--- a/svghmi/gen_index_xhtml.ysl2	Fri Mar 13 10:36:13 2020 +0100
+++ b/svghmi/gen_index_xhtml.ysl2	Fri Mar 13 21:42:40 2020 +0100
@@ -306,9 +306,9 @@
 
 
     def "func:is_descendant_path" {
+        param "descend";
         param "ancest";
-        param "descend";
-        result "starts-with($descend,$ancest)";
+        result "string-length($ancest) > 0 and starts-with($descend,$ancest)";
     }
 
     //////////////// Inline SVG
@@ -603,7 +603,7 @@
             const "all_page_widgets","$hmi_elements[@id = $page_all_elements/@id and @id != $page/@id]";
 
             const "page_relative_widgets",
-                "$all_page_widgets[func:is_descendant_path($desc/path/@value, path/@value)]";
+                "$all_page_widgets[func:is_descendant_path(func:parselabel(@inkscape:label)/widget/path/@value, $desc/path/@value)]";
 
             // Take closest ancestor in detachable_elements
             // since nested detachable elements are filtered out
--- a/svghmi/svghmi.js	Fri Mar 13 10:36:13 2020 +0100
+++ b/svghmi/svghmi.js	Fri Mar 13 21:42:40 2020 +0100
@@ -5,13 +5,19 @@
 
 function dispatch_value_to_widget(widget, index, value, oldval) {
     try {
-        let idxidx = widget.indexes.indexOf(index);
+        let idx = widget.offset ? index - widget.offset : index;
+        let idxidx = widget.indexes.indexOf(idx);
         let d = widget.dispatch;
+        console.log(index, idx, idxidx, value);
         if(typeof(d) == "function" && idxidx == 0){
             d.call(widget, value, oldval);
-        }else if(typeof(d) == "object" && d.length >= idxidx){
+        }
+        /* TODO deal with multiple paths
+           and dispatch according to index+page_offset */
+        /*else if(typeof(d) == "object" && d.length >= idxidx){
             d[idxidx].call(widget, value, oldval);
-        }/* else dispatch_0, ..., dispatch_n ? */
+        }*/
+        /* else dispatch_0, ..., dispatch_n ? */
         /*else {
             throw new Error("Dunno how to dispatch to widget at index = " + index);
         }*/
@@ -257,7 +263,7 @@
     }
 };
 
-function switch_page(page_name, root_index) {
+function switch_page(page_name, page_index) {
     if(current_subscribed_page != current_visible_page){
         /* page switch already going */
         /* TODO LOG ERROR */
@@ -267,7 +273,7 @@
         /* TODO LOG ERROR */
         return;
     }
-    switch_subscribed_page(page_name);
+    switch_subscribed_page(page_name, page_index);
 };
 
 function* chain(a,b){
@@ -275,7 +281,7 @@
     yield* b;
 };
 
-function switch_subscribed_page(page_name) {
+function switch_subscribed_page(page_name, page_index) {
     let old_desc = page_desc[current_subscribed_page];
     let new_desc = page_desc[page_name];
 
@@ -284,20 +290,42 @@
         return;
     }
 
+    if(page_index == undefined){
+        page_index = new_desc.page_index;
+    }
+
     if(old_desc){
-        for(let widget of chain(old_desc.absolute_widgets,old_desc.relative_widgets)){
+        for(let widget of old_desc.absolute_widgets){
             /* remove subsribers */
             for(let index of widget.indexes){
                 subscribers[index].delete(widget);
             }
         }
-    }
-    for(let widget of chain(new_desc.absolute_widgets,new_desc.relative_widgets)){
+        for(let widget of old_desc.relative_widgets){
+            /* remove subsribers */
+            for(let index of widget.indexes){
+                let idx = widget.offset ? index + widget.offset : index;
+                subscribers[idx].delete(widget);
+            }
+            /* lose the offset */
+            delete widget.offset;
+        }
+    }
+    for(let widget of new_desc.absolute_widgets){
         /* add widget's subsribers */
         for(let index of widget.indexes){
             subscribers[index].add(widget);
         }
     }
+    var new_offset = page_index == undefined ? 0 : page_index - new_desc.page_index;
+    for(let widget of new_desc.relative_widgets){
+        /* 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);
+        }
+    }
 
     update_subscriptions();