svghmi/widget_switch.ysl2
author Edouard Tisserant <edouard@beremiz.fr>
Fri, 30 Aug 2024 11:50:23 +0200
changeset 4008 f30573e98600
parent 3518 c663d1f9f03b
permissions -rw-r--r--
IDE: allow structures to be located.
// 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()" > ,`
    }
    |     ],
}