# HG changeset patch # User Edouard Tisserant # Date 1663160563 -7200 # Node ID 5c983ead9db0183df7ca8a63700d2c1363dea626 # Parent 0e0252339e837d29f888845fcadd1c3e9b0c083a SVGHMI: update generated XSLT files diff -r 0e0252339e83 -r 5c983ead9db0 svghmi/analyse_widget.xslt --- a/svghmi/analyse_widget.xslt Wed Sep 14 14:59:18 2022 +0200 +++ b/svghmi/analyse_widget.xslt Wed Sep 14 15:02:43 2022 +0200 @@ -2,18 +2,18 @@ - + - + - - - + + + @@ -27,23 +27,23 @@ - + - + - - + + - + @@ -84,7 +84,7 @@ Widget id: label: - + has wrong syntax of frequency forcing @@ -93,6 +93,25 @@ + + + + + + + + + + + + + + + + + + + @@ -100,21 +119,29 @@ - + - - + + + + Widget id: + + label: + + has wrong syntax + + - - - + + + @@ -131,7 +158,7 @@ Widget id: label: - + has wrong syntax of path section @@ -157,7 +184,7 @@ Widget id: label: - + path section use min and max on non mumeric value @@ -274,8 +301,6 @@ - display = "inactive"; - state = "init"; dispatch(value) { @@ -302,19 +327,13 @@ } - animate(){ - - this.set_activation_state(this.display == "active"); - - } - init() { this.bound_onmouseup = this.onmouseup.bind(this); this.element.addEventListener("pointerdown", this.onmousedown.bind(this)); - this.set_activation_state(undefined); + this.activity_state = undefined; } @@ -604,15 +623,27 @@ - Jump widget brings focus to a different page. Mandatory single argument + Jump widget brings focus to a different page. Mandatory first argument gives name of the page. - Optional single path is used as new reference when jumping to a relative - - page, it must point to a HMI_NODE. + If first path is pointint to HMI_NODE variable is used as new reference + + when jumping to a relative page. + + + + Additional arguments are unordered options: + + + + - Absolute: force page jump to be not relative even if first path is of type HMI_NODE + + + + - name=value: Notify PLC about jump by setting variable with path having same name assigned @@ -622,9 +653,47 @@ - "disabled" labeled element, if provided, is shown instead of "active" or - - "inactive" widget when pointed HMI_NODE is null. + Exemples: + + + + Relative jump: + + + + HMI:Jump:RelativePage@/PUMP9 + + HMI:Jump:RelativePage@/PUMP9@role=.userrole#role=="admin" + + + + Absolute jump: + + + + HMI:Jump:AbsolutePage + + HMI:Jump:AbsolutePage@role=.userrole#role=="admin" + + + + Forced absolute jump: + + + + HMI:Jump:AbsolutePage:Absolute@/PUMP9 + + HMI:Jump:AbsolutePage:Absolute:notify=1@notify=/PUMP9 + + + + Jump with feedback + + + + HMI:Jump:AbsolutePage:notify=1@notify=.did_jump + + @@ -637,6 +706,10 @@ reference for relative jump + + + + diff -r 0e0252339e83 -r 5c983ead9db0 svghmi/gen_dnd_widget_svg.xslt --- a/svghmi/gen_dnd_widget_svg.xslt Wed Sep 14 14:59:18 2022 +0200 +++ b/svghmi/gen_dnd_widget_svg.xslt Wed Sep 14 15:02:43 2022 +0200 @@ -4,18 +4,18 @@ - + - + - - - + + + @@ -29,23 +29,23 @@ - + - + - - + + - + @@ -86,7 +86,7 @@ Widget id: label: - + has wrong syntax of frequency forcing @@ -95,6 +95,25 @@ + + + + + + + + + + + + + + + + + + + @@ -102,21 +121,29 @@ - + - - + + + + Widget id: + + label: + + has wrong syntax + + - - - + + + @@ -133,7 +160,7 @@ Widget id: label: - + has wrong syntax of path section @@ -159,7 +186,7 @@ Widget id: label: - + path section use min and max on non mumeric value diff -r 0e0252339e83 -r 5c983ead9db0 svghmi/gen_index_xhtml.xslt --- a/svghmi/gen_index_xhtml.xslt Wed Sep 14 14:59:18 2022 +0200 +++ b/svghmi/gen_index_xhtml.xslt Wed Sep 14 15:02:43 2022 +0200 @@ -159,18 +159,18 @@ - + - + - - - + + + @@ -184,23 +184,23 @@ - + - + - - + + - + @@ -241,7 +241,7 @@ Widget id: label: - + has wrong syntax of frequency forcing @@ -250,6 +250,25 @@ + + + + + + + + + + + + + + + + + + + @@ -257,21 +276,29 @@ - + - - + + + + Widget id: + + label: + + has wrong syntax + + - - - + + + @@ -288,7 +315,7 @@ Widget id: label: - + has wrong syntax of path section @@ -314,7 +341,7 @@ Widget id: label: - + path section use min and max on non mumeric value @@ -1246,6 +1273,14 @@ + + , + + + + + + [ @@ -1282,25 +1317,23 @@ - - , + , { + + minmax:[ + + , + + ] + + , + - - - - - - - [ - - , - - ] - - - undefined - - + + assign:" + + " + + }] , @@ -1318,6 +1351,16 @@ + + + + true + + + false + + + " ": new @@ -1329,11 +1372,57 @@ ,[ ],[ - - ],[ - - ],{ - + + ], + + ,{ + + + assignments: [], + + compute_enable: function(value, oldval, varnum) { + + let result = false; + + do { + + + + + + + + if(varnum == + + ) this.assignments[ + + ] = value; + + let + + = this.assignments[ + + ]; + + if( + + == undefined) break; + + + + + + result = + + ; + + } while(0); + + this.enable(result); + + }, + + @@ -1520,7 +1609,7 @@ - function set_activation_state(eltsub, state){ + function set_activity_state(eltsub, state){ if(eltsub.active_elt != undefined){ @@ -1554,22 +1643,6 @@ - function activate_activable(eltsub) { - - set_activation_state(eltsub, true); - - } - - - - function inactivate_activable(eltsub) { - - set_activation_state(eltsub, false); - - } - - - class Widget { offset = 0; @@ -1582,7 +1655,7 @@ - constructor(elt_id, freq, args, indexes, minmaxes, members){ + constructor(elt_id, freq, args, variables, enable_expr, members){ this.element_id = elt_id; @@ -1590,27 +1663,41 @@ this.args = args; - this.indexes = indexes; - - this.minmaxes = minmaxes; + + + [this.indexes, this.variables_options] = (variables.length>0) ? zip(...variables) : [[],[]]; + + this.indexes_length = this.indexes.length; + + + + this.enable_expr = enable_expr; + + this.enable_state = true; + + this.enable_displayed_state = true; + + this.enabled_elts = []; + + Object.keys(members).forEach(prop => this[prop]=members[prop]); - this.lastapply = indexes.map(() => undefined); - - this.inhibit = indexes.map(() => undefined); - - this.pending = indexes.map(() => undefined); + this.lastapply = this.indexes.map(() => undefined); + + this.inhibit = this.indexes.map(() => undefined); + + this.pending = this.indexes.map(() => undefined); this.bound_uninhibit = this.uninhibit.bind(this); - this.lastdispatch = indexes.map(() => undefined); - - this.deafen = indexes.map(() => undefined); - - this.incoming = indexes.map(() => undefined); + this.lastdispatch = this.indexes.map(() => undefined); + + this.deafen = this.indexes.map(() => undefined); + + this.incoming = this.indexes.map(() => undefined); this.bound_undeafen = this.undeafen.bind(this); @@ -1680,6 +1767,30 @@ } + + + if(this.enable_expr){ + + this.enable_state = false; + + this.enable_displayed_state = false; + + for(let child of Array.from(this.element.children)){ + + let label = child.getAttribute("inkscape:label"); + + if(label!="disabled"){ + + this.enabled_elts.push(child); + + this.element.removeChild(child); + + } + + } + + } + } @@ -1688,257 +1799,479 @@ /* remove subsribers */ - if(!this.unsubscribable) - - for(let i = 0; i < this.indexes.length; i++) { - - /* flush updates pending because of inhibition */ - - let inhibition = this.inhibit[i]; - - if(inhibition != undefined){ - - clearTimeout(inhibition); - - this.lastapply[i] = undefined; - - this.uninhibit(i); + for(let i = 0; i < this.indexes_length; i++) { + + /* flush updates pending because of inhibition */ + + let inhibition = this.inhibit[i]; + + if(inhibition != undefined){ + + clearTimeout(inhibition); + + this.lastapply[i] = undefined; + + this.uninhibit(i); + + } + + let deafened = this.deafen[i]; + + if(deafened != undefined){ + + clearTimeout(deafened); + + this.lastdispatch[i] = undefined; + + this.undeafen(i); + + } + + let index = this.get_variable_index(i); + + subscribers(index).delete(this); + + } + + this.offset = 0; + + this.relativeness = undefined; + + } + + + + sub(new_offset=0, relativeness, container_id){ + + this.offset = new_offset; + + this.relativeness = relativeness; + + this.container_id = container_id ; + + /* add this's subsribers */ + + for(let i = 0; i < this.indexes_length; i++) { + + let index = this.get_variable_index(i); + + if(index == undefined) continue; + + subscribers(index).add(this); + + } + + this.apply_cache(); + + } + + + + apply_cache() { + + for(let i = 0; i < this.indexes_length; i++) { + + /* dispatch current cache in newly opened page widgets */ + + let realindex = this.get_variable_index(i); + + if(realindex == undefined) continue; + + let cached_val = cache[realindex]; + + if(cached_val != undefined) + + this.feed_data_for_dispatch(cached_val, cached_val, i); + + } + + } + + + + get_variable_index(varnum) { + + let index = this.indexes[varnum]; + + if(typeof(index) == "string"){ + + index = page_local_index(index, this.container_id); + + } else { + + if(this.relativeness[varnum]){ + + index += this.offset; + + } + + } + + return index; + + } + + + + overshot(new_val, max) { + + } + + + + undershot(new_val, min) { + + } + + + + clip_min_max(index, new_val) { + + let minmax = this.variables_options[index].minmax; + + if(minmax !== undefined && typeof new_val == "number") { + + let [min,max] = minmax; + + if(new_val < min){ + + this.undershot(new_val, min); + + return min; + + } + + if(new_val > max){ + + this.overshot(new_val, max); + + return max; + + } + + } + + return new_val; + + } + + + + change_hmi_value(index, opstr) { + + let realindex = this.get_variable_index(index); + + if(realindex == undefined) return undefined; + + let old_val = cache[realindex]; + + let new_val = eval_operation_string(old_val, opstr); + + if(this.clip) + + new_val = this.clip_min_max(index, new_val); + + return apply_hmi_value(realindex, new_val); + + } + + + + _apply_hmi_value(index, new_val) { + + let realindex = this.get_variable_index(index); + + if(realindex == undefined) return undefined; + + if(this.clip) + + new_val = this.clip_min_max(index, new_val); + + return apply_hmi_value(realindex, new_val); + + } + + + + uninhibit(index){ + + this.inhibit[index] = undefined; + + let new_val = this.pending[index]; + + this.pending[index] = undefined; + + return this.apply_hmi_value(index, new_val); + + } + + + + apply_hmi_value(index, new_val) { + + if(this.inhibit[index] == undefined){ + + let now = Date.now(); + + let min_interval = 1000/this.frequency; + + let lastapply = this.lastapply[index]; + + if(lastapply == undefined || now > lastapply + min_interval){ + + this.lastapply[index] = now; + + return this._apply_hmi_value(index, new_val); + + } + + else { + + let elapsed = now - lastapply; + + this.pending[index] = new_val; + + this.inhibit[index] = setTimeout(this.bound_uninhibit, min_interval - elapsed, index); + + } + + } + + else { + + this.pending[index] = new_val; + + return new_val; + + } + + } + + + + new_hmi_value(index, value, oldval) { + + // TODO avoid searching, store index at sub() + + for(let i = 0; i < this.indexes_length; i++) { + + let refindex = this.get_variable_index(i); + + if(refindex == undefined) continue; + + + + if(index == refindex) { + + this.feed_data_for_dispatch(value, oldval, i); + + break; + + } + + } + + } + + + + undeafen(index){ + + this.deafen[index] = undefined; + + let [new_val, old_val] = this.incoming[index]; + + this.incoming[index] = undefined; + + this.do_dispatch(new_val, old_val, index); + + } + + + + enable(enabled){ + + if(this.enable_state != enabled){ + + this.enable_state = enabled; + + this.request_animate(); + + } + + } + + + + animate_enable(){ + + if(this.enable_state && !this.enable_displayed_state){ + + //show widget + + 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){ + + + + //hide widget + + for(let child of this.enabled_elts){ + + if(child.parentNode != null) + + this.element.removeChild(child); + + } + + + + //show disabled content + + if(this.disabled_elt) + + this.element.appendChild(this.disabled_elt); + + + + this.enable_displayed_state = false; + + + + // once disabled activity display is lost + + this.activity_displayed_state = undefined; + + } + + } + + + + feed_data_for_dispatch(value, oldval, varnum) { + + if(this.dispatch || this.enable_expr){ + + if(this.deafen[varnum] == undefined){ + + let now = Date.now(); + + let min_interval = 1000/this.frequency; + + let lastdispatch = this.lastdispatch[varnum]; + + if(lastdispatch == undefined || now > lastdispatch + min_interval){ + + this.lastdispatch[varnum] = now; + + this.do_dispatch(value, oldval, varnum) } - let deafened = this.deafen[i]; - - if(deafened != undefined){ - - clearTimeout(deafened); - - this.lastdispatch[i] = undefined; - - this.undeafen(i); + else { + + let elapsed = now - lastdispatch; + + this.incoming[varnum] = [value, oldval]; + + this.deafen[varnum] = setTimeout(this.bound_undeafen, min_interval - elapsed, varnum); } - let index = this.indexes[i]; - - if(this.relativeness[i]) - - index += this.offset; - - subscribers(index).delete(this); - } - this.offset = 0; - - this.relativeness = undefined; - - } - - - - sub(new_offset=0, relativeness, container_id){ - - this.offset = new_offset; - - this.relativeness = relativeness; - - this.container_id = container_id ; - - /* add this's subsribers */ - - if(!this.unsubscribable) - - for(let i = 0; i < this.indexes.length; i++) { - - let index = this.get_variable_index(i); - - if(index == undefined) continue; - - subscribers(index).add(this); + else { + + this.incoming[varnum] = [value, oldval]; } - need_cache_apply.push(this); - - } - - - - apply_cache() { - - if(!this.unsubscribable) for(let index in this.indexes){ - - /* dispatch current cache in newly opened page widgets */ - - let realindex = this.get_variable_index(index); - - if(realindex == undefined) continue; - - let cached_val = cache[realindex]; - - if(cached_val != undefined) - - this._dispatch(cached_val, cached_val, index); - } } - get_variable_index(varnum) { - - let index = this.indexes[varnum]; - - if(typeof(index) == "string"){ - - index = page_local_index(index, this.container_id); - - } else { - - if(this.relativeness[varnum]){ - - index += this.offset; - - } + do_dispatch(value, oldval, varnum) { + + if(this.dispatch) try { + + this.dispatch(value, oldval, varnum); + + } catch(err) { + + console.log(err); } - return index; - - } - - - - overshot(new_val, max) { - - } - - - - undershot(new_val, min) { - - } - - - - clip_min_max(index, new_val) { - - let minmax = this.minmaxes[index]; - - if(minmax !== undefined && typeof new_val == "number") { - - let [min,max] = minmax; - - if(new_val < min){ - - this.undershot(new_val, min); - - return min; - - } - - if(new_val > max){ - - this.overshot(new_val, max); - - return max; - - } + if(this.enable_expr) try { + + this.compute_enable(value, oldval, varnum); + + } catch(err) { + + console.log(err); } - return new_val; - - } - - - - change_hmi_value(index, opstr) { - - let realindex = this.get_variable_index(index); - - if(realindex == undefined) return undefined; - - let old_val = cache[realindex]; - - let new_val = eval_operation_string(old_val, opstr); - - if(this.clip) - - new_val = this.clip_min_max(index, new_val); - - return apply_hmi_value(realindex, new_val); - - } - - - - _apply_hmi_value(index, new_val) { - - let realindex = this.get_variable_index(index); - - if(realindex == undefined) return undefined; - - if(this.clip) - - new_val = this.clip_min_max(index, new_val); - - return apply_hmi_value(realindex, new_val); - - } - - - - uninhibit(index){ - - this.inhibit[index] = undefined; - - let new_val = this.pending[index]; - - this.pending[index] = undefined; - - return this.apply_hmi_value(index, new_val); - - } - - - - apply_hmi_value(index, new_val) { - - if(this.inhibit[index] == undefined){ - - let now = Date.now(); - - let min_interval = 1000/this.frequency; - - let lastapply = this.lastapply[index]; - - if(lastapply == undefined || now > lastapply + min_interval){ - - this.lastapply[index] = now; - - return this._apply_hmi_value(index, new_val); - - } - - else { - - let elapsed = now - lastapply; - - this.pending[index] = new_val; - - this.inhibit[index] = setTimeout(this.bound_uninhibit, min_interval - elapsed, index); - - } + } + + + + _animate(){ + + if(this.enable_expr) + + this.animate_enable(); + + // inhibit widget animation when disabled + + if(!this.enable_expr || this.enable_state){ + + if(this.has_activity) + + this.animate_activity(); + + if(this.animate != undefined) + + this.animate(); } - else { - - this.pending[index] = new_val; - - return new_val; + this.pending_animate = false; + + } + + + + request_animate(){ + + if(!this.pending_animate){ + + pending_widget_animates.push(this); + + this.pending_animate = true; + + requestHMIAnimation(); } @@ -1946,132 +2279,18 @@ - new_hmi_value(index, value, oldval) { - - // TODO avoid searching, store index at sub() - - for(let i = 0; i < this.indexes.length; i++) { - - let refindex = this.get_variable_index(i); - - if(refindex == undefined) continue; - - - - if(index == refindex) { - - this._dispatch(value, oldval, i); - - break; - - } + animate_activity(){ + + if(this.activity_displayed_state != this.activity_state){ + + set_activity_state(this.activable_sub, this.activity_state); + + this.activity_displayed_state = this.activity_state; } } - - - undeafen(index){ - - this.deafen[index] = undefined; - - let [new_val, old_val] = this.incoming[index]; - - this.incoming[index] = undefined; - - this.dispatch(new_val, old_val, index); - - } - - - - _dispatch(value, oldval, varnum) { - - let dispatch = this.dispatch; - - if(dispatch != undefined){ - - if(this.deafen[varnum] == undefined){ - - let now = Date.now(); - - let min_interval = 1000/this.frequency; - - let lastdispatch = this.lastdispatch[varnum]; - - if(lastdispatch == undefined || now > lastdispatch + min_interval){ - - this.lastdispatch[varnum] = now; - - try { - - dispatch.call(this, value, oldval, varnum); - - } catch(err) { - - console.log(err); - - } - - } - - else { - - let elapsed = now - lastdispatch; - - this.incoming[varnum] = [value, oldval]; - - this.deafen[varnum] = setTimeout(this.bound_undeafen, min_interval - elapsed, varnum); - - } - - } - - else { - - this.incoming[varnum] = [value, oldval]; - - } - - } - - } - - - - _animate(){ - - this.animate(); - - this.pending_animate = false; - - } - - - - request_animate(){ - - if(!this.pending_animate){ - - pending_widget_animates.push(this); - - this.pending_animate = true; - - requestHMIAnimation(); - - } - - } - - - - set_activation_state(state){ - - set_activation_state(this.activable_sub, state); - - } - } @@ -2693,9 +2912,9 @@ - this.display = " - - "; + this.activity_state = + + ; this.request_animate(); @@ -2708,8 +2927,6 @@ - display = "inactive"; - state = "init"; dispatch(value) { @@ -2736,19 +2953,13 @@ } - animate(){ - - this.set_activation_state(this.display == "active"); - - } - init() { this.bound_onmouseup = this.onmouseup.bind(this); this.element.addEventListener("pointerdown", this.onmousedown.bind(this)); - this.set_activation_state(undefined); + this.activity_state = undefined; } @@ -2769,16 +2980,37 @@ + + + + + /disabled + + + + + + activable_sub:{ - - - - /active /inactive - - - - } + + + + + /active /inactive + + + warn + + + + + + }, + + has_activity: + + , @@ -2797,16 +3029,37 @@ + + + + + /disabled + + + + + + activable_sub:{ - - - - /active /inactive - - - - } + + + + + /active /inactive + + + warn + + + + + + }, + + has_activity: + + , @@ -2948,6 +3201,17 @@ + + + + + /disabled + + + + + + @@ -3463,6 +3727,17 @@ + + + + + /disabled + + + + + + @@ -3543,6 +3818,17 @@ + + + + + /disabled + + + + + + @@ -3614,6 +3900,17 @@ + + + + + /disabled + + + + + + @@ -4420,6 +4717,17 @@ + + + + + /disabled + + + + + + @@ -4558,6 +4866,17 @@ + + + + + /disabled + + + + + + ForEach widget @@ -4797,7 +5116,7 @@ update_subscriptions(); - need_cache_apply.push(this); + this.apply_cache(); jumps_need_update = true; @@ -4910,6 +5229,17 @@ + + + + + /disabled + + + + + + @@ -5441,6 +5771,17 @@ + + + + + /disabled + + + + + + @@ -5490,27 +5831,77 @@ - Jump widget brings focus to a different page. Mandatory single argument + Jump widget brings focus to a different page. Mandatory first argument gives name of the page. - Optional single path is used as new reference when jumping to a relative - - page, it must point to a HMI_NODE. + If first path is pointint to HMI_NODE variable is used as new reference + + when jumping to a relative page. + Additional arguments are unordered options: + + + + - Absolute: force page jump to be not relative even if first path is of type HMI_NODE + + + + - name=value: Notify PLC about jump by setting variable with path having same name assigned + + + "active"+"inactive" labeled elements can be provided and reflect current page being shown. - "disabled" labeled element, if provided, is shown instead of "active" or - - "inactive" widget when pointed HMI_NODE is null. + Exemples: + + + + Relative jump: + + + + HMI:Jump:RelativePage@/PUMP9 + + HMI:Jump:RelativePage@/PUMP9@role=.userrole#role=="admin" + + + + Absolute jump: + + + + HMI:Jump:AbsolutePage + + HMI:Jump:AbsolutePage@role=.userrole#role=="admin" + + + + Forced absolute jump: + + + + HMI:Jump:AbsolutePage:Absolute@/PUMP9 + + HMI:Jump:AbsolutePage:Absolute:notify=1@notify=/PUMP9 + + + + Jump with feedback + + + + HMI:Jump:AbsolutePage:notify=1@notify=.did_jump + + @@ -5530,35 +5921,41 @@ activable = false; - active = false; - - disabled = false; - frequency = 2; - update_activity() { - - if(this.active) { - - /* show active */ - - this.active_elt.style.display = ""; - - /* hide inactive */ - - this.inactive_elt.style.display = "none"; - - } else { - - /* show inactive */ - - this.inactive_elt.style.display = ""; - - /* hide active */ - - this.active_elt.style.display = "none"; + make_on_click() { + + let that = this; + + const name = this.args[0]; + + return function(evt){ + + /* TODO: in order to allow jumps to page selected through + + for exemple a dropdown, support path pointing to local + + variable whom value would be an HMI_TREE index and then + + jump to a relative page not hard-coded in advance + + */ + + if(that.enable_state) { + + const index = + + (that.is_relative && that.indexes.length > 0) ? + + that.indexes[0] + that.offset : undefined; + + fading_page_switch(name, index); + + that.notify(); + + } } @@ -5566,156 +5963,124 @@ - update_disability() { - - if(this.disabled) { - - /* show disabled */ - - this.disabled_elt.style.display = ""; - - /* hide inactive */ - - this.inactive_elt.style.display = "none"; - - /* hide active */ - - this.active_elt.style.display = "none"; - - } else { - - /* hide disabled */ - - this.disabled_elt.style.display = "none"; - - this.update_activity(); + notify_page_change(page_name, index) { + + // called from animate() + + if(this.activable) { + + const ref_index = this.indexes.length > 0 ? this.indexes[0] + this.offset : undefined; + + const ref_name = this.args[0]; + + this.activity_state = ((ref_name == undefined || ref_name == page_name) && index == ref_index); + + // Since called from animate, update activity directly + + if(this.enable_displayed_state && this.has_activity) { + + this.animate_activity(); + + } } } - - - make_on_click() { - - let that = this; - - const name = this.args[0]; - - return function(evt){ - - /* TODO: in order to allow jumps to page selected through for exemple a dropdown, - - support path pointing to local variable whom value - - would be an HMI_TREE index and then jump to a relative page not hard-coded in advance */ - - if(!that.disabled) { - - const index = that.indexes.length > 0 ? that.indexes[0] + that.offset : undefined; - - fading_page_switch(name, index); - - } - - } - - } - - - - notify_page_change(page_name, index) { - - if(this.activable) { - - const ref_index = this.indexes.length > 0 ? this.indexes[0] + this.offset : undefined; - - const ref_name = this.args[0]; - - this.active = ((ref_name == undefined || ref_name == page_name) && index == ref_index); - - this.update_state(); - - } - - } - - - - dispatch(value) { - - this.disabled = !Number(value); - - - - // TODO : use RequestAnimate and animate() - - - - this.update_state(); - - } - } + + + + + + + + + /disabled + + + + + + + activable_sub:{ + - active inactive + /active /inactive - + + no + - - - - - - disabled - - - - - - + + }, + + has_activity: + + , + + init: function() { this.element.onclick = this.make_on_click(); - + this.activable = true; - - this.unsubscribable = true; - - - this.update_state = + this.is_relative = - - this.update_disability - - - this.update_activity + + true - null + false ; }, + notify: function() { + + + + + + + + + + + + + // + + + + this.apply_hmi_value( + + , + + ); + + + }, + - + @@ -5800,6 +6165,8 @@ function update_jumps() { + // called from animate() + page_desc[current_visible_page].jumps.map(w=>w.notify_page_change(current_visible_page,current_page_index)); jumps_need_update = false; @@ -6048,7 +6415,7 @@ this._shift = this.shift; - set_activation_state(this.Shift_sub, this.shift); + set_activity_state(this.Shift_sub, this.shift); } @@ -6056,7 +6423,7 @@ this._caps = this.caps; - set_activation_state(this.CapsLock_sub, this.caps); + set_activity_state(this.CapsLock_sub, this.caps); } @@ -6067,6 +6434,17 @@ + + + + + /disabled + + + + + + @@ -6159,6 +6537,17 @@ + + + + + /disabled + + + + + + items: { @@ -6223,6 +6612,17 @@ + + + + + /disabled + + + + + + dispatch: function(value) { @@ -6329,6 +6729,17 @@ + + + + + /disabled + + + + + + @@ -6345,6 +6756,17 @@ + + + + + /disabled + + + + + + Mutlistateh widget hides all subelements whose label do not match given @@ -6460,6 +6882,17 @@ + + + + + /disabled + + + + + + choices: [ @@ -6822,6 +7255,17 @@ + + + + + /disabled + + + + + + @@ -7030,6 +7474,17 @@ + + + + + /disabled + + + + + + @@ -7757,6 +8212,17 @@ + + + + + /disabled + + + + + + @@ -7860,6 +8326,17 @@ + + + + + /disabled + + + + + + choices: [ @@ -7933,6 +8410,17 @@ + + + + + /disabled + + + + + + texts: [ @@ -7979,6 +8467,17 @@ + + + + + /disabled + + + + + + styles: { @@ -8027,8 +8526,6 @@ frequency = 5; - state = 0; - active_style = undefined; inactive_style = undefined; @@ -8037,7 +8534,7 @@ dispatch(value) { - this.state = value; + this.activity_state = Boolean(value); //redraw toggle button @@ -8051,9 +8548,9 @@ //toggle state and apply - this.state = this.state ? false : true; - - this.apply_hmi_value(0, this.state); + this.activity_state = this.activity_state ? false : true; + + this.apply_hmi_value(0, this.activity_state); @@ -8065,21 +8562,11 @@ - animate(){ - - // redraw toggle button on screen refresh - - this.set_activation_state(this.state); - - } - - - init() { this.element.onclick = (evt) => this.on_click(evt); - this.set_activation_state(undefined); + this.activity_state = undefined; } @@ -8088,16 +8575,37 @@ + + + + + /disabled + + + + + + activable_sub:{ - - - - /active /inactive - - - - } + + + + + /active /inactive + + + warn + + + + + + }, + + has_activity: + + , @@ -8571,6 +9079,17 @@ + + + + + /disabled + + + + + + @@ -9448,6 +9967,436 @@