--- a/svghmi/gen_index_xhtml.xslt Sun Feb 14 05:29:51 2021 +0100
+++ b/svghmi/gen_index_xhtml.xslt Sun Feb 14 05:30:29 2021 +0100
@@ -1244,6 +1244,8 @@
<xsl:text> cache[new_index] = defaultval;
+ <xsl:text> updates[new_index] = defaultval; <xsl:text> if(persistent_locals.has(varname))
<xsl:text> persistent_indexes.set(new_index, varname);
@@ -1305,6 +1307,14 @@
<xsl:text> Object.keys(members).forEach(prop => this[prop]=members[prop]);
+ <xsl:text> this.lastapply = indexes.map(() => undefined); + <xsl:text> this.inhibit = indexes.map(() => undefined); + <xsl:text> this.pending = indexes.map(() => undefined); + <xsl:text> this.bound_unhinibit = this.unhinibit.bind(this); @@ -1317,6 +1327,20 @@
<xsl:text> for(let i = 0; i < this.indexes.length; i++) {
+ <xsl:text> /* flush updates pending because of inhibition */ + <xsl:text> let inhibition = this.inhibit[index]; + <xsl:text> if(inhibition != undefined){ + <xsl:text> clearTimeout(inhibition); + <xsl:text> this.lastapply[index] = undefined; + <xsl:text> this.unhinibit(index); <xsl:text> let index = this.indexes[i];
<xsl:text> if(this.relativeness[i])
@@ -1471,7 +1495,7 @@
- <xsl:text> apply_hmi_value(index, new_val) {
+ <xsl:text> _apply_hmi_value(index, new_val) { <xsl:text> let realindex = this.get_variable_index(index);
@@ -1485,6 +1509,62 @@
+ <xsl:text> unhinibit(index){ + <xsl:text> this.inhibit[index] = undefined; + <xsl:text> let new_val = this.pending[index]; + <xsl:text> this.pending[index] = undefined; + <xsl:text> return this.apply_hmi_value(index, new_val); + <xsl:text> apply_hmi_value(index, new_val) { + <xsl:text> if(this.inhibit[index] == undefined){ + <xsl:text> let now = Date.now(); + <xsl:text> let min_interval = 1000/this.frequency; + <xsl:text> let lastapply = this.lastapply[index]; + <xsl:text> if(lastapply == undefined || now > lastapply + min_interval){ + <xsl:text> this.lastapply[index] = now; + <xsl:text> return this._apply_hmi_value(index, new_val); + <xsl:text> let elapsed = now - lastapply; + <xsl:text> this.pending[index] = new_val; + <xsl:text> this.inhibit[index] = setTimeout(this.bound_unhinibit, min_interval - elapsed, index); + <xsl:text> this.pending[index] = new_val; + <xsl:text> return new_val; <xsl:text> new_hmi_value(index, value, oldval) {
<xsl:text> // TODO avoid searching, store index at sub()
@@ -5501,6 +5581,214 @@
+ <xsl:template mode="widget_class" match="widget[@type='ScrollBar']"> + <xsl:text>class ScrollBarWidget extends Widget{ + <xsl:text> frequency = 10; + <xsl:text> position = undefined; + <xsl:text> range = undefined; + <xsl:text> size = undefined; + <xsl:text> mincursize = 0.1; + <xsl:text> dispatch(value,oldval, index) { + <xsl:text> switch(index) { + <xsl:text> if (Math.round(this.position) != value) + <xsl:text> this.position = value; + <xsl:text> this.range = value; + <xsl:text> this.size = value; + <xsl:text> this.request_animate(); + <xsl:text> get_ratios() { + <xsl:text> let range = this.range; + <xsl:text> let size = Math.max(this.range * this.mincursize, Math.min(this.size, range)); + <xsl:text> let maxh = this.range_elt.height.baseVal.value; + <xsl:text> let pixels = (range - size) * maxh; + <xsl:text> let units = range*range; + <xsl:text> return [size, maxh, range, pixels, units]; + <xsl:text> if(this.position == undefined || this.range == undefined || this.size == undefined) + <xsl:text> let [size, maxh, range, pixels, units] = this.get_ratios(); + <xsl:text> let new_y = this.range_elt.y.baseVal.value + Math.round(Math.min(this.position,range) * pixels / units); + <xsl:text> let new_height = Math.round(maxh * size/range); + <xsl:text> this.cursor_elt.y.baseVal.value = new_y; + <xsl:text> this.cursor_elt.height.baseVal.value = new_height; + <xsl:text> init_mandatory() { + <xsl:text> this.cursor_elt.onpointerdown = () => this.on_cursor_down(); + <xsl:text> this.bound_drag = this.drag.bind(this); + <xsl:text> this.bound_drop = this.drop.bind(this); + <xsl:text> apply_position(position){ + <xsl:text> this.position = Math.max(Math.min(position, this.range), 0); + <xsl:text> this.apply_hmi_value(0, Math.round(this.position)); + <xsl:text> on_page_click(is_up){ + <xsl:text> this.apply_position(is_up ? this.position-this.size + <xsl:text> : this.position+this.size); + <xsl:text> on_cursor_down(e){ + <xsl:text> // get scrollbar -> root transform + <xsl:text> let ctm = this.range_elt.getCTM(); + <xsl:text> // relative motion -> discard translation + <xsl:text> // root -> scrollbar transform + <xsl:text> this.invctm = ctm.inverse(); + <xsl:text> svg_root.addEventListener("pointerup", this.bound_drop, true); + <xsl:text> svg_root.addEventListener("pointermove", this.bound_drag, true); + <xsl:text> svg_root.removeEventListener("pointerup", this.bound_drop, true); + <xsl:text> svg_root.removeEventListener("pointermove", this.bound_drag, true); + <xsl:text> let [size, maxh, range, pixels, units] = this.get_ratios(); + <xsl:text> if(pixels == 0) return; + <xsl:text> let point = new DOMPoint(e.movementX, e.movementY); + <xsl:text> let movement = point.matrixTransform(this.invctm).y; + <xsl:text> this.apply_position(this.position + movement * units / pixels); + <xsl:template mode="widget_defs" match="widget[@type='ScrollBar']"> + <xsl:param name="hmi_element"/> + <xsl:call-template name="defs_by_labels"> + <xsl:with-param name="hmi_element" select="$hmi_element"/> + <xsl:with-param name="labels"> + <xsl:text>cursor range</xsl:text> + <xsl:variable name="pagebuttons"> + <xsl:call-template name="defs_by_labels"> + <xsl:with-param name="hmi_element" select="$hmi_element"/> + <xsl:with-param name="labels"> + <xsl:text>pageup pagedown</xsl:text> + <xsl:with-param name="mandatory" select="'no'"/> + <xsl:variable name="have_pagebuttons" select="string-length($pagebuttons)>0"/> + <xsl:value-of select="$pagebuttons"/> + <xsl:text> init: function() { + <xsl:text> this.init_mandatory(); + <xsl:if test="$have_pagebuttons"> + <xsl:text> this.pageup_elt.onclick = () => this.on_page_click(true); + <xsl:text> this.pagedown_elt.onclick = () => this.on_page_click(false); <xsl:template mode="widget_class" match="widget[@type='Slider']">
<xsl:text>class SliderWidget extends Widget{
@@ -6964,8 +7252,6 @@
<xsl:text> let varname = persistent_indexes.get(index);
- <xsl:text> console.log(varname+"="+value+"; max-age=3153600000");
<xsl:text> document.cookie = varname+"="+value+"; max-age=3153600000";