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