edouard@3136: // widget_scrollbar.ysl2 edouard@3136: edouard@3136: template "widget[@type='ScrollBar']", mode="widget_class"{ edouard@3136: || edouard@3136: class ScrollBarWidget extends Widget{ edouard@3139: frequency = 10; edouard@3136: position = undefined; edouard@3136: range = undefined; edouard@3136: size = undefined; edouard@3136: mincursize = 0.1; edouard@3136: edouard@3136: dispatch(value,oldval, index) { edouard@3136: switch(index) { edouard@3136: case 0: edouard@3136: if (Math.round(this.position) != value) edouard@3136: this.position = value; edouard@3136: break; edouard@3136: case 1: edouard@3136: this.range = value; edouard@3136: break; edouard@3136: case 2: edouard@3136: this.size = value; edouard@3136: break; edouard@3136: } edouard@3136: edouard@3136: this.request_animate(); edouard@3136: } edouard@3136: edouard@3136: get_ratios() { edouard@3136: let range = this.range; edouard@3136: let size = Math.max(this.range * this.mincursize, Math.min(this.size, range)); edouard@3136: let maxh = this.range_elt.height.baseVal.value; edouard@3136: let pixels = (range - size) * maxh; edouard@3136: let units = range*range; edouard@3136: return [size, maxh, range, pixels, units]; edouard@3136: } edouard@3136: edouard@3136: animate(){ edouard@3136: if(this.position == undefined || this.range == undefined || this.size == undefined) edouard@3136: return; edouard@3136: let [size, maxh, range, pixels, units] = this.get_ratios(); edouard@3136: edouard@3136: let new_y = this.range_elt.y.baseVal.value + Math.round(Math.min(this.position,range) * pixels / units); edouard@3136: let new_height = Math.round(maxh * size/range); edouard@3136: edouard@3136: this.cursor_elt.y.baseVal.value = new_y; edouard@3136: this.cursor_elt.height.baseVal.value = new_height; edouard@3136: } edouard@3136: edouard@3136: init_mandatory() { edouard@3136: this.cursor_elt.onpointerdown = () => this.on_cursor_down(); edouard@3136: edouard@3136: this.bound_drag = this.drag.bind(this); edouard@3136: this.bound_drop = this.drop.bind(this); edouard@3136: } edouard@3136: edouard@3136: apply_position(position){ edouard@3136: this.position = Math.max(Math.min(position, this.range), 0); edouard@3136: this.apply_hmi_value(0, Math.round(this.position)); edouard@3136: } edouard@3136: edouard@3136: on_page_click(is_up){ edouard@3136: this.apply_position(is_up ? this.position-this.size edouard@3136: : this.position+this.size); edouard@3136: } edouard@3136: edouard@3136: on_cursor_down(e){ edouard@3138: // get scrollbar -> root transform edouard@3138: let ctm = this.range_elt.getCTM(); edouard@3138: // relative motion -> discard translation edouard@3138: ctm.e = 0; edouard@3138: ctm.f = 0; edouard@3138: // root -> scrollbar transform edouard@3138: this.invctm = ctm.inverse(); edouard@3136: svg_root.addEventListener("pointerup", this.bound_drop, true); edouard@3136: svg_root.addEventListener("pointermove", this.bound_drag, true); edouard@3136: } edouard@3136: edouard@3136: drop(e) { edouard@3136: svg_root.removeEventListener("pointerup", this.bound_drop, true); edouard@3136: svg_root.removeEventListener("pointermove", this.bound_drag, true); edouard@3136: } edouard@3136: edouard@3136: drag(e) { edouard@3136: let [size, maxh, range, pixels, units] = this.get_ratios(); edouard@3136: if(pixels == 0) return; edouard@3136: let point = new DOMPoint(e.movementX, e.movementY); edouard@3138: let movement = point.matrixTransform(this.invctm).y; edouard@3136: this.apply_position(this.position + movement * units / pixels); edouard@3136: } edouard@3136: } edouard@3136: || edouard@3136: } edouard@3136: edouard@3136: template "widget[@type='ScrollBar']", mode="widget_defs" { edouard@3136: param "hmi_element"; edouard@3136: labels("cursor range"); edouard@3136: edouard@3136: const "pagebuttons" optional_labels("pageup pagedown"); edouard@3136: const "have_pagebuttons","string-length($pagebuttons)>0"; edouard@3136: value "$pagebuttons"; edouard@3136: edouard@3136: | init: function() { edouard@3136: | this.init_mandatory(); edouard@3136: edouard@3136: if "$have_pagebuttons" { edouard@3136: | this.pageup_elt.onclick = () => this.on_page_click(true); edouard@3136: | this.pagedown_elt.onclick = () => this.on_page_click(false); edouard@3136: } edouard@3136: | }, edouard@3136: }