diff -r b18f78582f8c -r 910290aec533 svghmi/gen_index_xhtml.xslt --- a/svghmi/gen_index_xhtml.xslt Tue Feb 16 11:32:37 2021 +0100 +++ b/svghmi/gen_index_xhtml.xslt Tue Feb 16 11:35:56 2021 +0100 @@ -1,6 +1,6 @@ - - + + @@ -1135,6 +1135,8 @@ + + let hmi_locals = {}; var last_remote_index = hmitree_types.length - 1; @@ -1206,6 +1208,8 @@ var cache = hmitree_types.map(_ignored => undefined); + var updates = {}; + function page_local_index(varname, pagename){ @@ -1329,15 +1333,15 @@ /* flush updates pending because of inhibition */ - let inhibition = this.inhibit[index]; + let inhibition = this.inhibit[i]; if(inhibition != undefined){ clearTimeout(inhibition); - this.lastapply[index] = undefined; - - this.unhinibit(index); + this.lastapply[i] = undefined; + + this.unhinibit(i); } @@ -1665,7 +1669,7 @@ - + @@ -2876,7 +2880,7 @@ this.fields[index] = value; - this.element.textContent = this.args.length == 1 ? vsprintf(this.args[0],this.fields) : this.fields.join(' '); + this.request_animate(); } @@ -2885,11 +2889,22 @@ - + + + + + format + + + + + + + Display Widget id=" - " is not a svg::text element + " must be a svg::text element itself or a group containing a svg:text element labelled "format" @@ -2911,6 +2926,42 @@ ], + animate: function(){ + + + + if(this.format_elt.getAttribute("lang")) { + + this.format = svg_text_to_multiline(this.format_elt); + + this.format_elt.removeAttribute("lang"); + + } + + let str = vsprintf(this.format,this.fields); + + multiline_to_svg_text(this.format_elt, str); + + + + let str = this.args.length == 1 ? vsprintf(this.args[0],this.fields) : this.fields.join(' '); + + multiline_to_svg_text(this.element, str); + + + + }, + + + + + init: function() { + + this.format = svg_text_to_multiline(this.format_elt); + + }, + + @@ -5602,15 +5653,13 @@ case 0: - if (Math.round(this.position) != value) - - this.position = value; + this.position = value; break; case 1: - this.range = value; + this.range = Math.max(1,value); break; @@ -5688,9 +5737,9 @@ apply_position(position){ - this.position = Math.max(Math.min(position, this.range), 0); - - this.apply_hmi_value(0, Math.round(this.position)); + this.position = Math.round(Math.max(Math.min(position, this.range), 0)); + + this.apply_hmi_value(0, this.position); } @@ -5726,6 +5775,8 @@ svg_root.addEventListener("pointermove", this.bound_drag, true); + this.dragpos = this.position; + } @@ -5750,7 +5801,9 @@ let movement = point.matrixTransform(this.invctm).y; - this.apply_position(this.position + movement * units / pixels); + this.dragpos += movement * units / pixels; + + this.apply_position(this.dragpos); } @@ -6653,7 +6706,7 @@ - + @@ -6694,14 +6747,10 @@ - var updates = {}; - var need_cache_apply = []; - - function dispatch_value(index, value) { let widgets = subscribers(index); @@ -6982,6 +7031,8 @@ NODE: (truth) => new Int16Array([truth]), + REAL: (number) => new Float32Array([number]), + STRING: (str) => { // beremiz default string max size is 128 @@ -7102,7 +7153,19 @@ - var translated = false; + function svg_text_to_multiline(elt) { + + return(Array.prototype.map.call(elt.children, x=>x.textContent).join("\n")); + + } + + + + function multiline_to_svg_text(elt, str) { + + str.split('\n').map((line,i) => {elt.children[i].textContent = line;}); + + } @@ -7116,350 +7179,352 @@ - if (!translated) { - - translated = true; - - for (let translation of translations) { - - let [objs] = translation; - - translation.push(Array.prototype.map.call(objs[0].children, x=>x.textContent).join("\n")); + for (let translation of translations) { + + let [objs, msgs, orig] = translation; + + let msg = langnum == 0 ? orig : msgs[langnum - 1]; + + for (let obj of objs) { + + multiline_to_svg_text(obj, msg); + + obj.setAttribute("lang",langnum); } } - - - for (let translation of translations) { - - let [objs, msgs, orig] = translation; - - let msg = langnum == 0 ? orig : msgs[langnum - 1]; - - for (let obj of objs) { - - msg.split('\n').map((line,i) => {obj.children[i].textContent = line;}); + current_lang = langnum; + + } + + + + // backup original texts + + for (let translation of translations) { + + let [objs] = translation; + + translation.push(svg_text_to_multiline(objs[0])); + + } + + + + var lang_local_index = hmi_local_index("lang"); + + subscribers(lang_local_index).add({ + + indexes: [lang_local_index], + + new_hmi_value: function(index, value, oldval) { + + switch_langnum(value); + + switch_page(); + + } + + }); + + var current_lang = 0; + + switch_langnum(cache[lang_local_index]); + + + + function update_subscriptions() { + + let delta = []; + + for(let index in subscriptions){ + + let widgets = subscribers(index); + + + + // periods are in ms + + let previous_period = get_subscription_period(index); + + + + // subscribing with a zero period is unsubscribing + + let new_period = 0; + + if(widgets.size > 0) { + + let maxfreq = 0; + + for(let widget of widgets){ + + let wf = widget.frequency; + + if(wf != undefined && maxfreq < wf) + + maxfreq = wf; + + } + + + + if(maxfreq != 0) + + new_period = 1000/maxfreq; } + + + if(previous_period != new_period) { + + set_subscription_period(index, new_period); + + if(index <= last_remote_index){ + + delta.push( + + new Uint8Array([2]), /* subscribe = 2 */ + + new Uint32Array([index]), + + new Uint16Array([new_period])); + + } + + } + } - current_lang = langnum; + send_blob(delta); + + }; + + + + function send_hmi_value(index, value) { + + if(index > last_remote_index){ + + updates[index] = value; + + + + if(persistent_indexes.has(index)){ + + let varname = persistent_indexes.get(index); + + document.cookie = varname+"="+value+"; max-age=3153600000"; + + } + + + + requestHMIAnimation(); + + return; + + } + + + + let iectype = hmitree_types[index]; + + let tobinary = typedarray_types[iectype]; + + send_blob([ + + new Uint8Array([0]), /* setval = 0 */ + + new Uint32Array([index]), + + tobinary(value)]); + + + + // DON'T DO THAT unless read_iterator in svghmi.c modifies wbuf as well, not only rbuf + + // cache[index] = value; + + }; + + + + function apply_hmi_value(index, new_val) { + + let old_val = cache[index] + + if(new_val != undefined && old_val != new_val) + + send_hmi_value(index, new_val); + + return new_val; } - var lang_local_index = hmi_local_index("lang"); - - subscribers(lang_local_index).add({ - - indexes: [lang_local_index], - - new_hmi_value: function(index, value, oldval) { - - switch_langnum(value); + + + const quotes = {"'":null, '"':null}; + + + + function eval_operation_string(old_val, opstr) { + + let op = opstr[0]; + + let given_val; + + if(opstr.length < 2) + + return undefined; + + if(opstr[1] in quotes){ + + if(opstr.length < 3) + + return undefined; + + if(opstr[opstr.length-1] == opstr[1]){ + + given_val = opstr.slice(2,opstr.length-1); + + } + + } else { + + given_val = Number(opstr.slice(1)); } - }); - - var current_lang = 0; - - switch_langnum(cache[lang_local_index]); - - - - function update_subscriptions() { - - let delta = []; - - for(let index in subscriptions){ - - let widgets = subscribers(index); - - - - // periods are in ms - - let previous_period = get_subscription_period(index); - - - - // subscribing with a zero period is unsubscribing - - let new_period = 0; - - if(widgets.size > 0) { - - let maxfreq = 0; - - for(let widget of widgets){ - - let wf = widget.frequency; - - if(wf != undefined && maxfreq < wf) - - maxfreq = wf; - - } - - - - if(maxfreq != 0) - - new_period = 1000/maxfreq; - - } - - - - if(previous_period != new_period) { - - set_subscription_period(index, new_period); - - if(index <= last_remote_index){ - - delta.push( - - new Uint8Array([2]), /* subscribe = 2 */ - - new Uint32Array([index]), - - new Uint16Array([new_period])); - - } - - } + let new_val; + + switch(op){ + + case "=": + + new_val = given_val; + + break; + + case "+": + + new_val = old_val + given_val; + + break; + + case "-": + + new_val = old_val - given_val; + + break; + + case "*": + + new_val = old_val * given_val; + + break; + + case "/": + + new_val = old_val / given_val; + + break; } - send_blob(delta); + return new_val; + + } + + + + var current_visible_page; + + var current_subscribed_page; + + var current_page_index; + + + + function prepare_svg() { + + // prevents context menu from appearing on right click and long touch + + document.body.addEventListener('contextmenu', e => { + + e.preventDefault(); + + }); + + + + for(let eltid in detachable_elements){ + + let [element,parent] = detachable_elements[eltid]; + + parent.removeChild(element); + + } }; - function send_hmi_value(index, value) { - - if(index > last_remote_index){ - - updates[index] = value; - - - - if(persistent_indexes.has(index)){ - - let varname = persistent_indexes.get(index); - - document.cookie = varname+"="+value+"; max-age=3153600000"; - - } - - - - requestHMIAnimation(); - - return; + function switch_page(page_name, page_index) { + + if(current_subscribed_page != current_visible_page){ + + /* page switch already going */ + + /* TODO LOG ERROR */ + + return false; } - let iectype = hmitree_types[index]; - - let tobinary = typedarray_types[iectype]; - - send_blob([ - - new Uint8Array([0]), /* setval = 0 */ - - new Uint32Array([index]), - - tobinary(value)]); - - - - // DON'T DO THAT unless read_iterator in svghmi.c modifies wbuf as well, not only rbuf - - // cache[index] = value; - - }; - - - - function apply_hmi_value(index, new_val) { - - let old_val = cache[index] - - if(new_val != undefined && old_val != new_val) - - send_hmi_value(index, new_val); - - return new_val; - - } - - - - const quotes = {"'":null, '"':null}; - - - - function eval_operation_string(old_val, opstr) { - - let op = opstr[0]; - - let given_val; - - if(opstr.length < 2) - - return undefined; - - if(opstr[1] in quotes){ - - if(opstr.length < 3) - - return undefined; - - if(opstr[opstr.length-1] == opstr[1]){ - - given_val = opstr.slice(2,opstr.length-1); - - } - - } else { - - given_val = Number(opstr.slice(1)); + if(page_name == undefined) + + page_name = current_subscribed_page; + + + + + + let old_desc = page_desc[current_subscribed_page]; + + let new_desc = page_desc[page_name]; + + + + if(new_desc == undefined){ + + /* TODO LOG ERROR */ + + return false; } - let new_val; - - switch(op){ - - case "=": - - new_val = given_val; - - break; - - case "+": - - new_val = old_val + given_val; - - break; - - case "-": - - new_val = old_val - given_val; - - break; - - case "*": - - new_val = old_val * given_val; - - break; - - case "/": - - new_val = old_val / given_val; - - break; + + + if(page_index == undefined){ + + page_index = new_desc.page_index; } - return new_val; - - } - - - - var current_visible_page; - - var current_subscribed_page; - - var current_page_index; - - - - function prepare_svg() { - - // prevents context menu from appearing on right click and long touch - - document.body.addEventListener('contextmenu', e => { - - e.preventDefault(); - - }); - - - - for(let eltid in detachable_elements){ - - let [element,parent] = detachable_elements[eltid]; - - parent.removeChild(element); + + + if(old_desc){ + + old_desc.widgets.map(([widget,relativeness])=>widget.unsub()); } - }; - - - - function switch_page(page_name, page_index) { - - if(current_subscribed_page != current_visible_page){ - - /* page switch already going */ - - /* TODO LOG ERROR */ - - return false; - - } - - - - if(page_name == undefined) - - page_name = current_subscribed_page; - - - - - - let old_desc = page_desc[current_subscribed_page]; - - let new_desc = page_desc[page_name]; - - - - if(new_desc == undefined){ - - /* TODO LOG ERROR */ - - return false; - - } - - - - if(page_index == undefined){ - - page_index = new_desc.page_index; - - } - - - - if(old_desc){ - - old_desc.widgets.map(([widget,relativeness])=>widget.unsub()); - - } - const new_offset = page_index == undefined ? 0 : page_index - new_desc.page_index; @@ -7488,8 +7553,6 @@ requestHMIAnimation(); - - jump_history.push([page_name, page_index]); if(jump_history.length > 42)