# HG changeset patch # User Edouard Tisserant # Date 1669199275 -3600 # Node ID 570a738239f46ba72d015f4d49c6bb2a36c71be7 # Parent 2239f8e3de48dc71e319ddaed87a398f8bdb01cf SVGHMI: Add arbitrary variable assignment when entering Pages Usage similar to Assign widget. Required instanciating PageWidgets for each page, so that assigned variables can be subsribed. diff -r 2239f8e3de48 -r 570a738239f4 exemples/svghmi_jumps/svghmi_0@svghmi/svghmi.svg --- a/exemples/svghmi_jumps/svghmi_0@svghmi/svghmi.svg Fri Nov 18 10:44:56 2022 +0100 +++ b/exemples/svghmi_jumps/svghmi_0@svghmi/svghmi.svg Wed Nov 23 11:27:55 2022 +0100 @@ -25,7 +25,7 @@ image/svg+xml - + @@ -40,17 +40,17 @@ guidetolerance="10" inkscape:pageopacity="0" inkscape:pageshadow="2" - inkscape:window-width="1600" - inkscape:window-height="836" + inkscape:window-width="1850" + inkscape:window-height="1036" id="namedview4" showgrid="false" - inkscape:zoom="0.23177389" - inkscape:cx="1999.5317" - inkscape:cy="-682.74047" + inkscape:zoom="0.46354778" + inkscape:cx="-544.27948" + inkscape:cy="655.56978" inkscape:window-x="0" inkscape:window-y="27" inkscape:window-maximized="1" - inkscape:current-layer="hmi0" + inkscape:current-layer="g2496" showguides="true" inkscape:guide-bbox="true" borderlayer="true" @@ -67,7 +67,7 @@ transform="translate(1320,1520)" width="100%" height="100%" - inkscape:label="HMI:Page:RelativePage@/FB_ZERO" /> + inkscape:label="HMI:Page:RelativePage:p=6@p=page_number@/FB_ZERO" /> + inkscape:label="HMI:Page:Relative:p=5@p=page_number" /> HMI:Jump:RelativePage + 0 + transform="translate(620.54487,-11.353461)"> + transform="translate(4.2410198,-11.353461)"> - Press Ctrl+X to edit SVG elements directly with XML editor + + declaration of user_level HMI local variable(not a PLC variable) + diff -r 2239f8e3de48 -r 570a738239f4 svghmi/detachable_pages.ysl2 --- a/svghmi/detachable_pages.ysl2 Fri Nov 18 10:44:56 2022 +0100 +++ b/svghmi/detachable_pages.ysl2 Wed Nov 23 11:27:55 2022 +0100 @@ -137,6 +137,10 @@ const "_detachable_elements", "func:detachable_elements($hmi_pages | $keypads)"; const "detachable_elements", "$_detachable_elements[not(ancestor::*/@id = $_detachable_elements/@id)]"; +emit "declarations:page-class" { + | class PageWidget extends Widget{} +} + emit "declarations:detachable-elements" { | | var detachable_elements = { @@ -165,8 +169,13 @@ const "all_page_widgets","$hmi_widgets[@id = $page_all_elements/@id and @id != $page/@id]"; const "page_managed_widgets","$all_page_widgets[not(@id=$in_forEach_widget_ids)]"; + + const "page_root_path", "$desc/path[not(@assign)]"; + if "count($page_root_path)>1" + error > Page id="«$page/@id»" : only one root path can be declared + const "page_relative_widgets", - "$page_managed_widgets[func:is_descendant_path(func:widget(@id)/path/@value, $desc/path/@value)]"; + "$page_managed_widgets[func:is_descendant_path(func:widget(@id)/path/@value, $page_root_path/@value)]"; // Take closest ancestor in detachable_elements // since nested detachable elements are filtered out @@ -178,19 +187,19 @@ ancestor-or-self::*[@id = $detachable_elements/@id]"""; | "«$pagename»": { - //| widget: hmi_widgets["«@id»"], | bbox: [«$p/@x», «$p/@y», «$p/@w», «$p/@h»], - if "$desc/path/@value" { - if "count($desc/path/@index)=0" - warning > Page id="«$page/@id»" : No match for path "«$desc/path/@value»" in HMI tree - | page_index: «$desc/path/@index», - | page_class: "«$indexed_hmitree/*[@hmipath = $desc/path/@value]/@class»", + if "count($page_root_path)=1"{ + if "count($page_root_path/@index)=0" + warning > Page id="«$page/@id»" : No match for path "«$page_root_path/@value»" in HMI tree + | page_index: «$page_root_path/@index», + | page_class: "«$indexed_hmitree/*[@hmipath = $page_root_path/@value]/@class»", } | widgets: [ + | [hmi_widgets["«$page/@id»"], []], foreach "$page_managed_widgets" { const "widget_paths_relativeness" foreach "func:widget(@id)/path" { - value "func:is_descendant_path(@value, $desc/path/@value)"; + value "func:is_descendant_path(@value, $page_root_path/@value)"; if "position()!=last()" > , } | [hmi_widgets["«@id»"], [«$widget_paths_relativeness»]]`if "position()!=last()" > ,` diff -r 2239f8e3de48 -r 570a738239f4 svghmi/svghmi.js --- a/svghmi/svghmi.js Fri Nov 18 10:44:56 2022 +0100 +++ b/svghmi/svghmi.js Wed Nov 23 11:27:55 2022 +0100 @@ -525,6 +525,9 @@ ? page_name : page_name + "@" + hmitree_paths[page_index]); + // when entering a page, assignments are evaluated + new_desc.widgets[0][0].assign(); + return true; }; diff -r 2239f8e3de48 -r 570a738239f4 svghmi/widget_jump.ysl2 --- a/svghmi/widget_jump.ysl2 Fri Nov 18 10:44:56 2022 +0100 +++ b/svghmi/widget_jump.ysl2 Wed Nov 23 11:27:55 2022 +0100 @@ -143,8 +143,8 @@ otherwise value "$page_desc/arg[1]/@value"; } const "target_page_path" choose { - when "arg" value "$hmi_pages_descs[arg[1]/@value = $target_page_name]/path[1]/@value"; - otherwise value "$page_desc/path[1]/@value"; + when "arg" value "$hmi_pages_descs[arg[1]/@value = $target_page_name]/path[not(@assign)]/@value"; + otherwise value "$page_desc/path[not(@assign)]/@value"; } if "not(func:same_class_paths($target_page_path, path[1]/@value))" diff -r 2239f8e3de48 -r 570a738239f4 svghmi/widget_page.ysl2 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/svghmi/widget_page.ysl2 Wed Nov 23 11:27:55 2022 +0100 @@ -0,0 +1,60 @@ +// widget_page.ysl2 + +widget_desc("Page") { + longdesc + || + + Arguments are either: + + - XXX reference path TODO + + - name=value: setting variable with literal value. + - name=other_name: copy variable content into another + + "active"+"inactive" labeled elements can be provided to show feedback when pressed + + Exemples: + + HMI:Page:notify=1@notify=/PLCVAR + HMI:Page:ack=2:notify=1@ack=.local_var@notify=/PLCVAR + + || + + shortdesc > Page + +} + +widget_defs("Page") { + + | assignments: {}, + | dispatch: function(value, oldval, varnum) { + const "widget", "."; + foreach "path" { + const "varid","generate-id()"; + const "varnum","position()-1"; + if "@assign" foreach "$widget/path[@assign]" if "$varid = generate-id()" { + | if(varnum == «$varnum») this.assignments["«@assign»"] = value; + } + } + | }, + | assign: function() { + const "paths","path"; + foreach "arg[contains(@value,'=')]"{ + const "name","substring-before(@value,'=')"; + const "value","substring-after(@value,'=')"; + const "index" foreach "$paths" if "@assign = $name" value "position()-1"; + const "isVarName", "regexp:test($value,'^[a-zA-Z_][a-zA-Z0-9_]+$')"; + choose { + when "$isVarName"{ + | const «$value» = this.assignments["«$value»"]; + | if(«$value» != undefined) + | this.apply_hmi_value(«$index», «$value»); + } + otherwise { + | this.apply_hmi_value(«$index», «$value»); + } + } + } + | }, +} + diff -r 2239f8e3de48 -r 570a738239f4 svghmi/widgets_common.ysl2 --- a/svghmi/widgets_common.ysl2 Fri Nov 18 10:44:56 2022 +0100 +++ b/svghmi/widgets_common.ysl2 Wed Nov 23 11:27:55 2022 +0100 @@ -600,12 +600,14 @@ } const "included_ids","$parsed_widgets/widget[not(@type = $excluded_types) and not(@id = $discardable_elements/@id)]/@id"; +const "page_ids","$parsed_widgets/widget[@type = 'Page']/@id"; const "hmi_widgets","$hmi_elements[@id = $included_ids]"; +const "page_widgets","$hmi_elements[@id = $page_ids]"; const "result_widgets","$result_svg_ns//*[@id = $hmi_widgets/@id]"; emit "declarations:hmi-elements" { | var hmi_widgets = { - apply "$hmi_widgets", mode="hmi_widgets"; + apply "$hmi_widgets | $page_widgets", mode="hmi_widgets"; | } | }