svghmi/widget_multistate.ysl2
author Edouard Tisserant <edouard.tisserant@gmail.com>
Sun, 01 Jan 2023 22:39:41 +0100
branchwxPython4
changeset 3713 cf7c91183995
parent 3577 6c7a7b22bec9
permissions -rw-r--r--
Tests: use expedited termination of IDE with SIGTERM instead of normal close

Work around test not finishing when IDE ask for confirmation on exit when
project is modified.
// widget_multistate.ysl2

widget_defs("MultiState") {

    longdesc
    ||
    Mutlistateh widget hides all subelements whose label do not match given
    variable 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'.

    Click on widget changes variable value to next value in given list, or to
    first one if not initialized to value already part of the list.
    ||

    shortdesc > Show elements whose label match value.

    // TODO: add optional format/precision argument to support floating points

    path name="value" accepts="HMI_INT,HMI_STRING" > value to compare to labels
    
}

widget_class("MultiState")
    ||
        frequency = 5;
        state = 0;
        dispatch(value) {
            this.state = value;
            for(let choice of this.choices){
                if(this.state != choice.value){
                    choice.elt.setAttribute("style", "display:none");
                } else {
                    choice.elt.setAttribute("style", choice.style);
                }
            }
            // TODO : use RequestAnimate and animate()
        }

        on_click(evt) {
            //get current selected value
            let next_ind;
            for(next_ind=0; next_ind<this.choices.length; next_ind++){
                if(this.state == this.choices[next_ind].value){
                   next_ind = next_ind + 1;
                   break;
                }
            }

            //get next selected value
            if(this.choices.length > next_ind){
                this.state = this.choices[next_ind].value;
            }
            else{
                this.state = this.choices[0].value;
            }

            //post value to plc
            this.apply_hmi_value(0, this.state);
        }

        init() {
            this.element.setAttribute("onclick", "hmi_widgets['"+this.element_id+"'].on_click(evt)");
        }
    ||

widget_defs("MultiState") {
    |     choices: [
    const "regex",!"'^(\"[^\"].*\"|\-?[0-9]+|false|true)(#.*)?$'"!;
    foreach "$result_svg_ns//*[@id = $hmi_element/@id]//*[regexp:test(@inkscape:label,$regex)]" {
        const "literal", "regexp:match(@inkscape:label,$regex)[2]";
    |         {
    |             elt:id("«@id»"),
    |             style:"«@style»",
    |             value:«$literal»
    |         }`if "position()!=last()" > ,`
    }
    |     ],
}