--- a/svghmi/parse_labels.ysl2 Tue May 17 13:22:20 2022 +0200
+++ b/svghmi/parse_labels.ysl2 Tue May 17 14:49:23 2022 +0200
@@ -44,7 +44,12 @@
- if "$freq" attrib "freq" > «$freq»
+ if "not(regexp:test($freq,'^[0-9]*(\.[0-9]+)?[smh]'))" { + error > Widget id:«$id» label:«$label» has wrong syntax of frequency forcing «$freq» + attrib "freq" > «$freq» foreach "str:split(substring-after($args, ':'), ':')" {
--- a/svghmi/sprintf.js Tue May 17 13:22:20 2022 +0200
+++ b/svghmi/sprintf.js Tue May 17 14:49:23 2022 +0200
@@ -15,7 +15,7 @@
- placeholder: /^\x25(?:([1-9]\d*)\$|\(([^)]+)\))?(\+)?(0|'[^$])?(-)?(\d+)?(?:\.(\d+))?([b-gijostTuvxX])/,
+ placeholder: /^\x25(?:([1-9]\d*)\$|\(([^)]+)\))?(\+)?(0|'[^$])?(-)?(\d+)?(?:\.(\d+))?([b-gijostTuvxXD])/, key: /^([a-z_][a-z_\d]*)/i,
key_access: /^\.([a-z_][a-z_\d]*)/i,
index_access: /^\[(\d+)\]/,
@@ -78,6 +78,51 @@
+ select date format with width + select time format with precision + %D => 13:31 AM (default) + %1.1D => 07/07/20, 13:31 AM + %1.2D => 07/07/20, 13:31:55 AM + %2.2D => May 5, 2022, 9:29:16 AM + %3.3D => May 5, 2022 at 9:28:16 AM GMT+2 + %4.4D => Thursday, May 5, 2022 at 9:26:59 AM Central European Summer Time + see meaning of DateTimeFormat's options "datestyle" and "timestyle" in MDN + let [datestyle, timestyle] = [ph.width, ph.precision].map(val => { + if(timestyle === undefined && datestyle === undefined){ + /* get lang from globals */ + let lang = get_current_lang_code(); + arg = Date(arg).toLocaleString('en-US', options); + TODO: select with padding char + a: absolute time and date (default) arg = JSON.stringify(arg, null, ph.width ? parseInt(ph.width) : 0)
--- a/svghmi/svghmi.js Tue May 17 13:22:20 2022 +0200
+++ b/svghmi/svghmi.js Tue May 17 14:49:23 2022 +0200
@@ -18,16 +18,7 @@
function init_widgets() {
Object.keys(hmi_widgets).forEach(function(id) {
let widget = hmi_widgets[id];
- let init = widget.init;
- if(typeof(init) == "function"){
- if(widget.forced_frequency !== undefined)
- widget.frequency = widget.forced_frequency;
@@ -264,6 +255,11 @@
+// returns en_US, fr_FR or en_UK depending on selected language +function get_current_lang_code(){ + return cache[langcode_local_index]; let current_lang = cache[lang_local_index];
let new_lang = switch_langnum(current_lang);
--- a/svghmi/ui.py Tue May 17 13:22:20 2022 +0200
+++ b/svghmi/ui.py Tue May 17 14:49:23 2022 +0200
@@ -621,17 +621,20 @@
self.args_box.Show(len(args)!=0)
for arg, prefillarg in izip(args,prefillargs):
self.AddArgToSignature(arg, prefillarg)
+ # TODO support predefined path count (as for XYGraph) paths = defs.findall("path")
self.paths_box.Show(len(paths)!=0)
self.AddPathToSignature(path)
- widget_type = widget.get("type")
- for path in widget.iterchildren("path"):
- path_value = path.get("value")
- str.strip, path.get("accepts", '')[1:-1].split(','))
+ # for widget in widgets: + # widget_type = widget.get("type") + # for path in widget.iterchildren("path"): + # path_value = path.get("value") + # str.strip, path.get("accepts", '')[1:-1].split(',')) self.main_panel.SetupScrolling(scroll_x=False)
--- a/svghmi/widget_pathslider.ysl2 Tue May 17 13:22:20 2022 +0200
+++ b/svghmi/widget_pathslider.ysl2 Tue May 17 14:49:23 2022 +0200
@@ -1,8 +1,8 @@
// widget_pathslider.ysl2
widget_desc("PathSlider") {
shortdesc > Slide an SVG element along a path by dragging it
@@ -10,7 +10,7 @@
path name="value" accepts="HMI_INT,HMI_REAL" > value
path name="min" count="optional" accepts="HMI_INT,HMI_REAL" > min
path name="max" count="optional" accepts="HMI_INT,HMI_REAL" > max
arg name="min" count="optional" accepts="int,real" > minimum value
arg name="max" count="optional" accepts="int,real" > maximum value
@@ -25,7 +25,7 @@
this.pathLength = this.path_elt.getTotalLength();
@@ -67,7 +67,7 @@
bestLength = beforeLength,
bestDistance = beforeDistance;
- } else if ((afterLength = bestLength + precision) <= this.pathLength &&
+ } else if ((afterLength = bestLength + precision) <= this.pathLength && (afterDistance = distance2(afterPoint = this.path_elt.getPointAtLength(afterLength))) < bestDistance) {
bestLength = afterLength,
--- a/svghmi/widgets_common.ysl2 Tue May 17 13:22:20 2022 +0200
+++ b/svghmi/widgets_common.ysl2 Tue May 17 14:49:23 2022 +0200
@@ -85,7 +85,7 @@
@@ -183,6 +183,37 @@
this.pending = indexes.map(() => undefined);
this.bound_unhinibit = this.unhinibit.bind(this);
this.forced_frequency = freq;
+ if(widget.forced_frequency !== undefined){ + let s = widget.forced_frequency; + once every 10 seconds : 10s + let unit = s.slice(-1); + widget.frequency = factor ? 1/(factor * Number(s.slice(0,-1))) + if(typeof(init) == "function"){ @@ -269,14 +300,16 @@
if(realindex == undefined) return undefined;
let old_val = cache[realindex];
let new_val = eval_operation_string(old_val, opstr);
- new_val = this.clip_min_max(index, new_val);
+ 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;
- new_val = this.clip_min_max(index, new_val);
+ new_val = this.clip_min_max(index, new_val); return apply_hmi_value(realindex, new_val);
@@ -395,8 +428,10 @@
const "widget_type","@type";
foreach "str:split($labels)" {
- const "elt","$result_widgets[@id = $hmi_element/@id]//*[@inkscape:label=$name][1]";
+ const "absolute", "starts-with(., '/')"; + const "name","substring(.,number($absolute)+1)"; + const "widget","$result_widgets[@id = $hmi_element/@id]"; + const "elt","($widget//*[not($absolute) and @inkscape:label=$name] | $widget/*[$absolute and @inkscape:label=$name])[1]";