diff -r d723472a18a4 -r 784c839d4259 svghmi/widget_scrollbar.ysl2 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/svghmi/widget_scrollbar.ysl2 Fri Feb 12 22:00:07 2021 +0100 @@ -0,0 +1,106 @@ +// widget_scrollbar.ysl2 + +template "widget[@type='ScrollBar']", mode="widget_class"{ + || + class ScrollBarWidget extends Widget{ + frequency = 5; + position = undefined; + range = undefined; + size = undefined; + mincursize = 0.1; + + dispatch(value,oldval, index) { + switch(index) { + case 0: + if (Math.round(this.position) != value) + this.position = value; + break; + case 1: + this.range = value; + break; + case 2: + this.size = value; + break; + } + + this.request_animate(); + } + + get_ratios() { + let range = this.range; + let size = Math.max(this.range * this.mincursize, Math.min(this.size, range)); + let maxh = this.range_elt.height.baseVal.value; + let pixels = (range - size) * maxh; + let units = range*range; + return [size, maxh, range, pixels, units]; + } + + animate(){ + if(this.position == undefined || this.range == undefined || this.size == undefined) + return; + let [size, maxh, range, pixels, units] = this.get_ratios(); + + let new_y = this.range_elt.y.baseVal.value + Math.round(Math.min(this.position,range) * pixels / units); + let new_height = Math.round(maxh * size/range); + console.log(new_y, new_height); + + this.cursor_elt.y.baseVal.value = new_y; + this.cursor_elt.height.baseVal.value = new_height; + } + + init_mandatory() { + this.cursor_elt.onpointerdown = () => this.on_cursor_down(); + + this.bound_drag = this.drag.bind(this); + this.bound_drop = this.drop.bind(this); + } + + apply_position(position){ + this.position = Math.max(Math.min(position, this.range), 0); + this.apply_hmi_value(0, Math.round(this.position)); + } + + on_page_click(is_up){ + this.apply_position(is_up ? this.position-this.size + : this.position+this.size); + } + + on_cursor_down(e){ + svg_root.addEventListener("pointerup", this.bound_drop, true); + svg_root.addEventListener("pointermove", this.bound_drag, true); + } + + drop(e) { + svg_root.removeEventListener("pointerup", this.bound_drop, true); + svg_root.removeEventListener("pointermove", this.bound_drag, true); + } + + drag(e) { + let [size, maxh, range, pixels, units] = this.get_ratios(); + if(pixels == 0) return; + let matrix = this.range_elt.getCTM().inverse(); + let point = new DOMPoint(e.movementX, e.movementY); + let movement = point.matrixTransform(matrix).y; + this.apply_position(this.position + movement * units / pixels); + } + } + || +} + +template "widget[@type='ScrollBar']", mode="widget_defs" { + param "hmi_element"; + labels("cursor range"); + + const "pagebuttons" optional_labels("pageup pagedown"); + const "have_pagebuttons","string-length($pagebuttons)>0"; + value "$pagebuttons"; + + | init: function() { + | this.init_mandatory(); + + if "$have_pagebuttons" { + | this.pageup_elt.onclick = () => this.on_page_click(true); + | this.pagedown_elt.onclick = () => this.on_page_click(false); + } + | }, +}