svghmi/widget_circularslider.ysl2
author Edouard Tisserant
Mon, 10 Aug 2020 13:58:55 +0200
branchsvghmi
changeset 3019 497aac6522a3
parent 3018 22b969b409b0
child 3045 f6d428330e04
permissions -rw-r--r--
SVGHMI: provide request_animate() to Widget authors so that they can register redraw code when events lead to redraw. Widget member animate() is called when it is time to update DOM.
3013
0ea6b4f435de Create new CircularSlider widget which extand class widget
usveticic
parents:
diff changeset
     1
// widget_circuralslider.ysl2
0ea6b4f435de Create new CircularSlider widget which extand class widget
usveticic
parents:
diff changeset
     2
0ea6b4f435de Create new CircularSlider widget which extand class widget
usveticic
parents:
diff changeset
     3
template "widget[@type='CircularSlider']", mode="widget_class"
0ea6b4f435de Create new CircularSlider widget which extand class widget
usveticic
parents:
diff changeset
     4
    ||
0ea6b4f435de Create new CircularSlider widget which extand class widget
usveticic
parents:
diff changeset
     5
    class CircularSliderWidget extends Widget{
0ea6b4f435de Create new CircularSlider widget which extand class widget
usveticic
parents:
diff changeset
     6
        frequency = 5;
0ea6b4f435de Create new CircularSlider widget which extand class widget
usveticic
parents:
diff changeset
     7
        range = undefined;
0ea6b4f435de Create new CircularSlider widget which extand class widget
usveticic
parents:
diff changeset
     8
        circle = undefined;
0ea6b4f435de Create new CircularSlider widget which extand class widget
usveticic
parents:
diff changeset
     9
        handle_pos = undefined;
0ea6b4f435de Create new CircularSlider widget which extand class widget
usveticic
parents:
diff changeset
    10
        drag = false;
0ea6b4f435de Create new CircularSlider widget which extand class widget
usveticic
parents:
diff changeset
    11
        enTimer = false;
0ea6b4f435de Create new CircularSlider widget which extand class widget
usveticic
parents:
diff changeset
    12
0ea6b4f435de Create new CircularSlider widget which extand class widget
usveticic
parents:
diff changeset
    13
        dispatch(value) {
0ea6b4f435de Create new CircularSlider widget which extand class widget
usveticic
parents:
diff changeset
    14
            if(!this.drag){
0ea6b4f435de Create new CircularSlider widget which extand class widget
usveticic
parents:
diff changeset
    15
                if(this.value_elt)
0ea6b4f435de Create new CircularSlider widget which extand class widget
usveticic
parents:
diff changeset
    16
                    this.value_elt.textContent = String(value);
0ea6b4f435de Create new CircularSlider widget which extand class widget
usveticic
parents:
diff changeset
    17
0ea6b4f435de Create new CircularSlider widget which extand class widget
usveticic
parents:
diff changeset
    18
                this.handle_position(value);
0ea6b4f435de Create new CircularSlider widget which extand class widget
usveticic
parents:
diff changeset
    19
            }
0ea6b4f435de Create new CircularSlider widget which extand class widget
usveticic
parents:
diff changeset
    20
        }
0ea6b4f435de Create new CircularSlider widget which extand class widget
usveticic
parents:
diff changeset
    21
0ea6b4f435de Create new CircularSlider widget which extand class widget
usveticic
parents:
diff changeset
    22
        handle_position(value){
0ea6b4f435de Create new CircularSlider widget which extand class widget
usveticic
parents:
diff changeset
    23
            let [min,max,totalDistance] = this.range;
0ea6b4f435de Create new CircularSlider widget which extand class widget
usveticic
parents:
diff changeset
    24
            let length = Math.max(0,Math.min((totalDistance),(Number(value)-min)/(max-min)*(totalDistance)));
0ea6b4f435de Create new CircularSlider widget which extand class widget
usveticic
parents:
diff changeset
    25
            let tip = this.range_elt.getPointAtLength(length);
0ea6b4f435de Create new CircularSlider widget which extand class widget
usveticic
parents:
diff changeset
    26
            this.handle_elt.setAttribute('transform',"translate("+(tip.x-this.handle_pos.x)+","+(tip.y-this.handle_pos.y)+")");
0ea6b4f435de Create new CircularSlider widget which extand class widget
usveticic
parents:
diff changeset
    27
        }
0ea6b4f435de Create new CircularSlider widget which extand class widget
usveticic
parents:
diff changeset
    28
0ea6b4f435de Create new CircularSlider widget which extand class widget
usveticic
parents:
diff changeset
    29
        on_release(evt) {
0ea6b4f435de Create new CircularSlider widget which extand class widget
usveticic
parents:
diff changeset
    30
            if(this.drag){
0ea6b4f435de Create new CircularSlider widget which extand class widget
usveticic
parents:
diff changeset
    31
                this.drag = false;
0ea6b4f435de Create new CircularSlider widget which extand class widget
usveticic
parents:
diff changeset
    32
            }
0ea6b4f435de Create new CircularSlider widget which extand class widget
usveticic
parents:
diff changeset
    33
        }
0ea6b4f435de Create new CircularSlider widget which extand class widget
usveticic
parents:
diff changeset
    34
0ea6b4f435de Create new CircularSlider widget which extand class widget
usveticic
parents:
diff changeset
    35
        update_position(evt){
0ea6b4f435de Create new CircularSlider widget which extand class widget
usveticic
parents:
diff changeset
    36
            if(this.drag && this.enTimer){
0ea6b4f435de Create new CircularSlider widget which extand class widget
usveticic
parents:
diff changeset
    37
                var svg_dist = 0;
0ea6b4f435de Create new CircularSlider widget which extand class widget
usveticic
parents:
diff changeset
    38
0ea6b4f435de Create new CircularSlider widget which extand class widget
usveticic
parents:
diff changeset
    39
                //calculate center of widget in html
0ea6b4f435de Create new CircularSlider widget which extand class widget
usveticic
parents:
diff changeset
    40
                // --TODO maybe it would be better to bind this part to window change size event ???
0ea6b4f435de Create new CircularSlider widget which extand class widget
usveticic
parents:
diff changeset
    41
                let [xdest,ydest,svgWidth,svgHeight] = page_desc[current_visible_page].bbox;
0ea6b4f435de Create new CircularSlider widget which extand class widget
usveticic
parents:
diff changeset
    42
                let [cX, cY,fiStart,fiEnd,minMax,x1,y1,width,height] = this.circle;
0ea6b4f435de Create new CircularSlider widget which extand class widget
usveticic
parents:
diff changeset
    43
                let htmlCirc = this.range_elt.getBoundingClientRect();
0ea6b4f435de Create new CircularSlider widget which extand class widget
usveticic
parents:
diff changeset
    44
                let cxHtml = ((htmlCirc.right-htmlCirc.left)/(width)*(cX-x1))+htmlCirc.left;
0ea6b4f435de Create new CircularSlider widget which extand class widget
usveticic
parents:
diff changeset
    45
                let cyHtml = ((htmlCirc.bottom-htmlCirc.top)/(height)*(cY-y1))+htmlCirc.top;
0ea6b4f435de Create new CircularSlider widget which extand class widget
usveticic
parents:
diff changeset
    46
0ea6b4f435de Create new CircularSlider widget which extand class widget
usveticic
parents:
diff changeset
    47
0ea6b4f435de Create new CircularSlider widget which extand class widget
usveticic
parents:
diff changeset
    48
                //get mouse coordinates
0ea6b4f435de Create new CircularSlider widget which extand class widget
usveticic
parents:
diff changeset
    49
                let mouseX = undefined;
0ea6b4f435de Create new CircularSlider widget which extand class widget
usveticic
parents:
diff changeset
    50
                let mouseY = undefined;
0ea6b4f435de Create new CircularSlider widget which extand class widget
usveticic
parents:
diff changeset
    51
                if (evt.type.startsWith("touch")){
0ea6b4f435de Create new CircularSlider widget which extand class widget
usveticic
parents:
diff changeset
    52
                    mouseX = Math.ceil(evt.touches[0].clientX);
0ea6b4f435de Create new CircularSlider widget which extand class widget
usveticic
parents:
diff changeset
    53
                    mouseY = Math.ceil(evt.touches[0].clientY);
0ea6b4f435de Create new CircularSlider widget which extand class widget
usveticic
parents:
diff changeset
    54
                }
0ea6b4f435de Create new CircularSlider widget which extand class widget
usveticic
parents:
diff changeset
    55
                else{
0ea6b4f435de Create new CircularSlider widget which extand class widget
usveticic
parents:
diff changeset
    56
                    mouseX = evt.pageX;
0ea6b4f435de Create new CircularSlider widget which extand class widget
usveticic
parents:
diff changeset
    57
                    mouseY = evt.pageY;
0ea6b4f435de Create new CircularSlider widget which extand class widget
usveticic
parents:
diff changeset
    58
                }
0ea6b4f435de Create new CircularSlider widget which extand class widget
usveticic
parents:
diff changeset
    59
0ea6b4f435de Create new CircularSlider widget which extand class widget
usveticic
parents:
diff changeset
    60
                //calculate angle
0ea6b4f435de Create new CircularSlider widget which extand class widget
usveticic
parents:
diff changeset
    61
                let fi = Math.atan2(cyHtml-mouseY, mouseX-cxHtml);
0ea6b4f435de Create new CircularSlider widget which extand class widget
usveticic
parents:
diff changeset
    62
0ea6b4f435de Create new CircularSlider widget which extand class widget
usveticic
parents:
diff changeset
    63
                // transform from 0 to 2PI
0ea6b4f435de Create new CircularSlider widget which extand class widget
usveticic
parents:
diff changeset
    64
                if (fi > 0){
0ea6b4f435de Create new CircularSlider widget which extand class widget
usveticic
parents:
diff changeset
    65
                    fi = 2*Math.PI-fi;
0ea6b4f435de Create new CircularSlider widget which extand class widget
usveticic
parents:
diff changeset
    66
                }
0ea6b4f435de Create new CircularSlider widget which extand class widget
usveticic
parents:
diff changeset
    67
                else{
0ea6b4f435de Create new CircularSlider widget which extand class widget
usveticic
parents:
diff changeset
    68
                    fi = -fi;
0ea6b4f435de Create new CircularSlider widget which extand class widget
usveticic
parents:
diff changeset
    69
                }
0ea6b4f435de Create new CircularSlider widget which extand class widget
usveticic
parents:
diff changeset
    70
0ea6b4f435de Create new CircularSlider widget which extand class widget
usveticic
parents:
diff changeset
    71
                //offset it to 0
0ea6b4f435de Create new CircularSlider widget which extand class widget
usveticic
parents:
diff changeset
    72
                fi = fi - fiStart;
0ea6b4f435de Create new CircularSlider widget which extand class widget
usveticic
parents:
diff changeset
    73
                if (fi < 0){
0ea6b4f435de Create new CircularSlider widget which extand class widget
usveticic
parents:
diff changeset
    74
                    fi = fi + 2*Math.PI;
0ea6b4f435de Create new CircularSlider widget which extand class widget
usveticic
parents:
diff changeset
    75
                }
0ea6b4f435de Create new CircularSlider widget which extand class widget
usveticic
parents:
diff changeset
    76
0ea6b4f435de Create new CircularSlider widget which extand class widget
usveticic
parents:
diff changeset
    77
                //get handle distance from mouse position
0ea6b4f435de Create new CircularSlider widget which extand class widget
usveticic
parents:
diff changeset
    78
                if(fi<fiEnd){
0ea6b4f435de Create new CircularSlider widget which extand class widget
usveticic
parents:
diff changeset
    79
                    svg_dist=(fi)/(fiEnd)*(this.range[1]-this.range[0]);
0ea6b4f435de Create new CircularSlider widget which extand class widget
usveticic
parents:
diff changeset
    80
                }
0ea6b4f435de Create new CircularSlider widget which extand class widget
usveticic
parents:
diff changeset
    81
                else if(fiEnd<fi && fi<fiEnd+minMax){
0ea6b4f435de Create new CircularSlider widget which extand class widget
usveticic
parents:
diff changeset
    82
                    svg_dist = this.range[1];
0ea6b4f435de Create new CircularSlider widget which extand class widget
usveticic
parents:
diff changeset
    83
                }
0ea6b4f435de Create new CircularSlider widget which extand class widget
usveticic
parents:
diff changeset
    84
                else{
0ea6b4f435de Create new CircularSlider widget which extand class widget
usveticic
parents:
diff changeset
    85
                    svg_dist = this.range[0];
0ea6b4f435de Create new CircularSlider widget which extand class widget
usveticic
parents:
diff changeset
    86
                }
0ea6b4f435de Create new CircularSlider widget which extand class widget
usveticic
parents:
diff changeset
    87
0ea6b4f435de Create new CircularSlider widget which extand class widget
usveticic
parents:
diff changeset
    88
                //redraw handle --TODO is it fast enough if I just call change_hmi_value???
0ea6b4f435de Create new CircularSlider widget which extand class widget
usveticic
parents:
diff changeset
    89
                this.handle_position(svg_dist);
0ea6b4f435de Create new CircularSlider widget which extand class widget
usveticic
parents:
diff changeset
    90
                if(this.value_elt)
0ea6b4f435de Create new CircularSlider widget which extand class widget
usveticic
parents:
diff changeset
    91
                    this.value_elt.textContent = String(Math.ceil(svg_dist));
3018
Edouard Tisserant
parents: 3013
diff changeset
    92
                this.apply_hmi_value(0, Math.ceil(svg_dist));
3013
0ea6b4f435de Create new CircularSlider widget which extand class widget
usveticic
parents:
diff changeset
    93
0ea6b4f435de Create new CircularSlider widget which extand class widget
usveticic
parents:
diff changeset
    94
                //reset timer
0ea6b4f435de Create new CircularSlider widget which extand class widget
usveticic
parents:
diff changeset
    95
                this.enTimer = false;
0ea6b4f435de Create new CircularSlider widget which extand class widget
usveticic
parents:
diff changeset
    96
                setTimeout("{hmi_widgets['"+this.element_id+"'].enTimer = true;}", 100);
0ea6b4f435de Create new CircularSlider widget which extand class widget
usveticic
parents:
diff changeset
    97
            }
0ea6b4f435de Create new CircularSlider widget which extand class widget
usveticic
parents:
diff changeset
    98
0ea6b4f435de Create new CircularSlider widget which extand class widget
usveticic
parents:
diff changeset
    99
        }
0ea6b4f435de Create new CircularSlider widget which extand class widget
usveticic
parents:
diff changeset
   100
0ea6b4f435de Create new CircularSlider widget which extand class widget
usveticic
parents:
diff changeset
   101
        on_select(evt){
0ea6b4f435de Create new CircularSlider widget which extand class widget
usveticic
parents:
diff changeset
   102
            this.drag = true;
0ea6b4f435de Create new CircularSlider widget which extand class widget
usveticic
parents:
diff changeset
   103
            this.enTimer = true;
0ea6b4f435de Create new CircularSlider widget which extand class widget
usveticic
parents:
diff changeset
   104
            this.update_position(evt);
0ea6b4f435de Create new CircularSlider widget which extand class widget
usveticic
parents:
diff changeset
   105
        }
0ea6b4f435de Create new CircularSlider widget which extand class widget
usveticic
parents:
diff changeset
   106
0ea6b4f435de Create new CircularSlider widget which extand class widget
usveticic
parents:
diff changeset
   107
        init() {
0ea6b4f435de Create new CircularSlider widget which extand class widget
usveticic
parents:
diff changeset
   108
            //get min max
0ea6b4f435de Create new CircularSlider widget which extand class widget
usveticic
parents:
diff changeset
   109
            let min = this.min_elt ?
0ea6b4f435de Create new CircularSlider widget which extand class widget
usveticic
parents:
diff changeset
   110
                        Number(this.min_elt.textContent) :
0ea6b4f435de Create new CircularSlider widget which extand class widget
usveticic
parents:
diff changeset
   111
                        this.args.length >= 1 ? this.args[0] : 0;
0ea6b4f435de Create new CircularSlider widget which extand class widget
usveticic
parents:
diff changeset
   112
            let max = this.max_elt ?
0ea6b4f435de Create new CircularSlider widget which extand class widget
usveticic
parents:
diff changeset
   113
                        Number(this.max_elt.textContent) :
0ea6b4f435de Create new CircularSlider widget which extand class widget
usveticic
parents:
diff changeset
   114
                        this.args.length >= 2 ? this.args[1] : 100;
0ea6b4f435de Create new CircularSlider widget which extand class widget
usveticic
parents:
diff changeset
   115
0ea6b4f435de Create new CircularSlider widget which extand class widget
usveticic
parents:
diff changeset
   116
            //fiStart ==> offset
0ea6b4f435de Create new CircularSlider widget which extand class widget
usveticic
parents:
diff changeset
   117
            let fiStart = Number(this.range_elt.getAttribute('sodipodi:start'));
0ea6b4f435de Create new CircularSlider widget which extand class widget
usveticic
parents:
diff changeset
   118
            let fiEnd = Number(this.range_elt.getAttribute('sodipodi:end'));
0ea6b4f435de Create new CircularSlider widget which extand class widget
usveticic
parents:
diff changeset
   119
            fiEnd = fiEnd - fiStart;
0ea6b4f435de Create new CircularSlider widget which extand class widget
usveticic
parents:
diff changeset
   120
0ea6b4f435de Create new CircularSlider widget which extand class widget
usveticic
parents:
diff changeset
   121
            //fiEnd ==> size of angle
0ea6b4f435de Create new CircularSlider widget which extand class widget
usveticic
parents:
diff changeset
   122
            if (fiEnd < 0){
0ea6b4f435de Create new CircularSlider widget which extand class widget
usveticic
parents:
diff changeset
   123
                fiEnd = 2*Math.PI + fiEnd;
0ea6b4f435de Create new CircularSlider widget which extand class widget
usveticic
parents:
diff changeset
   124
            }
0ea6b4f435de Create new CircularSlider widget which extand class widget
usveticic
parents:
diff changeset
   125
0ea6b4f435de Create new CircularSlider widget which extand class widget
usveticic
parents:
diff changeset
   126
            //min max barrier angle
0ea6b4f435de Create new CircularSlider widget which extand class widget
usveticic
parents:
diff changeset
   127
            let minMax = (2*Math.PI - fiEnd)/2;
0ea6b4f435de Create new CircularSlider widget which extand class widget
usveticic
parents:
diff changeset
   128
0ea6b4f435de Create new CircularSlider widget which extand class widget
usveticic
parents:
diff changeset
   129
            //get parameters from svg
0ea6b4f435de Create new CircularSlider widget which extand class widget
usveticic
parents:
diff changeset
   130
            let cX = Number(this.range_elt.getAttribute('sodipodi:cx'));
0ea6b4f435de Create new CircularSlider widget which extand class widget
usveticic
parents:
diff changeset
   131
            let cY = Number(this.range_elt.getAttribute('sodipodi:cy'));
0ea6b4f435de Create new CircularSlider widget which extand class widget
usveticic
parents:
diff changeset
   132
            this.range_elt.style.strokeMiterlimit="0"; //eliminates some weird border around html object
0ea6b4f435de Create new CircularSlider widget which extand class widget
usveticic
parents:
diff changeset
   133
            this.range = [min, max,this.range_elt.getTotalLength()];
0ea6b4f435de Create new CircularSlider widget which extand class widget
usveticic
parents:
diff changeset
   134
            let cPos = this.range_elt.getBBox();
0ea6b4f435de Create new CircularSlider widget which extand class widget
usveticic
parents:
diff changeset
   135
            this.handle_pos = this.range_elt.getPointAtLength(0);
0ea6b4f435de Create new CircularSlider widget which extand class widget
usveticic
parents:
diff changeset
   136
            this.circle = [cX, cY,fiStart,fiEnd,minMax,cPos.x,cPos.y,cPos.width,cPos.height];
0ea6b4f435de Create new CircularSlider widget which extand class widget
usveticic
parents:
diff changeset
   137
0ea6b4f435de Create new CircularSlider widget which extand class widget
usveticic
parents:
diff changeset
   138
            //init events
0ea6b4f435de Create new CircularSlider widget which extand class widget
usveticic
parents:
diff changeset
   139
            this.handle_elt.addEventListener("touchstart", hmi_widgets[this.element_id].on_select.bind(this));
0ea6b4f435de Create new CircularSlider widget which extand class widget
usveticic
parents:
diff changeset
   140
            this.handle_elt.addEventListener("mousedown", hmi_widgets[this.element_id].on_select.bind(this));
0ea6b4f435de Create new CircularSlider widget which extand class widget
usveticic
parents:
diff changeset
   141
            this.element.addEventListener("mousedown", hmi_widgets[this.element_id].on_select.bind(this));
0ea6b4f435de Create new CircularSlider widget which extand class widget
usveticic
parents:
diff changeset
   142
0ea6b4f435de Create new CircularSlider widget which extand class widget
usveticic
parents:
diff changeset
   143
            window.addEventListener("touchmove", hmi_widgets[this.element_id].update_position.bind(this));
0ea6b4f435de Create new CircularSlider widget which extand class widget
usveticic
parents:
diff changeset
   144
            window.addEventListener("mousemove", hmi_widgets[this.element_id].update_position.bind(this));
0ea6b4f435de Create new CircularSlider widget which extand class widget
usveticic
parents:
diff changeset
   145
0ea6b4f435de Create new CircularSlider widget which extand class widget
usveticic
parents:
diff changeset
   146
            window.addEventListener("mouseup", hmi_widgets[this.element_id].on_release.bind(this))
0ea6b4f435de Create new CircularSlider widget which extand class widget
usveticic
parents:
diff changeset
   147
            window.addEventListener("touchend", hmi_widgets[this.element_id].on_release.bind(this));
0ea6b4f435de Create new CircularSlider widget which extand class widget
usveticic
parents:
diff changeset
   148
            window.addEventListener("touchcancel", hmi_widgets[this.element_id].on_release.bind(this));
0ea6b4f435de Create new CircularSlider widget which extand class widget
usveticic
parents:
diff changeset
   149
0ea6b4f435de Create new CircularSlider widget which extand class widget
usveticic
parents:
diff changeset
   150
        }
0ea6b4f435de Create new CircularSlider widget which extand class widget
usveticic
parents:
diff changeset
   151
    }
0ea6b4f435de Create new CircularSlider widget which extand class widget
usveticic
parents:
diff changeset
   152
    ||
0ea6b4f435de Create new CircularSlider widget which extand class widget
usveticic
parents:
diff changeset
   153
0ea6b4f435de Create new CircularSlider widget which extand class widget
usveticic
parents:
diff changeset
   154
template "widget[@type='CircularSlider']", mode="widget_defs" {
0ea6b4f435de Create new CircularSlider widget which extand class widget
usveticic
parents:
diff changeset
   155
    param "hmi_element";
0ea6b4f435de Create new CircularSlider widget which extand class widget
usveticic
parents:
diff changeset
   156
    labels("handle range");
0ea6b4f435de Create new CircularSlider widget which extand class widget
usveticic
parents:
diff changeset
   157
    optional_labels("value min max");
0ea6b4f435de Create new CircularSlider widget which extand class widget
usveticic
parents:
diff changeset
   158
    |,
3018
Edouard Tisserant
parents: 3013
diff changeset
   159
}