svghmi/widget_scrollbar.ysl2
changeset 3302 c89fc366bebd
parent 3241 fe945f1f48b7
child 3325 3930916a2e0d
equal deleted inserted replaced
2744:577118ebd179 3302:c89fc366bebd
       
     1 // widget_scrollbar.ysl2
       
     2 widget_desc("ScrollBar") {
       
     3     longdesc
       
     4     || 
       
     5     ScrollBar - documentation to be written
       
     6     ||
       
     7 
       
     8     shortdesc > ScrollBar
       
     9 
       
    10     path name="value" accepts="HMI_INT" > value
       
    11     path name="range" accepts="HMI_INT" > range
       
    12     path name="visible" accepts="HMI_INT" > visible
       
    13     
       
    14 }
       
    15 
       
    16 widget_class("ScrollBar") {
       
    17     ||
       
    18         frequency = 10;
       
    19         position = undefined;
       
    20         range = undefined;
       
    21         size = undefined;
       
    22         mincursize = 0.1;
       
    23 
       
    24         dispatch(value,oldval, index) {
       
    25             switch(index) {
       
    26                 case 0:
       
    27                     this.range = Math.max(1,value);
       
    28                     break;
       
    29                 case 1:
       
    30                     this.position = value;
       
    31                     break;
       
    32                 case 2:
       
    33                     this.size = value;
       
    34                     break;
       
    35             }
       
    36 
       
    37             this.request_animate();
       
    38         }
       
    39 
       
    40         get_ratios() {
       
    41             let range = this.range;
       
    42             let size = Math.max(this.range * this.mincursize, Math.min(this.size, range));
       
    43             let maxh = this.range_elt.height.baseVal.value;
       
    44             let pixels = maxh;
       
    45             let units = range;
       
    46             return [size, maxh, range, pixels, units];
       
    47         }
       
    48 
       
    49         animate(){
       
    50             if(this.position == undefined || this.range == undefined || this.size == undefined)
       
    51                 return;
       
    52             let [size, maxh, range, pixels, units] = this.get_ratios();
       
    53 
       
    54             let new_y = this.range_elt.y.baseVal.value + Math.round(Math.min(this.position,range-size) * pixels / units);
       
    55             let new_height = Math.round(maxh * size/range);
       
    56 
       
    57             this.cursor_elt.y.baseVal.value = new_y;
       
    58             this.cursor_elt.height.baseVal.value = new_height;
       
    59         }
       
    60 
       
    61         init_mandatory() {
       
    62             this.cursor_elt.onpointerdown = () => this.on_cursor_down();
       
    63 
       
    64             this.bound_drag = this.drag.bind(this);
       
    65             this.bound_drop = this.drop.bind(this);
       
    66         }
       
    67 
       
    68         apply_position(position){
       
    69             this.position = Math.round(Math.max(Math.min(position, this.range - this.size), 0));
       
    70             this.apply_hmi_value(1, this.position);
       
    71         }
       
    72 
       
    73         on_page_click(is_up){
       
    74             this.apply_position(is_up ? this.position-this.size
       
    75                                       : this.position+this.size);
       
    76         }
       
    77 
       
    78         on_cursor_down(e){
       
    79             // get scrollbar -> root transform
       
    80             let ctm = this.range_elt.getCTM();
       
    81             // relative motion -> discard translation
       
    82             ctm.e = 0;
       
    83             ctm.f = 0;
       
    84             // root -> scrollbar transform
       
    85             this.invctm = ctm.inverse();
       
    86             svg_root.addEventListener("pointerup", this.bound_drop, true);
       
    87             svg_root.addEventListener("pointermove", this.bound_drag, true);
       
    88             this.dragpos = this.position;
       
    89         }
       
    90 
       
    91         drop(e) {
       
    92             svg_root.removeEventListener("pointerup", this.bound_drop, true);
       
    93             svg_root.removeEventListener("pointermove", this.bound_drag, true);
       
    94         }
       
    95 
       
    96         drag(e) {
       
    97             let [size, maxh, range, pixels, units] = this.get_ratios();
       
    98             if(pixels == 0) return;
       
    99             let point = new DOMPoint(e.movementX, e.movementY);
       
   100             let movement = point.matrixTransform(this.invctm).y;
       
   101             this.dragpos += movement * units / pixels;
       
   102             this.apply_position(this.dragpos);
       
   103         }
       
   104     ||
       
   105 }
       
   106 
       
   107 widget_defs("ScrollBar") {
       
   108     labels("cursor range");
       
   109 
       
   110     const "pagebuttons" optional_labels("pageup pagedown");
       
   111     const "have_pagebuttons","string-length($pagebuttons)>0";
       
   112     value "$pagebuttons";
       
   113 
       
   114     |     init: function() {
       
   115     |         this.init_mandatory();
       
   116 
       
   117     if "$have_pagebuttons" {
       
   118     |         this.pageup_elt.onclick = () => this.on_page_click(true);
       
   119     |         this.pagedown_elt.onclick = () => this.on_page_click(false);
       
   120     }
       
   121     |     },
       
   122 }