--- a/svghmi/parse_labels.ysl2 Fri Aug 12 09:34:24 2022 +0200
+++ b/svghmi/parse_labels.ysl2 Fri Aug 19 10:22:16 2022 +0200
@@ -2,7 +2,7 @@
-// "HMI:WidgetType|freq:param1:param2@path1,path1min,path1max@path2"
+// "HMI:WidgetType|freq:param1:param2@path1,path1min,path1max@path2#" // widget type="WidgetType" id="blah456" {
@@ -75,7 +75,18 @@
- const "paths", "substring-after($declaration,'@')";
+ const "tail", "substring-after($declaration,'@')"; + const "taillen","string-length($tail)"; + const "has_enable", "substring($tail,$taillen,1)='#'"; + value "substring($tail,1,$taillen - 1)"; + otherwise value "$tail"; + attrib "has_enable" > yes foreach "str:split($paths, '@')" {
if "string-length(.) > 0" path {
--- a/svghmi/widgets_common.ysl2 Fri Aug 12 09:34:24 2022 +0200
+++ b/svghmi/widgets_common.ysl2 Fri Aug 19 10:22:16 2022 +0200
@@ -104,7 +104,14 @@
- | "«@id»": new «$widget/@type»Widget ("«@id»",«$freq»,[«$args»],[«$indexes»],[«$minmaxes»],{
+ const "has_enable" choose { + when "$widget/@has_enable = 'yes'" + | "«@id»": new «$widget/@type»Widget ("«@id»",«$freq»,[«$args»],[«$indexes»],[«$minmaxes»],«$has_enable»,{ apply "$widget", mode="widget_defs" with "hmi_element",".";
| })`if "position()!=last()" > ,`
@@ -218,12 +225,14 @@
- constructor(elt_id, freq, args, indexes, minmaxes, members){
+ constructor(elt_id, freq, args, indexes, minmaxes, has_enable, members){ this.element_id = elt_id;
this.element = id(elt_id);
+ this.indexes_length = indexes.length; this.minmaxes = minmaxes;
+ this.has_enable = has_enable; Object.keys(members).forEach(prop => this[prop]=members[prop]);
this.lastapply = indexes.map(() => undefined);
this.inhibit = indexes.map(() => undefined);
@@ -267,12 +276,27 @@
+ this.disabled_elt = null; + this.enabled_elts = []; + this.enable_state = false; + this.enable_displayed_state = false; + for(let child of Array.from(this.element.children)){ + if(child.getAttribute("inkscape:label")=="disabled"){ + this.disabled_elt = child; + this.enabled_elts.push(child); + this.element.removeChild(child); - for(let i = 0; i < this.indexes.length; i++) {
+ for(let i = 0; i < this.indexes_length; i++) { /* flush updates pending because of inhibition */
let inhibition = this.inhibit[i];
if(inhibition != undefined){
@@ -301,7 +325,7 @@
this.container_id = container_id ;
/* add this's subsribers */
- for(let i = 0; i < this.indexes.length; i++) {
+ for(let i = 0; i < this.indexes_length; i++) { let index = this.get_variable_index(i);
if(index == undefined) continue;
subscribers(index).add(this);
@@ -402,7 +426,7 @@
new_hmi_value(index, value, oldval) {
// TODO avoid searching, store index at sub()
- for(let i = 0; i < this.indexes.length; i++) {
+ for(let i = 0; i < this.indexes_length; i++) { let refindex = this.get_variable_index(i);
if(refindex == undefined) continue;
@@ -420,20 +444,63 @@
this.dispatch(new_val, old_val, index);
+ if(this.enable_state != enabled){ + this.enable_state = enabled; + this.request_animate(); + if(this.enable_state && !this.enable_displayed_state){ + for(let child of this.enabled_elts){ + this.element.appendChild(child); + //hide disabled content + if(this.disabled_elt && this.disabled_elt.parentNode != null) + this.element.removeChild(this.disabled_elt); + this.enable_displayed_state = true; + }else if(!this.enable_state && this.enable_displayed_state){ + for(let child of this.enabled_elts){ + if(child.parentNode != null) + this.element.removeChild(child); + //show disabled content + this.element.appendChild(this.disabled_elt); + this.enable_displayed_state = false; _dispatch(value, oldval, varnum) {
let dispatch = this.dispatch;
- if(dispatch != undefined){
+ let has_dispatch = dispatch != undefined; + let is_enable_var = this.has_enable && (varnum == (this.indexes_length - 1)); + if(has_dispatch || is_enable_var){ if(this.deafen[varnum] == undefined){
let min_interval = 1000/this.frequency;
let lastdispatch = this.lastdispatch[varnum];
if(lastdispatch == undefined || now > lastdispatch + min_interval){
this.lastdispatch[varnum] = now;
dispatch.call(this, value, oldval, varnum);
+ if(is_enable_var) try { + this.enable(Boolean(value)); let elapsed = now - lastdispatch;
@@ -448,7 +515,10 @@
+ if(this.animate != undefined && (!this.has_enable || this.enable_state)) this.pending_animate = false;
--- a/tests/projects/svghmi_scrollbar/svghmi_0@svghmi/svghmi.svg Fri Aug 12 09:34:24 2022 +0200
+++ b/tests/projects/svghmi_scrollbar/svghmi_0@svghmi/svghmi.svg Fri Aug 19 10:22:16 2022 +0200
@@ -59,9 +59,9 @@
inkscape:current-layer="hmi0"
- inkscape:cx="476.03774"
- inkscape:cy="444.53549"
+ inkscape:zoom="0.90509668" + inkscape:cx="474.80696" + inkscape:cy="335.41469" inkscape:window-width="1600"
inkscape:window-height="836"
@@ -751,8 +751,15 @@
+ inkscape:connector-curvature="0" + d="m 972,603 h 75 l -37.5,58 z m 37.5,-579.999998 37.5,58 H 972 Z M 969,236 h 81 V 407 H 969 Z M 960,84.000002 h 100 V 600 H 960 Z" + style="opacity:1;vector-effect:none;fill:none;fill-opacity:1;stroke:#000000;stroke-width:4;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:8, 8;stroke-dashoffset:0;stroke-opacity:1;marker:none" + inkscape:label="disabled" />