# HG changeset patch # User Edouard Tisserant # Date 1584996268 -3600 # Node ID 4cf9ad35e6d0151217a9b130b0e141f774838fdd # Parent d57a12b8f5dbc64fa5e59dbd0d8fc193b2d3adff SVGHMI: Easier way to match HMI tree elements to paths. ForEach widget now looks for paths and indexes of all items, and enforce path to be consistent with ForEach items sub widgets diff -r d57a12b8f5db -r 4cf9ad35e6d0 svghmi/detachable_pages.ysl2 --- a/svghmi/detachable_pages.ysl2 Mon Mar 23 15:13:36 2020 +0100 +++ b/svghmi/detachable_pages.ysl2 Mon Mar 23 21:44:28 2020 +0100 @@ -91,13 +91,6 @@ const "_detachable_elements", "func:detachable_elements($hmi_pages)"; const "detachable_elements", "$_detachable_elements[not(ancestor::*/@id = $_detachable_elements/@id)]"; -def "func:is_descendant_path" { - param "descend"; - param "ancest"; - result "string-length($ancest) > 0 and starts-with($descend,$ancest)"; -} - - const "forEach_widgets_ids", "$parsed_widgets/widget[@type = 'ForEach']/@id"; const "forEach_widgets", "$hmi_elements[@id = $forEach_widgets_ids]"; const "in_forEach_widget_ids", "func:refered_elements($forEach_widgets)[not(@id = $forEach_widgets_ids)]/@id"; diff -r d57a12b8f5db -r 4cf9ad35e6d0 svghmi/gen_index_xhtml.xslt --- a/svghmi/gen_index_xhtml.xslt Mon Mar 23 15:13:36 2020 +0100 +++ b/svghmi/gen_index_xhtml.xslt Mon Mar 23 21:44:28 2020 +0100 @@ -74,49 +74,6 @@ - - - - - get_hmi_tree_elt - - - - - Given path " - - " should start with a "/" - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -185,6 +142,11 @@ + + + + + @@ -362,11 +324,6 @@ - - - - - @@ -746,21 +703,28 @@ - frequency: 2, - - dispatch: function(value) { - - // do something - - }, - + + + + + + + index_pool: [ + + + + + , + + + + ], buttons: [ - @@ -787,19 +751,18 @@ items: [ - - /* - - */ - - [ /* + + + [ /* item=" - */ + " path=" + + " */ @@ -810,6 +773,19 @@ + + + Widget id=" + + " label=" + + " is having wrong path. Accroding to ForEach widget ancestor id=" + + ", path should be descendant of + + . + + hmi_widgets[" "] @@ -832,13 +808,13 @@ sub: function(off){ - subscribe.call(this,off); + /*subscribe.call(this,off);*/ }, unsub: function(){ - unsubscribe.call(this); + /*unsubscribe.call(this);*/ }, diff -r d57a12b8f5db -r 4cf9ad35e6d0 svghmi/hmi_tree.ysl2 --- a/svghmi/hmi_tree.ysl2 Mon Mar 23 15:13:36 2020 +0100 +++ b/svghmi/hmi_tree.ysl2 Mon Mar 23 21:44:28 2020 +0100 @@ -52,36 +52,6 @@ } } -def "func:get_hmi_tree_elt" { - param "path"; - param "root", "$hmitree"; - message > get_hmi_tree_elt «$path» - if "not(starts-with($path, '/'))" error > Given path "«$path»" should start with a "/" - const "stripped", "substring($path, 2)"; - const "token" choose { - when "contains($stripped, '/')" value "substring-before($stripped, '/')"; - otherwise value "$stripped"; - } - - choose { - when "string-length($token) = 0"{ - result "$root"; - } - otherwise{ - const "rest", "substring-after($stripped, $token)"; - const "match", "$root/*[@name = $token]"; - choose { - when "string-length($rest) > 0"{ - result "func:get_hmi_tree_el($rest, $match)"; - } - otherwise{ - result "$match"; - } - } - } - } -} - // Parses: // "HMI:WidgetType:param1:param2@path1@path2" // @@ -139,6 +109,14 @@ } +def "func:is_descendant_path" { + param "descend"; + param "ancest"; + // TODO : use HMI tree to answer more accurately + result "string-length($ancest) > 0 and starts-with($descend,$ancest)"; +} + + // Debug data template "*", mode="testtree"{ param "indent", "''"; diff -r d57a12b8f5db -r 4cf9ad35e6d0 svghmi/widget_foreach.ysl2 --- a/svghmi/widget_foreach.ysl2 Mon Mar 23 15:13:36 2020 +0100 +++ b/svghmi/widget_foreach.ysl2 Mon Mar 23 21:44:28 2020 +0100 @@ -2,14 +2,21 @@ template "widget[@type='ForEach']", mode="widget_defs" { param "hmi_element"; const "widgets", "func:refered_elements($forEach_widgets)[not(@id = $forEach_widgets_ids)]"; - | frequency: 2, - | dispatch: function(value) { - | // do something - | }, + + const "class","arg[1]/@value"; + + const "base_path","path/@value"; + const "hmi_index_base", "$indexed_hmitree/*[@hmipath = $base_path]"; + const "hmi_tree_base", "$hmitree/descendant-or-self::*[@path = $hmi_index_base/@path]"; + const "hmi_tree_items", "$hmi_tree_base/*[@class = $class]"; + const "hmi_index_items", "$indexed_hmitree/*[@path = $hmi_tree_items/@path]"; + const "items_paths", "$hmi_index_items/@hmipath"; | index_pool: [ + foreach "$hmi_index_items" { + | «@index»`if "position()!=last()" > ,` + } | ], | buttons: [ - const "class","arg[1]/@value"; const "prefix","concat($class,':')"; const "buttons_regex","concat('^',$prefix,'[+\-][0-9]+')"; foreach "$hmi_element/*[regexp:test(@inkscape:label, $buttons_regex)]" { @@ -21,17 +28,18 @@ | }, | items: [ - const "base_path","path/@value"; const "items_regex","concat('^',$prefix,'[0-9]+')"; const "unordered_items","$hmi_element//*[regexp:test(@inkscape:label, $items_regex)]"; foreach "$unordered_items" { const "elt_label","concat($prefix, string(position()))"; const "elt","$unordered_items[@inkscape:label = $elt_label]"; - - | /* `apply "func:get_hmi_tree_elt($base_path)", mode="testtree";` */ - | [ /* «$elt_label» */ + const "pos","position()"; + const "item_path", "$items_paths[$pos]"; + | [ /* 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()" > ,` } | ]`if "position()!=last()" > ,` @@ -42,12 +50,12 @@ template "widget[@type='ForEach']", mode="widget_subscribe"{ // param "hmi_element"; | sub: function(off){ - | subscribe.call(this,off); + | /*subscribe.call(this,off);*/ /* TODO */ | }, | unsub: function(){ - | unsubscribe.call(this); + | /*unsubscribe.call(this);*/ /* TODO */ | }, }