# HG changeset patch # User Edouard Tisserant # Date 1584132160 -3600 # Node ID 634b43d69897278f15f4efab76c1327b7fd5be38 # Parent d9eb50c015d1c9e1ab9f10b2b9026d9902909775 SVGHMI: relative pages and page jumps diff -r d9eb50c015d1 -r 634b43d69897 svghmi/gen_index_xhtml.xslt --- 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) > 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)/ 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" && idxidx == 0){ </xsl:text> <xsl:text> d.call(widget, value, oldval); </xsl:text> - <xsl:text> }else if(typeof(d) == "object" && d.length >= 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" && d.length >= 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(); diff -r d9eb50c015d1 -r 634b43d69897 svghmi/gen_index_xhtml.ysl2 --- 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 diff -r d9eb50c015d1 -r 634b43d69897 svghmi/svghmi.js --- 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();