svghmi/widget_meter.ysl2
author Edouard Tisserant <edouard.tisserant@gmail.com>
Tue, 22 Mar 2022 14:50:46 +0100
branchwxPython4
changeset 3442 29dbdb09da2e
parent 3330 c3b1a4bfdf0a
permissions -rw-r--r--
Tests: fix project edit test sikuli IDE test.

Background click based on bitmap matching doesn't work.
Grid dots are not good match candidates.
Rendering probably affected by virtual display's bpp or rasterizer approximations.
// widget_meter.ysl2

widget_desc("Meter") {
    longdesc
    ||
    Meter widget moves the end of "needle" labeled path along "range" labeled
    path, according to value of the single accepted variable.

    Needle is reduced to a single segment. If "min" a "max" labeled texts
    are provided, or if first and second argument are given, then they are used
    as respective minimum and maximum value. Otherwise, value is expected to be
    in between 0 and 100.
    ||

    shortdesc > Moves "needle" along "range"

    arg name="min" count="optional" accepts="int,real" > minimum value

    arg name="max" count="optional" accepts="int,real" > maximum value

    path name="value" accepts="HMI_INT,HMI_REAL" > Value to display
    
}

widget_class("Meter"){
    ||
        frequency = 10;
        origin = undefined;
        range = undefined;

        dispatch(value) {
            this.display_val = value;
            this.request_animate();
        }

        animate(){
            if(this.value_elt)
                this.value_elt.textContent = String(this.display_val);
            let [min,max,totallength] = this.range;
            let length = Math.max(0,Math.min(totallength,(Number(this.display_val)-min)*totallength/(max-min)));
            let tip = this.range_elt.getPointAtLength(length);
            this.needle_elt.setAttribute('d', "M "+this.origin.x+","+this.origin.y+" "+tip.x+","+tip.y);
        }

        init() {
            let [min,max] = [[this.min_elt,0],[this.max_elt,100]].map(([elt,def],i)=>elt?
                Number(elt.textContent) :
                this.args.length >= i+1 ? this.args[i] : def);

            this.range = [min, max, this.range_elt.getTotalLength()]
            this.origin = this.needle_elt.getPointAtLength(0);
        }
    ||
}

widget_defs("Meter") {
    labels("needle range");
    optional_labels("min max");
}