dgaberscek@2944: // widget_circularbar.ysl2
dgaberscek@2944: 
edouard@3241: widget_desc("CircularBar") {
edouard@3241:     longdesc
edouard@3241:     ||
edouard@3241:     CircularBar widget changes the end angle of a "path" labeled arc according
edouard@3241:     to value of the single accepted variable.
edouard@3241: 
edouard@3241:     If "min" a "max" labeled texts are provided, then they are used as
edouard@3241:     respective minimum and maximum value. Otherwise, value is expected to be
edouard@3241:     in between 0 and 100.
edouard@3241:     ||
edouard@3241: 
edouard@3241:     shortdesc > Change end angle of Inkscape's arc
edouard@3241: 
edouard@3330:     arg name="min" count="optional" accepts="int,real" > minimum value
edouard@3330:     arg name="max" count="optional" accepts="int,real" > maximum value
edouard@3241: 
edouard@3241:     path name="value" accepts="HMI_INT,HMI_REAL" > Value to display
edouard@3241:     
edouard@3241: }
edouard@3232: widget_class("CircularBar") {
usveticic@3045:     ||
usveticic@3045:         frequency = 10;
usveticic@3045:         range = undefined;
usveticic@3045: 
usveticic@3045:         dispatch(value) {
edouard@3105:             this.display_val = value;
edouard@3105:             this.request_animate();
edouard@3105:         }
edouard@3105: 
edouard@3105:         animate(){
usveticic@3045:             if(this.value_elt)
edouard@3105:                 this.value_elt.textContent = String(this.display_val);
usveticic@3045:             let [min,max,start,end] = this.range;
usveticic@3045:             let [cx,cy] = this.center;
usveticic@3045:             let [rx,ry] = this.proportions;
edouard@3105:             let tip = start + (end-start)*Number(this.display_val)/(max-min);
usveticic@3045:             let size = 0;
edouard@3105: 
edouard@3105:             if (tip-start > Math.PI)
usveticic@3045:                 size = 1;
edouard@3105:             else
usveticic@3045:                 size = 0;
edouard@3105: 
edouard@3105:             this.path_elt.setAttribute('d', "M "+(cx+rx*Math.cos(start))+","+(cy+ry*Math.sin(start))+
edouard@3105:                                             " A "+rx+","+ry+
edouard@3105:                                             " 0 "+size+
edouard@3105:                                             " 1 "+(cx+rx*Math.cos(tip))+","+(cy+ry*Math.sin(tip)));
usveticic@3045:         }
usveticic@3045: 
usveticic@3045:         init() {
edouard@3330:             if(this.args.length >= 2)
edouard@3330:                 [this.min, this.max]=this.args;
edouard@3330: 
edouard@3105:             let [start, end, cx, cy, rx, ry] = ["start", "end", "cx", "cy", "rx", "ry"].
edouard@3105:                 map(tag=>Number(this.path_elt.getAttribute('sodipodi:'+tag)))
edouard@3105: 
edouard@3105:             if (ry == 0) 
usveticic@3045:                 ry = rx;
edouard@3105: 
edouard@3105:             if (start > end)
usveticic@3045:                 end = end + 2*Math.PI;
edouard@3105: 
edouard@3105:             let [min,max] = [[this.min_elt,0],[this.max_elt,100]].map(([elt,def],i)=>elt?
edouard@3105:                 Number(elt.textContent) :
edouard@3105:                 this.args.length >= i+1 ? this.args[i] : def);
edouard@3105: 
usveticic@3045:             this.range = [min, max, start, end];
usveticic@3045:             this.center = [cx, cy];
usveticic@3045:             this.proportions = [rx, ry];
usveticic@3045:         }
usveticic@3045:     ||
usveticic@3045: }
dgaberscek@2944: 
edouard@3232: widget_defs("CircularBar") {
dgaberscek@2944:     labels("path");
edouard@3330:     optional_labels("min max");
edouard@3105: }