SVGHMI: add support for "reference" and "frame" rectangles to spread-out ovelapping elements.
When HMI become complicated, designer needs to spread-out ovelapping elements
in order to unclutter drawing and facilitate maintenance.
// widget_switch.ysl2
widget_desc("Switch") {
longdesc
||
Switch widget hides all subelements whose label do not match given
variable current value representation. For exemple if given variable type
is HMI_INT and value is 1, then elements with label '1' will be displayed.
Label can have comments, so '1#some comment' would also match. If matching
variable of type HMI_STRING, then double quotes must be used. For exemple,
'"hello"' or '"hello"#another comment' match HMI_STRING 'hello'.
||
shortdesc > Show elements whose label matches value.
// TODO: add optional format/precision argument to support floating points
// TODO: support (in)equations and ranges
path name="value" accepts="HMI_INT,HMI_STRING" > value to compare to labels
}
widget_class("Switch")
||
frequency = 5;
current_value = undefined;
init(){
this.animate();
}
dispatch(value) {
this.current_value = value;
this.request_animate();
}
animate(){
for(let choice of this.choices){
if(this.current_value != choice.value){
if(choice.parent == undefined){
choice.parent = choice.elt.parentElement;
choice.parent.removeChild(choice.elt);
}
} else {
if(choice.parent != undefined){
choice.parent.insertBefore(choice.elt,choice.sibling);
choice.parent = undefined;
}
}
}
}
||
widget_defs("Switch") {
| choices: [
const "regex",!"'^(\"[^\"].*\"|\-?[0-9]+|false|true)(#.*)?$'"!;
// this prevents matching element in sub-widgets
const "subelts", "$result_widgets[@id = $hmi_element/@id]//*";
const "subwidgets", "$subelts//*[@id = $hmi_widgets/@id]";
const "accepted", "$subelts[not(ancestor-or-self::*/@id = $subwidgets/@id)]";
const "choices", "$accepted[regexp:test(@inkscape:label,$regex)]";
foreach "$choices" {
const "literal", "regexp:match(@inkscape:label,$regex)[2]";
const "sibling", "following-sibling::*[not(@id = $choices/@id)][position()=1]";
| {
| elt:id("«@id»"),
| parent:undefined,
choose {
when "count($sibling)=0" {
| sibling:null,
}
otherwise {
| sibling:id("«$sibling/@id»"),
}
}
| value:«$literal»
| }`if "position()!=last()" > ,`
}
| ],
}