# 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";
| }
|
}