diff -r cae53fe54cf2 -r 6d4c1e6560ac svghmi/gen_index_xhtml.xslt
--- 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 @@
cache[new_index] = defaultval;
+ updates[new_index] = defaultval;
+
if(persistent_locals.has(varname))
persistent_indexes.set(new_index, varname);
@@ -1305,6 +1307,14 @@
Object.keys(members).forEach(prop => this[prop]=members[prop]);
+ this.lastapply = indexes.map(() => undefined);
+
+ this.inhibit = indexes.map(() => undefined);
+
+ this.pending = indexes.map(() => undefined);
+
+ this.bound_unhinibit = this.unhinibit.bind(this);
+
}
@@ -1317,6 +1327,20 @@
for(let i = 0; i < this.indexes.length; i++) {
+ /* flush updates pending because of inhibition */
+
+ let inhibition = this.inhibit[index];
+
+ if(inhibition != undefined){
+
+ clearTimeout(inhibition);
+
+ this.lastapply[index] = undefined;
+
+ this.unhinibit(index);
+
+ }
+
let index = this.indexes[i];
if(this.relativeness[i])
@@ -1471,15 +1495,71 @@
+ _apply_hmi_value(index, new_val) {
+
+ let realindex = this.get_variable_index(index);
+
+ if(realindex == undefined) return undefined;
+
+ new_val = this.clip_min_max(index, new_val);
+
+ return apply_hmi_value(realindex, new_val);
+
+ }
+
+
+
+ unhinibit(index){
+
+ this.inhibit[index] = undefined;
+
+ let new_val = this.pending[index];
+
+ this.pending[index] = undefined;
+
+ return this.apply_hmi_value(index, new_val);
+
+ }
+
+
+
apply_hmi_value(index, new_val) {
- let realindex = this.get_variable_index(index);
-
- if(realindex == undefined) return undefined;
-
- new_val = this.clip_min_max(index, new_val);
-
- return apply_hmi_value(realindex, new_val);
+ if(this.inhibit[index] == undefined){
+
+ let now = Date.now();
+
+ let min_interval = 1000/this.frequency;
+
+ let lastapply = this.lastapply[index];
+
+ if(lastapply == undefined || now > lastapply + min_interval){
+
+ this.lastapply[index] = now;
+
+ return this._apply_hmi_value(index, new_val);
+
+ }
+
+ else {
+
+ let elapsed = now - lastapply;
+
+ this.pending[index] = new_val;
+
+ this.inhibit[index] = setTimeout(this.bound_unhinibit, min_interval - elapsed, index);
+
+ }
+
+ }
+
+ else {
+
+ this.pending[index] = new_val;
+
+ return new_val;
+
+ }
}
@@ -5501,6 +5581,214 @@
],
+
+ class ScrollBarWidget extends Widget{
+
+ frequency = 10;
+
+ 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);
+
+
+
+ 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){
+
+ // get scrollbar -> root transform
+
+ let ctm = this.range_elt.getCTM();
+
+ // relative motion -> discard translation
+
+ ctm.e = 0;
+
+ ctm.f = 0;
+
+ // root -> scrollbar transform
+
+ this.invctm = ctm.inverse();
+
+ 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 point = new DOMPoint(e.movementX, e.movementY);
+
+ let movement = point.matrixTransform(this.invctm).y;
+
+ this.apply_position(this.position + movement * units / pixels);
+
+ }
+
+ }
+
+
+
+
+
+
+
+ cursor range
+
+
+
+
+
+
+ pageup pagedown
+
+
+
+
+
+
+ init: function() {
+
+ this.init_mandatory();
+
+
+ this.pageup_elt.onclick = () => this.on_page_click(true);
+
+ this.pagedown_elt.onclick = () => this.on_page_click(false);
+
+
+ },
+
+
class SliderWidget extends Widget{
@@ -6964,8 +7252,6 @@
let varname = persistent_indexes.get(index);
- console.log(varname+"="+value+"; max-age=3153600000");
-
document.cookie = varname+"="+value+"; max-age=3153600000";
}